Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

systemd service doesn't/can't get correct SSH_AUTH_SOCK when using GPG as SSH agent with custom $GNUPGHOME #49

Open
illode opened this issue Nov 27, 2023 · 1 comment

Comments

@illode
Copy link

illode commented Nov 27, 2023

When setting GNUPGHOME=$XDG_STATE_HOME/gnupg, or anything except GNUPGHOME=~/.gnupg, the systemd service will never be able to get the right $SSH_AUTH_SOCK. Instead, at startup, it will print:

Nov 26 20:55:56 redacted yubikey-touch-detector[23252]: time="2023-11-26T20:55:56-08:00" level=error msg="Cannot watch SSH, the socket '/run/user/1000/gnupg/S.gpg-agent.ssh' does not exist: stat /run/user/1000/gnupg/S.gpg-agent.ssh: no such file or directory"

The cause of the problem is that GPG will change the socket path to an effectively random subdirectory of /run/user/<uid>/gpg, such as /run/user/1000/gnupg/d.ua3izggs38hms8x3fa1edxxz/S.gpg-agent.ssh (more details). Since the correct $SSH_AUTH_SOCK is set by gpg-agent in the shell rc files (.zshrc in my case) which systemd doesn't run, the service will never get the right value.

My current workaround is a janky hack. I override the systemd service and add the following:

[Service]
ExecStartPre=-/usr/bin/mkdir -p %E/yubikey-touch-detector
ExecStartPre=/usr/bin/sh -c 'echo "SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)\nYUBIKEY_TOUCH_DETECTOR_LIBNOTIFY=true" > %E/yubikey-touch-detector/service.conf'

Aside from GPG fixing it upstream, the ideal fix would be for yubikey-touch-detector to run gpgconf --list-dirs agent-ssh-socket once at the start, and fall back to that. If for some reason the hash changes (which is possible, although it shouldn't happen during normal use - by the time I finished setting up my yubikey I had 9 subdirs), then it would only take a systemctl --user restart yubikey-touch-detector to fix.

@maximbaz
Copy link
Owner

Thanks for the detailed report! I agree on your proposal to make the app execute gpgconf on startup. I'm thinking the priorities should be SSH_AUTH_SOCK > gpgconf > XDG_RUNTIME_DIR, would you agree?

Here's the relevant piece of code:

socketFile := os.Getenv("SSH_AUTH_SOCK")
if socketFile == "" {
runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
if runtimeDir == "" {
log.Error("Cannot watch SSH, neither $SSH_AUTH_SOCK nor $XDG_RUNTIME_DIR are defined.")
return
}
socketFile = path.Join(runtimeDir, "gnupg/S.gpg-agent.ssh")
}

If you feel like it, feel free to adapt the code snippet above to respect gpgconf and send a PR, which would automatically ensure that it solves your problem 😉

exec.Command("gpgconf", "--list-dirs", "agent-ssh-socket").Output() is probably a starting point 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants