def validateReencryptVPath(path): (plainPath, vpath) = validateVPaths(path) if not os.path.exists(vpath): raise errors.VaultError(f"'{vpath}' does not exist") if os.path.exists(plainPath): raise errors.VaultError(f"'{plainPath}' exists") return (plainPath, vpath)
def validateOpenVPath(path): (plainPath, vpath) = validateVPaths(path) if os.path.exists(plainPath): raise errors.VaultError("'" + plainPath + "' exists") if not os.path.exists(vpath): raise errors.VaultError("'" + vpath + "' does not exist") return (plainPath, vpath)
def deleteDir(path): if not re.match("^/\w+/\w+", path): raise errors.VaultError(f"invalid vault directory") log.verbose(f"deleteDir path={path}") if not os.path.exists(path): log.info(f"path {path} does not exist") else: utils.runCommand('delete_dir', path) if os.path.exists(path): raise errors.VaultError(f"error deleting directory {path}")
def validateVPath(path): log.verbose(f"validating path='{path}'") (base, ext) = utils.splitPath(path) log.verbose(f"base={base}, ext={ext}") (vext) = getVPathExt(base + ext) log.verbose(f"vpath ext={vext}") if base == '': raise errors.VaultError(f"Invalid path '{path}' (base)") if ext == '': raise errors.VaultError(f"Invalid path '{path}' (ext)") if vext == '': raise errors.VaultError(f"Invalid path '{path}' (vext)") return (base + ext, base + ext + vext)
def validateVPaths(path): (plainPath, vpath) = validateVPath(path) log.verbose(f"validating plainPath={plainPath}, vpath={vpath}") if os.path.islink(plainPath): raise errors.VaultError("'" + plainPath + "' is a symbolic link") if os.path.exists(plainPath) and os.path.exists(vpath): if os.path.getmtime(plainPath) > os.path.getmtime(vpath): older = f"{plainPath} is more recent" else: older = f"{vpath} is more recent" raise errors.VaultError( f"both '{plainPath}' and '{vpath}' exist ({older})") if os.path.islink(vpath): raise errors.VaultError(f"'{vpath}' is a symbolic link") return (plainPath, vpath)
def encryptFile(srcPath, destPath, pp64): log.verbose(f"encyptFile srcPath={srcPath} destPath={destPath}") passphrase = utils.b642str(pp64) log.sensitive(f"passphrase |{passphrase}|") if os.path.exists(destPath): file.deletePath(destPath) args = [ 'gpg', '--quiet', '--batch', '-c', '--symmetric', '--passphrase-fd', '0', '--output', destPath, srcPath ] log.verbose(f"args: {args}") gpgErrorLog = os.path.join(utils.getVaultDir(), "gpg.stderr.log") log.info(f"encrypting file {srcPath} to {destPath}") try: gpgError = open(gpgErrorLog, "a") except IOError: raise errors.VaultError("Unable to open gpg error log file '" + gpgErrorLog + "'") try: gpg = subprocess.Popen(args=args, shell=False, stdin=subprocess.PIPE, stderr=gpgError) gpg.stdin.write(passphrase.encode('utf-8')) gpg.stdin.close() gpg.wait() if gpg.returncode != 0: raise errors.VaultSecurityError( "Failed to encrypt file '" + srcPath + "'", []) finally: log.verbose("closing gpg error file") if gpgError: gpgError.close
def decryptFile(vpath, destPath, pp64): log.verbose(f"decyptFile vpath={vpath} destPath={destPath}") passphrase = utils.b642str(pp64) log.sensitive(f"passphrase |{passphrase}|") args = [ 'gpg', '--quiet', '--batch', '--ignore-mdc-error', '--decrypt', '--passphrase-fd', '0' ] if destPath is not None: args.extend(['--output', destPath]) args.append(vpath) log.verbose(f"args: {args}") gpgErrorLog = os.path.join(utils.getVaultDir(), "gpg.error.log") try: gpgError = open(gpgErrorLog, "a") except IOError: raise errors.VaultError( f"Unable to open gpg error log file '{gpgErrorlog}'") try: gpg = subprocess.Popen(args=args, shell=False, stdin=subprocess.PIPE, stderr=gpgError) gpg.stdin.write(passphrase.encode('utf-8')) gpg.stdin.close() gpg.wait() if gpg.returncode != 0: raise errors.VaultSecurityError("Failed to decrypt file '" + vpath + "'") finally: log.verbose("closing gpg error file") if gpgError: gpgError.close
def deletePath(path): log.verbose(f"deletePath path={path}") if not os.path.exists(path): log.info("path " + path + " does not exist") else: utils.runCommand('delete_file', path) if os.path.exists(path): raise errors.VaultError(f"error deleting file {path}")
def sendRequest(args): log.verbose(f"sendRequest args={args}") req = " ".join(args) tryAgain = True while tryAgain: tryAgain = False port = getServerPort(utils.getVaultDir()) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: if connect(sock, port): log.verbose("sending request to server") sock.sendall((req + "\n").encode('utf-8')) reply = sock.recv(1024) else: # Assume the server is not running log.info("cannot connect; trying again") time.sleep(1) deleteServerPort(utils.getVaultDir()) tryAgain = True continue finally: sock.close() ret = re.split('\s+', reply.decode('utf-8')) if ret is None or len(ret) < 1: raise VaultError('unable to process reply') log.sensitive(f"response: {ret}") if ret[0] == 'ok': log.verbose('reply ok') return ret[1:] elif ret[0] == 'error': log.verbose(f"reply {ret}") raise errors.VaultSecurityError(str(ret)) else: log.verbose(f"unexpected reply {ret}") raise errors.VaultError('unable to process reply')
def validateEditVPath(path): (plainPath, vpath) = validateVPaths(path) if os.path.exists(plainPath): raise errors.VaultError("'" + plainPath + "' exists") return (plainPath, vpath)