diff options
author | Timo Wilken | 2024-03-09 14:52:56 +0100 |
---|---|---|
committer | Timo Wilken | 2024-03-10 16:19:00 +0100 |
commit | de20fc8d904643ffe6957febfc6a24e57c12b512 (patch) | |
tree | 8177459e40786bd432a37c5833f26350fb689356 /tw/services/files/passmenu | |
parent | da5e9d5ee98dfc216eb7e3b1559c09f4bf868bf6 (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-x | tw/services/files/passmenu | 93 |
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 |