MATCH = True
PARENT_MATCH = 2
+# encryption direction
+CRYPTO_MODE_ENCRYPT = 0
+CRYPTO_MODE_DECRYPT = 1
+
# The canonical extension for encrypted backup files regardless of the actual
# encryption parameters is “.pdtcrypt”. This is analogous to the encryption
# header which starts with the eight ASCII bytes “PDTCRYPT”. Historical note:
# on decryption since the required settings are determined from the headers
crypto_paramversion = None
- # when encrypting or decrypting, this holds crypto handler; created before
+ # when encrypting or decrypting, these hold crypto handlers; created before
# establishing the Tarfile stream iff a password is supplied.
- crypto_ctx = None
+ encryptor = None
+ decryptor = None
# python logger object.
logger = None
if kind == PDT_TYPE_ARCHIVE:
ret += ".tar"
ret += mode
- if self.crypto_ctx is not None:
+ if self.encryptor is not None or self.decryptor is not None:
ret += "." + PDTCRYPT_EXTENSION
return ret
return path[len(prefix):]
return path
+
+ def initialize_encryption (self, mode):
+ password = self.password
+
+ if password is None:
+ return
+ if mode == CRYPTO_MODE_ENCRYPT:
+ if self.encryptor is None:
+ self.encryptor = \
+ crypto.Encrypt (password,
+ version=DELTATAR_HEADER_VERSION,
+ paramversion=self.crypto_paramversion)
+ return
+ if mode == CRYPTO_MODE_DECRYPT:
+ if self.decryptor is None:
+ self.decryptor = crypto.Decrypt (password)
+ return
+
+ raise Exception ("invalid encryption mode [%r]" % mode)
+
+
def open_auxiliary_file(self, path, mode='r', kind=AUXILIARY_FILE_INDEX):
'''
Given the specified configuration, opens a file for reading or writing,
else:
comptype = 'tar'
+ crypto_ctx = None
+ if mode == "w":
+ self.initialize_encryption (CRYPTO_MODE_ENCRYPT)
+ crypto_ctx = self.encryptor
+ elif mode == "r":
+ self.initialize_encryption (CRYPTO_MODE_DECRYPT)
+ crypto_ctx = self.decryptor
+
sink = tarfile._Stream(name=path, mode=mode, comptype=comptype,
bufsize=tarfile.RECORDSIZE, fileobj=None,
- encryption=self.crypto_ctx)
- if self.crypto_ctx is not None and mode == "w":
+ encryption=crypto_ctx)
+ if self.encryptor is not None and mode == "w":
counter = None
if kind == AUXILIARY_FILE_INFO:
counter = crypto.AES_GCM_IV_CNT_INFOFILE
raise Exception('Unrecognized extension')
# setup for encrypting payload
- if self.password is not None:
- self.crypto_ctx = \
- crypto.Encrypt (self.password,
- version=DELTATAR_HEADER_VERSION,
- paramversion=self.crypto_paramversion)
+ self.initialize_encryption (CRYPTO_MODE_ENCRYPT)
# some initialization
self.vol_no = 0
tarobj.open_volume(volume_path, encryption=encryption)
# wraps some args from context into the handler
- new_volume_handler = partial(new_volume_handler, self, cwd, backup_path, self.crypto_ctx)
+ new_volume_handler = partial(new_volume_handler, self, cwd, backup_path, self.encryptor)
index_accu.write(bytes('{"type": "python-delta-tar-index", "version": 1, "backup-type": "full", "extra_data": %s}\n' % extra_data_str, 'UTF-8'))
mode='w' + self.mode,
format=tarfile.GNU_FORMAT,
concat_compression='#gz' in self.mode,
- encryption=self.crypto_ctx,
+ encryption=self.encryptor,
max_volume_size=max_volume_size,
new_volume_handler=new_volume_handler,
save_to_members=False,
raise Exception('Unrecognized extension')
# setup for encrypting payload
- if self.password is not None:
- self.crypto_ctx = \
- crypto.Encrypt (self.password,
- version=DELTATAR_HEADER_VERSION,
- paramversion=self.crypto_paramversion)
+ self.initialize_encryption (CRYPTO_MODE_ENCRYPT)
+
# some initialization
self.vol_no = 0
mode='w' + self.mode,
format=tarfile.GNU_FORMAT,
concat_compression='#gz' in self.mode,
- encryption=self.crypto_ctx,
+ encryption=self.encryptor,
max_volume_size=max_volume_size,
new_volume_handler=new_volume_handler,
save_to_members=False,
mode='r' + self.delta_tar.mode,
format=tarfile.GNU_FORMAT,
concat_compression='#gz' in self.delta_tar.mode,
- encryption=self.delta_tar.crypto_ctx,
+ encryption=self.delta_tar.decryptor,
new_volume_handler=self.new_volume_handler,
save_to_members=False,
dereference=True)
volume_path = os.path.join(cwd, volume_path)
tarobj.open_volume(volume_path, encryption=encryption)
- if self.password is not None:
- self.crypto_ctx = crypto.Decrypt (self.password)
+ self.initialize_encryption (CRYPTO_MODE_DECRYPT)
backup_path = os.path.dirname(backup_tar_path)
if not os.path.isabs(backup_path):
backup_path = os.path.join(cwd, backup_path)
- new_volume_handler = partial(new_volume_handler, self, cwd, backup_path, self.crypto_ctx)
+ new_volume_handler = partial(new_volume_handler, self, cwd, backup_path, self.decryptor)
tarobj = tarfile.TarFile.open(backup_tar_path,
mode='r' + self.mode,
format=tarfile.GNU_FORMAT,
concat_compression='#gz' in self.mode,
- encryption=self.crypto_ctx,
+ encryption=self.decryptor,
new_volume_handler=new_volume_handler,
save_to_members=False,
dereference=True)
# setup for decrypting payload
if self.password is not None:
- self.crypto_ctx = crypto.Decrypt (self.password)
+ self.decryptor = crypto.Decrypt (self.password)
if mode == 'tar':
index_it = self.iterate_tar_path(backup_tar_path)
last_lno = 0,
new_volume_handler = partial(self.new_volume_handler,
self._deltatar, self._cwd, is_full,
- os.path.dirname(index), self._deltatar.crypto_ctx)
+ os.path.dirname(index), self._deltatar.decryptor)
)
self._data.append(s)
else:
# update the new_volume_handler of tar_obj
tarobj.new_volume_handler = partial(self.new_volume_handler,
self._deltatar, self._cwd, True, os.path.dirname(backup_path),
- self._deltatar.crypto_ctx)
+ self._deltatar.decryptor)
s = dict(
curr_vol_no = None,
vol_fd = None,
fileobj=index_data['vol_fd'],
format=tarfile.GNU_FORMAT,
concat_compression='#gz' in self._deltatar.mode,
- encryption=self._deltatar.crypto_ctx,
+ encryption=self._deltatar.decryptor,
new_volume_handler=index_data['new_volume_handler'],
save_to_members=False)