backup: fix handling already encoded passphrase

When passphrase is retrieved from VM, it is already encoded. Do not try
to encode it again.

QubesOS/qubes-issues#2931
This commit is contained in:
Marek Marczykowski-Górecki 2017-07-28 22:48:49 +02:00
parent cdbe1d14b3
commit 1556814f59
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
3 changed files with 10 additions and 9 deletions

View File

@ -1146,7 +1146,6 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI):
except KeyError:
raise qubes.exc.QubesException(
'Invalid backup profile - invalid passphrase_vm')
# TODO .decode()?
passphrase, _ = yield from passphrase_vm.run_service_for_stdio(
'qubes.BackupPassphrase+' + self.arg)
else:

View File

@ -200,6 +200,7 @@ def launch_scrypt(action, input_name, output_name, passphrase):
:param input_name: input path or '-' for stdin
:param output_name: output path or '-' for stdout
:param passphrase: passphrase
:type passphrase: bytes
:return: subprocess.Popen object
'''
command_line = ['scrypt', action, input_name, output_name]
@ -217,7 +218,7 @@ def launch_scrypt(action, input_name, output_name, passphrase):
if actual_prompt != prompt:
raise qubes.exc.QubesException(
'Unexpected prompt from scrypt: {}'.format(actual_prompt))
pty.write(passphrase.encode('utf-8') + b'\n')
pty.write(passphrase + b'\n')
pty.flush()
# save it here, so garbage collector would not close it (which would kill
# the child)
@ -492,8 +493,8 @@ class Backup(object):
backup_header.save(header_file_path)
# Start encrypt, scrypt will also handle integrity
# protection
scrypt_passphrase = u'{filename}!{passphrase}'.format(
filename=HEADER_FILENAME, passphrase=self.passphrase)
scrypt_passphrase = '{filename}!'.format(
filename=HEADER_FILENAME).encode() + self.passphrase
scrypt = yield from launch_scrypt(
'enc', header_file_path, header_file_path + '.hmac',
scrypt_passphrase)
@ -545,11 +546,10 @@ class Backup(object):
# Start encrypt, scrypt will also handle integrity
# protection
scrypt_passphrase = \
u'{backup_id}!{filename}!{passphrase}'.format(
'{backup_id}!{filename}!'.format(
backup_id=self.backup_id,
filename=os.path.relpath(chunkfile[:-4],
self.tmpdir),
passphrase=self.passphrase)
self.tmpdir)).encode() + self.passphrase
try:
scrypt = yield from launch_scrypt(
"enc", "-", chunkfile, scrypt_passphrase)
@ -691,6 +691,8 @@ class Backup(object):
# pylint: disable=too-many-statements
if self.passphrase is None:
raise qubes.exc.QubesException("No passphrase set")
if not isinstance(self.passphrase, bytes):
self.passphrase = self.passphrase.encode('utf-8')
qubes_xml = self.app.store
self.tmpdir = tempfile.mkdtemp()
shutil.copy(qubes_xml, os.path.join(self.tmpdir, 'qubes.xml'))

View File

@ -1930,7 +1930,7 @@ class TC_00_VMs(AdminAPITestCase):
@asyncio.coroutine
def service_passphrase(*args, **kwargs):
return ('pass-from-vm', None)
return (b'pass-from-vm', None)
mock_backup.return_value.backup_do.side_effect = self.dummy_coro
self.vm.run_service_for_stdio = unittest.mock.Mock(
@ -1950,7 +1950,7 @@ class TC_00_VMs(AdminAPITestCase):
target_vm=self.vm,
target_dir='/home/user',
compressed=True,
passphrase='pass-from-vm')
passphrase=b'pass-from-vm')
mock_backup.return_value.backup_do.assert_called_once_with()
self.vm.run_service_for_stdio.assert_called_with(
'qubes.BackupPassphrase+testprofile')