aboutsummaryrefslogtreecommitdiff
path: root/tw/services/files/passmenu
diff options
context:
space:
mode:
authorTimo Wilken2024-03-09 14:52:56 +0100
committerTimo Wilken2024-03-10 16:19:00 +0100
commitde20fc8d904643ffe6957febfc6a24e57c12b512 (patch)
tree8177459e40786bd432a37c5833f26350fb689356 /tw/services/files/passmenu
parentda5e9d5ee98dfc216eb7e3b1559c09f4bf868bf6 (diff)
Separate home service into PIM, dev env and graphical parts
This means we only instantiate Shepherd and mcron services if we really need them, to avoid annoyance on servers.
Diffstat (limited to 'tw/services/files/passmenu')
-rwxr-xr-xtw/services/files/passmenu93
1 files changed, 93 insertions, 0 deletions
diff --git a/tw/services/files/passmenu b/tw/services/files/passmenu
new file mode 100755
index 00000000..9bf7f7e3
--- /dev/null
+++ b/tw/services/files/passmenu
@@ -0,0 +1,93 @@
+#!/bin/sh -eu
+
+usage() {
+ cat << EOF
+$(basename "$0") [-c | -p | -a]
+
+ -c, --clip copy the user-selected password to the clipboard
+ -p, --type-pass auto-type the user-selected password only
+ -o, --type-otp auto-type the user-selected six-digit OTP code
+ -a, --type-all auto-type the user-selected username <tab> password
+ -h, --help show this help message and exit
+ -v, --version show the program version number and exit
+
+Later options override conflicting earlier ones.
+If no option is given, -c/--clip is the default.
+GNU-style combination of short options (e.g. -pa) is not supported.
+
+Abnormal exit codes:
+ 1 no password selected by user
+ 2 invalid command-line argument
+ 3 internal error
+
+(C) 2019-2023 Timo Wilken; MIT Licence.
+Adapted from https://git.zx2c4.com/password-store/tree/contrib/dmenu/passmenu.
+EOF
+}
+
+version() {
+ # Changelog:
+ # 1.0.0 (2019-??-??) initial version
+ # 1.0.1 (2022-07-17) script formatting; throw away passwords asap
+ # 1.0.2 (2022-10-??) remove fix_xdotool; this should be done on login
+ # 1.0.3 (2023-12-11) customise prompt to show what will be typed
+ echo "$(basename "$0") 1.0.3"
+}
+
+password_names() {
+ find "${PASSWORD_STORE_DIR-$HOME/.password-store}" -name '*.gpg' -type f \
+ -printf '%P\n' | sed 's/\.gpg$//'
+}
+
+extract_key() {
+ sed -rn "s/^$1:\\s+(.+)\$/\\1/p"
+}
+
+type_stdin() {
+ tr -d '\n' | xdotool getactivewindow type --clearmodifiers --file -
+}
+
+## Command-line arguments
+while [ $# -gt 0 ]; do
+ case "$1" in
+ -o|--type-otp) mode=type-otp prompt=OTP; shift;;
+ -p|--type-pass) mode=type-pass prompt=Password; shift;;
+ -a|--type-all) mode=type-all prompt=Login; shift;;
+ -c|--clip) mode=clip prompt=Copy; shift;;
+ -h|--help) usage; exit;;
+ -v|--version) version; exit;;
+
+ *)
+ echo "$(basename "$0"): unknown option: $1" >&2
+ usage >&2
+ exit 2;;
+ esac
+done
+: "${mode=clip}" "${prompt=Copy}"
+
+## Password selection menu
+password_name=$(password_names | rofi -dmenu -i -p "$prompt" -no-custom)
+[ -n "$password_name" ] || exit 1
+
+## Password typing
+case "$mode" in
+ clip)
+ # Suppress "copied ... to clipboard" notice on stdout.
+ pass show --clip "$password_name" > /dev/null;;
+
+ type-otp)
+ pass otp "$password_name" | type_stdin;;
+
+ type-pass|type-all)
+ entry=$(pass show "$password_name")
+ if [ "$mode" = type-all ]; then
+ echo "$entry" | extract_key username | type_stdin
+ xdotool getactivewindow key Tab
+ fi
+ echo "$entry" | head -1 | type_stdin
+ unset entry;;
+
+ *)
+ echo "$(basename "$0"): internal error: unknown mode: $mode" >&2
+ exit 3;;
+esac