From 576005a34a9b3bbdb0fbe1ce1548fb1fb02fd9ef Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Sat, 27 Aug 2022 23:18:00 +0200 Subject: [PATCH] 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 --- nixos/modules/programs/gnupg.nix | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/nixos/modules/programs/gnupg.nix b/nixos/modules/programs/gnupg.nix index 1028ef53bae1..1a9006aad14e 100644 --- a/nixos/modules/programs/gnupg.nix +++ b/nixos/modules/programs/gnupg.nix @@ -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