From simon.blum at posteo.org Thu Dec 1 19:19:38 2022 From: simon.blum at posteo.org (Simon Blum) Date: Thu, 1 Dec 2022 19:19:38 +0000 Subject: Completion files of extensions not working properly? Message-ID: <73816447-56c4-c9cf-2719-4b2025f7944d@posteo.org> Hello, I'm new here, so let me know if there already is an ongoing discussion on this topic or if I get anything wrong about this. I noticed that some extensions for pass (like pass-update or pass-tomb) provide completion files, which are poorly integrated in pass. This is due to the fact, that completion files are loaded dynamically on demand. For example in bash the file $BASHCOMPDIR/pass is loaded when you enter "pass ". As the completion file for pass-update is stored in $BASHCOMPDIR/pass-update it is not loaded unless you type "pass-update ". The completion files in fish and zsh are handled in a similar manner. I'd like to suggest a fix for that issue. The completion files of pass may automatically seek completion files of extensions and source them. Enclosed you find a patch that provides that feature together with example completion files for the extension pass-file. Regards, Simon Blum -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-automatically-source-extension-completion-files.patch Type: text/x-patch Size: 4778 bytes Desc: not available URL: -------------- next part -------------- # completion file for bash PASSWORD_STORE_EXTENSION_COMMANDS+=("file") __password_store_extension_complete_file() { local cur="${COMP_WORDS[COMP_CWORD]}" case "$COMP_CWORD" in 2) COMPREPLY+=($(compgen -W "add get" -- ${cur})) ;; 3) case "${COMP_WORDS[2]}" in a|add) COMPREPLY+=($(compgen -f ${cur})) ;; g|get) _pass_complete_entries 1 ;; esac ;; 4) case "${COMP_WORDS[2]}" in a|add) _pass_complete_entries ;; esac ;; esac } -------------- next part -------------- #autoload PASSWORD_STORE_EXTENSION_COMMANDS+=("file:add/get file to/from password-store") __password_store_extension_complete_file () { case "$CURRENT" in 2) local -a subcommands subcommands=( "add:add file to password-store" "get:get file from password-store" ) _describe -t commands 'pass' subcommands ;; 3) local cmd=${words[2]} case "${cmd}" in a|add) _files ;; g|get) _pass_complete_entries ;; esac ;; 4) local cmd=${words[2]} case "${cmd}" in a|add) _pass_complete_entries ;; esac ;; esac } unfunction $(basename $(print -P %x)) -------------- next part -------------- set -l PROG 'pass' function __fish_pass-file_needs_command set -l cmd (commandline -opc) if [ (count $cmd) -eq 2 -a "$cmd[2]" = file ] return 0 end return 1 end function __fish_pass-file_arg_nr_of_command set -l cmd (commandline -opc) set -l expected_length (math 2 + $argv[1]) if [ (count $cmd) -eq $expected_length -a "$cmd[2]" = "file" -a "$cmd[3]" = $argv[2] ] return 0 end return 1 end complete -c $PROG -f -n '__fish_pass_needs_command' -a file -d 'Command: add/get file to/from password-store' complete -c $PROG -f -n '__fish_pass-file_needs_command' -a add -d 'add file to password-store' complete -c $PROG -n '__fish_pass-file_arg_nr_of_command 1 a' complete -c $PROG -n '__fish_pass-file_arg_nr_of_command 1 add' complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 2 a' -a "(__fish_pass_print_entries)" complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 2 add' -a "(__fish_pass_print_entries)" complete -c $PROG -f -n '__fish_pass-file_needs_command' -a get -d 'get file from password-store' complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 1 g' -a "(__fish_pass_print_entries)" complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 1 get' -a "(__fish_pass_print_entries)" From t.fitschen at indiscale.com Fri Dec 2 10:04:12 2022 From: t.fitschen at indiscale.com (t.fitschen at indiscale.com) Date: Fri, 2 Dec 2022 11:04:12 +0100 Subject: Completion files of extensions not working properly? In-Reply-To: <73816447-56c4-c9cf-2719-4b2025f7944d@posteo.org> References: <73816447-56c4-c9cf-2719-4b2025f7944d@posteo.org> Message-ID: <20221202100412.4geyu6rafnmdoyp3@belial> Hi, this issue is bothering me as well. Also, there are bug reports in several pass extension projects, see * https://github.com/tadfisher/pass-otp/issues/137 * https://github.com/roddhjav/pass-update/issues/25 to name just two. I figure they have no chance of fixing it in their code base. Regards Timm On Thu, Dec 01, 2022 at 07:19:38PM +0000, Simon Blum wrote: > Hello, > > I'm new here, so let me know if there already is an ongoing discussion on > this topic or if I get anything wrong about this. > > I noticed that some extensions for pass (like pass-update or pass-tomb) > provide completion files, which are poorly integrated in pass. This is due > to the fact, that completion files are loaded dynamically on demand. For > example in bash the file $BASHCOMPDIR/pass is loaded when you enter "pass > ". As the completion file for pass-update is stored in > $BASHCOMPDIR/pass-update it is not loaded unless you type "pass-update > ". The completion files in fish and zsh are handled in a similar > manner. > > I'd like to suggest a fix for that issue. The completion files of pass may > automatically seek completion files of extensions and source them. Enclosed > you find a patch that provides that feature together with example completion > files for the extension pass-file. > > Regards, > Simon Blum > > # completion file for bash > > PASSWORD_STORE_EXTENSION_COMMANDS+=("file") > > __password_store_extension_complete_file() { > local cur="${COMP_WORDS[COMP_CWORD]}" > case "$COMP_CWORD" in > 2) > COMPREPLY+=($(compgen -W "add get" -- ${cur})) > ;; > 3) > case "${COMP_WORDS[2]}" in > a|add) > COMPREPLY+=($(compgen -f ${cur})) > ;; > g|get) > _pass_complete_entries 1 > ;; > esac > ;; > 4) > case "${COMP_WORDS[2]}" in > a|add) > _pass_complete_entries > ;; > esac > ;; > esac > } > #autoload > > PASSWORD_STORE_EXTENSION_COMMANDS+=("file:add/get file to/from password-store") > > __password_store_extension_complete_file () { > case "$CURRENT" in > 2) > local -a subcommands > subcommands=( > "add:add file to password-store" > "get:get file from password-store" > ) > _describe -t commands 'pass' subcommands > ;; > 3) > local cmd=${words[2]} > case "${cmd}" in > a|add) > _files > ;; > g|get) > _pass_complete_entries > ;; > esac > ;; > 4) > local cmd=${words[2]} > case "${cmd}" in > a|add) > _pass_complete_entries > ;; > esac > ;; > esac > } > > unfunction $(basename $(print -P %x)) > set -l PROG 'pass' > > function __fish_pass-file_needs_command > set -l cmd (commandline -opc) > if [ (count $cmd) -eq 2 -a "$cmd[2]" = file ] > return 0 > end > return 1 > end > > function __fish_pass-file_arg_nr_of_command > set -l cmd (commandline -opc) > set -l expected_length (math 2 + $argv[1]) > if [ (count $cmd) -eq $expected_length -a "$cmd[2]" = "file" -a "$cmd[3]" = $argv[2] ] > return 0 > end > return 1 > end > > complete -c $PROG -f -n '__fish_pass_needs_command' -a file -d 'Command: add/get file to/from password-store' > > complete -c $PROG -f -n '__fish_pass-file_needs_command' -a add -d 'add file to password-store' > complete -c $PROG -n '__fish_pass-file_arg_nr_of_command 1 a' > complete -c $PROG -n '__fish_pass-file_arg_nr_of_command 1 add' > complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 2 a' -a "(__fish_pass_print_entries)" > complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 2 add' -a "(__fish_pass_print_entries)" > > complete -c $PROG -f -n '__fish_pass-file_needs_command' -a get -d 'get file from password-store' > complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 1 g' -a "(__fish_pass_print_entries)" > complete -c $PROG -f -n '__fish_pass-file_arg_nr_of_command 1 get' -a "(__fish_pass_print_entries)" > -- Herr/Mr Timm Fitschen (er/he) Development T: +49 551 288 76 48-3 E: t.fitschen at indiscale.com I: indiscale.com IndiScale - Wir machen individuelles Datenmanagement skalierbar. IndiScale GmbH Lotzestra?e 22a 37083 G?ttingen Amtsgericht G?ttingen ? HRB 205721 Gesch?ftsf?hrung Henrik tom W?rden -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 906 bytes Desc: not available URL: From danolo at danoloan.es Sun Dec 4 21:39:52 2022 From: danolo at danoloan.es (danolo at danoloan.es) Date: Sun, 4 Dec 2022 22:39:52 +0100 (CET) Subject: Supporting use case of having a different GPG key in each device Message-ID: Hello all, I have been thinking of ways of configuring pass in my multiple devices. Currently, I use: - pass + gpg2 in a void-linux desktop - QtPass + Kleopatra in Windows on the same desktop - QtPass + GNOME Keyring in Fedora on a laptop - Password Store + OpenKeyChain in my Android phone Transferring a single GPG private key to all my devices is anything but secure, so I thought it could be a good idea to have a single GPG key in each one of my devices. This however is anything but scalable right now, as for each new device I have to add the public key of all previously added devices. I have thought that this may be supported implementing these two use cases: - Calling the PGP backend to create a new key when init'ing a new repository - Calling the PGP backend to create a new key when cloning a repository to a new device - Fetching currently active public keys in a repository from a public index (such as https://keys.openpgp.org/) Of course these use cases should be implemented in all clients, but I'm willing to start with pass itself. Do you think it's a good idea? Thanks & BR P.S.: I have searched for this topic using a search engine and have not found anything similar, short of a thread about migrating GPG keys. From louis at bettens.info Sun Dec 4 22:37:29 2022 From: louis at bettens.info (Louis Bettens) Date: Sun, 4 Dec 2022 23:37:29 +0100 Subject: [BUG] GnuPG release_dotlock error on re-encryption Message-ID: Hello there, I ran into an issue with gpg 2.3.7 that causes pass init to fail to re-encrypt a random subset of passwords. The error message is as follows. gpg: release_dotlock: not our lock (pid=2013175) gpg: can't unlock '/home/louis/.gnupg/pubring.kbx' gpg: encrypted with rsa2048 key, ID CBACA7AF7D2E9CB6, created 2022-12-03 ????? "Louis Bettens " I have been able to narrow it down to line 136 and to the pattern of piping gpg -d into gpg -er [...]. This is a race condition where sometimes the second process will acquire the lock after the first and cause it to complain. Importantly, the pipeline still outputs a correct PGP message (I think) but one of the processes will exit with 2 which causes pass to skip that password. I can reproduce the behavior in isolation by running echo test | gpg -er louis at bettens.info | gpg -d and observe that, with some unknown probability, the second process will exit with 2 after printing the message. I am using NixOS 22.11 and a Nitrokey Pro, although this also occurs with keys stored on disk. For possible fixes, I think the most straightforward would be to use $SECURE_TMPDIR. Of course this adds an requirement on the running environment (as well as a security assumption) but unless there is a simple way to sequence two commands in a pipeline and also ensure the pipe buffer doesn't fill up, this seems like the best approach. I can produce a patch if there is no objection. Louis -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_0xDFE1D4A017337E2A.asc Type: application/pgp-keys Size: 2619 bytes Desc: OpenPGP public key URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From emk.mymail at gmail.com Mon Dec 5 03:33:49 2022 From: emk.mymail at gmail.com (Edward Kamau) Date: Sun, 4 Dec 2022 22:33:49 -0500 Subject: columnar pass list terminal output Message-ID: Hi, I'm wondering if there is a way to get pass to display the password tree in multiple columns across a terminal rather than in a single one straight down. The current behavior leads to a lot of scrolling when you have many passwords. I've looked around and can't find any way or an extension to do that. Alternatively and perhaps better would be pass integration with the ls shell command so that you can do 'pass ls -C' for example and get columnar output. It would also be nice to be able to list just the categories (directories in .password-store) without the passwords. If there is no way, currently, to do this perhaps any devs who see this might consider it a feature request :-) thanks for what is one of the most useful tools on my computer! Edward From matt at connell.tech Mon Dec 5 13:56:17 2022 From: matt at connell.tech (Matt Connell) Date: Mon, 05 Dec 2022 08:56:17 -0500 Subject: columnar pass list terminal output In-Reply-To: References: Message-ID: <083ea7f3a9ee7e364392be75ebd367eda84d8c44.camel@connell.tech> On Sun, 2022-12-04 at 22:33 -0500, Edward Kamau wrote: > a lot of scrolling when you have many passwords. If you're trying to find something in particular, you can use `pass find` and even `pass grep` if you need to search file contents. This seems faster and easier to me as opposed to visually searching, but maybe my eyes aren't so quick anymore. > It would also be nice to be able to list just the > categories (directories in .password-store) without the passwords. This is easy with the find command, from your shell:? find .password_store -type d From louis at bettens.info Mon Dec 5 22:16:24 2022 From: louis at bettens.info (Louis Bettens) Date: Mon, 5 Dec 2022 23:16:24 +0100 Subject: [PATCH] Bug: race condition in reencrypt_path Message-ID: <20221205221624.3491370-1-louis@bettens.info> --- src/password-store.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/password-store.sh b/src/password-store.sh index 22e818f..549848e 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -110,6 +110,7 @@ set_gpg_recipients() { reencrypt_path() { local prev_gpg_recipients="" gpg_keys="" current_keys="" index passfile local groups="$($GPG $PASSWORD_STORE_GPG_OPTS --list-config --with-colons | grep "^cfg:group:.*")" + [[ -d "$SECURE_TMPDIR" ]] || die "Error: secure temporary directory not found" while read -r -d "" passfile; do [[ -L $passfile ]] && continue local passfile_dir="${passfile%/*}" @@ -117,7 +118,7 @@ reencrypt_path() { passfile_dir="${passfile_dir#/}" local passfile_display="${passfile#$PREFIX/}" passfile_display="${passfile_display%.gpg}" - local passfile_temp="${passfile}.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--" + local passfile_temp="${SECURE_TMPDIR}/passfile.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--" set_gpg_recipients "$passfile_dir" if [[ $prev_gpg_recipients != "${GPG_RECIPIENTS[*]}" ]]; then @@ -133,8 +134,9 @@ reencrypt_path() { if [[ $gpg_keys != "$current_keys" ]]; then echo "$passfile_display: reencrypting to ${gpg_keys//$'\n'/ }" - $GPG -d "${GPG_OPTS[@]}" "$passfile" | $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}" && - mv "$passfile_temp" "$passfile" || rm -f "$passfile_temp" + $GPG -d "${GPG_OPTS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}" "$passfile" && + $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" "$passfile_temp" || + shred "$passfile_temp" fi prev_gpg_recipients="${GPG_RECIPIENTS[*]}" done < <(find "$1" -path '*/.git' -prune -o -path '*/.extensions' -prune -o -iname '*.gpg' -print0) @@ -335,6 +337,8 @@ cmd_init() { local gpg_id="$PREFIX/$id_path/.gpg-id" set_git "$gpg_id" + tmpdir #Defines $SECURE_TMPDIR, required for reencrypt_path + if [[ $# -eq 1 && -z $1 ]]; then [[ ! -f "$gpg_id" ]] && die "Error: $gpg_id does not exist and so cannot be removed." rm -v -f "$gpg_id" || exit 1 @@ -624,6 +628,8 @@ cmd_copy_move() { local interactive="-i" [[ ! -t 0 || $force -eq 1 ]] && interactive="-f" + tmpdir #Defines $SECURE_TMPDIR, required for reencrypt_path + set_git "$new_path" if [[ $move -eq 1 ]]; then mv $interactive -v "$old_path" "$new_path" || exit 1 -- 2.38.1 From t.fitschen at indiscale.com Tue Dec 6 14:44:37 2022 From: t.fitschen at indiscale.com (t.fitschen at indiscale.com) Date: Tue, 6 Dec 2022 15:44:37 +0100 Subject: [PATCH] Bug: race condition in reencrypt_path In-Reply-To: <20221205221624.3491370-1-louis@bettens.info> References: <20221205221624.3491370-1-louis@bettens.info> Message-ID: <20221206144437.hukdbppijklxr2r6@belial> Sorry, Louis, what is tmpdir? It's not a bash built-in, is it? Did I miss something? I would suggest using `mktemp` which is as secure as gets when you are writing unencrypted content on the disk, I suppose. And yes, I think it is not ideal to do that. Apart from that, I don't know if fixing a gpg bug here is the way to go. While I didn't run into this bug yet, I think it is good that you found a work-around anyways, because I know that there have been some issues with the locking (https://dev.gnupg.org/T5884), so thank you. Regards Timm On Mon, Dec 05, 2022 at 11:16:24PM +0100, Louis Bettens wrote: > --- > src/password-store.sh | 12 +++++++++--- > 1 file changed, 9 insertions(+), 3 deletions(-) > > diff --git a/src/password-store.sh b/src/password-store.sh > index 22e818f..549848e 100755 > --- a/src/password-store.sh > +++ b/src/password-store.sh > @@ -110,6 +110,7 @@ set_gpg_recipients() { > reencrypt_path() { > local prev_gpg_recipients="" gpg_keys="" current_keys="" index passfile > local groups="$($GPG $PASSWORD_STORE_GPG_OPTS --list-config --with-colons | grep "^cfg:group:.*")" > + [[ -d "$SECURE_TMPDIR" ]] || die "Error: secure temporary directory not found" > while read -r -d "" passfile; do > [[ -L $passfile ]] && continue > local passfile_dir="${passfile%/*}" > @@ -117,7 +118,7 @@ reencrypt_path() { > passfile_dir="${passfile_dir#/}" > local passfile_display="${passfile#$PREFIX/}" > passfile_display="${passfile_display%.gpg}" > - local passfile_temp="${passfile}.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--" > + local passfile_temp="${SECURE_TMPDIR}/passfile.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--" > > set_gpg_recipients "$passfile_dir" > if [[ $prev_gpg_recipients != "${GPG_RECIPIENTS[*]}" ]]; then > @@ -133,8 +134,9 @@ reencrypt_path() { > > if [[ $gpg_keys != "$current_keys" ]]; then > echo "$passfile_display: reencrypting to ${gpg_keys//$'\n'/ }" > - $GPG -d "${GPG_OPTS[@]}" "$passfile" | $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}" && > - mv "$passfile_temp" "$passfile" || rm -f "$passfile_temp" > + $GPG -d "${GPG_OPTS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}" "$passfile" && > + $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" "$passfile_temp" || > + shred "$passfile_temp" > fi > prev_gpg_recipients="${GPG_RECIPIENTS[*]}" > done < <(find "$1" -path '*/.git' -prune -o -path '*/.extensions' -prune -o -iname '*.gpg' -print0) > @@ -335,6 +337,8 @@ cmd_init() { > local gpg_id="$PREFIX/$id_path/.gpg-id" > set_git "$gpg_id" > > + tmpdir #Defines $SECURE_TMPDIR, required for reencrypt_path > + > if [[ $# -eq 1 && -z $1 ]]; then > [[ ! -f "$gpg_id" ]] && die "Error: $gpg_id does not exist and so cannot be removed." > rm -v -f "$gpg_id" || exit 1 > @@ -624,6 +628,8 @@ cmd_copy_move() { > local interactive="-i" > [[ ! -t 0 || $force -eq 1 ]] && interactive="-f" > > + tmpdir #Defines $SECURE_TMPDIR, required for reencrypt_path > + > set_git "$new_path" > if [[ $move -eq 1 ]]; then > mv $interactive -v "$old_path" "$new_path" || exit 1 > -- > 2.38.1 > -- Herr/Mr Timm Fitschen (er/he) Development T: +49 551 288 76 48-3 E: t.fitschen at indiscale.com I: indiscale.com IndiScale - Wir machen individuelles Datenmanagement skalierbar. IndiScale GmbH Lotzestra?e 22a 37083 G?ttingen Amtsgericht G?ttingen ? HRB 205721 Gesch?ftsf?hrung Henrik tom W?rden -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 906 bytes Desc: not available URL: From congdanhqx at gmail.com Tue Dec 6 15:12:09 2022 From: congdanhqx at gmail.com (=?utf-8?B?xJBvw6BuIFRy4bqnbiBDw7RuZw==?= Danh) Date: Tue, 6 Dec 2022 22:12:09 +0700 Subject: [PATCH] Bug: race condition in reencrypt_path In-Reply-To: <20221206144437.hukdbppijklxr2r6@belial> References: <20221205221624.3491370-1-louis@bettens.info> <20221206144437.hukdbppijklxr2r6@belial> Message-ID: On 2022-12-06 15:44:37+0100, t.fitschen at indiscale.com wrote: > Sorry, Louis, what is tmpdir? It's not a bash built-in, is it? Did I > miss something? tmpdir is a function in password-store. It will create temporary directories in /dev/shm if available which is guaranteed to be in devtmpfs on Linux. It also falls back to "mktemp" on system that lacks /dev/shm and shred the file later. > I would suggest using `mktemp` which is as secure as gets when you are > writing unencrypted content on the disk, I suppose. And yes, I think it > is not ideal to do that. > > Apart from that, I don't know if fixing a gpg bug here is the way to go. > > While I didn't run into this bug yet, I think it is good that you > found a work-around anyways, because I know that there have been some > issues with the locking (https://dev.gnupg.org/T5884), so thank you. > > Regards > Timm > > On Mon, Dec 05, 2022 at 11:16:24PM +0100, Louis Bettens wrote: > > --- > > src/password-store.sh | 12 +++++++++--- > > 1 file changed, 9 insertions(+), 3 deletions(-) > > > > diff --git a/src/password-store.sh b/src/password-store.sh > > index 22e818f..549848e 100755 > > --- a/src/password-store.sh > > +++ b/src/password-store.sh > > @@ -110,6 +110,7 @@ set_gpg_recipients() { > > reencrypt_path() { > > local prev_gpg_recipients="" gpg_keys="" current_keys="" index passfile > > local groups="$($GPG $PASSWORD_STORE_GPG_OPTS --list-config --with-colons | grep "^cfg:group:.*")" > > + [[ -d "$SECURE_TMPDIR" ]] || die "Error: secure temporary directory not found" > > while read -r -d "" passfile; do > > [[ -L $passfile ]] && continue > > local passfile_dir="${passfile%/*}" > > @@ -117,7 +118,7 @@ reencrypt_path() { > > passfile_dir="${passfile_dir#/}" > > local passfile_display="${passfile#$PREFIX/}" > > passfile_display="${passfile_display%.gpg}" > > - local passfile_temp="${passfile}.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--" > > + local passfile_temp="${SECURE_TMPDIR}/passfile.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--" > > > > set_gpg_recipients "$passfile_dir" > > if [[ $prev_gpg_recipients != "${GPG_RECIPIENTS[*]}" ]]; then > > @@ -133,8 +134,9 @@ reencrypt_path() { > > > > if [[ $gpg_keys != "$current_keys" ]]; then > > echo "$passfile_display: reencrypting to ${gpg_keys//$'\n'/ }" > > - $GPG -d "${GPG_OPTS[@]}" "$passfile" | $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}" && > > - mv "$passfile_temp" "$passfile" || rm -f "$passfile_temp" > > + $GPG -d "${GPG_OPTS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}" "$passfile" && > > + $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" "$passfile_temp" || > > + shred "$passfile_temp" > > fi > > prev_gpg_recipients="${GPG_RECIPIENTS[*]}" > > done < <(find "$1" -path '*/.git' -prune -o -path '*/.extensions' -prune -o -iname '*.gpg' -print0) > > @@ -335,6 +337,8 @@ cmd_init() { > > local gpg_id="$PREFIX/$id_path/.gpg-id" > > set_git "$gpg_id" > > > > + tmpdir #Defines $SECURE_TMPDIR, required for reencrypt_path > > + > > if [[ $# -eq 1 && -z $1 ]]; then > > [[ ! -f "$gpg_id" ]] && die "Error: $gpg_id does not exist and so cannot be removed." > > rm -v -f "$gpg_id" || exit 1 > > @@ -624,6 +628,8 @@ cmd_copy_move() { > > local interactive="-i" > > [[ ! -t 0 || $force -eq 1 ]] && interactive="-f" > > > > + tmpdir #Defines $SECURE_TMPDIR, required for reencrypt_path > > + > > set_git "$new_path" > > if [[ $move -eq 1 ]]; then > > mv $interactive -v "$old_path" "$new_path" || exit 1 > > -- > > 2.38.1 > > > > -- > Herr/Mr Timm Fitschen > (er/he) > Development > > T: +49 551 288 76 48-3 > E: t.fitschen at indiscale.com > I: indiscale.com > > IndiScale - Wir machen individuelles Datenmanagement skalierbar. > > IndiScale GmbH > Lotzestra?e 22a > 37083 G?ttingen > > Amtsgericht G?ttingen ? HRB 205721 > Gesch?ftsf?hrung Henrik tom W?rden -- Danh From git at grubix.eu Tue Dec 6 17:26:16 2022 From: git at grubix.eu (Michael J Gruber) Date: Tue, 6 Dec 2022 18:26:16 +0100 Subject: [PATCH] Bug: race condition in reencrypt_path In-Reply-To: References: <20221205221624.3491370-1-louis@bettens.info> <20221206144437.hukdbppijklxr2r6@belial> Message-ID: I guess this whole discussion shows the importance of a git commit message which addresses the "why" (what race condition) and "how" (does the patch solve this), since (only) the "what" (is changed) can be read from the diff. BTW: Are we supposed to top-post or bottom-post here? Michael Am Di., 6. Dez. 2022 um 16:15 Uhr schrieb ?o?n Tr?n C?ng Danh : > > On 2022-12-06 15:44:37+0100, t.fitschen at indiscale.com wrote: > > Sorry, Louis, what is tmpdir? It's not a bash built-in, is it? Did I > > miss something? > > tmpdir is a function in password-store. > It will create temporary directories in /dev/shm if available which is > guaranteed to be in devtmpfs on Linux. It also falls back to "mktemp" > on system that lacks /dev/shm and shred the file later. > > > I would suggest using `mktemp` which is as secure as gets when you are > > writing unencrypted content on the disk, I suppose. And yes, I think it > > is not ideal to do that. > > > > Apart from that, I don't know if fixing a gpg bug here is the way to go. > > > > While I didn't run into this bug yet, I think it is good that you > > found a work-around anyways, because I know that there have been some > > issues with the locking (https://dev.gnupg.org/T5884), so thank you. > > > > Regards > > Timm > > > > On Mon, Dec 05, 2022 at 11:16:24PM +0100, Louis Bettens wrote: > > > --- > > > src/password-store.sh | 12 +++++++++--- > > > 1 file changed, 9 insertions(+), 3 deletions(-) > > > > > > diff --git a/src/password-store.sh b/src/password-store.sh > > > index 22e818f..549848e 100755 > > > --- a/src/password-store.sh > > > +++ b/src/password-store.sh > > > @@ -110,6 +110,7 @@ set_gpg_recipients() { > > > reencrypt_path() { > > > local prev_gpg_recipients="" gpg_keys="" current_keys="" index passfile > > > local groups="$($GPG $PASSWORD_STORE_GPG_OPTS --list-config --with-colons | grep "^cfg:group:.*")" > > > + [[ -d "$SECURE_TMPDIR" ]] || die "Error: secure temporary directory not found" > > > while read -r -d "" passfile; do > > > [[ -L $passfile ]] && continue > > > local passfile_dir="${passfile%/*}" > > > @@ -117,7 +118,7 @@ reencrypt_path() { > > > passfile_dir="${passfile_dir#/}" > > > local passfile_display="${passfile#$PREFIX/}" > > > passfile_display="${passfile_display%.gpg}" > > > - local passfile_temp="${passfile}.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--" > > > + local passfile_temp="${SECURE_TMPDIR}/passfile.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--" > > > > > > set_gpg_recipients "$passfile_dir" > > > if [[ $prev_gpg_recipients != "${GPG_RECIPIENTS[*]}" ]]; then > > > @@ -133,8 +134,9 @@ reencrypt_path() { > > > > > > if [[ $gpg_keys != "$current_keys" ]]; then > > > echo "$passfile_display: reencrypting to ${gpg_keys//$'\n'/ }" > > > - $GPG -d "${GPG_OPTS[@]}" "$passfile" | $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}" && > > > - mv "$passfile_temp" "$passfile" || rm -f "$passfile_temp" > > > + $GPG -d "${GPG_OPTS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}" "$passfile" && > > > + $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" "$passfile_temp" || > > > + shred "$passfile_temp" > > > fi > > > prev_gpg_recipients="${GPG_RECIPIENTS[*]}" > > > done < <(find "$1" -path '*/.git' -prune -o -path '*/.extensions' -prune -o -iname '*.gpg' -print0) > > > @@ -335,6 +337,8 @@ cmd_init() { > > > local gpg_id="$PREFIX/$id_path/.gpg-id" > > > set_git "$gpg_id" > > > > > > + tmpdir #Defines $SECURE_TMPDIR, required for reencrypt_path > > > + > > > if [[ $# -eq 1 && -z $1 ]]; then > > > [[ ! -f "$gpg_id" ]] && die "Error: $gpg_id does not exist and so cannot be removed." > > > rm -v -f "$gpg_id" || exit 1 > > > @@ -624,6 +628,8 @@ cmd_copy_move() { > > > local interactive="-i" > > > [[ ! -t 0 || $force -eq 1 ]] && interactive="-f" > > > > > > + tmpdir #Defines $SECURE_TMPDIR, required for reencrypt_path > > > + > > > set_git "$new_path" > > > if [[ $move -eq 1 ]]; then > > > mv $interactive -v "$old_path" "$new_path" || exit 1 > > > -- > > > 2.38.1 > > > > > > > -- > > Herr/Mr Timm Fitschen > > (er/he) > > Development > > > > T: +49 551 288 76 48-3 > > E: t.fitschen at indiscale.com > > I: indiscale.com > > > > IndiScale - Wir machen individuelles Datenmanagement skalierbar. > > > > IndiScale GmbH > > Lotzestra?e 22a > > 37083 G?ttingen > > > > Amtsgericht G?ttingen ? HRB 205721 > > Gesch?ftsf?hrung Henrik tom W?rden > > > > -- > Danh From congdanhqx at gmail.com Wed Dec 7 01:09:26 2022 From: congdanhqx at gmail.com (=?utf-8?B?xJBvw6BuIFRy4bqnbiBDw7RuZw==?= Danh) Date: Wed, 7 Dec 2022 08:09:26 +0700 Subject: [PATCH] Bug: race condition in reencrypt_path In-Reply-To: References: <20221205221624.3491370-1-louis@bettens.info> <20221206144437.hukdbppijklxr2r6@belial> Message-ID: On 2022-12-06 18:26:16+0100, Michael J Gruber wrote: > I guess this whole discussion shows the importance of a git commit > message which addresses the "why" (what race condition) and "how" > (does the patch solve this), since (only) the "what" (is changed) can > be read from the diff. > > BTW: Are we supposed to top-post or bottom-post here? I think we're supposed to interleaved but Timm didn't. > > Michael > > Am Di., 6. Dez. 2022 um 16:15 Uhr schrieb ?o?n Tr?n C?ng Danh > : > > > > On 2022-12-06 15:44:37+0100, t.fitschen at indiscale.com wrote: > > > Sorry, Louis, what is tmpdir? It's not a bash built-in, is it? Did I > > > miss something? > > > > tmpdir is a function in password-store. > > It will create temporary directories in /dev/shm if available which is > > guaranteed to be in devtmpfs on Linux. It also falls back to "mktemp" > > on system that lacks /dev/shm and shred the file later. > > > > > I would suggest using `mktemp` which is as secure as gets when you are > > > writing unencrypted content on the disk, I suppose. And yes, I think it > > > is not ideal to do that. > > > > > > Apart from that, I don't know if fixing a gpg bug here is the way to go. > > > > > > While I didn't run into this bug yet, I think it is good that you > > > found a work-around anyways, because I know that there have been some > > > issues with the locking (https://dev.gnupg.org/T5884), so thank you. > > > > > > Regards > > > Timm > > > > > > On Mon, Dec 05, 2022 at 11:16:24PM +0100, Louis Bettens wrote: > > > > --- > > > > src/password-store.sh | 12 +++++++++--- > > > > 1 file changed, 9 insertions(+), 3 deletions(-) > > > > > > > > diff --git a/src/password-store.sh b/src/password-store.sh > > > > index 22e818f..549848e 100755 > > > > --- a/src/password-store.sh > > > > +++ b/src/password-store.sh > > > > @@ -110,6 +110,7 @@ set_gpg_recipients() { > > > > reencrypt_path() { > > > > local prev_gpg_recipients="" gpg_keys="" current_keys="" index passfile > > > > local groups="$($GPG $PASSWORD_STORE_GPG_OPTS --list-config --with-colons | grep "^cfg:group:.*")" > > > > + [[ -d "$SECURE_TMPDIR" ]] || die "Error: secure temporary directory not found" > > > > while read -r -d "" passfile; do > > > > [[ -L $passfile ]] && continue > > > > local passfile_dir="${passfile%/*}" > > > > @@ -117,7 +118,7 @@ reencrypt_path() { > > > > passfile_dir="${passfile_dir#/}" > > > > local passfile_display="${passfile#$PREFIX/}" > > > > passfile_display="${passfile_display%.gpg}" > > > > - local passfile_temp="${passfile}.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--" > > > > + local passfile_temp="${SECURE_TMPDIR}/passfile.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--" > > > > > > > > set_gpg_recipients "$passfile_dir" > > > > if [[ $prev_gpg_recipients != "${GPG_RECIPIENTS[*]}" ]]; then > > > > @@ -133,8 +134,9 @@ reencrypt_path() { > > > > > > > > if [[ $gpg_keys != "$current_keys" ]]; then > > > > echo "$passfile_display: reencrypting to ${gpg_keys//$'\n'/ }" > > > > - $GPG -d "${GPG_OPTS[@]}" "$passfile" | $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}" && > > > > - mv "$passfile_temp" "$passfile" || rm -f "$passfile_temp" > > > > + $GPG -d "${GPG_OPTS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}" "$passfile" && > > > > + $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" "$passfile_temp" || > > > > + shred "$passfile_temp" > > > > fi > > > > prev_gpg_recipients="${GPG_RECIPIENTS[*]}" > > > > done < <(find "$1" -path '*/.git' -prune -o -path '*/.extensions' -prune -o -iname '*.gpg' -print0) > > > > @@ -335,6 +337,8 @@ cmd_init() { > > > > local gpg_id="$PREFIX/$id_path/.gpg-id" > > > > set_git "$gpg_id" > > > > > > > > + tmpdir #Defines $SECURE_TMPDIR, required for reencrypt_path > > > > + > > > > if [[ $# -eq 1 && -z $1 ]]; then > > > > [[ ! -f "$gpg_id" ]] && die "Error: $gpg_id does not exist and so cannot be removed." > > > > rm -v -f "$gpg_id" || exit 1 > > > > @@ -624,6 +628,8 @@ cmd_copy_move() { > > > > local interactive="-i" > > > > [[ ! -t 0 || $force -eq 1 ]] && interactive="-f" > > > > > > > > + tmpdir #Defines $SECURE_TMPDIR, required for reencrypt_path > > > > + > > > > set_git "$new_path" > > > > if [[ $move -eq 1 ]]; then > > > > mv $interactive -v "$old_path" "$new_path" || exit 1 > > > > -- > > > > 2.38.1 > > > > > > > > > > -- > > > Herr/Mr Timm Fitschen > > > (er/he) > > > Development > > > > > > T: +49 551 288 76 48-3 > > > E: t.fitschen at indiscale.com > > > I: indiscale.com > > > > > > IndiScale - Wir machen individuelles Datenmanagement skalierbar. > > > > > > IndiScale GmbH > > > Lotzestra?e 22a > > > 37083 G?ttingen > > > > > > Amtsgericht G?ttingen ? HRB 205721 > > > Gesch?ftsf?hrung Henrik tom W?rden > > > > > > > > -- > > Danh -- Danh From pkk at spth.de Sat Dec 10 20:34:16 2022 From: pkk at spth.de (Philipp Klaus Krause) Date: Sat, 10 Dec 2022 21:34:16 +0100 Subject: How to search by login name? Message-ID: <1a38f544-0a77-e26f-56e1-0249e522b3d3@spth.de> I would like to get a list of all sites, for which I use a specific username, i.e. search the password store by the login field. How could I do that? From astrian at fastmail.com Sat Dec 10 22:18:06 2022 From: astrian at fastmail.com (Astrian Zheng) Date: Sun, 11 Dec 2022 09:18:06 +1100 Subject: How to search by login name? In-Reply-To: <1a38f544-0a77-e26f-56e1-0249e522b3d3@spth.de> References: <1a38f544-0a77-e26f-56e1-0249e522b3d3@spth.de> Message-ID: <62959398-F3FA-4F70-BB57-D8982FB02F44@fastmail.com> Hello Philipp: As you describe, I would recommend that use a specific folder structure. For example: ? PasswordStore ? ? Website A ? ? ? Username1.pgp ? ? ? Username2.pgp ? ? Website B ? ? Username1.pgp ? ? Username2.pgp As this structure, you can directly search your login name as regular file/folder search methods. However, there is a problem that your username may not be able to encrypted. There are some ways to encrypt the volume address for hide your username, but you may need to find them by yourself. Astrian Zheng On 11 Dec 2022, at 7:34, Philipp Klaus Krause wrote: > I would like to get a list of all sites, for which I use a specific username, i.e. search the password store by the login field. > How could I do that? -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 862 bytes Desc: OpenPGP digital signature URL: From minshall at umich.edu Sun Dec 11 03:38:05 2022 From: minshall at umich.edu (Greg Minshall) Date: Sun, 11 Dec 2022 06:38:05 +0300 Subject: How to search by login name? In-Reply-To: <1a38f544-0a77-e26f-56e1-0249e522b3d3@spth.de> References: <1a38f544-0a77-e26f-56e1-0249e522b3d3@spth.de> Message-ID: <1238901.1670729885@archlinux> Philipp, how about something like : pass grep -l minshall at umich.edu From pkk at spth.de Sun Dec 11 18:22:35 2022 From: pkk at spth.de (Philipp Klaus Krause) Date: Sun, 11 Dec 2022 19:22:35 +0100 Subject: How to search by login name? In-Reply-To: <62959398-F3FA-4F70-BB57-D8982FB02F44@fastmail.com> References: <1a38f544-0a77-e26f-56e1-0249e522b3d3@spth.de> <62959398-F3FA-4F70-BB57-D8982FB02F44@fastmail.com> Message-ID: <86da0498-f3b0-c0a8-3d45-19648b14bb7d@spth.de> Am 10.12.22 um 23:18 schrieb Astrian Zheng: > Hello Philipp: > > As you describe, I would recommend that use a specific folder structure [?] Unfortunately it's too late for that now. I have 105 files in .password-store and need to know which of them use an email address that I am about to loose as login name. Philipp From low.dusk9299 at revolto.net Sun Dec 11 19:16:31 2022 From: low.dusk9299 at revolto.net (low.dusk9299 at revolto.net) Date: Sun, 11 Dec 2022 16:16:31 -0300 Subject: How to search by login name? In-Reply-To: <86da0498-f3b0-c0a8-3d45-19648b14bb7d@spth.de> References: <1a38f544-0a77-e26f-56e1-0249e522b3d3@spth.de> <62959398-F3FA-4F70-BB57-D8982FB02F44@fastmail.com> <86da0498-f3b0-c0a8-3d45-19648b14bb7d@spth.de> Message-ID: <2e74e4e9-d36d-4221-823c-c63709e58c12@app.fastmail.com> pass grep your-username Read all about it by running man pass On Sun, Dec 11, 2022, at 15:22, Philipp Klaus Krause wrote: > Am 10.12.22 um 23:18 schrieb Astrian Zheng: >> Hello Philipp: >> >> As you describe, I would recommend that use a specific folder structure [?] > > Unfortunately it's too late for that now. I have 105 files in > .password-store and need to know which of them use an email address that > I am about to loose as login name. > > Philipp From declantsien at riseup.net Thu Dec 15 08:10:01 2022 From: declantsien at riseup.net (Declan Tsien) Date: Thu, 15 Dec 2022 16:10:01 +0800 Subject: [BUG] emacs/password-store.el Package-Requires metadata is invalid now Message-ID: <87mt7pytnq.fsf@riseup.net> Since =auth-source-pass= no longer being distributed externally, which makes =emacs/password-store.el= Package-Requires metadata invalid now. I wonder that whether you guys interested in updating Package-Requires in light of =auth-source-pass=. According to author of elpaca[0], we'd have to remove the explicit dependency declaration for =auth-source-pass= and bump the min required Emacs version to when it was added to core. Looking at the Emacs repository, that looks like Emacs 26: #+begin_src git tag --contains 0e066efe3b8 | head -n 1 emacs-26.0.90 #+end_src [0]: https://github.com/progfolio/elpaca/issues/38#issuecomment-1336362140 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 690 bytes Desc: not available URL: From tino.calancha at gmail.com Mon Dec 26 18:40:12 2022 From: tino.calancha at gmail.com (Tino Calancha) Date: Mon, 26 Dec 2022 19:40:12 +0100 (CET) Subject: [BUG] emacs/password-store.el Package-Requires metadata is invalid now In-Reply-To: <87mt7pytnq.fsf@riseup.net> References: <87mt7pytnq.fsf@riseup.net> Message-ID: On Thu, 15 Dec 2022, Declan Tsien wrote: > > Since =auth-source-pass= no longer being distributed externally, which > makes =emacs/password-store.el= Package-Requires metadata invalid now. > > I wonder that whether you guys interested in updating Package-Requires > in light of =auth-source-pass=. According to author of elpaca[0], we'd have > to remove the explicit dependency declaration for =auth-source-pass= and > bump the min required Emacs version to when it was added to > core. Looking at the Emacs repository, that looks like Emacs 26: Thank you for the report! You are right, auth-surce-pass was added into Emacs 26. >From the Emacs sources, in etc/NEWS.26: ** New package 'auth-source-pass' integrates 'auth-source' with the password manager password-store (https://passwordstore.org). I agree, we should bump the minor version required to Emacs 26. I have pushed a commit doing that. Thanks again. Tino From ngraves at ngraves.fr Tue Dec 27 12:59:37 2022 From: ngraves at ngraves.fr (Nicolas Graves) Date: Tue, 27 Dec 2022 13:59:37 +0100 Subject: [PATCH] emacs: Add variable password-store-file-extension. In-Reply-To: <20221013213107.24749-1-ngraves@ngraves.fr> References: <20221013213107.24749-1-ngraves@ngraves.fr> Message-ID: <875ydxngsm.fsf@ngraves.fr> Hi ! I don't have an answer to this patch, can someone review this? Thanks in advance, Nicolas Graves On 2022-10-13 23:31, Nicolas Graves wrote: > --- > contrib/emacs/password-store.el | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/contrib/emacs/password-store.el b/contrib/emacs/password-store.el > index 6561eb1..72aee3e 100644 > --- a/contrib/emacs/password-store.el > +++ b/contrib/emacs/password-store.el > @@ -66,6 +66,9 @@ > (defvar password-store-timeout-timer nil > "Timer for clearing clipboard.") > > +(defvar password-store-file-extension ".gpg" > + "File extension to expect in the password store.") > + > (defun password-store-timeout () > "Number of seconds to wait before clearing the password. > > @@ -187,7 +190,8 @@ Nil arguments are ignored. Output is discarded." > > (defun password-store--entry-to-file (entry) > "Return file name corresponding to ENTRY." > - (concat (expand-file-name entry (password-store-dir)) ".gpg")) > + (concat (expand-file-name entry (password-store-dir)) > + password-store-file-extension)) > > (defun password-store--file-to-entry (file) > "Return entry name corresponding to FILE." > @@ -218,7 +222,8 @@ ENTRY is the name of a password-store entry." > (if (file-directory-p dir) > (delete-dups > (mapcar 'password-store--file-to-entry > - (directory-files-recursively dir ".+\\.gpg\\'")))))) > + (directory-files-recursively > + dir (concat ".+\\" password-store-file-extension "\\'"))))))) > > ;;;###autoload > (defun password-store-edit (entry) -- Best regards, Nicolas Graves From eankeen at gmail.com Thu Dec 29 08:34:35 2022 From: eankeen at gmail.com (Edwin Kofler) Date: Thu, 29 Dec 2022 00:34:35 -0800 Subject: [PATCH] Use $VISUAL over $EDITOR when calculating editor to use Message-ID: It is more correct to use $VISUAL first, then $EDITOR. See: https://unix.stackexchange.com/a/4861 --- src/password-store.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/password-store.sh b/src/password-store.sh index 22e818f..ffaf24f 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -294,7 +294,7 @@ cmd_usage() { during entry. Or, optionally, the entry may be multiline. Prompt before overwriting existing password unless forced. $PROGRAM edit pass-name - Insert a new password or edit an existing password using ${EDITOR:-vi}. + Insert a new password or edit an existing password using ${VISUAL:-${EDITOR:-vi}}. $PROGRAM generate [--no-symbols,-n] [--clip,-c] [--in-place,-i | --force,-f] pass-name [pass-length] Generate a new password of pass-length (or $GENERATED_LENGTH if unspecified) with optionally no symbols. Optionally put it on the clipboard and clear board after $CLIP_TIME seconds. @@ -500,13 +500,13 @@ cmd_edit() { $GPG -d -o "$tmp_file" "${GPG_OPTS[@]}" "$passfile" || exit 1 action="Edit" fi - ${EDITOR:-vi} "$tmp_file" + ${VISUAL:-${EDITOR:-vi}} "$tmp_file" [[ -f $tmp_file ]] || die "New password not saved." $GPG -d -o - "${GPG_OPTS[@]}" "$passfile" 2>/dev/null | diff - "$tmp_file" &>/dev/null && die "Password unchanged." while ! $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" "$tmp_file"; do yesno "GPG encryption failed. Would you like to try again?" done - git_add_file "$passfile" "$action password for $path using ${EDITOR:-vi}." + git_add_file "$passfile" "$action password for $path using ${VISUAL:-${EDITOR:-vi}}." } cmd_generate() { -- 2.34.1 From git at levis.name Fri Dec 30 11:24:29 2022 From: git at levis.name (Cyril Levis) Date: Fri, 30 Dec 2022 12:24:29 +0100 Subject: [PATCH] feat: add the possibility to create relative symlink Message-ID: <20221230112429.541603-1-git@levis.name> I known several people doing this manually and myself. This work well with android app too. Thanks for this cool toy ! --- src/password-store.sh | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/password-store.sh b/src/password-store.sh index 22e818f..e95802c 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -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] old-path new-path + Link src-path to dst-path, optionally forcefully. $PROGRAM git git-command-args... If the password store is a git repository, execute a git command specified by git-command-args. @@ -649,6 +651,39 @@ cmd_copy_move() { fi } +cmd_link() { + local opts force=0 + opts="$($GETOPT -o f -l force -n "$PROGRAM" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + -f|--force) force=1; shift ;; + --) shift; break ;; + esac done + [[ $# -ne 2 ]] && die "Usage: $PROGRAM $COMMAND [--force,-f] old-path new-path" + check_sneaky_paths "$@" + local src_path="$PREFIX/${1%/}" + local src_dir="$src_path" + local dst_path="$PREFIX/$2" + + if ! [[ -f $src_path.gpg && -d $src_path && $1 == */ || ! -f $src_path.gpg ]]; then + src_dir="${src_path%/*}" + src_path="${src_path}.gpg" + fi + echo "$src_path" + [[ -e $src_path ]] || die "Error: $1 is not in the password store." + + mkdir -p -v "${dst_path%/*}" + [[ -d $src_path || -d $dst_path || $dst_path == */ ]] || dst_path="${dst_path}.gpg" + + local interactive="-i" + [[ ! -t 0 || $force -eq 1 ]] && interactive="-f" + + set_git "$dst_path" + ln -s $interactive -r -v "$src_path" "$dst_path" || exit 1 + git_add_file "$dst_path" "Link ${1} to ${2}." +} + cmd_git() { set_git "$PREFIX/" if [[ $1 == "init" ]]; then @@ -715,6 +750,7 @@ case "$1" in delete|rm|remove) shift; cmd_delete "$@" ;; rename|mv) shift; cmd_copy_move "move" "$@" ;; copy|cp) shift; cmd_copy_move "copy" "$@" ;; + link|ln) shift; cmd_link "$@" ;; git) shift; cmd_git "$@" ;; *) cmd_extension_or_show "$@" ;; esac -- 2.39.0 From git at levis.name Fri Dec 30 11:53:33 2022 From: git at levis.name (Cyril Levis) Date: Fri, 30 Dec 2022 12:53:33 +0100 Subject: [PATCH v2] feat: add the possibility to create relative symlink Message-ID: <20221230115333.580706-1-git@levis.name> I known several people doing this manually and myself. This work well with android app too. Thanks for this cool toy ! --- man/pass.1 | 6 ++++++ src/password-store.sh | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/man/pass.1 b/man/pass.1 index a555dcb..bcc34a3 100644 --- a/man/pass.1 +++ b/man/pass.1 @@ -164,6 +164,12 @@ 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 ] \fIsrc-path\fP \fIdst-path\fP +Link the password or directory named \fIsrc-path\fP to \fIdst-path\fP. This +command is alternatively named \fBlink\fP. If \fI--force\fP is specified, +silently overwrite \fIdst-path\fP if it exists. If \fIdst-path\fP ends in a +trailing \fI/\fP, it is always treated as a directory. +.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/password-store.sh b/src/password-store.sh index 22e818f..e95802c 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -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] old-path new-path + Link src-path to dst-path, optionally forcefully. $PROGRAM git git-command-args... If the password store is a git repository, execute a git command specified by git-command-args. @@ -649,6 +651,39 @@ cmd_copy_move() { fi } +cmd_link() { + local opts force=0 + opts="$($GETOPT -o f -l force -n "$PROGRAM" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + -f|--force) force=1; shift ;; + --) shift; break ;; + esac done + [[ $# -ne 2 ]] && die "Usage: $PROGRAM $COMMAND [--force,-f] old-path new-path" + check_sneaky_paths "$@" + local src_path="$PREFIX/${1%/}" + local src_dir="$src_path" + local dst_path="$PREFIX/$2" + + if ! [[ -f $src_path.gpg && -d $src_path && $1 == */ || ! -f $src_path.gpg ]]; then + src_dir="${src_path%/*}" + src_path="${src_path}.gpg" + fi + echo "$src_path" + [[ -e $src_path ]] || die "Error: $1 is not in the password store." + + mkdir -p -v "${dst_path%/*}" + [[ -d $src_path || -d $dst_path || $dst_path == */ ]] || dst_path="${dst_path}.gpg" + + local interactive="-i" + [[ ! -t 0 || $force -eq 1 ]] && interactive="-f" + + set_git "$dst_path" + ln -s $interactive -r -v "$src_path" "$dst_path" || exit 1 + git_add_file "$dst_path" "Link ${1} to ${2}." +} + cmd_git() { set_git "$PREFIX/" if [[ $1 == "init" ]]; then @@ -715,6 +750,7 @@ case "$1" in delete|rm|remove) shift; cmd_delete "$@" ;; rename|mv) shift; cmd_copy_move "move" "$@" ;; copy|cp) shift; cmd_copy_move "copy" "$@" ;; + link|ln) shift; cmd_link "$@" ;; git) shift; cmd_git "$@" ;; *) cmd_extension_or_show "$@" ;; esac -- 2.39.0