fix(gpg): Point pinentry-program at a real binary, split conf per-platform - #2
Open
triwats wants to merge 2 commits into
Open
fix(gpg): Point pinentry-program at a real binary, split conf per-platform#2triwats wants to merge 2 commits into
triwats wants to merge 2 commits into
Conversation
…tform
pinentry-program had been corrupted to point at the config file itself:
pinentry-program /Users/triwats/src/dotfiles/gpg-agent.conf
That is not an executable, so gpg-agent cannot spawn a pinentry at all:
$ printf 'BYE\n' | .../gpg-agent.conf
permission denied
With commit.gpgsign=true and enable-ssh-support, that breaks commit signing
and gpg-agent-backed SSH the moment the passphrase cache expires or the
agent restarts. It survived unnoticed only because the running agent still
held the pre-corruption config in memory.
Fixed by restoring a real pinentry path. Because the correct path is
platform-specific, and gpg-agent.conf has no `include` directive while
pinentry-program requires a literal absolute path (no ~ or $HOME
expansion), a single shared file cannot work across both platforms. So:
gpg-agent.conf -> gpg-agent-linux.conf /usr/bin/pinentry-gnome3
gpg-agent-macos.conf /opt/homebrew/bin/pinentry-mac
The two files are otherwise byte-identical; the rename is a pure rename
(the linux variant matches the previous committed content exactly).
install.conf.yaml selects between them with dotbot's `if:` on uname. They
are separate `link:` blocks on purpose: both map the same destination,
which would collide as a duplicate YAML key inside a single block.
Verified: ./install links the macos variant and skips the linux one on
this machine; the linked pinentry completes an Assuan handshake.
Note for Intel Macs: Homebrew's prefix is /usr/local, not /opt/homebrew,
so gpg-agent-macos.conf will need adjusting there.
…with #1 The previous revision rewrote install.conf.yaml wholesale, including its trailing whitespace. #1 inserts its link entry directly above that same trailing whitespace, so the two branches overlapped there and `git merge-tree` reported a conflict in this file. Rebuilt from master byte-for-byte, changing only two well-separated hunks: remove the old gpg-agent.conf entry, and append the conditional blocks after the existing tail. No functional change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found while secret-scanning #1. Unrelated to that PR, so raising separately.
The bug
gpg-agent.confhadpinentry-programpointing at the config file itself:That's not an executable, so gpg-agent cannot spawn a pinentry at all:
With
commit.gpgsign = trueandenable-ssh-supportin play, this breaks commit signing and gpg-agent-backed SSH the moment the passphrase cache expires or the agent restarts. It went unnoticed only because the running agent still held the pre-corruption config in memory — the on-disk config was already broken.This was an uncommitted local edit, so it never reached
master. It looks like a bad find/replace.The fix
Restore a real pinentry path. The correct path is platform-specific, and a single shared file can't cover both:
gpg-agent.confhas noincludedirectivepinentry-programrequires a literal absolute path — no~or$HOMEexpansionSo the file is split:
gpg-agent-linux.conf/usr/bin/pinentry-gnome3gpg-agent-macos.conf/opt/homebrew/bin/pinentry-macThe two are otherwise byte-identical, and the rename is a pure rename (
R100) — the linux variant matches the previously committed content exactly, so the diff is only the rename plus the new macOS file.install.conf.yamlpicks between them using dotbot's nativeif:(supported in the vendored v1.20.1):These are separate
link:blocks on purpose — both map the same destination, which would collide as a duplicate YAML key inside one block (last-wins, silently).Verification
OK Pleased to meet you)gpg-connect-agent reloadagent, passphrase cache confirmed empty, then this PR's own commit signed successfully — sopinentry-macwas genuinely invoked end-to-end, not served from cache:Known limitations / follow-ups
/usr/local, not/opt/homebrew.gpg-agent-macos.confwould need adjusting there. Theunametest can't distinguish; a[ -x /opt/homebrew/bin/pinentry-mac ]test could, if you ever run both.log-file /var/log/gpg-agent.logis unwritable —/var/logis root-owned on both macOS and Linux, so withdebug-level advancedset, gpg-agent is trying to write a log it has no permission to create. This is pre-existing and platform-independent, so I deliberately left it out of this PR to keep the rename clean. Worth a follow-up: either drop the two debug lines or point the log at a writable path.Interaction with #1
Independent in content — different files, both branched from
master— but they did initially conflict ininstall.conf.yaml.My first revision rewrote that file wholesale, including its trailing whitespace, and #1 inserts its entry directly above that same whitespace.
git merge-treeflagged it. Fixed in a follow-up commit that rebuilds the file frommasterbyte-for-byte and changes only two well-separated hunks.Now verified clean:
The merged tree was inspected directly and contains both the statusline link entry and both conditional gpg blocks, with the old entry removed. Merge order doesn't matter.