From 86ba00e029a0f636f1daa69c36f48d19fa357c3b Mon Sep 17 00:00:00 2001 From: Fabien Dupont Date: Wed, 13 Nov 2019 22:16:47 +0100 Subject: [PATCH] Add ability to use a LUKS keys vault (#65) --- wrapper/hosts.py | 1 - wrapper/tests/test_v2v_args.py | 24 ++++++++++++++++++++++ wrapper/virt_v2v_wrapper.py | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/wrapper/hosts.py b/wrapper/hosts.py index 94f160b0..941e91d4 100644 --- a/wrapper/hosts.py +++ b/wrapper/hosts.py @@ -780,7 +780,6 @@ def prepare_command(self, data, v2v_args, v2v_env, v2v_caps): v2v_args.extend(['-oo', 'rhv-verifypeer=%s' % ('false' if data['insecure_connection'] else 'true')]) - elif 'export_domain' in data: v2v_args.extend([ '-o', 'rhv', diff --git a/wrapper/tests/test_v2v_args.py b/wrapper/tests/test_v2v_args.py index 7a7fcd85..c70954ea 100644 --- a/wrapper/tests/test_v2v_args.py +++ b/wrapper/tests/test_v2v_args.py @@ -66,6 +66,30 @@ def test_vddk_basic(self): v2v_args, v2v_env = wrapper.prepare_command(data, []) self.assertEqual(v2v_args, expected) + def test_luks(self): + state = wrapper.State().instance + state.machine_readable_log = '/some/path' + data = self.VDDK_RHV.copy() + data['luks_keys_files'] = [ + { + 'device': '/dev/sda1', + 'filename': '/tmp/luks/sda1', + }, + { + 'device': '/dev/sda2', + 'filename': '/tmp/luks/sda2', + }, + ] + v2v_args, v2v_env = wrapper.prepare_command(data, []) + self.assert_has_args( + v2v_args, + ['--key', '/dev/sda1:file:/tmp/luks/sda1'], + 'Looking for LUKS key of device sda1 %r' % v2v_args) + self.assert_has_args( + v2v_args, + ['--key', '/dev/sda2:file:/tmp/luks/sda2'], + 'Looking for LUKS key of device sda2 %r' % v2v_args) + def test_network_mappings(self): data = self.VDDK_RHV.copy() data['network_mappings'] = [ diff --git a/wrapper/virt_v2v_wrapper.py b/wrapper/virt_v2v_wrapper.py index 523e059b..b179cd18 100644 --- a/wrapper/virt_v2v_wrapper.py +++ b/wrapper/virt_v2v_wrapper.py @@ -25,6 +25,7 @@ import re import signal import subprocess +import stat import sys import six import tempfile @@ -124,6 +125,16 @@ def prepare_command(data, v2v_caps, agent_sock=None): v2v_args.extend(['--bridge', '%s:%s' % (mapping['source'], mapping['destination'])]) + if 'luks_keys_files' in data: + for luks_key in data['luks_keys_files']: + v2v_args.extend([ + '--key', + '%s:file:%s' % ( + luks_key['device'], + luks_key['filename'] + ) + ]) + # Prepare environment v2v_env = os.environ.copy() v2v_env['LANG'] = 'C' @@ -487,6 +498,32 @@ def main(): host.get_uid(), host.get_gid()) + if 'luks_keys_vault' not in data: + data['luks_keys_vault'] = os.path.join( + os.environ['HOME'], + '.v2v_luks_keys_vault.json' + ) + if os.exists(data['luks_keys_vault']): + file_stat = os.stat(data['luks_keys_vaul']) + if file_stat.st_uid != host.get_uid(): + hard_error('LUKS keys vault does\'nt belong to' + 'user running virt-v2v-wrapper') + if file_stat.st_mode & stat.S_IRWXO > 0: + hard_error('LUKS keys vault is accessible to others') + if file_stat.st_mode & stat.S_IRWXG > 0: + hard_error('LUKS keys vault is accessible to group') + luks_keys_vault = json.load(data['luks_keys_vault']) + if data['vm_name'] in luks_keys_vault: + data['luks_keys_files'] = [] + for luks_key in luks_keys_vault[data['vm_name']]: + data['luks_keys_files'].append({ + 'device': luks_key['device'], + 'filename': write_password(luks_key['key'], + password_files, + host.get_uid(), + host.get_gid()) + }) + try: if 'source_disks' in data: logging.debug('Initializing disk list from %r',