pinentry w bemenu

This commit is contained in:
tavo-wasd 2024-02-06 23:00:36 -06:00
parent e0b0296509
commit 1a7674c83a

299
scripts/anypinentry Executable file
View file

@ -0,0 +1,299 @@
#!/bin/sh
# Ref: http://info2html.sourceforge.net/cgi-bin/info2html-demo/info2html?%28pinentry%29Protocol
set -e
VERSION="0.1";
if [ -z "$DISPLAY" ]; then
DISPLAY=":1";
export DISPLAY;
fi
prompt_string_default="PIN: "
title="";
prompt_string="$prompt_string_default";
description="";
keyinfo="";
repeat="";
error__password_mismatch="Passwords don't match";
AP_YES="Yes";
AP_NO="No";
prompt_action='/home/tavo/.config/scripts/menu/menu "$AP_PROMPT" pass';
confirm_action='echo -e "$AP_YES\n$AP_NO" | /home/tavo/.config/scripts/menu/menu "$AP_PROMPT"';
display_error_action='notify-send -a "Pinentry" "$AP_ERROR"';
# :: Prompt string (default if empty)
ask_password() {
export AP_PROMPT="${1:-"$prompt_string"}";
printf '' | sh -c "$prompt_action" 2> /dev/null;
}
# :: Prompt string (default if empty)
confirm() {
export AP_PROMPT="${1:-"$prompt_string"}";
export AP_YES; export AP_NO;
printf '' | sh -c "$confirm_action" 2> /dev/null;
}
# :: Error text
show_error() {
export AP_ERROR="$1";
sh -c "$display_error_action" 2> /dev/null;
}
cancelled_error() { echo "ERR 83886179 Operation cancelled <Pinentry>"; }
com_error() { echo "ERR 83886360 IP parameter error <Pinentry>>"; }
not_implemented_error() { echo "ERR 536870981 Not implemented <User defined source 1>"; }
unknown_error() { echo "ERR 536871187 Unknown IPC command <User defined source 1>"; }
reset() {
description=
prompt_string="$prompt_string_default"
keyinfo=
repeat=
error__password_mismatch=
setok=
setnotok=
setcancel=
title=
}
save_option() {
echo "OK";
}
get_info() {
arg=$(echo "$1" | tr a-z A-Z)
case "$arg" in
VERSION) echo "D $VERSION" && echo "OK" ;;
PID) echo "D $$" && echo "OK" ;;
*) com_error ;;
esac;
}
# :: Repeat string -> Password -> OK | ERR
password_prompt() {
pass="";
if pass=$(ask_password "$([ -z "$1" ] && echo "$repeat")"); then
if [ -n "$1" ]; then
password_prompt "" "$pass";
else
# If password repeat attempt failed, try again,
# Else continue
if [ -n "$2" ] && [ "$pass" != "$2" ]; then
show_error "$error__password_mismatch";
password_prompt "$repeat";
else
if [ ! -z "$pass" ]; then
echo "D $pass" |
sed 's/%/%25/; s/\r/%0D/' | # % = 25 and CR = %0D
awk 'BEGIN {ORS="%0A"} /^..*$/ {print}' | # LF = %0A
sed 's/%0A$//' # Strip trailing %0A
echo
fi
echo "OK";
fi;
fi;
else
cancelled_error;
fi;
repeat=
}
# :: OK | ERR
confirm_prompt() {
if [ "$(confirm)" = "$AP_YES" ]; then
echo "OK"
else
cancelled_error;
fi
}
pinentry_help() {
cat <<END
# NOP
# CANCEL
# OPTION
# BYE
# AUTH
# RESET
# END
# HELP
# SETDESC
# SETPROMPT
# SETKEYINFO
# SETREPEAT
# SETREPEATERROR
# SETERROR
# SETOK
# SETNOTOK
# SETCANCEL
# GETPIN
# CONFIRM
# MESSAGE
# SETQUALITYBAR
# SETQUALITYBAR_TT
# SETGENPIN
# SETGENPIN_TT
# GETINFO
# SETTITLE
# SETTIMEOUT
# CLEARPASSPHRASE
END
}
interpret_command() {
# Refuse lines of more than 1000 bytes + newline
if [ $(echo "$1" | wc -c) -gt 1001 ]; then
echo "ERR too long"
return
fi
cmd="$(echo "$1" | cut -d' ' -f1 | tr a-z A-Z)";
data="$(echo "$1" | cut -d' ' -f2-)";
case "${cmd}" in
NOP) ;;
CANCEL) not_implemented_error ;;
OPTION) save_option "$data" ;;
BYE) exit 0 ;;
AUTH) not_implemented_error ;;
RESET) reset ;;
END) not_implemented_error ;;
HELP) pinentry_help ;;
SETDESC) description="$data"; echo "OK" ;;
SETPROMPT) prompt_string="$data"; echo "OK" ;;
SETKEYINFO) keyinfo="$data"; echo "OK" ;;
SETREPEAT) repeat="${data:-"repeat"}"; echo "OK" ;;
SETREPEATERROR) error__password_mismatch="$data"; echo "OK" ;;
SETERROR) not_implemented_error ;;
SETOK) setok="$data" ;;
SETNOTOK) setnotok="$data" ;;
SETCANCEL) setcancel="$data" ;;
GETPIN) password_prompt "$repeat" "" ;;
CONFIRM) confirm_prompt ;;
MESSAGE) not_implemented_error ;;
SETQUALITYBAR) not_implemented_error ;;
SETQUALITYBAR_TT) not_implemented_error ;;
SETGENPIN) not_implemented_error ;;
SETGENPIN_TT) not_implemented_error ;;
GETINFO) get_info "$data" ;;
SETTITLE) title="$data"; echo "OK" ;;
SETTIMEOUT) not_implemented_error ;;
CLEARPASSPHRASE) not_implemented_error ;;
'' | \#*) ;;
*) unknown_error ;;
esac;
}
help() {
echo "Usage: $0 [-D DISPLAY] [--prompt script] [--confirm script] [-hv]";
cat <<END
$0 (pinentry) $VERSION
Copyright (C) 2020 Akshay Nair
This software is released under the MIT License <https://www.mit-license.org/>
END
printf "Usage: %s [options] (-h for help)\n" "$0" >&2
cat <<END
Ask securely for a secret and print it to stdout.
Options:
--prompt CMD How to ask for the secret
--confirm CMD How to confirm the secret
--error-command CMD What to do if secret is not confirmed
CMD will be executed by sh(1). The defaults are:
prompt ='dmenu -P -p "$prompt_string"';
confirm ='echo -e "$AP_YES\n$AP_NO" | dmenu -p "$prompt_string"';
error-command ='notify-send -a "Pinentry" "$error__password_mismatch"';
Standard pinentry options
-d, --debug Turn on debugging output
-D, --display DISPLAY Set the X display
-T, --ttyname FILE Set the tty terminal node name
-N, --ttytype NAME Set the tty terminal type
-C, --lc-ctype STRING Set the tty LC_CTYPE value
-M, --lc-messages STRING Set the tty LC_MESSAGES value
-o, --timeout SECS Timeout waiting for input after this many seconds
-g, --no-global-grab Grab keyboard only while window is focused
-W, --parent-wid Parent window ID (for positioning)
-c, --colors STRING Set custom colors for ncurses
-a, --ttyalert STRING Set the alert mode (none, beep or flash)
Please report bugs to <https://github.com/phenax/any-pinentry/issues>.
END
}
parse_cliargs() {
getopt -T || exit_status=$?
if [ $exit_status -ne 4 ]; then
printf "Your version of getopt(1) is out of date\n" >&2
exit 1
fi
TEMP=$(getopt -n "$0" -o dD:T:N:C:M:o:gWc:a:h \
--long debug,display:,ttyname:,ttytype:,lc-ctype:,lc-messages:,timeout:,no-global-grab,parent-wid,colors:,ttyalert:,prompt:,confirm:,error:,help,version \
-- "$@")
if [ $? -ne 0 ]; then
help
exit 1
fi
eval set -- "$TEMP"
unset TEMP
while true; do
case "$1" in
-d | --debug) shift ;;
-D | --display) shift 2 ;;
-T | --ttyname) shift 2 ;;
-N | --ttytype) shift 2 ;;
-C | --lc-ctype) shift 2 ;;
-M | --lc-messages) shift 2 ;;
-o | --timeout) shift 2 ;;
-g | --no-global-grab) shift ;;
-W | --parent-wid) shift ;;
-c | --colors) echo "colors=$2"; shift 2 ;;
-a | --ttyalert) shift 2 ;;
--error-command) display_error_action="$2"; shift 2 ;;
--prompt) prompt_action="$2"; shift 2 ;;
--confirm) confirm_action="$2"; shift 2 ;;
-h | --help) help && exit 0 ;;
--version) echo "anypinentry-$VERSION" && exit 0 ;;
--) shift; break ;;
*) ;;
esac
done
}
# Main
parse_cliargs "$@";
# Initialize protocol
echo "OK Pleased to meet you"
while read -r line; do
interpret_command "$line";
done;
# "SETERROR"
# "SETOK"
# "SETNOTOK"
# "SETCANCEL"
# "MESSAGE"
# "SETQUALITYBAR"
# "SETQUALITYBAR_TT"
# "SETTIMEOUT"
# "CLEARPASSPHRASE"