Password store and symlinks

David Jack Wange Olrik david at olrik.dk
Mon May 27 13:53:38 CEST 2019


Hello world,

I have a small issue where pass breaks because it fails to resolve
symlinks.

In my primary ~/.password-store folder I have a number of symlinks
that point to other password store repositories.

Eg.

    ~/.password-store/secret1.gpg
    ~/.password-store/works -> ~/Projects/works
    ~/.password-store/broken -> ~/Projects/broken/password-store

    ~/Projects/works/.git
    ~/Projects/works/.gpg-id
    ~/Projects/works/secret2.gpg

    ~/Projects/broken/README.md
    ~/Projects/broken/password-store/.git
    ~/Projects/broken/password-store/.gpg-id
    ~/Projects/broken/password-store/secret2.gpg

If the included repo has a top level git folder it works, but if
I point to a subdirectory in an included repo it does not work.

The reason for linking to a subfolder is to prevent READMEs and
other non password-store stuff from being exposed via the pass
command.

I found the problem to be the use of git -C throughout pass, which
places the burden of resolving the symlink on the pass command.

A fix could be implemented by not using git -C and instead changing
directory into the same directory the git -C command specified,
like so:

diff --git a/src/password-store.sh b/src/password-store.sh
index 284eabf..dd6c242 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -35,15 +35,21 @@ set_git() {
 }
 git_add_file() {
        [[ -n $INNER_GIT_DIR ]] || return
-       git -C "$INNER_GIT_DIR" add "$1" || return
-       [[ -n $(git -C "$INNER_GIT_DIR" status --porcelain "$1") ]] || return
+       local file_dir=$(dirname "$1")
+       local file_name=$(basename "$1")
+       cd "$file_dir"
+       git add "$file_name" || return
+       [[ -n $(git status --porcelain "$file_name") ]] || return
+       cd -
        git_commit "$2"
 }
 git_commit() {
        local sign=""
        [[ -n $INNER_GIT_DIR ]] || return
-       [[ $(git -C "$INNER_GIT_DIR" config --bool --get pass.signcommits) == "true" ]] && sign="-S"
-       git -C "$INNER_GIT_DIR" commit $sign -m "$1"
+       cd "$INNER_GIT_DIR"
+       [[ $(git config --bool --get pass.signcommits) == "true" ]] && sign="-S"
+       git commit $sign -m "$1"
+       cd -
 }
 yesno() {
        [[ -t 0 ]] || return 0


This only fixes adding new passwords, and would need to be
implemented everywhere there is a git -C command.

By changing directory into the actual git repo, the burden of
resolving symlinks will be placed on the git command which just
works.

Thoughts?

-- 
Best regards,
David Jack Wange Olrik <david at olrik.dk>       http://david.olrik.dk
GnuPG fingerprint ECC3 95B7 9872 5570 D869 9DCB 5B3B AADE DDEE 156E
["The first rule of Perl club is  You do not talk about Perl club"]



More information about the Password-Store mailing list