From vnctdj at laposte.net Sat Aug 2 21:31:10 2025 From: vnctdj at laposte.net (vnctdj) Date: Sat, 2 Aug 2025 23:31:10 +0200 Subject: [PATCH] Make sleep_argv0 selection-specific Message-ID: <20250802213110.6881-1-vnctdj@laposte.net> In my passmenu I use: PASSWORD_STORE_X_SELECTION=primary pass show -c2 "$password" 2>/dev/null sleep 1 PASSWORD_STORE_X_SELECTION=clipboard pass show -c "$password" 2>/dev/null and I noticed that the copied text in primary is only usable for 1 s instead of PASSWORD_STORE_CLIP_TIME seconds unlike the password copied in clipboard. This patch fixes that by telling kill to be selection-specific. --- src/password-store.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/password-store.sh b/src/password-store.sh index 22e818f..88e5526 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -170,7 +170,7 @@ clip() { else die "Error: No X11 or Wayland display and clipper detected" fi - local sleep_argv0="password store sleep on display $display_name" + local sleep_argv0="password store sleep on display $display_name for X selection $X_SELECTION" # This base64 business is because bash cannot store binary data in a shell # variable. Specifically, it cannot store nulls nor (non-trivally) store -- 2.50.1 From ealker1 at gmail.com Sun Aug 3 01:49:36 2025 From: ealker1 at gmail.com (Ethan Alker) Date: Sat, 2 Aug 2025 21:49:36 -0400 Subject: [PATCH] Add symbolic link command Message-ID: <20250803015244.285065-1-ealker1@gmail.com> --- A small patch to add a symbolic link command, for cases where the same credentials are used in multiple places. For example, Microsoft has about twenty domains that accept login information, so in order for auto-fill to work on each domain with my setup I had to link each domain to the same password. While you could also just use 'cp', that would then require updating each password individually if the password ever changed or if other entries are added. man/pass.1 | 8 +++++ src/completion/pass.bash-completion | 4 +-- src/completion/pass.fish-completion | 4 +++ src/completion/pass.zsh-completion | 3 +- src/password-store.sh | 21 ++++++++---- tests/t0070-ln-tests.sh | 51 +++++++++++++++++++++++++++++ 6 files changed, 81 insertions(+), 10 deletions(-) create mode 100755 tests/t0070-ln-tests.sh diff --git a/man/pass.1 b/man/pass.1 index a555dcb..d0e9943 100644 --- a/man/pass.1 +++ b/man/pass.1 @@ -164,6 +164,14 @@ silently overwrite \fInew-path\fP if it exists. If \fInew-path\fP ends in a trailing \fI/\fP, it is always treated as a directory. Passwords are selectively reencrypted to the corresponding keys of their new destination. .TP +\fBln\fP [ \fI--force\fP, \fI-f\fP ] \fItarget\fP \fIlink-path\fP +Adds a symbolic link at the path \fIlink-path\fP to the password or directory +named \fItarget\fP. This command is alternatively named \fBlink\fP. If +\fI--force\fP is specified, silently overwrite \fIlink-path\fP if it exists. If +\fIlink-path\fP ends in a trailing \fI/\fP, it is always treated as a directory. +Passwords are not reencrypted to the corresponding keys of the link +destination. +.TP \fBgit\fP \fIgit-command-args\fP... If the password store is a git repository, pass \fIgit-command-args\fP as arguments to .BR git (1) diff --git a/src/completion/pass.bash-completion b/src/completion/pass.bash-completion index 2d23cbf..e7dc9dc 100644 --- a/src/completion/pass.bash-completion +++ b/src/completion/pass.bash-completion @@ -84,7 +84,7 @@ _pass() { COMPREPLY=() local cur="${COMP_WORDS[COMP_CWORD]}" - local commands="init ls find grep show insert generate edit rm mv cp git help version ${PASSWORD_STORE_EXTENSION_COMMANDS[*]}" + local commands="init ls find grep show insert generate edit rm mv cp ln git help version ${PASSWORD_STORE_EXTENSION_COMMANDS[*]}" if [[ $COMP_CWORD -gt 1 ]]; then local lastarg="${COMP_WORDS[$COMP_CWORD-1]}" case "${COMP_WORDS[1]}" in @@ -112,7 +112,7 @@ _pass() COMPREPLY+=($(compgen -W "-n --no-symbols -c --clip -f --force -i --in-place" -- ${cur})) _pass_complete_entries ;; - cp|copy|mv|rename) + cp|copy|mv|rename|ln|link) COMPREPLY+=($(compgen -W "-f --force" -- ${cur})) _pass_complete_entries ;; diff --git a/src/completion/pass.fish-completion b/src/completion/pass.fish-completion index 0f57dd2..6690ab5 100644 --- a/src/completion/pass.fish-completion +++ b/src/completion/pass.fish-completion @@ -87,6 +87,10 @@ complete -c $PROG -f -n '__fish_pass_needs_command' -a cp -d 'Command: copy exis complete -c $PROG -f -n '__fish_pass_uses_command cp' -s f -l force -d 'Force copy' complete -c $PROG -f -n '__fish_pass_uses_command cp' -a "(__fish_pass_print_entries_and_dirs)" +complete -c $PROG -f -n '__fish_pass_needs_command' -a ln -d 'Command: add symbolic link to existing password' +complete -c $PROG -f -n '__fish_pass_uses_command ln' -s f -l force -d 'Force link' +complete -c $PROG -f -n '__fish_pass_uses_command ln' -a "(__fish_pass_print_entries_and_dirs)" + complete -c $PROG -f -n '__fish_pass_needs_command' -a rm -d 'Command: remove existing password' complete -c $PROG -f -n '__fish_pass_uses_command rm' -s r -l recursive -d 'Remove password groups recursively' complete -c $PROG -f -n '__fish_pass_uses_command rm' -s f -l force -d 'Force removal' diff --git a/src/completion/pass.zsh-completion b/src/completion/pass.zsh-completion index d911e12..9faa135 100644 --- a/src/completion/pass.zsh-completion +++ b/src/completion/pass.zsh-completion @@ -58,7 +58,7 @@ _pass () { "--in-place[replace first line]" _pass_complete_entries_with_subdirs ;; - cp|copy|mv|rename) + cp|copy|mv|rename|ln|link) _arguments : \ "-f[force rename]" \ "--force[force rename]" @@ -101,6 +101,7 @@ _pass () { "edit:Edit a password with \$EDITOR" "mv:Rename the password" "cp:Copy the password" + "ln:Add symbolic link to the password" "rm:Remove the password" "git:Call git on the password store" "version:Output version information" diff --git a/src/password-store.sh b/src/password-store.sh index 22e818f..5d33164 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -283,7 +283,7 @@ cmd_usage() { $PROGRAM [ls] [subfolder] List passwords. $PROGRAM find pass-names... - List passwords that match pass-names. + List passwords that match pass-names. $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. @@ -306,6 +306,8 @@ cmd_usage() { Renames or moves old-path to new-path, optionally forcefully, selectively reencrypting. $PROGRAM cp [--force,-f] old-path new-path Copies old-path to new-path, optionally forcefully, selectively reencrypting. + $PROGRAM ln [--force,-f] target link-path + Add symbolic link from link-path to target, optionally forcefully. Does not reencrypt. $PROGRAM git git-command-args... If the password store is a git repository, execute a git command specified by git-command-args. @@ -594,9 +596,10 @@ cmd_delete() { rmdir -p "${passfile%/*}" 2>/dev/null } -cmd_copy_move() { - local opts move=1 force=0 - [[ $1 == "copy" ]] && move=0 +cmd_copy_move_link() { + local opts action="move" force=0 + [[ $1 == "copy" ]] && action="copy" + [[ $1 == "link" ]] && action="link" shift opts="$($GETOPT -o f -l force -n "$PROGRAM" -- "$@")" local err=$? @@ -625,7 +628,7 @@ cmd_copy_move() { [[ ! -t 0 || $force -eq 1 ]] && interactive="-f" set_git "$new_path" - if [[ $move -eq 1 ]]; then + if [[ $action == "move" ]]; then mv $interactive -v "$old_path" "$new_path" || exit 1 [[ -e "$new_path" ]] && reencrypt_path "$new_path" @@ -642,6 +645,9 @@ cmd_copy_move() { [[ -n $(git -C "$INNER_GIT_DIR" status --porcelain "$old_path") ]] && git_commit "Remove ${1}." fi rmdir -p "$old_dir" 2>/dev/null + elif [[ $action == "link" ]]; then + ln $interactive -s -r -v "$old_path" "$new_path" || exit 1 + git_add_file "$new_path" "Link ${2} to ${1}." else cp $interactive -r -v "$old_path" "$new_path" || exit 1 [[ -e "$new_path" ]] && reencrypt_path "$new_path" @@ -713,8 +719,9 @@ case "$1" in edit) shift; cmd_edit "$@" ;; generate) shift; cmd_generate "$@" ;; delete|rm|remove) shift; cmd_delete "$@" ;; - rename|mv) shift; cmd_copy_move "move" "$@" ;; - copy|cp) shift; cmd_copy_move "copy" "$@" ;; + rename|mv) shift; cmd_copy_move_link "move" "$@" ;; + copy|cp) shift; cmd_copy_move_link "copy" "$@" ;; + link|ln) shift; cmd_copy_move_link "link" "$@" ;; git) shift; cmd_git "$@" ;; *) cmd_extension_or_show "$@" ;; esac diff --git a/tests/t0070-ln-tests.sh b/tests/t0070-ln-tests.sh new file mode 100755 index 0000000..203d2f5 --- /dev/null +++ b/tests/t0070-ln-tests.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +test_description='Test ln command' +cd "$(dirname "$0")" +. ./setup.sh + +INITIAL_PASSWORD="bla bla bla will we make it!!" + +test_expect_success 'Basic link command' ' + "$PASS" init $KEY1 && + "$PASS" git init && + "$PASS" insert -e cred1 <<<"$INITIAL_PASSWORD" && + "$PASS" ln cred1 cred2 && + [[ -L $PASSWORD_STORE_DIR/cred2.gpg && -e $PASSWORD_STORE_DIR/cred1.gpg ]] +' + +test_expect_success 'Directory creation' ' + "$PASS" ln cred2 directory/ && + [[ -d $PASSWORD_STORE_DIR/directory && -L $PASSWORD_STORE_DIR/directory/cred2.gpg ]] +' + +test_expect_success 'Directory creation with file rename' ' + "$PASS" ln directory/cred2 "new directory with spaces"/cred && + [[ -d $PASSWORD_STORE_DIR/"new directory with spaces" && -e $PASSWORD_STORE_DIR/"new directory with spaces"/cred.gpg && -d $PASSWORD_STORE_DIR/directory ]] +' + +test_expect_success 'Directory link' ' + "$PASS" ln "new directory with spaces" anotherdirectory && + [[ -L $PASSWORD_STORE_DIR/anotherdirectory && -e $PASSWORD_STORE_DIR/anotherdirectory/cred.gpg && -d $PASSWORD_STORE_DIR/"new directory with spaces" ]] +' + +test_expect_success 'Directory ln into new directory' ' + "$PASS" ln anotherdirectory "another directory with spaces"/ && + [[ -L $PASSWORD_STORE_DIR/"another directory with spaces"/anotherdirectory && -e $PASSWORD_STORE_DIR/"new directory with spaces"/cred.gpg && -L $PASSWORD_STORE_DIR/anotherdirectory ]] +' + +test_expect_success 'Multi-directory creation and multi-directory empty removal' ' + "$PASS" ln "new directory with spaces"/cred new1/new2/new3/new4/thecred && + "$PASS" ln new1/new2/new3/new4/thecred cred && + [[ -d $PASSWORD_STORE_DIR/"new directory with spaces" && -d $PASSWORD_STORE_DIR/new1/new2/new3/new4 && -L $PASSWORD_STORE_DIR/cred.gpg ]] +' + +test_expect_success 'Password made it until the end' ' + [[ $("$PASS" show cred) == "$INITIAL_PASSWORD" ]] +' + +test_expect_success 'Git is consistent' ' + [[ -z $(git status --porcelain 2>&1) ]] +' + +test_done -- 2.50.1 From alx at kernel.org Mon Aug 18 08:37:35 2025 From: alx at kernel.org (Alejandro Colomar) Date: Mon, 18 Aug 2025 10:37:35 +0200 Subject: [PATCH v2 0/2] pass {find,ls}: --find: Add flag In-Reply-To: <2wdvnucnrypxxzatk6xxc36k44rn3kh4lmv2kpxla7vyn5cgv3@tb233sdkoh4l> References: <2wdvnucnrypxxzatk6xxc36k44rn3kh4lmv2kpxla7vyn5cgv3@tb233sdkoh4l> Message-ID: Hi! Here's a revision of the patch set I sent two years ago. I've addressed the comments by Tobias. Here's what changes in v2: - Do not depend on previous patches. This patch set applies on current master. - Do not print search terms with --find. - Minor changes in commit messages. - Minor formatting improvements in the manual page changes. Here's how the additions to the manual page look like after formatting (I guess this helps review): $ export MANWIDTH=64; $ diffman-git HEAD; --- HEAD^:man/pass.1 +++ HEAD:man/pass.1 @@ -71,6 +71,13 @@ COMMANDS folder by using the tree(1) program. This command is alternatively named list. + If the --find flag is used, find(1) is used in? + stead; this is useful to be able to reuse the + output as an input to pass show. Here's an exam? + ple: + + $ pass ls --find foo/bar/ | xargs pass show; + grep [GREPOPTIONS] search-string Searches inside each decrypted password file for search-string, and displays line containing $ diffman-git HEAD^; --- HEAD^^:man/pass.1 +++ HEAD^:man/pass.1 @@ -79,11 +79,18 @@ COMMANDS as-is. (Note: the GREP_OPTIONS environment vari? able functions as well.) - find pass-names... + find [ --find ] pass-names... List names of passwords inside the tree that match pass-names by using the tree(1) program. This command is alternatively named search. + If the --find flag is used, find(1) is used in? + stead; this is useful to be able to reuse the + output as an input to pass ls. Here's an exam? + ple: + + $ pass find --find | xargs pass ls; + show [ --clip[=line-number], -c[line-number] ] [ --qr? code[=line-number], -q[line-number] ] pass-name Decrypt and print a password named pass-name. If Below you can find a range-diff. Have a lovely day! Alex Alejandro Colomar (2): pass find: --find: Add flag pass ls: --find: Add flag man/pass.1 | 32 +++++++++++++++++++++++++++++++- src/password-store.sh | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 63 insertions(+), 9 deletions(-) Range-diff against v1: 1: ea93997 ! 1: 8562aaa pass find: Add --find flag @@ Metadata Author: Alejandro Colomar ## Commit message ## - pass find: Add --find flag + pass find: --find: Add flag This flag modifies the command to use find(1) instead of tree(1). @@ Commit message (3) Remove the .gpg suffix from files (as is historic behavior of pass(1)). + As this is intended for scripting (machine readable output), the search + terms are not printed if this flag is used. + Examples of use: $ pass find --find bugzilla - Search Terms: bugzilla www/foss/kernel/bugzilla/ www/foss/mozilla/bugzilla/ www/foss/gentoo/bugzilla/ www/foss/gnu/gcc/bugzilla/ $ pass find --find kernel - Search Terms: kernel www/foss/kernel/ Those tweaks to the output of find(1) make the output directly usable in a subsequent invocation of pass(1): $ pass find --find kernel \ - | tail -n -1 \ - | xargs pass show; + | xargs pass ls; www/foss/kernel ??? bugzilla ??? ??? alx.manpages @@ Commit message ??? smtp ??? pass - The tail(1) above is to hide the search terms. - + Cc: Tobias Girstmair + Cc: Fabian Pflug Signed-off-by: Alejandro Colomar ## man/pass.1 ## @@ man/pass.1: .SH COMMANDS - as-is. - (Note: the \fIGREP_OPTIONS\fP environment variable functions as well.) + .BR grep (1) + as-is. (Note: the \fIGREP_OPTIONS\fP environment variable functions as well.) .TP -\fBfind\fP \fIpass-names\fP... +\fBfind\fP [ \fI\-\-find\fP ] \fIpass-names\fP... List names of passwords inside the tree that match \fIpass-names\fP by using the .BR tree (1) - program. - This command is alternatively named \fBsearch\fP. + program. This command is alternatively named \fBsearch\fP. ++.IP +If the +.I \-\-find +flag is used, +.BR find (1) +is used instead; +this is useful to be able to reuse the output as an input to -+.IR "pass ls" . ++.IR pass\~ls . +Here's an example: +.IP +.in +4n +.EX -+$ pass find \-\-find foo | tail \-n \-1 | xargs pass ls ++.RB $\~ "pass find \-\-find | xargs pass ls" ; +.EE +.in .TP - \fBshow\fP [ \fI\-\-clip\fP[=\fIline-number\fP], \fI\-c\fP[\fIline-number\fP] ] [ \fI\-\-qrcode\fP[=\fIline-number\fP], \fI\-q\fP[\fIline-number\fP] ] \fIpass-name\fP - Decrypt and print a password named \fIpass-name\fP. + \fBshow\fP [ \fI--clip\fP[=\fIline-number\fP], \fI-c\fP[\fIline-number\fP] ] [ \fI--qrcode\fP[=\fIline-number\fP], \fI-q\fP[\fIline-number\fP] ] \fIpass-name\fP + Decrypt and print a password named \fIpass-name\fP. If \fI--clip\fP or \fI-c\fP ## src/password-store.sh ## @@ src/password-store.sh: cmd_show() { @@ src/password-store.sh: cmd_show() { + esac done + [[ $# -eq 0 ]] && die "Usage: $PROGRAM $COMMAND pass-names..." - IFS="," eval 'echo "Search Terms: $*"' +- IFS="," eval 'echo "Search Terms: $*"' local terms="*$(printf '%s*|*' "$@")" - tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' + @@ src/password-store.sh: cmd_show() { + + find -L "$PREFIX" -iname "${terms%|*}" | sed 's,$,/,' | sed "s/^.\{$n\}//" | sed 's,\.gpg/$,,' + else ++ IFS="," eval 'echo "Search Terms: $*"' + tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' + fi } 2: 972dcbb ! 2: 1a5b0a2 pass ls: Add --find flag @@ Metadata Author: Alejandro Colomar ## Commit message ## - pass ls: Add --find flag + pass ls: --find: Add flag Similarly to `pass find --find`, this flag changes the `pass ls` command to use find(1) instead of tree(1). @@ Commit message Examples of use: $ pass find --find kernel \ - | tail -n -1 \ - | xargs ./password-store.sh ls --find; + | xargs pass ls --find; www/foss/kernel/ www/foss/kernel/smtp/ www/foss/kernel/smtp/pass @@ Commit message www/foss/kernel/bugzilla/alx/pass $ pass find --find kernel \ - | tail -n -1 \ | xargs pass ls --find \ - | tail -n1 \ | xargs pass show; pw + Cc: Tobias Girstmair + Cc: Fabian Pflug Signed-off-by: Alejandro Colomar ## man/pass.1 ## @@ man/pass.1: .SH COMMANDS + by using the .BR tree (1) - program. - This command is alternatively named \fBlist\fP. + program. This command is alternatively named \fBlist\fP. ++.IP +If the +.I \-\-find +flag is used, +.BR find (1) +is used instead; +this is useful to be able to reuse the output as an input to -+.IR "pass show" . ++.IR pass\~show . +Here's an example: +.IP +.in +4n +.EX -+$ pass ls \-\-find foo/bar/ | tail \-n1 | xargs pass show ++.RB $\~ "pass ls \-\-find foo/bar/ | xargs pass show" ; +.EE +.in -+.TP .TP \fBgrep\fP [\fIGREPOPTIONS\fP] \fIsearch-string\fP Searches inside each decrypted password file for \fIsearch-string\fP, and displays line -- 2.50.1 From alx at kernel.org Mon Aug 18 08:37:40 2025 From: alx at kernel.org (Alejandro Colomar) Date: Mon, 18 Aug 2025 10:37:40 +0200 Subject: [PATCH v2 1/2] pass find: --find: Add flag In-Reply-To: References: Message-ID: <8562aaa1fbf754690d1af30bd09bccb5ca01dc27.1755505113.git.alx@kernel.org> This flag modifies the command to use find(1) instead of tree(1). A few tweaks are performed to the result of find: (1) Add a trailing slash to directories. This is a useful way to distinguish files from dirs at first glance. In the tree(1) version, it colors differently (as tree(1) does by default), so it seems consistent to distinguish them. (2) Remove the location of the password-store prefix from the path. (3) Remove the .gpg suffix from files (as is historic behavior of pass(1)). As this is intended for scripting (machine readable output), the search terms are not printed if this flag is used. Examples of use: $ pass find --find bugzilla www/foss/kernel/bugzilla/ www/foss/mozilla/bugzilla/ www/foss/gentoo/bugzilla/ www/foss/gnu/gcc/bugzilla/ $ pass find --find kernel www/foss/kernel/ Those tweaks to the output of find(1) make the output directly usable in a subsequent invocation of pass(1): $ pass find --find kernel \ | xargs pass ls; www/foss/kernel ??? bugzilla ??? ??? alx.manpages ??? ??? ??? id ??? ??? ??? pass ??? ??? url ??? smtp ??? pass Cc: Tobias Girstmair Cc: Fabian Pflug Signed-off-by: Alejandro Colomar --- man/pass.1 | 17 ++++++++++++++++- src/password-store.sh | 20 ++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/man/pass.1 b/man/pass.1 index a555dcb..0f2231e 100644 --- a/man/pass.1 +++ b/man/pass.1 @@ -89,10 +89,25 @@ .SH COMMANDS .BR grep (1) as-is. (Note: the \fIGREP_OPTIONS\fP environment variable functions as well.) .TP -\fBfind\fP \fIpass-names\fP... +\fBfind\fP [ \fI\-\-find\fP ] \fIpass-names\fP... List names of passwords inside the tree that match \fIpass-names\fP by using the .BR tree (1) program. This command is alternatively named \fBsearch\fP. +.IP +If the +.I \-\-find +flag is used, +.BR find (1) +is used instead; +this is useful to be able to reuse the output as an input to +.IR pass\~ls . +Here's an example: +.IP +.in +4n +.EX +.RB $\~ "pass find \-\-find | xargs pass ls" ; +.EE +.in .TP \fBshow\fP [ \fI--clip\fP[=\fIline-number\fP], \fI-c\fP[\fIline-number\fP] ] [ \fI--qrcode\fP[=\fIline-number\fP], \fI-q\fP[\fIline-number\fP] ] \fIpass-name\fP Decrypt and print a password named \fIpass-name\fP. If \fI--clip\fP or \fI-c\fP diff --git a/src/password-store.sh b/src/password-store.sh index 22e818f..20d9377 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -411,10 +411,26 @@ cmd_show() { } cmd_find() { + local opts find=0 + opts="$($GETOPT -o "" -l find -n "$PROGRAM" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + --find) find=1; shift ;; + --) shift; break ;; + esac done + [[ $# -eq 0 ]] && die "Usage: $PROGRAM $COMMAND pass-names..." - IFS="," eval 'echo "Search Terms: $*"' local terms="*$(printf '%s*|*' "$@")" - tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' + + if [[ $find -eq 1 ]]; then + local n="$(echo "$PREFIX" | wc -c)" + + find -L "$PREFIX" -iname "${terms%|*}" | sed 's,$,/,' | sed "s/^.\{$n\}//" | sed 's,\.gpg/$,,' + else + IFS="," eval 'echo "Search Terms: $*"' + tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' + fi } cmd_grep() { -- 2.50.1 From alx at kernel.org Mon Aug 18 08:37:45 2025 From: alx at kernel.org (Alejandro Colomar) Date: Mon, 18 Aug 2025 10:37:45 +0200 Subject: [PATCH v2 2/2] pass ls: --find: Add flag In-Reply-To: References: Message-ID: <1a5b0a28664e9645067750e6353e954e1a1bcf01.1755505113.git.alx@kernel.org> Similarly to `pass find --find`, this flag changes the `pass ls` command to use find(1) instead of tree(1). With this flag, the output is directly usable in a subsequent call to `pass show`. Examples of use: $ pass find --find kernel \ | xargs pass ls --find; www/foss/kernel/ www/foss/kernel/smtp/ www/foss/kernel/smtp/pass www/foss/kernel/bugzilla/ www/foss/kernel/bugzilla/url www/foss/kernel/bugzilla/alx/ www/foss/kernel/bugzilla/alx/id www/foss/kernel/bugzilla/alx/pass $ pass find --find kernel \ | xargs pass ls --find \ | xargs pass show; pw Cc: Tobias Girstmair Cc: Fabian Pflug Signed-off-by: Alejandro Colomar --- man/pass.1 | 15 +++++++++++++++ src/password-store.sh | 20 ++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/man/pass.1 b/man/pass.1 index 0f2231e..6927155 100644 --- a/man/pass.1 +++ b/man/pass.1 @@ -80,6 +80,21 @@ .SH COMMANDS by using the .BR tree (1) program. This command is alternatively named \fBlist\fP. +.IP +If the +.I \-\-find +flag is used, +.BR find (1) +is used instead; +this is useful to be able to reuse the output as an input to +.IR pass\~show . +Here's an example: +.IP +.in +4n +.EX +.RB $\~ "pass ls \-\-find foo/bar/ | xargs pass show" ; +.EE +.in .TP \fBgrep\fP [\fIGREPOPTIONS\fP] \fIsearch-string\fP Searches inside each decrypted password file for \fIsearch-string\fP, and displays line diff --git a/src/password-store.sh b/src/password-store.sh index 20d9377..34d07e7 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -366,11 +366,12 @@ cmd_init() { } cmd_show() { - local opts selected_line clip=0 qrcode=0 - opts="$($GETOPT -o q::c:: -l qrcode::,clip:: -n "$PROGRAM" -- "$@")" + local opts selected_line clip=0 find=0 qrcode=0 + opts="$($GETOPT -o q::c:: -l qrcode::,clip::,find -n "$PROGRAM" -- "$@")" local err=$? eval set -- "$opts" while true; do case $1 in + --find) find=1; shift ;; -q|--qrcode) qrcode=1; selected_line="${2:-1}"; shift 2 ;; -c|--clip) clip=1; selected_line="${2:-1}"; shift 2 ;; --) shift; break ;; @@ -397,12 +398,19 @@ cmd_show() { fi fi elif [[ -d $PREFIX/$path ]]; then - if [[ -z $path ]]; then - echo "Password Store" + if [[ $find -eq 1 ]]; then + local n="$(echo "$PREFIX" | wc -c)" + + find -L "$PREFIX/$path" | sed '/[^\/]$/s,$,/,' | sed "s/^.\{$n\}//" | sed 's,\.gpg/$,,' else - echo "${path%\/}" + if [[ -z $path ]]; then + echo "Password Store" + else + echo "${path%\/}" + fi + + tree -N -C -l --noreport "$PREFIX/$path" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors fi - tree -N -C -l --noreport "$PREFIX/$path" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors elif [[ -z $path ]]; then die "Error: password store is empty. Try \"pass init\"." else -- 2.50.1 From alx at kernel.org Mon Aug 18 08:43:00 2025 From: alx at kernel.org (Alejandro Colomar) Date: Mon, 18 Aug 2025 10:43:00 +0200 Subject: [PATCH v2 0/2] pass {find,ls}: --find: Add flag In-Reply-To: References: <2wdvnucnrypxxzatk6xxc36k44rn3kh4lmv2kpxla7vyn5cgv3@tb233sdkoh4l> Message-ID: On Mon, Aug 18, 2025 at 10:37:35AM +0200, Alejandro Colomar wrote: > Hi! > > Here's a revision of the patch set I sent two years ago. I've addressed > the comments by Tobias. Here's what changes in v2: > > - Do not depend on previous patches. This patch set applies on current > master. > - Do not print search terms with --find. > - Minor changes in commit messages. > - Minor formatting improvements in the manual page changes. > > Here's how the additions to the manual page look like after formatting > (I guess this helps review): > > $ export MANWIDTH=64; > $ diffman-git HEAD; > --- HEAD^:man/pass.1 > +++ HEAD:man/pass.1 > @@ -71,6 +71,13 @@ COMMANDS > folder by using the tree(1) program. This command > is alternatively named list. > > + If the --find flag is used, find(1) is used in? > + stead; this is useful to be able to reuse the > + output as an input to pass show. Here's an exam? > + ple: > + > + $ pass ls --find foo/bar/ | xargs pass show; > + > grep [GREPOPTIONS] search-string > Searches inside each decrypted password file for > search-string, and displays line containing > $ diffman-git HEAD^; > --- HEAD^^:man/pass.1 > +++ HEAD^:man/pass.1 > @@ -79,11 +79,18 @@ COMMANDS > as-is. (Note: the GREP_OPTIONS environment vari? > able functions as well.) > > - find pass-names... > + find [ --find ] pass-names... > List names of passwords inside the tree that > match pass-names by using the tree(1) program. > This command is alternatively named search. > > + If the --find flag is used, find(1) is used in? > + stead; this is useful to be able to reuse the > + output as an input to pass ls. Here's an exam? > + ple: > + > + $ pass find --find | xargs pass ls; Oops, I should have written $ pass find --find foo | xargs pass ls > + > show [ --clip[=line-number], -c[line-number] ] [ --qr? > code[=line-number], -q[line-number] ] pass-name > Decrypt and print a password named pass-name. If > > Below you can find a range-diff. > > > Have a lovely day! > Alex > > > Alejandro Colomar (2): > pass find: --find: Add flag > pass ls: --find: Add flag > > man/pass.1 | 32 +++++++++++++++++++++++++++++++- > src/password-store.sh | 40 ++++++++++++++++++++++++++++++++-------- > 2 files changed, 63 insertions(+), 9 deletions(-) > > Range-diff against v1: > 1: ea93997 ! 1: 8562aaa pass find: Add --find flag > @@ Metadata > Author: Alejandro Colomar > > ## Commit message ## > - pass find: Add --find flag > + pass find: --find: Add flag > > This flag modifies the command to use find(1) instead of tree(1). > > @@ Commit message > (3) Remove the .gpg suffix from files (as is historic behavior of > pass(1)). > > + As this is intended for scripting (machine readable output), the search > + terms are not printed if this flag is used. > + > Examples of use: > > $ pass find --find bugzilla > - Search Terms: bugzilla > www/foss/kernel/bugzilla/ > www/foss/mozilla/bugzilla/ > www/foss/gentoo/bugzilla/ > www/foss/gnu/gcc/bugzilla/ > > $ pass find --find kernel > - Search Terms: kernel > www/foss/kernel/ > > Those tweaks to the output of find(1) make the output directly usable in > a subsequent invocation of pass(1): > > $ pass find --find kernel \ > - | tail -n -1 \ > - | xargs pass show; > + | xargs pass ls; > www/foss/kernel > ??? bugzilla > ??? ??? alx.manpages > @@ Commit message > ??? smtp > ??? pass > > - The tail(1) above is to hide the search terms. > - > + Cc: Tobias Girstmair > + Cc: Fabian Pflug > Signed-off-by: Alejandro Colomar > > ## man/pass.1 ## > @@ man/pass.1: .SH COMMANDS > - as-is. > - (Note: the \fIGREP_OPTIONS\fP environment variable functions as well.) > + .BR grep (1) > + as-is. (Note: the \fIGREP_OPTIONS\fP environment variable functions as well.) > .TP > -\fBfind\fP \fIpass-names\fP... > +\fBfind\fP [ \fI\-\-find\fP ] \fIpass-names\fP... > List names of passwords inside the tree that match \fIpass-names\fP by using the > .BR tree (1) > - program. > - This command is alternatively named \fBsearch\fP. > + program. This command is alternatively named \fBsearch\fP. > ++.IP > +If the > +.I \-\-find > +flag is used, > +.BR find (1) > +is used instead; > +this is useful to be able to reuse the output as an input to > -+.IR "pass ls" . > ++.IR pass\~ls . > +Here's an example: > +.IP > +.in +4n > +.EX > -+$ pass find \-\-find foo | tail \-n \-1 | xargs pass ls > ++.RB $\~ "pass find \-\-find | xargs pass ls" ; > +.EE > +.in > .TP > - \fBshow\fP [ \fI\-\-clip\fP[=\fIline-number\fP], \fI\-c\fP[\fIline-number\fP] ] [ \fI\-\-qrcode\fP[=\fIline-number\fP], \fI\-q\fP[\fIline-number\fP] ] \fIpass-name\fP > - Decrypt and print a password named \fIpass-name\fP. > + \fBshow\fP [ \fI--clip\fP[=\fIline-number\fP], \fI-c\fP[\fIline-number\fP] ] [ \fI--qrcode\fP[=\fIline-number\fP], \fI-q\fP[\fIline-number\fP] ] \fIpass-name\fP > + Decrypt and print a password named \fIpass-name\fP. If \fI--clip\fP or \fI-c\fP > > ## src/password-store.sh ## > @@ src/password-store.sh: cmd_show() { > @@ src/password-store.sh: cmd_show() { > + esac done > + > [[ $# -eq 0 ]] && die "Usage: $PROGRAM $COMMAND pass-names..." > - IFS="," eval 'echo "Search Terms: $*"' > +- IFS="," eval 'echo "Search Terms: $*"' > local terms="*$(printf '%s*|*' "$@")" > - tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' > + > @@ src/password-store.sh: cmd_show() { > + > + find -L "$PREFIX" -iname "${terms%|*}" | sed 's,$,/,' | sed "s/^.\{$n\}//" | sed 's,\.gpg/$,,' > + else > ++ IFS="," eval 'echo "Search Terms: $*"' > + tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' > + fi > } > 2: 972dcbb ! 2: 1a5b0a2 pass ls: Add --find flag > @@ Metadata > Author: Alejandro Colomar > > ## Commit message ## > - pass ls: Add --find flag > + pass ls: --find: Add flag > > Similarly to `pass find --find`, this flag changes the `pass ls` command > to use find(1) instead of tree(1). > @@ Commit message > Examples of use: > > $ pass find --find kernel \ > - | tail -n -1 \ > - | xargs ./password-store.sh ls --find; > + | xargs pass ls --find; > www/foss/kernel/ > www/foss/kernel/smtp/ > www/foss/kernel/smtp/pass > @@ Commit message > www/foss/kernel/bugzilla/alx/pass > > $ pass find --find kernel \ > - | tail -n -1 \ > | xargs pass ls --find \ > - | tail -n1 \ > | xargs pass show; > pw > > + Cc: Tobias Girstmair > + Cc: Fabian Pflug > Signed-off-by: Alejandro Colomar > > ## man/pass.1 ## > @@ man/pass.1: .SH COMMANDS > + by using the > .BR tree (1) > - program. > - This command is alternatively named \fBlist\fP. > + program. This command is alternatively named \fBlist\fP. > ++.IP > +If the > +.I \-\-find > +flag is used, > +.BR find (1) > +is used instead; > +this is useful to be able to reuse the output as an input to > -+.IR "pass show" . > ++.IR pass\~show . > +Here's an example: > +.IP > +.in +4n > +.EX > -+$ pass ls \-\-find foo/bar/ | tail \-n1 | xargs pass show > ++.RB $\~ "pass ls \-\-find foo/bar/ | xargs pass show" ; > +.EE > +.in > -+.TP > .TP > \fBgrep\fP [\fIGREPOPTIONS\fP] \fIsearch-string\fP > Searches inside each decrypted password file for \fIsearch-string\fP, and displays line > -- > 2.50.1 > -- -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From alx at kernel.org Mon Aug 18 08:50:48 2025 From: alx at kernel.org (Alejandro Colomar) Date: Mon, 18 Aug 2025 10:50:48 +0200 Subject: [PATCH v3 0/2] pass {find,ls}: --find: Add flag In-Reply-To: <2wdvnucnrypxxzatk6xxc36k44rn3kh4lmv2kpxla7vyn5cgv3@tb233sdkoh4l> References: <2wdvnucnrypxxzatk6xxc36k44rn3kh4lmv2kpxla7vyn5cgv3@tb233sdkoh4l> Message-ID: Hi! This v3 only fixes an issue in a manual page example. Below is how the additions to the manual page look like after formatting, and further below is the range diff. $ export MANWIDTH=64 $ diffman-git HEAD --- HEAD^:man/pass.1 +++ HEAD:man/pass.1 @@ -71,6 +71,13 @@ COMMANDS folder by using the tree(1) program. This command is alternatively named list. + If the --find flag is used, find(1) is used in? + stead; this is useful to be able to reuse the + output as an input to pass show. Here's an exam? + ple: + + $ pass ls --find foo/bar/ | xargs pass show; + grep [GREPOPTIONS] search-string Searches inside each decrypted password file for search-string, and displays line containing $ diffman-git HEAD^ --- HEAD^^:man/pass.1 +++ HEAD^:man/pass.1 @@ -79,11 +79,18 @@ COMMANDS as-is. (Note: the GREP_OPTIONS environment vari? able functions as well.) - find pass-names... + find [ --find ] pass-names... List names of passwords inside the tree that match pass-names by using the tree(1) program. This command is alternatively named search. + If the --find flag is used, find(1) is used in? + stead; this is useful to be able to reuse the + output as an input to pass ls. Here's an exam? + ple: + + $ pass find --find foo | xargs pass ls; + show [ --clip[=line-number], -c[line-number] ] [ --qr? code[=line-number], -q[line-number] ] pass-name Decrypt and print a password named pass-name. If Have a lovely day! Alex Alejandro Colomar (2): pass find: --find: Add flag pass ls: --find: Add flag man/pass.1 | 32 +++++++++++++++++++++++++++++++- src/password-store.sh | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 63 insertions(+), 9 deletions(-) Range-diff against v2: 1: 8562aaa ! 1: 5285722 pass find: --find: Add flag @@ man/pass.1: .SH COMMANDS +.IP +.in +4n +.EX -+.RB $\~ "pass find \-\-find | xargs pass ls" ; ++.RB $\~ "pass find \-\-find foo | xargs pass ls" ; +.EE +.in .TP 2: 1a5b0a2 = 2: 2e0a70d pass ls: --find: Add flag -- 2.50.1 From alx at kernel.org Mon Aug 18 08:50:54 2025 From: alx at kernel.org (Alejandro Colomar) Date: Mon, 18 Aug 2025 10:50:54 +0200 Subject: [PATCH v3 1/2] pass find: --find: Add flag In-Reply-To: References: Message-ID: <52857229377185b35c65d65d3cb101526205ad5e.1755506895.git.alx@kernel.org> This flag modifies the command to use find(1) instead of tree(1). A few tweaks are performed to the result of find: (1) Add a trailing slash to directories. This is a useful way to distinguish files from dirs at first glance. In the tree(1) version, it colors differently (as tree(1) does by default), so it seems consistent to distinguish them. (2) Remove the location of the password-store prefix from the path. (3) Remove the .gpg suffix from files (as is historic behavior of pass(1)). As this is intended for scripting (machine readable output), the search terms are not printed if this flag is used. Examples of use: $ pass find --find bugzilla www/foss/kernel/bugzilla/ www/foss/mozilla/bugzilla/ www/foss/gentoo/bugzilla/ www/foss/gnu/gcc/bugzilla/ $ pass find --find kernel www/foss/kernel/ Those tweaks to the output of find(1) make the output directly usable in a subsequent invocation of pass(1): $ pass find --find kernel \ | xargs pass ls; www/foss/kernel ??? bugzilla ??? ??? alx.manpages ??? ??? ??? id ??? ??? ??? pass ??? ??? url ??? smtp ??? pass Cc: Tobias Girstmair Cc: Fabian Pflug Signed-off-by: Alejandro Colomar --- man/pass.1 | 17 ++++++++++++++++- src/password-store.sh | 20 ++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/man/pass.1 b/man/pass.1 index a555dcb..bf44ba6 100644 --- a/man/pass.1 +++ b/man/pass.1 @@ -89,10 +89,25 @@ .SH COMMANDS .BR grep (1) as-is. (Note: the \fIGREP_OPTIONS\fP environment variable functions as well.) .TP -\fBfind\fP \fIpass-names\fP... +\fBfind\fP [ \fI\-\-find\fP ] \fIpass-names\fP... List names of passwords inside the tree that match \fIpass-names\fP by using the .BR tree (1) program. This command is alternatively named \fBsearch\fP. +.IP +If the +.I \-\-find +flag is used, +.BR find (1) +is used instead; +this is useful to be able to reuse the output as an input to +.IR pass\~ls . +Here's an example: +.IP +.in +4n +.EX +.RB $\~ "pass find \-\-find foo | xargs pass ls" ; +.EE +.in .TP \fBshow\fP [ \fI--clip\fP[=\fIline-number\fP], \fI-c\fP[\fIline-number\fP] ] [ \fI--qrcode\fP[=\fIline-number\fP], \fI-q\fP[\fIline-number\fP] ] \fIpass-name\fP Decrypt and print a password named \fIpass-name\fP. If \fI--clip\fP or \fI-c\fP diff --git a/src/password-store.sh b/src/password-store.sh index 22e818f..20d9377 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -411,10 +411,26 @@ cmd_show() { } cmd_find() { + local opts find=0 + opts="$($GETOPT -o "" -l find -n "$PROGRAM" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + --find) find=1; shift ;; + --) shift; break ;; + esac done + [[ $# -eq 0 ]] && die "Usage: $PROGRAM $COMMAND pass-names..." - IFS="," eval 'echo "Search Terms: $*"' local terms="*$(printf '%s*|*' "$@")" - tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' + + if [[ $find -eq 1 ]]; then + local n="$(echo "$PREFIX" | wc -c)" + + find -L "$PREFIX" -iname "${terms%|*}" | sed 's,$,/,' | sed "s/^.\{$n\}//" | sed 's,\.gpg/$,,' + else + IFS="," eval 'echo "Search Terms: $*"' + tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' + fi } cmd_grep() { -- 2.50.1 From alx at kernel.org Mon Aug 18 08:50:59 2025 From: alx at kernel.org (Alejandro Colomar) Date: Mon, 18 Aug 2025 10:50:59 +0200 Subject: [PATCH v3 2/2] pass ls: --find: Add flag In-Reply-To: References: Message-ID: <2e0a70dc4173744fe41851ae0f75e554fcf439e9.1755506895.git.alx@kernel.org> Similarly to `pass find --find`, this flag changes the `pass ls` command to use find(1) instead of tree(1). With this flag, the output is directly usable in a subsequent call to `pass show`. Examples of use: $ pass find --find kernel \ | xargs pass ls --find; www/foss/kernel/ www/foss/kernel/smtp/ www/foss/kernel/smtp/pass www/foss/kernel/bugzilla/ www/foss/kernel/bugzilla/url www/foss/kernel/bugzilla/alx/ www/foss/kernel/bugzilla/alx/id www/foss/kernel/bugzilla/alx/pass $ pass find --find kernel \ | xargs pass ls --find \ | xargs pass show; pw Cc: Tobias Girstmair Cc: Fabian Pflug Signed-off-by: Alejandro Colomar --- man/pass.1 | 15 +++++++++++++++ src/password-store.sh | 20 ++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/man/pass.1 b/man/pass.1 index bf44ba6..b4f5c91 100644 --- a/man/pass.1 +++ b/man/pass.1 @@ -80,6 +80,21 @@ .SH COMMANDS by using the .BR tree (1) program. This command is alternatively named \fBlist\fP. +.IP +If the +.I \-\-find +flag is used, +.BR find (1) +is used instead; +this is useful to be able to reuse the output as an input to +.IR pass\~show . +Here's an example: +.IP +.in +4n +.EX +.RB $\~ "pass ls \-\-find foo/bar/ | xargs pass show" ; +.EE +.in .TP \fBgrep\fP [\fIGREPOPTIONS\fP] \fIsearch-string\fP Searches inside each decrypted password file for \fIsearch-string\fP, and displays line diff --git a/src/password-store.sh b/src/password-store.sh index 20d9377..34d07e7 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -366,11 +366,12 @@ cmd_init() { } cmd_show() { - local opts selected_line clip=0 qrcode=0 - opts="$($GETOPT -o q::c:: -l qrcode::,clip:: -n "$PROGRAM" -- "$@")" + local opts selected_line clip=0 find=0 qrcode=0 + opts="$($GETOPT -o q::c:: -l qrcode::,clip::,find -n "$PROGRAM" -- "$@")" local err=$? eval set -- "$opts" while true; do case $1 in + --find) find=1; shift ;; -q|--qrcode) qrcode=1; selected_line="${2:-1}"; shift 2 ;; -c|--clip) clip=1; selected_line="${2:-1}"; shift 2 ;; --) shift; break ;; @@ -397,12 +398,19 @@ cmd_show() { fi fi elif [[ -d $PREFIX/$path ]]; then - if [[ -z $path ]]; then - echo "Password Store" + if [[ $find -eq 1 ]]; then + local n="$(echo "$PREFIX" | wc -c)" + + find -L "$PREFIX/$path" | sed '/[^\/]$/s,$,/,' | sed "s/^.\{$n\}//" | sed 's,\.gpg/$,,' else - echo "${path%\/}" + if [[ -z $path ]]; then + echo "Password Store" + else + echo "${path%\/}" + fi + + tree -N -C -l --noreport "$PREFIX/$path" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors fi - tree -N -C -l --noreport "$PREFIX/$path" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors elif [[ -z $path ]]; then die "Error: password store is empty. Try \"pass init\"." else -- 2.50.1 From mekeor at posteo.de Mon Aug 18 11:00:10 2025 From: mekeor at posteo.de (Mekeor Melire) Date: Mon, 18 Aug 2025 11:00:10 +0000 Subject: Commit =?utf-8?Q?=E2=80=9Cemacs=3A?= Avoid double decryption in field and secret =?utf-8?Q?access=E2=80=9D?= broke my setup Message-ID: <87ikikevzv.fsf@posteo.de> Hello. I'm reposting because my original message was badly formatted and got no response. If no one responds, let's please revert the mentioned commit. Hello. Git commit 3ca13cd8882cae4083c1c478858adbf2e82dd037 from 2025-06-18 broke my setup. To be precise, this part seems to break it: -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/x-patch Size: 596 bytes Desc: not available URL: -------------- next part -------------- Now, how does it break my setup? What is my setup? I use GNU/Linux with Wayland and wlroots based Wayland compositor. I also run an Emacs daemon. To temporarily put a password in my clipboard, I run something along these lines: emacsclient --create --no-wait \ --eval "(call-interactively #'password-store-copy)" \ --eval "(delete-frame)" I should also mention that I have an Elisp advice overriding password-store--run-1 without which my setup doesn't work. It makes sure that `1' is passed as SECONDS argument to accept-process-output. This used to work like a charm but with the mentioned commit active, the password doesn't end up in my clipboard. I didn't yet properly investigate the reasons. If I would wildly guess, I'd wonder if it's due to the removal of the invocation of password-store--run-show in the above mentioned commit snippet. Because --run-show will call password-store--run-1 which will call make-process. I'd guess that this means that before the patch, effectively my Emacs-daemon process was copying the password; whereas after the commit, effectively the emacsclient-process is copying. And since the emacsclient-process dies when its frame is closed, the Wayland clipboard is cleared. For now, my workaround is to call password-store-copy in an existing Emacs frame (i.e. one that I won't close until I at least have pasted the copied password). I'd be glad if my problem was solved upstream in password-store.el. Nevertheless, thank you for the commit and all the development labour. From info at rjekker.nl Mon Aug 18 11:48:05 2025 From: info at rjekker.nl (Code Sensei (info)) Date: Mon, 18 Aug 2025 11:48:05 +0000 Subject: =?utf-8?Q?Re:_Commit_=E2=80=9Cemacs:_Avoid_double_decryption_in_field_and_secret_access=E2=80=9D_broke_my_setup?= In-Reply-To: <87ikikevzv.fsf@posteo.de> References: <87ikikevzv.fsf@posteo.de> Message-ID: <58986D4D-1878-48B2-8501-134BBBB45C84@rjekker.nl> Hi, I do not have permissions to commit or revert commits, so unfortunately I can?t help you there. Just wondering - would it not be simpler to just call pass directly e.g. ?pass -c my secret? instead of doing this through emacs? Seems like that would solve your problem, probably be faster too. RJ > On 18 Aug 2025, at 13:00, Mekeor Melire wrote: > > Hello. I'm reposting because my original message was badly > formatted and got no response. If no one responds, let's please > revert the mentioned commit. > > > > Hello. Git commit 3ca13cd8882cae4083c1c478858adbf2e82dd037 from > 2025-06-18 broke my setup. To be precise, this part seems to break > it: > > > Now, how does it break my setup? What is my setup? I use GNU/Linux > with Wayland and wlroots based Wayland compositor. I also run an > Emacs daemon. To temporarily put a password in my clipboard, I run > something along these lines: > > emacsclient --create --no-wait \ > --eval "(call-interactively #'password-store-copy)" \ > --eval "(delete-frame)" > > I should also mention that I have an Elisp advice overriding > password-store--run-1 without which my setup doesn't work. It > makes sure that `1' is passed as SECONDS argument to > accept-process-output. > > This used to work like a charm but with the mentioned commit > active, the password doesn't end up in my clipboard. > > I didn't yet properly investigate the reasons. If I would wildly > guess, I'd wonder if it's due to the removal of the invocation of > password-store--run-show in the above mentioned commit > snippet. Because --run-show will call password-store--run-1 which > will call make-process. I'd guess that this means that before the > patch, effectively my Emacs-daemon process was copying the > password; whereas after the commit, effectively the > emacsclient-process is copying. And since the emacsclient-process > dies when its frame is closed, the Wayland clipboard is cleared. > > For now, my workaround is to call password-store-copy in an > existing Emacs frame (i.e. one that I won't close until I at least > have pasted the copied password). > > I'd be glad if my problem was solved upstream in > password-store.el. Nevertheless, thank you for the commit and all > the development labour. From tino.calancha at gmail.com Fri Aug 29 11:49:36 2025 From: tino.calancha at gmail.com (Tino Calancha) Date: Fri, 29 Aug 2025 13:49:36 +0200 Subject: =?UTF-8?Q?Re=3A_Commit_=E2=80=9Cemacs=3A_Avoid_double_decryption_in_fiel?= =?UTF-8?Q?d_and_secret_access=E2=80=9D_broke_my_setup?= In-Reply-To: <87ikikevzv.fsf@posteo.de> References: <87ikikevzv.fsf@posteo.de> Message-ID: Hello Mekeor, thanks so much for the detailed message. You have a great intuition for this problem. Your analysis correctly pointed to the root cause: the previous change in the Emacs frontend transferred clipboard ownership from the long-lived daemon to the short-lived emacsclient, causing the content to be cleared as soon as the process exited. Unless this change proves to be problematic for other users, let's stick with our solution of avoiding double encryption. I think a workaround for your clipboard problem is a simple Emacs Lisp function that ensures the emacs-daemon process, not the short-lived emacsclient, handles the clipboard operation. Please include the following function in your ~/.emacs or ~/.emacs.d/init.el file. ``` (defun mypassword-store-copy-to-clipboard-and-wait () "Copies a password to the system clipboard and ensures it persists. This function is a workaround for Wayland's clipboard management with emacsclient. It ensures that the `password-store-copy' command is run by the long-lived `emacs-daemon' process, transferring clipboard ownership to a non-expiring process." (interactive) (call-interactively #'password-store-copy)) ``` After adding this code and restarting your Emacs daemon, you can update your emacsclient command to call this new function. ``` emacsclient --create --no-wait \ --eval "(call-interactively #'mypassword-store-copy-to-clipboard-and-wait)" \ --eval "(delete-frame)" ``` I don't have an equivalent test environment to yours, but based on the code and the nature of the error, I believe this workaround should fix your problem. Cheers, Tino On Mon, Aug 18, 2025 at 1:00?PM Mekeor Melire wrote: > > Hello. I'm reposting because my original message was badly > formatted and got no response. If no one responds, let's please > revert the mentioned commit. > > > > Hello. Git commit 3ca13cd8882cae4083c1c478858adbf2e82dd037 from > 2025-06-18 broke my setup. To be precise, this part seems to break > it: > > > Now, how does it break my setup? What is my setup? I use GNU/Linux > with Wayland and wlroots based Wayland compositor. I also run an > Emacs daemon. To temporarily put a password in my clipboard, I run > something along these lines: > > emacsclient --create --no-wait \ > --eval "(call-interactively #'password-store-copy)" \ > --eval "(delete-frame)" > > I should also mention that I have an Elisp advice overriding > password-store--run-1 without which my setup doesn't work. It > makes sure that `1' is passed as SECONDS argument to > accept-process-output. > > This used to work like a charm but with the mentioned commit > active, the password doesn't end up in my clipboard. > > I didn't yet properly investigate the reasons. If I would wildly > guess, I'd wonder if it's due to the removal of the invocation of > password-store--run-show in the above mentioned commit > snippet. Because --run-show will call password-store--run-1 which > will call make-process. I'd guess that this means that before the > patch, effectively my Emacs-daemon process was copying the > password; whereas after the commit, effectively the > emacsclient-process is copying. And since the emacsclient-process > dies when its frame is closed, the Wayland clipboard is cleared. > > For now, my workaround is to call password-store-copy in an > existing Emacs frame (i.e. one that I won't close until I at least > have pasted the copied password). > > I'd be glad if my problem was solved upstream in > password-store.el. Nevertheless, thank you for the commit and all > the development labour.