diff options
author | Matěj Cepl <mcepl@cepl.eu> | 2023-05-17 17:51:52 +0200 |
---|---|---|
committer | Matěj Cepl <mcepl@cepl.eu> | 2023-08-11 11:59:00 +0200 |
commit | a67f3096128ff26b0a58e4eb09ae57756d6fd97c (patch) | |
tree | a5217ebd8817a4daabdcf595e62bca90ecbc5c96 /pinentry-rofi.py | |
parent | df3c4ae12a602d5316d16bf331644aff842a24c2 (diff) | |
download | pinentry-rofi-a67f3096128ff26b0a58e4eb09ae57756d6fd97c.tar.gz |
fix: First rewrite to Python should be complete, except it doesn't work.
Diffstat (limited to 'pinentry-rofi.py')
-rwxr-xr-x[-rw-r--r--] | pinentry-rofi.py | 103 |
1 files changed, 92 insertions, 11 deletions
diff --git a/pinentry-rofi.py b/pinentry-rofi.py index 3ce5556..e2266e6 100644..100755 --- a/pinentry-rofi.py +++ b/pinentry-rofi.py @@ -1,30 +1,111 @@ +#!/usr/bin/env python3 +# Some documentation +# https://info2html.sourceforge.net/cgi-bin/info2html-demo/info2html?(pinentry)Protocol +# https://superuser.com/a/1655428 + +# Although it is called a PIN-Entry, it does allow to enter reasonably +# long strings (at least 2048 characters are supported by every +# pinentry). + +# The client using the PIN-Entry has to check for correctness. + +# Note that all strings are expected to be encoded as UTF-8; +# PINENTRY takes care of converting it to the locally used codeset. +# To include linefeeds or other special characters, you may +# percent-escape them (i.e. a line feed is encoded as `%0A', the +# percent sign itself is encoded as `%25'). + + +import io +import os +import re +import logging import subprocess -rofi = ['rofi', '-dmenu', '-input', '/dev/null', '-password'] +logging.basicConfig(format='%(levelname)s:%(funcName)s:%(message)s', + filename="/tmp/pinentry-log.txt", + level=logging.DEBUG) +log = logging.getLogger() + +rofi_cmd = ['rofi', '-dmenu', '-input', '/dev/null', '-password'] + +GPIN_VALID = re.compile(r'([A-Za-z_]+)=(.+)$') def assuan_send(t): + log.debug(f'assuan_send: {t}') print(t) assuan_send("OK Please go ahead") +win_title = "Prompt for password" +win_prompt = "Password" +win_mesg = '' + while True: line = input() + log.debug(f'line = {line}') ok = True - if line.startswith("OPTION "): + if line.startswith("OPTION"): # OPTION grab # OPTION ttyname=/dev/pts/1 # OPTION ttytype=tmux-256color # OPTION lc-messages=C - # OPTI - pass - elif line == "BYE": - break + assuan_send('OK') + elif line.startswith("GETINFO"): + info = line.split()[1].strip() + # case ( info ) + # when 'pid' + # assuan_send "D #{Process.pid}" + # end + assuan_send('OK') + elif line.startswith("SETKEYINFO"): + # TODO SETKEYINFO s/FINGERPRINT + assuan_send('OK') + elif line.startswith(("SETOK","SETNOTOK","SETERROR","SETCANCEL","SETTIMEOUT", + "SETQUALITYBAR","SETGENPIN")): + assuan_send('OK') + elif line.startswith(("CONFIRM","MESSAGE",)): + assuan_send('OK') + elif line.startswith("SETDESC"): + #SETDESC Please enter the passphrase for the ssh key%0A ke:yf:in:ge:rp:ri:nt + # rofi << '-mesg' << $1.gsub('<', '<').gsub(/%([0-9A-Fa-f]{2})/) { $1.to_i(16).chr } + win_mesg = " ".join(line.split()[1:]).strip() + assuan_send('OK') + elif line.startswith("SETPROMPT"): + #SETPROMPT Passphrase: + win_prompt = line.split()[1].strip() + assuan_send('OK') + elif line.startswith("GETPIN"): + passw = None + with subprocess.check_output(['systemctl', '--user', 'show-environment']) as env_f: + for env_line in env_f: + log.debug(f'env_line = {env_line}') + if (env_match := GPIN_VALID.match(env_line)): + log.debug(f'env_match = {env_match}') + var, val = env_match.groups()[1:] + log.debug(f'var, val = {var}, {val}') + os.env[var] = val + + rofi_cmd.extend(('-p', win_prompt)) + rofi_cmd.extend(('-title', win_title)) + if win_mesg: + rofi_cmd.extend(('-mesg', win_mesg)) + try: + passw = subprocess.run(rofi_cmd, check=True, capture_output=True).stdout.strip() + except subprocess.SubprocessError as ex: + # assuan_send "ERR 83886179 Operation cancelled <rofi>" + log.exception(f"rofi failed to run: {ex.returncode}, out: {ex.output}, err: {ex.stderr}") + exit(ex.returncode) + ok = false + else: + if passw: + assuan_send(f'D {passw}') + assuan_send('OK') + elif line.startswith("BYE"): + exit(0) else: - rofi.append(line.strip()) - ok = False + assuan_send("BYE") + exit(1) if ok: break - -password = subprocess.check_output(rofi).decode().strip() -assuan_send(password) |