From: Philipp Gesang Date: Thu, 4 May 2017 13:12:50 +0000 (+0200) Subject: write auxiliary files whilst processing the backup X-Git-Tag: v2.2~7^2~132 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=774ca5389c37ff09b7cd5e803dfdc199f1fde898;p=python-delta-tar write auxiliary files whilst processing the backup Introduce a fixed value for the index file counter to allow encryption on the fly. --- diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index 2dcb6ee..62ad560 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -523,16 +523,11 @@ class DeltaTar(object): 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 + return crypto.Encrypt (password, + version=DELTATAR_HEADER_VERSION, + paramversion=self.crypto_paramversion) if mode == CRYPTO_MODE_DECRYPT: - if self.decryptor is None: - self.decryptor = crypto.Decrypt (password) - return + return crypto.Decrypt (password) raise Exception ("invalid encryption mode [%r]" % mode) @@ -546,9 +541,9 @@ class DeltaTar(object): :param mode: IO mode (read or write, ``"r"`` and ``"w"``, respectively). :type mode: str - :param kind: Role of the file, see AUXILIARY_FILE_* constants. The - only special value is AUXILIARY_FILE_INFO which - sets the appropriate counter in the crypto layer. + :param kind: Role of the file, see AUXILIARY_FILE_* constants. + Both the info and the auxiliary file have a globally + unique, constant counter value. :type kind: str ''' if self.index_mode.startswith('gz'): @@ -561,14 +556,16 @@ class DeltaTar(object): crypto_ctx = None enccounter = None if mode == "w": - self.initialize_encryption (CRYPTO_MODE_ENCRYPT) - crypto_ctx = self.encryptor - if crypto_ctx is not None and \ - kind == AUXILIARY_FILE_INFO: - enccounter = crypto.AES_GCM_IV_CNT_INFOFILE + crypto_ctx = self.initialize_encryption (CRYPTO_MODE_ENCRYPT) + if crypto_ctx is not None: + if kind == AUXILIARY_FILE_INFO: + enccounter = crypto.AES_GCM_IV_CNT_INFOFILE + elif kind == AUXILIARY_FILE_INDEX: + enccounter = crypto.AES_GCM_IV_CNT_INDEX + else: + raise Exception ("invalid kind of aux file %r" % kind) elif mode == "r": - self.initialize_encryption (CRYPTO_MODE_DECRYPT) - crypto_ctx = self.decryptor + crypto_ctx = self.initialize_encryption (CRYPTO_MODE_DECRYPT) sink = tarfile._Stream(name=path, mode=mode, comptype=comptype, bufsize=tarfile.RECORDSIZE, fileobj=None, @@ -639,7 +636,8 @@ class DeltaTar(object): raise Exception('Unrecognized extension') # setup for encrypting payload - self.initialize_encryption (CRYPTO_MODE_ENCRYPT) + if self.encryptor is None: + self.encryptor = self.initialize_encryption (CRYPTO_MODE_ENCRYPT) # some initialization self.vol_no = 0 @@ -648,7 +646,10 @@ class DeltaTar(object): vol_name = self.volume_name_func(backup_path, True, 0) tarfile_path = os.path.join(backup_path, vol_name) - index_accu = io.BytesIO () + # init index + index_name = self.index_name_func(True) + index_path = os.path.join(backup_path, index_name) + index_sink = self.open_auxiliary_file(index_path, 'w') cwd = os.getcwd() @@ -674,12 +675,12 @@ class DeltaTar(object): # wraps some args from context into the handler 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')) + index_sink.write(bytes('{"type": "python-delta-tar-index", "version": 1, "backup-type": "full", "extra_data": %s}\n' % extra_data_str, 'UTF-8')) s = bytes('{"type": "BEGIN-FILE-LIST"}\n', 'UTF-8') # calculate checksum and write into the stream crc = binascii.crc32(s) & 0xFFFFffff - index_accu.write(s) + index_sink.write(s) # start creating the tarfile tarobj = tarfile.TarFile.open(tarfile_path, @@ -710,21 +711,16 @@ class DeltaTar(object): # store the stat dict in the index s = bytes(json.dumps(statd) + '\n', 'UTF-8') crc = binascii.crc32(s, crc) & 0xffffffff - index_accu.write(s) + index_sink.write(s) s = bytes('{"type": "END-FILE-LIST"}\n', 'UTF-8') crc = binascii.crc32(s, crc) & 0xffffffff - index_accu.write(s) + index_sink.write(s) s = bytes('{"type": "file-list-checksum", "checksum": %d}\n' % crc, 'UTF-8') - index_accu.write(s) + index_sink.write(s) + os.chdir(cwd) tarobj.close() - - # init index - index_name = self.index_name_func(True) - index_path = os.path.join(backup_path, index_name) - index_sink = self.open_auxiliary_file(index_path, 'w') - index_sink.write (index_accu.getvalue ()) index_sink.close (close_fileobj=True) def create_diff_backup(self, source_path, backup_path, previous_index_path, @@ -802,7 +798,8 @@ class DeltaTar(object): raise Exception('Unrecognized extension') # setup for encrypting payload - self.initialize_encryption (CRYPTO_MODE_ENCRYPT) + if self.encryptor is None: + self.encryptor = self.initialize_encryption (CRYPTO_MODE_ENCRYPT) # some initialization self.vol_no = 0 @@ -1238,7 +1235,8 @@ class DeltaTar(object): volume_path = os.path.join(cwd, volume_path) tarobj.open_volume(volume_path, encryption=encryption) - self.initialize_encryption (CRYPTO_MODE_DECRYPT) + if self.decryptor is None: + self.decryptor = self.initialize_encryption (CRYPTO_MODE_DECRYPT) backup_path = os.path.dirname(backup_tar_path) if not os.path.isabs(backup_path): @@ -1345,8 +1343,8 @@ class DeltaTar(object): os.chdir(target_path) # setup for decrypting payload - if self.password is not None: - self.decryptor = crypto.Decrypt (self.password) + if self.decryptor is None: + self.decryptor = self.initialize_encryption (CRYPTO_MODE_DECRYPT) if mode == 'tar': index_it = self.iterate_tar_path(backup_tar_path)