diff options
-rwxr-xr-x | pinentry-rofi.sh (renamed from pinentry-rofi.py) | 160 |
1 files changed, 81 insertions, 79 deletions
diff --git a/pinentry-rofi.py b/pinentry-rofi.sh index 9d267ba..661152e 100755 --- a/pinentry-rofi.py +++ b/pinentry-rofi.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/bin/bash # SPDX-FileCopyrightText: 2016 Quentin "Sardem FF7" Glidic # SPDX-FileCopyrightText: 2018-2023 Fredrik Salomonsson <plattfot@posteo.net> @@ -22,32 +22,25 @@ # percent-escape them (i.e. a line feed is encoded as `%0A', the # percent sign itself is encoded as `%25'). -__version__="0.0.1" +VERSION="0.0.1" -import io -import os -import re -import logging -import subprocess +log_debug() { + echo "$@" >> /tmp/pinentry-log.txt +} -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" -rofi_cmd = ['rofi', '-dmenu', '-input', '/dev/null', '-password'] -GPIN_VALID = re.compile(r'([A-Za-z_]+)=(.+)$') +assuan_send() { + log_debug "assuan_send: $*" + echo "$@" +} -def assuan_send(t): - log.debug(f'assuan_send: {t}') - print(t) +assuan_send "OK Please go ahead" -assuan_send("OK Please go ahead") - -win_title = "Prompt for password" -win_prompt = "Password" -win_mesg = '' +win_title="Prompt for password" +win_prompt="Password" +win_mesg="" # gpg-agent[676]: DBG: chan_9 -> OK Pleased to meet you, process 3073 # gpg-agent[676]: DBG: chan_9 <- RESET @@ -77,72 +70,81 @@ win_mesg = '' # gpg-agent[676]: DBG: chan_9 -> OK # gpg-agent[676]: DBG: chan_9 <- KEYINFO 8EA96F4B4BD616DA44A2E297F31C0448A74B9D33 -while True: - line = input() - log.debug(f'line = {line}') - ok = True - if line.startswith("OPTION"): +while : ; do + read -r line + log_debug "line=$line" + if [[ "$line" =~ ^OPTION ]] ; then # OPTION grab # OPTION ttyname=/dev/pts/1 # OPTION ttytype=tmux-256color # OPTION lc-messages=C - assuan_send('OK') - elif line.startswith("GETINFO"): + assuan_send "OK" + elif [[ "$line" =~ ^GETINFO ]] ; then # https://www.gnupg.org/documentation/manuals/gnupg/Agent-GETINFO.html # version or pid of this script? # gpg-agent --version works but it must be filtered - subcommand = line.split(' ')[1] - log.debug(f'subcommand = {subcommand}') - if subcommand == 'version': - assuan_send(f'D {__version__}') - elif subcommand == 'pid': - assuan_send(f'D {os.getpid()}') - assuan_send('OK') - elif line.startswith("SETKEYINFO"): + IFS=" " read -ra line_arr <<< "$line" + subcommand=${line_arr[1]} + log_debug "subcommand=${subcommand}" + if [[ "$subcommand" == "version" ]] ; then + assuan_send "D ${VERSION}" + elif [[ "$subcommand" == "pid" ]] ; then + assuan_send f"D {os.getpid()}" + fi + assuan_send "OK" + elif [[ "$line" =~ ^SETKEYINFO ]] ; then # 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"): + assuan_send "OK" + elif [[ "$line" =~ ^SETOK|^SETNOTOK|^SETERROR|^SETCANCEL|^SETTIMEOUT|^SETQUALITYBAR|^SETGENPIN ]] ; then + assuan_send "OK" + elif [[ "$line" =~ ^CONFIRM|^MESSAGE ]] ; then + assuan_send "OK" + elif [[ "$line" =~ ^SETDESC ]] ; then #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"): + # rofi << "-mesg" << $1.gsub("<", "<").gsub(/%([0-9A-Fa-f]{2})/) { $1.to_i(16).chr } + IFS=" " read -ra line_arr <<< "$line" + unset "line_arr[0]" + win_mesg="${line_arr[*]}" + assuan_send "OK" + elif [[ "$line" =~ ^SETPROMPT ]] ; then #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: + IFS=" " read -ra line_arr <<< "$line" + win_prompt="${line_arr[1]}" + assuan_send "OK" + elif [[ "$line" =~ ^GETPIN ]] ; then + passw=None + sys_env="$(systemctl --user show-environment)" + IFS=" " read -ra sys_env_arr <<< "$sys_env" + for env_line in "${sys_env_arr[@]}" ; do + log_debug "env_line=${env_line}" + # GPIN_VALID=re.compile(r) + if [[ "$env_line" =~ ^[A-Za-z_]+=\(.\+\)$ ]] ; then + log_debug "env_match=${BASH_REMATCH[*]}" + export "${BASH_REMATCH[1]}=${BASH_REMATCH[2]}" + fi + done + + rofi_cmd+=" -p ${win_prompt}" + rofi_cmd+=" -title ${win_title}" + if [[ -n "${win_mesg}" ]] ; then + rofi_cmd+=" -mesg ${win_mesg}" + fi + passw="$(eval ${rofi_cmd})" + passw_err=$? + if [[ ${passw_err} -ne 0 ]] ; then # 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: - assuan_send("BYE") - exit(1) + log_debug "rofi failed to run: ${passw} (${passw_err})" + exit $passw_err + else + if [[ -n ${passw} ]] ; then + assuan_send "D ${passw}" + fi + fi + assuan_send "OK" + elif [[ ${line} =~ ^BYE ]] ; then + exit 0 + else + assuan_send "BYE" + exit 1 + fi +done |