From 60987ff81cd700c3e24a9707f6a724bb8de4a6ce Mon Sep 17 00:00:00 2001 From: bsgaurav Date: Tue, 28 Mar 2023 22:23:21 -0400 Subject: [PATCH 1/4] added otp support and pashmenu integration --- pash | 39 +++++++++++++++++++++++++++++++++++++++ pashmenu | 6 ++++++ 2 files changed, 45 insertions(+) create mode 100755 pashmenu diff --git a/pash b/pash index 4180492..9bb3d6f 100755 --- a/pash +++ b/pash @@ -100,6 +100,41 @@ pw_tree() { tree --noreport | sed 's/\.gpg$//' } +pw_otp() { + command -v oathtool >/dev/null 2>&1 || + die "'oathtool' command not found" + + oathtool -b --totp "$1" +} + +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() { printf '%s [y/n]: ' "$1" @@ -161,6 +196,8 @@ pash 2.3.0 - simple password manager. => [l]ist - List all entries. => [s]how [name] - Show password for an entry. => [t]ree - List all entries in a tree. +=> [o]tp [totp] - Generate 2FA code given a totp secret +=> [m]enu - Use a menu program to get password Using a key pair: export PASH_KEYID=XXXXXXXX Password length: export PASH_LENGTH=50 @@ -226,6 +263,8 @@ main() { 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..152d765 --- /dev/null +++ b/pashmenu @@ -0,0 +1,6 @@ +#!/bin/sh + +account=$( echo $(pash list) | sed 's/ /\n/g' | dmenu -p "pick an account") + +st -g 60x15 -c floatst /bin/sh -c "gpg -d $HOME/.password-store/$account.gpg | xclip -sel c && sleep 15" +xclip -sel c < /dev/null From ed70a1cd0376b40be16fef4013212a056937dcc0 Mon Sep 17 00:00:00 2001 From: bsgaurav Date: Fri, 7 Apr 2023 11:26:06 -0400 Subject: [PATCH 2/4] changed otp function to use encrypted file as input. previously you had to manually unencrypt and type in the secret. now it is not necessary --- pash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pash b/pash index 9bb3d6f..da082b8 100755 --- a/pash +++ b/pash @@ -104,7 +104,7 @@ pw_otp() { command -v oathtool >/dev/null 2>&1 || die "'oathtool' command not found" - oathtool -b --totp "$1" + oathtool -b --totp "$(gpg -d $PASH_DIR/otpsecrets/$1.gpg)" } pw_menu() { From c7d8c3ac28ad234d54e3dda2101d9f1b30303ea8 Mon Sep 17 00:00:00 2001 From: bsgaurav Date: Fri, 7 Apr 2023 11:28:52 -0400 Subject: [PATCH 3/4] made gpg output quiet for otp --- pash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pash b/pash index da082b8..38fe893 100755 --- a/pash +++ b/pash @@ -104,7 +104,7 @@ pw_otp() { command -v oathtool >/dev/null 2>&1 || die "'oathtool' command not found" - oathtool -b --totp "$(gpg -d $PASH_DIR/otpsecrets/$1.gpg)" + oathtool -b --totp "$(gpg -dq $PASH_DIR/otpsecrets/$1.gpg)" } pw_menu() { From 67ddfdae9b2f78bad9a13930f63c18b5ffe2197a Mon Sep 17 00:00:00 2001 From: bsgaurav Date: Mon, 22 May 2023 22:12:11 -0400 Subject: [PATCH 4/4] fixed pash otp --- pash | 88 ++++++++++++++++++++++++++++++++++++++++++++------------ pashmenu | 4 +-- 2 files changed, 71 insertions(+), 21 deletions(-) diff --git a/pash b/pash index 38fe893..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,18 +92,66 @@ 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" - - tree --noreport | sed 's/\.gpg$//' -} - pw_otp() { command -v oathtool >/dev/null 2>&1 || die "'oathtool' command not found" - oathtool -b --totp "$(gpg -dq $PASH_DIR/otpsecrets/$1.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() { @@ -190,14 +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. -=> [o]tp [totp] - Generate 2FA code given a totp secret -=> [m]enu - Use a menu program to get password +=> [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 @@ -206,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() { @@ -262,7 +313,6 @@ main() { d*) pw_del "$2" ;; s*) pw_show "$2" ;; l*) pw_list ;; - t*) pw_tree ;; o*) pw_otp "$2" ;; m*) pw_menu "$2" ;; *) usage diff --git a/pashmenu b/pashmenu index 152d765..66d7c13 100755 --- a/pashmenu +++ b/pashmenu @@ -1,6 +1,6 @@ #!/bin/sh -account=$( echo $(pash list) | sed 's/ /\n/g' | dmenu -p "pick an account") +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 $HOME/.password-store/$account.gpg | xclip -sel c && sleep 15" +st -g 60x15 -c floatst /bin/sh -c "gpg -d $PASH_DIR/$account.gpg | xclip -sel c && sleep 15" xclip -sel c < /dev/null