yubikey-touch-detector icon indicating copy to clipboard operation
yubikey-touch-detector copied to clipboard

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

Open illode opened this issue 1 year ago • 1 comments

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.

illode avatar Nov 27 '23 05:11 illode

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:

https://github.com/maximbaz/yubikey-touch-detector/blob/a241bcf70545821b89e9d5cc761e993a617aeae3/detector/ssh.go#L15-L23

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 :wink:

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

maximbaz avatar Nov 28 '23 20:11 maximbaz

@maximbaz I've submitted a PR: https://github.com/maximbaz/yubikey-touch-detector/pull/56

sebastianrasor avatar Jul 18 '24 03:07 sebastianrasor