def main(args, keys): if args.mode == MODE_ENCRYPT: # check if destination exists if args.force is False and os.path.exists(args.outputfile): if ask_overwrite(args.outputfile) is False: return # args.inputfile is a list of files for f in args.inputfile: if not os.path.exists(f): raise SesameError('File doesn\'t exist at {0}'.format(f)) encrypt(args.inputfile, args.outputfile, keys) elif args.mode == MODE_DECRYPT: # fail if input file doesn't exist if not os.path.exists(args.inputfile): raise SesameError('File doesn\'t exist at {0}'.format(args.inputfile)) # check input not zero-length statinfo = os.stat(args.inputfile) if statinfo.st_size == 0: raise SesameError('Input file is zero-length') decrypt(args.inputfile, args.force, args.output_dir, args.try_all)
def decrypt(inputfile, keys, force=False, output_dir=None, try_all=False): with make_secure_temp_directory() as working_dir: # create a temporary file working_file = tempfile.mkstemp(dir=working_dir) success = False # iterate all keys; first successful key will break for key in keys: try: # decrypt the input file with open(inputfile, 'rb') as i: data = zlib.decompress(key.Decrypt(i.read())) # write into our working file with os.fdopen(working_file[0], 'wb') as o: o.write(data) success = True break except InvalidSignatureError as e: if try_all is False: raise SesameError('Incorrect key') except KeyczarError as e: raise SesameError( 'An error occurred in keyczar.Decrypt\n {0}:{1}'.format( e.__class__.__name__, e ) ) # check failure if success is False: raise SesameError('No valid keys for decryption') # untar the decrypted temp file with tarfile.open(working_file[1], 'r') as tar: tar.extractall(path=working_dir) # get list of all files in working dir, including their full path working_items = [ os.path.join(rootdir[len(working_dir)+1:], filename) for rootdir, dirnames, filenames in os.walk(working_dir) for filename in filenames if filename != os.path.basename(working_file[1]) ] # move all files to the output path for name in working_items: # create some full paths path = os.path.join(working_dir, name) dest = os.path.join(output_dir, name) # ask user about overwrite if force is False and os.path.exists(dest): if ask_overwrite(dest) is False: continue # ensure destination dirs exist mkdir_p(os.path.dirname(dest)) # move file to output_dir shutil.copy(path, dest)