diff --git a/shell/qaskpass b/shell/qaskpass index 9f46a65..6d0c7f5 100755 --- a/shell/qaskpass +++ b/shell/qaskpass @@ -1,11 +1,15 @@ #!/usr/bin/env python3 +import argparse import curses +import hashlib import os import sys import termios import tty -import argparse + +__version__ = "20250309.a" + class getch: def get(self): @@ -18,25 +22,27 @@ class getch: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch + def get_opts(): parser = argparse.ArgumentParser( - description='Colorful password dialog', - epilog="Dialog printed to stderr, user input echoed to stdout, i.e. input=$( qaskpass )") - - parser.add_argument('--title','-t', action='store', default=None, - help="Title for dialog") - parser.add_argument('-w', action='store', type=int, default=5, - help="Width of display area. 0 to disable display.") - - parser.add_argument('--no-color', action='store_true', default=False, - help="Disable colors") + description="Colorful password dialog", + epilog="Dialog printed to stderr, user input echoed to stdout, i.e. input=$( qaskpass )", + ) + parser.add_argument("--title", "-t", action="store", default=None, help="Title for dialog") + parser.add_argument("-w", action="store", type=int, default=5, help="Width of display area. 0 to disable display.") + parser.add_argument("--no-color", action="store_true", default=False, help="Disable colors") + parser.add_argument( + "--expect-sha256", + action="store", + default=None, + help="Show green dots when string matches the sha256 sum. Note: strip newlines before calculating!. Exitcode = 10 if checksum does not match.", + ) + parser.add_argument("--version", action="version", version="%(prog)s {version}".format(version=__version__)) args = parser.parse_args() return args - - def termsize(): rows, columns = os.popen("stty size", "r").read().split() return (int(rows), int(columns)) @@ -57,7 +63,7 @@ class bc: setattr(self, x, "") -def animchar(i, pos, colorpos, width,c): +def animchar(i, pos, colorpos, width, c): if i < 0: return " " if pos == colorpos: @@ -91,15 +97,21 @@ if __name__ == "__main__": c.disable() if opts.title: print(f"{c.y}{c.B}{opts.title}{c.z}", file=sys.stderr) + enter_exitcode = 0 while True: - try: - if opts.w>0: + if opts.w > 0: + dot_color = c.m + if opts.expect_sha256: + enter_exitcode = 10 + if hashlib.sha256(user_input.encode("utf-8")).hexdigest() == opts.expect_sha256: + dot_color = c.g + c.B + enter_exitcode = 0 colorpos = len(user_input) % opts.w - display = c.m + "•••• " + display = dot_color + "•••• " for i in range(opts.w): - display += animchar(len(user_input) - i, i, colorpos,opts.w,c) - display += c.m + " ••••" + c.z + display += animchar(len(user_input) - i, i, colorpos, opts.w, c) + display += dot_color + " ••••" + c.z print("\r" + display, file=sys.stderr, end="") sys.stderr.flush() key = ch.get() @@ -107,7 +119,7 @@ if __name__ == "__main__": if ord(key) == 3: # ctrl-c pquit(e=1) if ord(key) == 13: # enter - pquit(user_input, e=0) + pquit(user_input, e=enter_exitcode) if ord(key) == 27: # esc (also starts control characters key = ch.get() if ord(key) == 27: @@ -121,4 +133,4 @@ if __name__ == "__main__": # ~ print(f'-{ord(key)}-',file=sys.stderr) except Exception as e: - pquit(s=str(e),e=1) + pquit(s=str(e), e=1)