Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cipher and hash options to luks_create #97

Merged
merged 1 commit into from
Aug 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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)."
36 changes: 34 additions & 2 deletions plugins/modules/luks_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,22 @@
type: str
choices: [luks1, luks2]
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:
- "cryptsetup"
Expand All @@ -176,6 +192,13 @@
state: "present"
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"
community.crypto.luks_device:
device: "/dev/loop0"
Expand Down Expand Up @@ -374,7 +397,7 @@ def is_luks(self, device):
result = self._run_command([self._cryptsetup_bin, 'isLuks', device])
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
luks_type = self._module.params['type']
label = self._module.params['label']
Expand All @@ -387,6 +410,10 @@ def run_luks_create(self, device, keyfile, passphrase, keysize):
luks_type = 'luks2'
if luks_type is not None:
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.extend(options)
Expand Down Expand Up @@ -638,6 +665,8 @@ def run_module():
label=dict(type='str'),
uuid=dict(type='str'),
type=dict(type='str', choices=['luks1', 'luks2']),
cipher=dict(type='str'),
hash=dict(type='str'),
)

mutually_exclusive = [
Expand Down Expand Up @@ -682,7 +711,10 @@ def run_module():
crypt.run_luks_create(conditions.device,
module.params['keyfile'],
module.params['passphrase'],
module.params['keysize'])
module.params['keysize'],
module.params['cipher'],
module.params['hash'],
)
except ValueError as e:
module.fail_json(msg="luks_device error: %s" % e)
result['changed'] = True
Expand Down
45 changes: 25 additions & 20 deletions tests/unit/plugins/modules/crypto/test_luks_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,27 @@ def run_command_check(self, command):

# ===== 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 = (
("dummy", "key", None, "present", False, None, True),
(None, "key", None, "present", False, None, False),
(None, "key", None, "present", False, "labelName", True),
("dummy", None, None, "present", False, None, False),
("dummy", "key", None, "absent", False, None, False),
("dummy", "key", None, "opened", True, None, False),
("dummy", "key", None, "closed", True, None, False),
("dummy", "key", None, "present", True, None, False),
("dummy", None, "foo", "present", False, None, True),
(None, None, "bar", "present", False, None, False),
(None, None, "baz", "present", False, "labelName", True),
("dummy", None, None, "present", False, None, False),
("dummy", None, "quz", "absent", False, None, False),
("dummy", None, "qux", "opened", True, None, False),
("dummy", None, "quux", "closed", True, None, False),
("dummy", None, "corge", "present", True, None, False))
("dummy", "key", None, "present", False, None, "dummy", "dummy", True),
(None, "key", None, "present", False, None, "dummy", "dummy", False),
(None, "key", None, "present", False, "labelName", "dummy", "dummy", True),
("dummy", None, None, "present", False, None, "dummy", "dummy", False),
("dummy", "key", None, "absent", False, None, "dummy", "dummy", False),
("dummy", "key", None, "opened", True, None, "dummy", "dummy", False),
("dummy", "key", None, "closed", True, None, "dummy", "dummy", False),
("dummy", "key", None, "present", True, None, "dummy", "dummy", False),
("dummy", None, "foo", "present", False, None, "dummy", "dummy", True),
(None, None, "bar", "present", False, None, "dummy", "dummy", False),
(None, None, "baz", "present", False, "labelName", "dummy", "dummy", True),
("dummy", None, None, "present", False, None, "dummy", "dummy", False),
("dummy", None, "quz", "absent", False, None, "dummy", "dummy", False),
("dummy", None, "qux", "opened", True, None, "dummy", "dummy", False),
("dummy", None, "quux", "closed", True, None, "dummy", "dummy", 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
LUKS_REMOVE_DATA = (
Expand Down Expand Up @@ -153,10 +156,10 @@ def run_command_check(self, command):


@pytest.mark.parametrize("device, keyfile, passphrase, state, is_luks, " +
"label, expected",
((d[0], d[1], d[2], d[3], d[4], d[5], d[6])
"label, cipher, hash_, expected",
((d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8])
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):
module = DummyModule()

Expand All @@ -165,6 +168,8 @@ def test_luks_create(device, keyfile, passphrase, state, is_luks, label,
module.params["passphrase"] = passphrase
module.params["state"] = state
module.params["label"] = label
module.params["cipher"] = cipher
module.params["hash"] = hash_

monkeypatch.setattr(luks_device.CryptHandler, "is_luks",
lambda x, y: is_luks)
Expand Down