diff --git a/pash b/pash index 4180492..ac4dc6c 100755 --- a/pash +++ b/pash @@ -45,7 +45,6 @@ pw_add() { # leaking the password through the '/proc' filesystem. # # Heredocs are sometimes implemented via temporary files, - # however this is typically done using 'mkstemp()' which # is more secure than a leak in '/proc'. "$gpg" "$@" -o "$name.gpg" <<-EOF && $pass @@ -93,11 +92,94 @@ pw_list() { find . -type f -name \*.gpg | sed 's/..//;s/\.gpg$//' } -pw_tree() { - command -v tree >/dev/null 2>&1 || - die "'tree' command not found" +pw_otp() { + command -v oathtool >/dev/null 2>&1 || + die "'oathtool' command not found" - tree --noreport | sed 's/\.gpg$//' + [ "$1" = "" ] && usage + + printf "Enter a name: " + read name + + case "$1" in + "add") + + sread secret "Enter OTP secret" + sread secret2 "Enter OTP secret (again)" + + [ "$secret" = "$secret2" ] || die "Secret do not match" + + if [ "$PASH_KEYID" ]; then + set -- --trust-model always -aer "$PASH_KEYID" + else + set -- -c + fi + + "$gpg" "$@" -o "$name.gpg" <<-EOF && + $secret + EOF + printf '%s\n' "Saved '$name' to the otp directory" + ;; + + "copy") + : "${PASH_CLIP:=xclip -sel c}" + + [ "$PASH_TIMEOUT" != off ] && { + printf 'Clearing clipboard in "%s" seconds.\n' "${PASH_TIMEOUT:=15}" + + sleep "$PASH_TIMEOUT" || kill 0 + $PASH_CLIP /dev/null || : + } + ;; + + "list") + find . -type f -name \*.gpg | sed 's/..//;s/\.gpg$//' + ;; + + "show") + oathtool -b --totp "$(gpg -dq $PASH_DIR/$name.gpg)" + ;; + + *) + usage ;; + esac +} + +pw_menu() { + # ISSUES + # - checks continue until end so wofi would always be set + # as the menu. this can be easily fixed with a lengthier check + # system, or by forcing the user to edit the code. for their + # particular menu program. + # + # - password is not saved to clipboard when "pash menu" is run + # from anything but a terminal. so gui menus will not work. a + # solution for this that i use on my own system is to open st + # and run the gpg decrypt command in that new window and keep + # it open for PASH_TIMEOUT seconds. another solution is to type + # out the password using xdotool type. another option is to do + # what pass does and not require a password. not 100% how that + # program does it though. + # + # right now "pash menu" can be run from the terminal using fzf + + #command -v dmenu >/dev/null 2>&1 && menu="dmenu" || + command -v fzf >/dev/null 2>&1 && menu="fzf" || + # command -v rofi >/dev/null 2>&1 && menu="rofi" || + # command -v wofi >/dev/null 2>&1 && menu="wofi" || + die "no menu program found" + + account=$(echo $(pash list) | sed 's/ /\n/g' | $menu) + pw_copy $account } yn() { @@ -155,12 +237,18 @@ die() { usage() { printf %s "\ pash 2.3.0 - simple password manager. -=> [a]dd [name] - Create a new password entry. -=> [c]opy [name] - Copy entry to the clipboard. -=> [d]el [name] - Delete a password entry. -=> [l]ist - List all entries. -=> [s]how [name] - Show password for an entry. -=> [t]ree - List all entries in a tree. +=> [a]dd [name] - Create a new password entry. +=> [c]opy [name] - Copy entry to the clipboard. +=> [d]el [name] - Delete a password entry. +=> [s]how [name] - Show password for an entry. +=> [o]tp [option] - Generate 2FA + => [add] + => [copy] [name] + => [del] [name] + => [show] [name] + => [list] +=> [l]ist - List all entries. +=> [m]enu - Use a menu program to get password Using a key pair: export PASH_KEYID=XXXXXXXX Password length: export PASH_LENGTH=50 @@ -169,7 +257,7 @@ Store location: export PASH_DIR=~/.local/share/pash Clipboard tool: export PASH_CLIP='xclip -sel c' Clipboard timeout: export PASH_TIMEOUT=15 ('off' to disable) " -exit 0 + exit 0 } main() { @@ -225,7 +313,8 @@ main() { d*) pw_del "$2" ;; s*) pw_show "$2" ;; l*) pw_list ;; - t*) pw_tree ;; + o*) pw_otp "$2" ;; + m*) pw_menu "$2" ;; *) usage esac } diff --git a/pashmenu b/pashmenu new file mode 100755 index 0000000..66d7c13 --- /dev/null +++ b/pashmenu @@ -0,0 +1,6 @@ +#!/bin/sh + +account=$( echo $(pash list) | sed 's/ /\n/g' | dmenu -p "pick an account" -l 25) + +st -g 60x15 -c floatst /bin/sh -c "gpg -d $PASH_DIR/$account.gpg | xclip -sel c && sleep 15" +xclip -sel c < /dev/null