nixos/gnupg: use better trick to update the agent TTY

Long story short: the SSH agent protocol doesn't support telling from
which tty the request is coming from, so the the pinentry curses prompt
appears on the login tty and messes up the output and may hang.

The current trick to workaround this is informing the gnupg agent every
time you start a shell: this assumes you will run `ssh` in the latest
tty, if you don't the latest tty will be messed up this time.
The ideal solution would be updating the tty exactly when (and where)
you run `ssh`. This is actually possible using a catch-all Match block
in ssh_config and using the `exec` feature that hooks a command to the
current shell.

Source for the new trick: https://unix.stackexchange.com/a/499133/110465
This commit is contained in:
rnhmjoj 2022-08-27 23:18:00 +02:00
parent 219b71278a
commit 576005a34a
No known key found for this signature in database
GPG key ID: BFBAF4C975F76450

View file

@ -129,12 +129,14 @@ in
environment.interactiveShellInit = ''
# Bind gpg-agent to this TTY if gpg commands are used.
export GPG_TTY=$(tty)
'';
'' + (optionalString cfg.agent.enableSSHSupport ''
# SSH agent protocol doesn't support changing TTYs, so bind the agent
# to every new TTY.
${cfg.package}/bin/gpg-connect-agent --quiet updatestartuptty /bye > /dev/null
'');
programs.ssh.extraConfig = optionalString cfg.agent.enableSSHSupport ''
# The SSH agent protocol doesn't have support for changing TTYs; however we
# can simulate this with the `exec` feature of openssh (see ssh_config(5))
# that hooks a command to the shell currently running the ssh program.
Match host * exec "${cfg.package}/bin/gpg-connect-agent --quiet updatestartuptty /bye > /dev/null"
'';
environment.extraInit = mkIf cfg.agent.enableSSHSupport ''
if [ -z "$SSH_AUTH_SOCK" ]; then