# establishing the Tarfile stream iff a password is supplied.
crypto_ctx = None
- # When encrypting, the salt is created by the first crypto operation, i. e.
- # opening the index for writing. The subsequently opened archive uses the
- # same salt.
- nacl = None
-
# python logger object.
logger = None
inheriting the encryption and compression settings from the backup.
Returns a file object ready to use.
+ :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.
else:
comptype = 'tar'
- encver = None
- counter = None
- if self.crypto_ctx is not None and kind == AUXILIARY_FILE_INFO:
- counter = crypto.AES_GCM_IV_CNT_INFOFILE
-
- return tarfile._Stream(name=path, mode=mode, comptype=comptype,
+ sink = tarfile._Stream(name=path, mode=mode, comptype=comptype,
+ concat_stream=True, # no global zlib header
bufsize=tarfile.RECORDSIZE, fileobj=None,
- encryption=self.crypto_ctx, enccounter=counter)
+ encryption=self.crypto_ctx)
+ if self.crypto_ctx is not None and mode == "w":
+ counter = None
+ if kind == AUXILIARY_FILE_INFO:
+ counter = crypto.AES_GCM_IV_CNT_INFOFILE
+ sink._init_write_encrypt (path, counter)
+
+ return sink
+
def create_full_backup(self, source_path, backup_path,
max_volume_size=None, extra_data=dict()):
# 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') # **NOT** an fd
- if index_sink.encryption is not None:
- self.nacl = index_sink.encryption.nacl
- dummyhdr = index_sink.encryption.next (path)
- index_sink.write (dummyhdr)
+ index_sink = self.open_auxiliary_file(index_path, 'w')
index_sink.write (index_accu.getvalue ())
- index_sink.close ()
+ index_sink.close (close_fileobj=True)
def create_diff_backup(self, source_path, backup_path, previous_index_path,
max_volume_size=None, extra_data=dict()):
remainder = -1 # track size in encrypted entries
def __init__(self, name, mode, comptype, fileobj, bufsize,
- concat_stream=False, encryption=None, enccounter=None,
- compresslevel=9):
+ concat_stream=False, encryption=None, compresslevel=9):
"""Construct a _Stream object.
"""
self._extfileobj = True
except ImportError:
raise CompressionError("zlib module is not available")
self.zlib = zlib
- if mode == "r":
- self._init_read_gz()
- self.exception = zlib.error
- elif mode == "w" and concat_stream is False:
- self._new_gz_block()
+ if concat_stream is False:
+ if mode == "r":
+ self._init_read_gz()
+ self.exception = zlib.error
+ elif mode == "w":
+ self._new_gz_block()
self.crc = zlib.crc32(b"") & 0xFFFFffff
elif comptype == "bz2":
self.close()
- def _init_write_encrypt (self, entry=None):
+ def _init_write_encrypt (self, entry=None, counter=None):
"""Save position for delayed write of header; fill the header location
with dummy bytes."""
if self.encryption is not None:
# secondly, assemble the header with the updated parameters
# and commit it directly to the underlying stream, bypassing the
# encryption layer in .__write().
- dummyhdr = self.encryption.next (entry)
+ dummyhdr = self.encryption.next (entry, counter=counter)
if dummyhdr is None:
raise EncryptionError ("Crypto.next(): bad dummy header") # XXX
Returns the list of IV fixed parts as used during encryption.
"""
- fixed = None
if self.encryption is not None \
and self.lasthdr is not None :
self.__sync ()
dpos = pos1 - self.lasthdr
assert dpos == crypto.PDTCRYPT_HDR_SIZE
self.fileobj.seek_set (pos0)
- data, hdr, fixed = self.encryption.done (dummy)
+ data, hdr, _ = self.encryption.done (dummy)
self.__write_to_file(hdr, pos=self.lasthdr)
self.__write_to_file(data) # append remainder of data
self.lasthdr = -1
- return fixed
def _finalize_write_gz (self):
"""Close the _Stream object. No operation should be
done on it afterwards.
"""
- fixed = None
if self.closed:
return
if close_fileobj is True:
if self.mode == "w":
# end of Tar archive marker (two empty blocks) was written
- fixed = self._finalize_write_encrypt ()
+ self._finalize_write_encrypt ()
if not self._extfileobj:
self.fileobj.close()
else:
raise CompressionError("bad gzip crc")
self.closed = True
- return fixed
-
def _init_read_gz(self):
"""Initialize for reading a gzip compressed fileobj.
"""
- if getattr(self, "zlib", None) is None:
- return
self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS)
# taken from gzip.GzipFile with some alterations