Add cipher and hash options to luks_create (#97)

pull/102/head
Arnoways 2020-08-13 22:17:36 +02:00 committed by GitHub
parent 7f6db5c4d9
commit e4c12fa4e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 22 deletions

View File

@ -0,0 +1,2 @@
minor_changes:
- "luks_device - add support for encryption options on container creation (https://github.com/ansible-collections/community.crypto/pull/97)."

View File

@ -152,6 +152,22 @@ options:
type: str type: str
choices: [luks1, luks2] choices: [luks1, luks2]
version_added: '1.0.0' version_added: '1.0.0'
cipher:
description:
- "This option allows the user to define the cipher specification
string for the LUKS container."
- "Will only be used on container creation."
- "For pre-2.6.10 kernels, use C(aes-plain) as they don't understand
the new cipher spec strings. To use ESSIV, use C(aes-cbc-essiv:sha256)."
type: str
version_added: '1.1.0'
hash:
description:
- "This option allows the user to specify the hash function used in LUKS
key setup scheme and volume key digest."
- "Will only be used on container creation."
type: str
version_added: '1.1.0'
requirements: requirements:
- "cryptsetup" - "cryptsetup"
@ -176,6 +192,13 @@ EXAMPLES = '''
state: "present" state: "present"
passphrase: "foo" passphrase: "foo"
- name: Create LUKS container with specific encryption
community.crypto.luks_device:
device: "/dev/loop0"
state: "present"
cipher: "aes"
hash: "sha256"
- name: (Create and) open the LUKS container; name it "mycrypt" - name: (Create and) open the LUKS container; name it "mycrypt"
community.crypto.luks_device: community.crypto.luks_device:
device: "/dev/loop0" device: "/dev/loop0"
@ -374,7 +397,7 @@ class CryptHandler(Handler):
result = self._run_command([self._cryptsetup_bin, 'isLuks', device]) result = self._run_command([self._cryptsetup_bin, 'isLuks', device])
return result[RETURN_CODE] == 0 return result[RETURN_CODE] == 0
def run_luks_create(self, device, keyfile, passphrase, keysize): def run_luks_create(self, device, keyfile, passphrase, keysize, cipher, hash_):
# create a new luks container; use batch mode to auto confirm # create a new luks container; use batch mode to auto confirm
luks_type = self._module.params['type'] luks_type = self._module.params['type']
label = self._module.params['label'] label = self._module.params['label']
@ -387,6 +410,10 @@ class CryptHandler(Handler):
luks_type = 'luks2' luks_type = 'luks2'
if luks_type is not None: if luks_type is not None:
options.extend(['--type', luks_type]) options.extend(['--type', luks_type])
if cipher is not None:
options.extend(['--cipher', cipher])
if hash_ is not None:
options.extend(['--hash', hash_])
args = [self._cryptsetup_bin, 'luksFormat'] args = [self._cryptsetup_bin, 'luksFormat']
args.extend(options) args.extend(options)
@ -638,6 +665,8 @@ def run_module():
label=dict(type='str'), label=dict(type='str'),
uuid=dict(type='str'), uuid=dict(type='str'),
type=dict(type='str', choices=['luks1', 'luks2']), type=dict(type='str', choices=['luks1', 'luks2']),
cipher=dict(type='str'),
hash=dict(type='str'),
) )
mutually_exclusive = [ mutually_exclusive = [
@ -682,7 +711,10 @@ def run_module():
crypt.run_luks_create(conditions.device, crypt.run_luks_create(conditions.device,
module.params['keyfile'], module.params['keyfile'],
module.params['passphrase'], module.params['passphrase'],
module.params['keysize']) module.params['keysize'],
module.params['cipher'],
module.params['hash'],
)
except ValueError as e: except ValueError as e:
module.fail_json(msg="luks_device error: %s" % e) module.fail_json(msg="luks_device error: %s" % e)
result['changed'] = True result['changed'] = True

View File

@ -64,24 +64,27 @@ def test_run_luks_remove(monkeypatch):
# ===== ConditionsHandler methods data and tests ===== # ===== ConditionsHandler methods data and tests =====
# device, key, passphrase, state, is_luks, label, expected # device, key, passphrase, state, is_luks, label, cipher, hash, expected
LUKS_CREATE_DATA = ( LUKS_CREATE_DATA = (
("dummy", "key", None, "present", False, None, True), ("dummy", "key", None, "present", False, None, "dummy", "dummy", True),
(None, "key", None, "present", False, None, False), (None, "key", None, "present", False, None, "dummy", "dummy", False),
(None, "key", None, "present", False, "labelName", True), (None, "key", None, "present", False, "labelName", "dummy", "dummy", True),
("dummy", None, None, "present", False, None, False), ("dummy", None, None, "present", False, None, "dummy", "dummy", False),
("dummy", "key", None, "absent", False, None, False), ("dummy", "key", None, "absent", False, None, "dummy", "dummy", False),
("dummy", "key", None, "opened", True, None, False), ("dummy", "key", None, "opened", True, None, "dummy", "dummy", False),
("dummy", "key", None, "closed", True, None, False), ("dummy", "key", None, "closed", True, None, "dummy", "dummy", False),
("dummy", "key", None, "present", True, None, False), ("dummy", "key", None, "present", True, None, "dummy", "dummy", False),
("dummy", None, "foo", "present", False, None, True), ("dummy", None, "foo", "present", False, None, "dummy", "dummy", True),
(None, None, "bar", "present", False, None, False), (None, None, "bar", "present", False, None, "dummy", "dummy", False),
(None, None, "baz", "present", False, "labelName", True), (None, None, "baz", "present", False, "labelName", "dummy", "dummy", True),
("dummy", None, None, "present", False, None, False), ("dummy", None, None, "present", False, None, "dummy", "dummy", False),
("dummy", None, "quz", "absent", False, None, False), ("dummy", None, "quz", "absent", False, None, "dummy", "dummy", False),
("dummy", None, "qux", "opened", True, None, False), ("dummy", None, "qux", "opened", True, None, "dummy", "dummy", False),
("dummy", None, "quux", "closed", True, None, False), ("dummy", None, "quux", "closed", True, None, "dummy", "dummy", False),
("dummy", None, "corge", "present", True, None, False)) ("dummy", None, "corge", "present", True, None, "dummy", "dummy", False),
("dummy", "key", None, "present", False, None, None, None, True),
("dummy", "key", None, "present", False, None, None, "dummy", True),
("dummy", "key", None, "present", False, None, "dummy", None, True))
# device, state, is_luks, expected # device, state, is_luks, expected
LUKS_REMOVE_DATA = ( LUKS_REMOVE_DATA = (
@ -153,10 +156,10 @@ LUKS_REMOVE_KEY_DATA = (
@pytest.mark.parametrize("device, keyfile, passphrase, state, is_luks, " + @pytest.mark.parametrize("device, keyfile, passphrase, state, is_luks, " +
"label, expected", "label, cipher, hash_, expected",
((d[0], d[1], d[2], d[3], d[4], d[5], d[6]) ((d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8])
for d in LUKS_CREATE_DATA)) for d in LUKS_CREATE_DATA))
def test_luks_create(device, keyfile, passphrase, state, is_luks, label, def test_luks_create(device, keyfile, passphrase, state, is_luks, label, cipher, hash_,
expected, monkeypatch): expected, monkeypatch):
module = DummyModule() module = DummyModule()
@ -165,6 +168,8 @@ def test_luks_create(device, keyfile, passphrase, state, is_luks, label,
module.params["passphrase"] = passphrase module.params["passphrase"] = passphrase
module.params["state"] = state module.params["state"] = state
module.params["label"] = label module.params["label"] = label
module.params["cipher"] = cipher
module.params["hash"] = hash_
monkeypatch.setattr(luks_device.CryptHandler, "is_luks", monkeypatch.setattr(luks_device.CryptHandler, "is_luks",
lambda x, y: is_luks) lambda x, y: is_luks)