Commit 4e1650b4 authored by Matthias Klumpp's avatar Matthias Klumpp

cryptsetup-helper: Rewrite crypttab with the appropriate settings

parent 069ecd43
......@@ -31,6 +31,20 @@ KEYFILE_OLD = '/crypto_keyfile.bin.old'
CALAMARES_LUKS_PARTITION_FILE = '/encrypted_partitions.json'
CRYPTTAB_HEADER = """# /etc/crypttab: mappings for encrypted partitions.
#
# Each mapped device will be created in /dev/mapper, so your /etc/fstab
# should use the /dev/mapper/<name> paths for encrypted devices.
#
# See crypttab(5) for the supported syntax.
#
# NOTE: Do not list your root (/) partition here, it must be set up
# beforehand by the initramfs (/etc/mkinitcpio.conf). The same applies
# to encrypted swap, which should be set up with mkinitcpio-openswap
# for resume support.
#
# <name> <device> <password> <options>"""
def run_command(command, input=None):
if not isinstance(command, list):
......@@ -58,6 +72,38 @@ def run_command(command, input=None):
return (output, stderr, pipe.returncode)
def generate_crypttab_line_info(partition, crypttab_options, use_password=False):
""" Generates information for each crypttab entry. """
if 'luksMapperName' not in partition or 'luksUuid' not in partition:
return None
mapper_name = partition['luksMapperName']
luks_uuid = partition['luksUuid']
if not mapper_name or not luks_uuid:
return None
if use_password:
pwd_s = 'none'
else:
pwd_s = '/crypto_keyfile.bin'
return dict(
name=mapper_name,
device='UUID=' + luks_uuid,
password=pwd_s,
options=crypttab_options)
def print_crypttab_line(dct, file=None):
""" Prints line to '/etc/crypttab' file. """
line = "{:21} {:<45} {} {}".format(dct['name'],
dct['device'],
dct['password'],
dct['options'])
print(line, file=file)
def run(new_password):
luks_partitions = json.load(open(CALAMARES_LUKS_PARTITION_FILE, 'r'))
luks_root_device = luks_partitions.get('rootDevice')
......@@ -85,13 +131,9 @@ def run(new_password):
partitions.insert(0, luks_root_device)
for partition in partitions:
partition = partition.strip()
if not partition:
continue
out, err, ret = run_command(['cryptsetup',
'luksAddKey',
partition,
partition['device'],
KEYFILE,
'--key-file', KEYFILE_OLD])
if ret != 0:
......@@ -99,7 +141,7 @@ def run(new_password):
out, err, ret = run_command(['cryptsetup',
'luksRemoveKey',
partition,
partition['device'],
KEYFILE_OLD])
if ret != 0:
raise Exception("Unable to remove old key file: {} - {}".format(out, err))
......@@ -107,10 +149,10 @@ def run(new_password):
# only add a real password to the root partition.
# once that is unlocked, the system has access to the keyfile and can automatically
# decrypt all other partitions
if partition == luks_root_device:
if partition['device'] == luks_root_device['device']:
out, err, ret = run_command(['cryptsetup',
'luksAddKey',
partition,
partition['device'],
'--key-file', KEYFILE,
'-q'],
input=new_password)
......@@ -127,6 +169,23 @@ def run(new_password):
os.remove(ENCRYPT_BYPASS_INITRAMFS_HOOK)
os.remove(CALAMARES_LUKS_PARTITION_FILE)
# rewrite crypttab with the new options
with open(CRYPTTAB_FILE, 'w') as crypttab_f:
print(CRYPTTAB_HEADER, file=crypttab_f)
# the root partition is decrypted using a password, not a keyfile
dct = generate_crypttab_line_info(luks_root_device, 'luks', True)
if dct:
print_crypttab_line(dct, file=crypttab_f)
# all other partitions are decrypted using a keyfile
for partition in additional_luks_devices:
dct = generate_crypttab_line_info(partition, 'luks,keyscript=/bin/cat')
if dct:
print_crypttab_line(dct, file=crypttab_f)
# update initramfs to make changes permanent
os.system('update-initramfs -u')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment