pinentry w bemenu
This commit is contained in:
parent
e0b0296509
commit
1a7674c83a
1 changed files with 299 additions and 0 deletions
299
scripts/anypinentry
Executable file
299
scripts/anypinentry
Executable 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"
|
||||||
|
|
Loading…
Reference in a new issue