From b3047fb947beac6df7f1c65739efb71dc38f036d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Mon, 24 Jul 2023 17:28:28 +0200 Subject: [PATCH] Fixed writing correct keyfile path to etc/crypttab The keyfile path was not correctly set in etc/crypttab which caused systemd not being able to read the keyfile, consequently asking for a passphrase. This commit fixes the writing of the crypttab and also fixes a python name clash with the "os" namespace. --- kiwi/builder/disk.py | 7 ++++--- kiwi/storage/luks_device.py | 28 +++++++++++++++------------ test/unit/builder/disk_test.py | 14 ++++++++------ test/unit/storage/luks_device_test.py | 19 ++++++++++++------ 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/kiwi/builder/disk.py b/kiwi/builder/disk.py index c681215c476..b17be379d68 100644 --- a/kiwi/builder/disk.py +++ b/kiwi/builder/disk.py @@ -370,10 +370,11 @@ def create_disk(self) -> Result: True if self.boot_is_crypto or self.luks == '' else False luks_root.create_crypto_luks( passphrase=self.luks, - os=self.luks_os, + osname=self.luks_os, options=self.luks_format_options, - keyfile=self.luks_boot_keyfile if luks_need_keyfile else '', - randomize=self.luks_randomize + keyfile=self.luks_boot_keyname if luks_need_keyfile else '', + randomize=self.luks_randomize, + root_dir=self.root_dir ) if luks_need_keyfile: self.luks_boot_keyfile_setup = ''.join( diff --git a/kiwi/storage/luks_device.py b/kiwi/storage/luks_device.py index fa92a7a3a6d..ad3b2fa07c4 100644 --- a/kiwi/storage/luks_device.py +++ b/kiwi/storage/luks_device.py @@ -46,7 +46,7 @@ def __init__(self, storage_provider: DeviceProvider) -> None: self.storage_provider = storage_provider self.luks_device: Optional[str] = None - self.luks_keyfile: Optional[str] = None + self.luks_keyfile: str = '' self.luks_name = 'luksRoot' self.option_map = { @@ -72,8 +72,9 @@ def get_device(self) -> Optional[MappedDevice]: return None def create_crypto_luks( - self, passphrase: str, os: str = None, - options: list = None, keyfile: str = '', randomize: bool = True + self, passphrase: str, osname: str = None, + options: list = None, keyfile: str = '', randomize: bool = True, + root_dir: str = '' ) -> None: """ Create luks device. Please note the passphrase is readable @@ -81,22 +82,23 @@ def create_crypto_luks( is secure while this process runs :param string passphrase: credentials - :param string os: + :param string osname: distribution name to match distribution specific options for cryptsetup :param list options: further cryptsetup options :param string keyfile: file path name file path name which contains an alternative key to unlock the luks device + :param string root_dir: root dir path """ if not options: options = [] - if os: - if os in self.option_map: - options += self.option_map[os] + if osname: + if osname in self.option_map: + options += self.option_map[osname] else: raise KiwiLuksSetupError( - 'no custom option configuration found for OS %s' % os + 'no custom option configuration found for OS %s' % osname ) extra_options = [] storage_device = self.storage_provider.get_device() @@ -141,12 +143,15 @@ def create_crypto_luks( ) if keyfile: self.luks_keyfile = keyfile - LuksDevice.create_random_keyfile(keyfile) + keyfile_path = os.path.normpath( + os.sep.join([root_dir, self.luks_keyfile]) + ) + LuksDevice.create_random_keyfile(keyfile_path) Command.run( [ 'cryptsetup', '--key-file', passphrase_file ] + extra_options + [ - 'luksAddKey', storage_device, keyfile + 'luksAddKey', storage_device, keyfile_path ] ) Command.run( @@ -170,8 +175,7 @@ def create_crypttab(self, filename: str) -> None: if self.luks_keyfile: crypttab.write( 'luks UUID={0} /{1}{2}'.format( - luks_uuid, os.path.basename(self.luks_keyfile), - os.linesep + luks_uuid, self.luks_keyfile.lstrip(os.sep), os.linesep ) ) else: diff --git a/test/unit/builder/disk_test.py b/test/unit/builder/disk_test.py index 107f11db357..b943b402db8 100644 --- a/test/unit/builder/disk_test.py +++ b/test/unit/builder/disk_test.py @@ -1045,9 +1045,10 @@ def test_create_disk_luks_root( self.disk_builder.create_disk() self.luks_root.create_crypto_luks.assert_called_once_with( - passphrase='passphrase', os=None, - options=[], keyfile='root_dir/root/.root.keyfile', - randomize=True + passphrase='passphrase', osname=None, + options=[], keyfile='/root/.root.keyfile', + randomize=True, + root_dir='root_dir' ) self.luks_root.create_crypttab.assert_called_once_with( 'root_dir/etc/crypttab' @@ -1089,9 +1090,10 @@ def test_create_disk_luks_root_with_disk_password( self.disk_builder.create_disk() self.luks_root.create_crypto_luks.assert_called_once_with( - passphrase='passphrase', os=None, - options=[], keyfile='root_dir/root/.root.keyfile', - randomize=True + passphrase='passphrase', osname=None, + options=[], keyfile='/root/.root.keyfile', + randomize=True, + root_dir='root_dir' ) self.luks_root.create_crypttab.assert_called_once_with( 'root_dir/etc/crypttab' diff --git a/test/unit/storage/luks_device_test.py b/test/unit/storage/luks_device_test.py index fdd2bab708b..bff2f32898a 100644 --- a/test/unit/storage/luks_device_test.py +++ b/test/unit/storage/luks_device_test.py @@ -52,7 +52,8 @@ def test_create_crypto_luks_empty_passphrase( ): with patch('builtins.open', create=True): self.luks.create_crypto_luks( - passphrase='', os='sle12', keyfile='some-keyfile' + passphrase='', osname='sle12', + keyfile='some-keyfile', root_dir='root' ) assert mock_command.call_args_list == [ call( @@ -74,7 +75,7 @@ def test_create_crypto_luks_empty_passphrase( [ 'cryptsetup', '--key-file', '/dev/zero', '--keyfile-size', '32', - 'luksAddKey', '/dev/some-device', 'some-keyfile' + 'luksAddKey', '/dev/some-device', 'root/some-keyfile' ] ), call( @@ -87,18 +88,20 @@ def test_create_crypto_luks_empty_passphrase( ] self.luks.luks_device = None + @patch('kiwi.storage.luks_device.LuksDevice') @patch('kiwi.storage.luks_device.Command.run') @patch('kiwi.storage.luks_device.Temporary.new_file') @patch('os.chmod') def test_create_crypto_luks( - self, mock_os_chmod, mock_tmpfile, mock_command + self, mock_os_chmod, mock_tmpfile, mock_command, mock_LuksDevice ): tmpfile = Mock() tmpfile.name = 'tmpfile' mock_tmpfile.return_value = tmpfile with patch('builtins.open', create=True): self.luks.create_crypto_luks( - passphrase='passphrase', os='sle12', keyfile='some-keyfile' + passphrase='passphrase', osname='sle12', + keyfile='some-keyfile', root_dir='root' ) assert mock_command.call_args_list == [ call( @@ -118,7 +121,7 @@ def test_create_crypto_luks( call( [ 'cryptsetup', '--key-file', 'tmpfile', 'luksAddKey', - '/dev/some-device', 'some-keyfile' + '/dev/some-device', 'root/some-keyfile' ] ), call( @@ -128,7 +131,11 @@ def test_create_crypto_luks( ] ) ] - self.luks.luks_device = None + mock_LuksDevice.create_random_keyfile.assert_called_once_with( + 'root/some-keyfile' + ) + assert self.luks.luks_keyfile == 'some-keyfile' + self.luks.luks_device = '' def test_create_crypttab(self): self.luks.luks_device = '/dev/mapper/luksRoot'