'|bz2': '.bz2',
'#gz': '.gz',
'#gz.aes128': '.gz.aes128',
- '#gz.aes256': '.gz.aes256',
'#aes128': '.aes128',
- '#aes256': '.aes256',
}
# valid index modes and their corresponding default file extension
'gz': '.gz',
'bz2': '.bz2',
'gz.aes128': '.gz.aes128',
- 'gz.aes256': '.gz.aes256',
'aes128': '.aes128',
- 'aes256': '.aes256'
}
# valid path prefixes
'|bz2' open a bzip2 compressed stream of tar blocks
'#gz' open a stream of gzip compressed tar blocks
'#gz.aes128' open an aes128 encrypted stream of gzip compressed tar blocks
- '#gz.aes256' open an aes256 encrypted stream of gzip compressed tar blocks
'#aes128' open an aes128 encrypted stream of tar blocks
- '#aes256' open an aes256 encrypted stream of tar blocks
- password: used together with aes modes to encrypt and decrypt backups.
'gz' open with gzip compression
'bz2' open with bzip2 compression
'gz.aes128' open an aes128 encrypted stream of gzip compressed tar blocks
- 'gz.aes256' open an aes256 encrypted stream of gzip compressed tar blocks
'aes128' open an aes128 encrypted stream of tar blocks
- 'aes256' open an aes256 encrypted stream of tar blocks
- index_name_func: function that sets a custom name for the index file.
This function receives the backup_path and if it's a full backup as
if 'aes' in self.index_mode:
enctype = 'aes'
- key_length = 128
- if 'aes256' in self.index_mode:
- key_length = 256
-
return tarfile._Stream(name=path, mode=mode, comptype=comptype,
bufsize=tarfile.RECORDSIZE, fileobj=None,
- enctype=enctype, password=self.password,
- key_length=key_length)
+ enctype=enctype, password=self.password)
def create_full_backup(self, source_path, backup_path,
max_volume_size=None, extra_data=dict()):
def __init__(self, name, mode, comptype, fileobj, bufsize,
concat_stream=False, enctype='', password="",
- key_length=128, compresslevel=9):
+ compresslevel=9):
"""Construct a _Stream object.
"""
self._extfileobj = True
self.internal_pos = 0
self.concat_stream = concat_stream
self.enctype = enctype
- self.key_length = key_length
self.password = password
self.last_block_offset = 0
self.dbuf = b""
- self.aes_buf = b""
+ self.aes_buf = b"" # ???
self.exception = None
self.compresslevel = compresslevel
self.bytes_written = 0
self.zlib = zlib
if mode == "r":
if self.enctype == 'aes':
- self.encryption = crypto.AES_GCM_context(self.password,
- key_length=self.key_length)
+ self.encryption = crypto.AES_GCM_context(self.password)
self._init_read_gz()
self.exception = zlib.error
else:
self.cmp = lzma.LZMACompressor()
elif self.enctype == 'aes':
- self.encryption = aescrypto.AESCrypt(self.password,
- key_length=self.key_length)
+ self.encryption = aescrypto.AESCrypt(self.password)
if mode != "r":
self.encryption.init()
self.__write_to_file(self.encryption.salt_str)
# if aes, we encrypt after compression
if self.enctype == 'aes':
- self.encryption = aescrypto.AESCrypt(self.password,
- key_length=self.key_length)
+ self.encryption = aescrypto.AESCrypt(self.password)
self.encryption.init()
self.__write_to_file(self.encryption.salt_str)
if set_last_block_offset:
self.last_block_offset = self.fileobj.tell()
- self.encryption = aescrypto.AESCrypt(self.password,
- key_length=self.key_length)
+ self.encryption = aescrypto.AESCrypt(self.password)
self.encryption.init()
self.__write_to_file(self.encryption.salt_str)
while c < size:
buf = self.__dec_read(self.bufsize)
if not buf:
+ ## XXX stream terminated prematurely; this should be an error
break
t.append(buf)
c += len(buf)
chars because the file is decrypted in multiples of the key size.
'''
if self.enctype == 'aes':
- kl = int(self.key_length/8)
- buf = self.fileobj.read(size - kl)
- last = len(buf) < (size - kl)
+ ## XXX
+ ## PHG: this logic doesn’t map to our header-based approach
+ ## and requires adjustment
+ buf = self.fileobj.read(size)
+ last = len(buf) < size
buf = self.aes_buf + buf
self.aes_buf = b""
# prevent setting last to False when it shouldn't
if not last:
+ kl = 16 ## XXX key length; obsolete
last = buf[-kl:].startswith(b'Salted__')
self.aes_buf = buf[-kl:]
buf = buf[:-kl]
return buf
def __split_enc_file(self, buf, last):
- if not buf:
- return buf
+ if not buf: # what else?
+ return buf ## XXX WTF‽
idx = buf.find(b'Salted__')
if idx == -1:
password = ''
# if not enctype there's no encryption
enctype = ''
- key_length = 128
if filemode not in "rw":
raise ValueError("mode must be 'r' or 'w'")
# encryption gz.aes128 or gz.aes256
if "." in comptype:
comptype, enctype = comptype.split(".", 1)
- kl = enctype[3:]
enctype = enctype[:3]
- key_length = 128 if kl == '128' else 256
password = kwargs.get('password', '')
if not password:
raise ValueError("you should give a password for encryption")
if comptype.startswith("aes"):
enctype = comptype
comptype = 'tar'
- kl = comptype[3:]
enctype = enctype[:3]
- key_length = 128 if kl == '128' else 256
password = kwargs.get('password', '')
if not password:
raise ValueError("you should give a password for encryption")
stream = _Stream(name, filemode, comptype, fileobj, bufsize,
concat_stream=True, enctype=enctype,
- password=password, key_length=key_length,
- compresslevel=compresslevel)
+ password=password, compresslevel=compresslevel)
try:
t = cls(name, filemode, stream, **kwargs)
except:
fileobj=None,
bufsize=self.fileobj.bufsize,
password=self.fileobj.password,
- key_length=self.fileobj.key_length,
enctype=self.fileobj.enctype,
concat_stream=self.fileobj.concat_stream)
else:
def main(do_encrypt, in_file, out_file, password, comptype='gz', enctype='aes',
- key_length=128, bufsize=tarfile.RECORDSIZE, encoding='UTF-8'):
+ bufsize=tarfile.RECORDSIZE, encoding='UTF-8'):
""" Main function, called when running file as script
see module doc for more info
read_handle = tarfile._Stream(name=in_file, mode='r',
comptype=comptype, bufsize=bufsize,
fileobj=None, enctype=enctype,
- key_length=key_length,
password=password)
return_code = 3
write_handle = tarfile._Stream(name=out_file, mode='w',
comptype=comptype, bufsize=bufsize,
fileobj=None, enctype=enctype,
- key_length=key_length,
password=password)
else:
write_handle = open(out_file, 'wt')