def _encrypt_block_device(args, client, config): """Encrypt and open a block device Stores the dm-crypt key direct in vault :param: args: argparser generated cli arguments :param: client: hvac.Client for Vault access :param: config: configparser object of vaultlocker config """ block_device = args.block_device[0] key = dmcrypt.generate_key() block_uuid = str(uuid.uuid4()) if not args.uuid else args.uuid vault_path = _get_vault_path(block_uuid, config) dmcrypt.luks_format(key, block_device, block_uuid) # Ensure sym link for new encrypted device is created # LP Bug #1780332 dmcrypt.udevadm_rescan(block_device) dmcrypt.udevadm_settle(block_uuid) # NOTE: store and validate key client.write(vault_path, dmcrypt_key=key) stored_data = client.read(vault_path) assert key == stored_data['data']['dmcrypt_key'] dmcrypt.luks_open(key, block_uuid) systemd.enable('vaultlocker-decrypt@{}.service'.format(block_uuid))
def _encrypt_block_device(args, client, config): """Encrypt and open a block device Stores the dm-crypt key direct in vault :param: args: argparser generated cli arguments :param: client: hvac.Client for Vault access :param: config: configparser object of vaultlocker config """ block_device = args.block_device[0] key = dmcrypt.generate_key() block_uuid = str(uuid.uuid4()) if not args.uuid else args.uuid vault_path = _get_vault_path(block_uuid, config) # NOTE: store and validate key before trying to encrypt disk try: client.write(vault_path, dmcrypt_key=key) except hvac.exceptions.VaultError as write_error: logger.error( 'Vault write to path {}. Failed with error: {}'.format( vault_path, write_error)) raise exceptions.VaultWriteError(vault_path, write_error) try: stored_data = client.read(vault_path) except hvac.exceptions.VaultError as read_error: logger.error('Vault access to path {}' 'failed with error: {}'.format(vault_path, read_error)) raise exceptions.VaultReadError(vault_path, read_error) if not key == stored_data['data']['dmcrypt_key']: raise exceptions.VaultKeyMismatch(vault_path) # All function calls within try/catch raise a CalledProcessError # if return code is non-zero # This way if any of the calls fail, the key can be removed from vault try: dmcrypt.luks_format(key, block_device, block_uuid) # Ensure sym link for new encrypted device is created # LP Bug #1780332 dmcrypt.udevadm_rescan(block_device) dmcrypt.udevadm_settle(block_uuid) dmcrypt.luks_open(key, block_uuid) except subprocess.CalledProcessError as luks_error: logger.error( 'LUKS formatting {} failed with error code: {}\n' 'LUKS output: {}'.format( block_device, luks_error.returncode, luks_error.output)) try: client.delete(vault_path) except hvac.exceptions.VaultError as del_error: raise exceptions.VaultDeleteError(vault_path, del_error) raise exceptions.LUKSFailure(block_device, luks_error.output) systemd.enable('vaultlocker-decrypt@{}.service'.format(block_uuid))
def test_luks_format(self, _subprocess): dmcrypt.luks_format('mykey', '/dev/sdb', 'test-uuid') _subprocess.check_output.assert_called_once_with( [ 'cryptsetup', '--batch-mode', '--uuid', 'test-uuid', '--key-file', '-', 'luksFormat', '/dev/sdb' ], input='mykey'.encode('UTF-8'))