From: Philipp Gesang Date: Mon, 24 Apr 2017 09:37:23 +0000 (+0200) Subject: implement passthrough mode in crypto.py X-Git-Tag: v2.2~7^2~150 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=89e1073cdfe9b6203d45f091a5788f11d1d49230;p=python-delta-tar implement passthrough mode in crypto.py When invoked with --no-decrypt, write object headers and ciphertext to output. Combined with --split this allows extracting encrypted objects from the archive. --- diff --git a/deltatar/crypto.py b/deltatar/crypto.py index 5b1c004..3339878 100755 --- a/deltatar/crypto.py +++ b/deltatar/crypto.py @@ -774,6 +774,32 @@ def noise (*a, **b): print (file=sys.stderr, *a, **b) +class PassthroughDecryptor (object): + + curhdr = None # write current header on first data write + + def __init__ (self): + if PDTCRYPT_VERBOSE is True: + noise ("PDT: no encryption; data passthrough") + + def next (self, hdr): + ok, curhdr = hdr_make (hdr) + if ok is False: + raise PDTDecryptionError ("bad header %r" % hdr) + self.curhdr = curhdr + + def done (self): + if self.curhdr is not None: + return self.curhdr + return b"" + + def process (self, d): + if self.curhdr is not None: + d = self.curhdr + d + self.curhdr = None + return d + + def depdtcrypt (mode, pw, ins, outs): """ Remove PDTCRYPT layer from obj encrypted with pw. Used on a Deltatar @@ -781,13 +807,17 @@ def depdtcrypt (mode, pw, ins, outs): """ ctleft = -1 # length of ciphertext to consume ctcurrent = 0 # total ciphertext of current object - decr = Decrypt (pw, strict_ivs=PDTCRYPT_STRICTIVS) # decryptor total_obj = 0 # total number of objects read total_pt = 0 # total plaintext bytes total_ct = 0 # total ciphertext bytes total_read = 0 # total bytes read outfile = None # Python file object for output + if mode & PDTCRYPT_DECRYPT: # decryptor + decr = Decrypt (pw, strict_ivs=PDTCRYPT_STRICTIVS) + else: + decr = PassthroughDecryptor () + def nextout (_): """Dummy for non-split mode: output file does not vary.""" return outs @@ -887,6 +917,7 @@ def depdtcrypt (mode, pw, ins, outs): noise (reduce (lambda a, e: (a + "\n" if a else "") + "PDT:\t· " + e, pretty.splitlines (), "")) ctcurrent = ctleft = hdr ["ctsize"] + decr.next (hdr) total_obj += 1 # used in file counter with split mode @@ -1058,7 +1089,7 @@ def parse_argv (argv): usage (err=True) raise Unreachable else: - outs = deptdcrypt_mk_stream (PDTCRYPT_SINK , outsspec or "-") + outs = deptdcrypt_mk_stream (PDTCRYPT_SINK, outsspec or "-") return mode, pw, ins, outs @@ -1075,6 +1106,14 @@ def main (argv): noise ("PDT: Did you specify the correct password?") noise ("") return 1 + except PDTSplitError as exn: + noise ("PDT: Split operation failed:") + noise ("PDT:") + noise ("PDT: “%s”" % exn) + noise ("PDT:") + noise ("PDT: Hint: target directory should to be empty.") + noise ("") + return 1 if PDTCRYPT_VERBOSE is True: noise ("PDT: decryption successful" )