pass choose
Philippe Biondi
zx2c4.web at secdev.org
Sat May 12 02:31:02 CEST 2018
Hello,
I've always been lazy, and I also tend to forget where I put my stuff.
For the second point, "pass find" was a benediction. But once the path
I'm looking for has been found, I find it painful to enter it again with
a new invocation of "pass". Even more painful that I already entered
enough to find it.
So I wrote this little quick patch to add a "choose" command:
pass choose [pass-names...]
List passwords that match pass-names and ask to choose one
It works a lot like "pass find", except that:
- when only one file has been found, it is decrypted
- when many files have been found, a choice is asked and the chosen file
is decrypted
Ex:
-----------8<---------------
$ pass choose mast
Search Terms: mast
├── work
│ └── bank
1 │ └── mastercard
└── infra
└── masterdb
2 ├── console
3 ├── db
4 └── infrasys_volume
Choose a line: 1
Choosing: work/bank/mastercard
Please enter the passphrase to unlock the OpenPGP secret key:
[...]
-----------8<---------------
The following patch is only a preliminary work on a late night and I
probably forgot one thing or two. But if you find this useful and are
willing to integrate it, let me know what is missing to have it accepted.
diff --git a/src/password-store.sh b/src/password-store.sh
index eac5404..dae31ea 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -263,6 +263,8 @@ cmd_usage() {
List passwords.
$PROGRAM find pass-names...
List passwords that match pass-names.
+ $PROGRAM choose [pass-names...]
+ List passwords that match pass-names and ask to choose one
$PROGRAM [show] [--clip[=line-number],-c[line-number]] pass-name
Show existing password and optionally put it on the clipboard.
If put on the clipboard, it will be cleared in $CLIP_TIME seconds.
@@ -394,6 +396,44 @@ cmd_find() {
tree -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g'
}
+cmd_choose() {
+ IFS="," eval 'echo "Search Terms: $*"'
+ local terms="*$(printf '%s*|*' "$@")"
+ readarray < <(tree -i -C -l -f --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case ~/.password-store|tail -n +2|grep '\.gpg$')
+ i=0
+ OIFS=$IFS
+ export IFS=""
+ tree -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" | tail -n +2 | while read a; do
+ b=$(echo $a|sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g')
+ if echo $a|grep -q '\.gpg$'; then
+ i=$((i+1))
+ printf "%3i %s\n" "$i" "$b"
+ else
+ printf " %s\n" "$b"
+ fi
+ done
+ IFS="$OIFS"
+ chosen=""
+ maplen=${#MAPFILE[*]}
+ if [ $maplen -eq 1 ]; then
+ chosen=${MAPFILE[0]}
+ fi
+ if [ $maplen -ge 1 ]; then
+ while [ "x$chosen" == "x" ]; do
+ read -p "Choose a line: " r
+ r=$(($r-1))
+ chosen=${MAPFILE[$r]}
+ done
+ chosen=$(echo ${chosen#$PREFIX/}) # get rid of trailing newline with echo
+ chosen=${chosen%.gpg}
+ echo "Choosing: $chosen"
+ echo
+ cmd_show $chosen
+ fi
+}
+
+
+
cmd_grep() {
[[ $# -ne 1 ]] && die "Usage: $PROGRAM $COMMAND search-string"
local search="$1" passfile grepresults
@@ -686,6 +726,7 @@ case "$1" in
version|--version) shift; cmd_version "$@" ;;
show|ls|list) shift; cmd_show "$@" ;;
find|search) shift; cmd_find "$@" ;;
+ choose) shift; cmd_choose "$@" ;;
grep) shift; cmd_grep "$@" ;;
insert|add) shift; cmd_insert "$@" ;;
edit) shift; cmd_edit "$@" ;;
More information about the Password-Store
mailing list