return pos - off
+def readable_objects_offsets (ifd, secret, cands):
+ """
+ From a list of candidates, locate the ones that mark the start of actual
+ readable PDTCRYPT objects.
+ """
+ good = []
+ nobj = 0
+ for cand in cands:
+ nobj += 1
+ vdt, hdr = inspect_hdr (ifd, cand)
+ if vdt == HDR_CAND_JUNK:
+ pass # ignore unreadable ones
+ elif vdt in [HDR_CAND_GOOD, HDR_CAND_FISHY]:
+ off0 = cand + PDTCRYPT_HDR_SIZE
+ ok = try_decrypt (ifd, off0, hdr, secret) == hdr ["ctsize"]
+ if ok is True:
+ good.append (cand)
+ return good
+
+
+def reconstruct_offsets (fname, secret):
+ ifd = os.open (fname, os.O_RDONLY)
+
+ try:
+ cands = locate_hdr_candidates (ifd)
+ return readable_objects_offsets (ifd, secret, cands)
+ finally:
+ os.close (ifd)
+
+
###############################################################################
## passthrough / null encryption
###############################################################################
outfd = -1
oflags = os.O_CREAT | os.O_WRONLY
- if PDTCRYPT_OVERWRITE is True:
+ if force is True:
oflags |= os.O_TRUNC
else:
oflags |= os.O_EXCL
def parse_argv (argv):
+ global PDTCRYPT_OVERWRITE
global SELF
mode = PDTCRYPT_DECRYPT
secret = None
outsspec = checked_arg ()
if PDTCRYPT_VERBOSE is True: noise ("PDT: decrypt to %s" % outsspec)
elif arg in [ "-f", "--force" ]:
- global PDTCRYPT_OVERWRITE
PDTCRYPT_OVERWRITE = True
if PDTCRYPT_VERBOSE is True: noise ("PDT: overwrite existing files")
elif arg in [ "-S", "--split" ]:
outsspec = checked_arg ()
if PDTCRYPT_VERBOSE is True: noise ("PDT: decrypt to %s" % outsspec)
elif arg in [ "-f", "--force" ]:
- global PDTCRYPT_OVERWRITE
PDTCRYPT_OVERWRITE = True
if PDTCRYPT_VERBOSE is True: noise ("PDT: overwrite existing files")
else:
disaster=tarfile.TOLERANCE_RECOVER)
- def rescue_backup(self, target_path, backup_indexes_paths=[],
+ def rescue_backup(self, target_path, backup_tar_path,
restore_callback=None):
"""
More aggressive “unfsck” mode: do not rely on the index data as the
files may be corrupt; skim files for header-like information and
attempt to retrieve the data.
"""
+ faux_index = tarfile.gen_rescue_index(backup_tar_path,
+ password=self.password,
+ key=self.crypto_key)
+
return self.restore_backup(target_path,
- backup_indexes_paths=backup_indexes_paths,
+ backup_index=faux_index,
disaster=tarfile.TOLERANCE_RESCUE)
return tarinfo
+#---------------------------------------------------------
+# support functionality for rescue mode
+#---------------------------------------------------------
+
+def gen_rescue_index (backup_tar_path, password=None, key=None):
+ psidx = [] # pseudo index, return value
+ offsets = None
+ secret = None
+
+ if password is not None:
+ secret = (crypto.PDTCRYPT_SECRET_PW, password)
+ elif key is not None:
+ secret = (crypto.PDTCRYPT_SECRET_KEY, key)
+
+ if secret is not None:
+ offsets = crypto.reconstruct_offsets (backup_tar_path, secret)
+
+ return psidx
#--------------------
# exported functions