backups: introduce configurable HMAC/encryption algo

For now always set it to default values (no frontend application uses
those parameters), but be prepared for further improvements.
This commit is contained in:
Marek Marczykowski-Górecki 2014-01-15 03:50:29 +01:00
parent 4b493b6d9a
commit 4c29d743c8

View File

@ -39,6 +39,8 @@ from multiprocessing import Queue,Process
BACKUP_DEBUG = False
DEFAULT_CRYPTO_ALGORITHM = 'aes-256-cbc'
DEFAULT_HMAC_ALGORITHM = 'SHA1'
# Maximum size of error message get from process stderr (including VM process)
MAX_STDERR_BYTES = 1024
# header + qubes.xml max size
@ -344,7 +346,8 @@ class SendWorker(Process):
def backup_do(base_backup_dir, files_to_backup, passphrase,
progress_callback = None, encrypted=False, appvm=None,
compressed=False):
compressed=False, hmac_algorithm=DEFAULT_HMAC_ALGORITHM,
crypto_algorithm=DEFAULT_CRYPTO_ALGORITHM):
total_backup_sz = 0
for file in files_to_backup:
total_backup_sz += file["size"]
@ -450,7 +453,8 @@ def backup_do(base_backup_dir, files_to_backup, passphrase,
pipe = open(backup_pipe,'rb')
# Start HMAC
hmac = subprocess.Popen (["openssl", "dgst", "-hmac", passphrase],
hmac = subprocess.Popen (["openssl", "dgst",
"-" + hmac_algorithm, "-hmac", passphrase],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
# Prepare a first chunk
@ -470,7 +474,7 @@ def backup_do(base_backup_dir, files_to_backup, passphrase,
# Start encrypt
# If no cipher is provided, the data is forwarded unencrypted !!!
encryptor = subprocess.Popen (["openssl", "enc",
"-e", "-aes-256-cbc",
"-e", "-" + crypto_algorithm,
"-pass", "pass:"+passphrase] +
(["-z"] if compressed else []),
stdin=pipe, stdout=subprocess.PIPE)
@ -628,7 +632,7 @@ def wait_backup_feedback(progress_callback, in_stream, streamproc,
return run_error
def verify_hmac(filename, hmacfile, passphrase):
def verify_hmac(filename, hmacfile, passphrase, algorithm):
if BACKUP_DEBUG:
print "Verifying file "+filename
@ -637,7 +641,8 @@ def verify_hmac(filename, hmacfile, passphrase):
"ERROR: expected hmac for {}, but got {}".\
format(filename, hmacfile))
hmac_proc = subprocess.Popen (["openssl", "dgst", "-hmac", passphrase],
hmac_proc = subprocess.Popen (["openssl", "dgst", "-" + algorithm,
"-hmac", passphrase],
stdin=open(filename,'rb'),
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
hmac_stdout, hmac_stderr = hmac_proc.communicate()
@ -666,13 +671,14 @@ def verify_hmac(filename, hmacfile, passphrase):
class ExtractWorker(Process):
def __init__(self, queue, base_dir, passphrase, encrypted, total_size,
print_callback, error_callback, progress_callback, vmproc=None,
compressed = False):
compressed = False, crypto_algorithm=DEFAULT_CRYPTO_ALGORITHM):
super(ExtractWorker, self).__init__()
self.queue = queue
self.base_dir = base_dir
self.passphrase = passphrase
self.encrypted = encrypted
self.compressed = compressed
self.crypto_algorithm = crypto_algorithm
self.total_size = total_size
self.blocks_backedup = 0
self.tar2_process = None
@ -766,7 +772,7 @@ class ExtractWorker(Process):
if self.encrypted:
# Start decrypt
self.decryptor_process = subprocess.Popen (["openssl", "enc",
"-d", "-aes-256-cbc",
"-d", "-" + self.crypto_algorithm,
"-pass", "pass:"+self.passphrase] +
(["-z"] if self.compressed else []),
stdin=open(filename,'rb'),
@ -832,7 +838,8 @@ class ExtractWorker(Process):
def restore_vm_dirs (backup_source, restore_tmpdir, passphrase, vms_dirs, vms,
vms_size, print_callback=None, error_callback=None,
progress_callback=None, encrypted=False, appvm=None,
compressed = False):
compressed = False, hmac_algorithm=DEFAULT_HMAC_ALGORITHM,
crypto_algorithm=DEFAULT_CRYPTO_ALGORITHM):
# Setup worker to extract encrypted data chunks to the restore dirs
to_extract = Queue()
@ -841,6 +848,7 @@ def restore_vm_dirs (backup_source, restore_tmpdir, passphrase, vms_dirs, vms,
passphrase=passphrase,
encrypted=encrypted,
compressed=compressed,
crypto_algorithm = crypto_algorithm,
total_size=vms_size,
print_callback=print_callback,
error_callback=error_callback,
@ -923,7 +931,7 @@ def restore_vm_dirs (backup_source, restore_tmpdir, passphrase, vms_dirs, vms,
if verify_hmac(os.path.join(restore_tmpdir,filename),
os.path.join(restore_tmpdir,hmacfile),
passphrase):
passphrase, hmac_algorithm):
to_extract.put(os.path.join(restore_tmpdir, filename))
if command.wait() != 0:
@ -988,7 +996,9 @@ def backup_detect_format_version(backup_location):
def backup_restore_header(source, passphrase,
print_callback = print_stdout, error_callback = print_stderr,
encrypted=False, appvm=None, compressed = False, format_version = None):
encrypted=False, appvm=None, compressed = False, format_version = None,
hmac_algorithm = DEFAULT_HMAC_ALGORITHM,
crypto_algorithm = DEFAULT_CRYPTO_ALGORITHM):
vmproc = None
@ -1013,6 +1023,8 @@ def backup_restore_header(source, passphrase,
vms_dirs=extract_filter,
vms=None,
vms_size=HEADER_QUBES_XML_MAX_SIZE,
hmac_algorithm=hmac_algorithm,
crypto_algorithm=crypto_algorithm,
print_callback=print_callback,
error_callback=error_callback,
progress_callback=None,
@ -1089,7 +1101,8 @@ def restore_info_verify(restore_info, host_collection):
def backup_restore_prepare(backup_location, passphrase, options = {},
host_collection = None, encrypted=False, appvm=None,
compressed = False, print_callback = print_stdout, error_callback = print_stderr,
format_version=None):
format_version=None, hmac_algorithm=DEFAULT_HMAC_ALGORITHM,
crypto_algorithm=DEFAULT_CRYPTO_ALGORITHM):
# Defaults
backup_restore_set_defaults(options)
@ -1134,11 +1147,14 @@ def backup_restore_prepare(backup_location, passphrase, options = {},
else:
raise QubesException("Unknown backup format version: %s" % str(format_version))
(restore_tmpdir, qubes_xml) = backup_restore_header(backup_location,
(restore_tmpdir, qubes_xml) = backup_restore_header(
backup_location,
passphrase,
encrypted=encrypted,
appvm=appvm,
compressed=compressed,
hmac_algorithm=hmac_algorithm,
crypto_algorithm=crypto_algorithm,
print_callback=print_callback,
error_callback=error_callback,
format_version=format_version)
@ -1193,6 +1209,8 @@ def backup_restore_prepare(backup_location, passphrase, options = {},
options['passphrase'] = passphrase
options['encrypted'] = encrypted
options['compressed'] = compressed
options['hmac_algorithm'] = hmac_algorithm
options['crypto_algorithm'] = crypto_algorithm
options['appvm'] = appvm
options['format_version'] = format_version
vms_to_restore['$OPTIONS$'] = options
@ -1352,6 +1370,8 @@ def backup_restore_do(restore_info,
passphrase = options['passphrase']
encrypted = options['encrypted']
compressed = options['compressed']
hmac_algorithm = options['hmac_algorithm']
crypto_algorithm = options['crypto_algorithm']
appvm = options['appvm']
format_version = options['format_version']
@ -1391,6 +1411,8 @@ def backup_restore_do(restore_info,
vms_dirs=vms_dirs,
vms=vms,
vms_size=vms_size,
hmac_algorithm=hmac_algorithm,
crypto_algorithm=crypto_algorithm,
print_callback=print_callback,
error_callback=error_callback,
progress_callback=progress_callback,