15

I use gpg-agent for managing both PGP e SSH identities. The agent is started with a script like this

gpg_agent_env="$XDG_CACHE_HOME/gpg-agent.env"

export GPG_TTY="$(tty)"

if ! ps -U "$USER" -o ucomm | grep -q gpg-agent; then
    eval "$({gpg-agent --daemon | tee $gpg_agent_env} 2> /dev/null)"
else
    source "$gpg_agent_env" 2> /dev/null
fi

which is sourced whenever I run an interactive shell. Everything works fine with this setup but there is an issue. Let's say I:

  1. open a terminal (launching the agent in background) and start working
  2. after a while open a second terminal
  3. do an action that requires entering a passphrase in the second terminal

At this point gpg-agent will start pinentry-curses prompting a passphrase but it will do this in the first terminal which results in its output mixed with whatever was running (usually a text editor) with no way to resume the program or stop pinentry (it starts using 100% cpu and I have to kill it).

I must be doing something wrong here. Anyone has experienced this?

Update:

I figured out this happens only for a prompt to unlock an SSH key, which looks like this, while prompts for PGP keys always open on the correct (i.e. current) tty.

Rnhmjoj
  • 293
  • 1
  • 2
  • 9
  • Have you tried starting the agent from your login shell, so you only have the one running? – jasonwryan May 03 '16 at 19:09
  • @jasonwryan I've just tried: It's the same thing for linux virtual terminals (agetty). By the way in the question with terminal I meant a terminal emulator window. – Rnhmjoj May 03 '16 at 19:53
  • 2
    It was `export GPG_TTY="$(tty)"` that fixed it for me – naisanza May 08 '18 at 21:00

2 Answers2

18

The gpg-agent man page explains under the option --enable-ssh-support that the ssh agent protocol is not able to provide the name of the tty to the agent, so it defaults to using the original terminal it was started in. Before running the ssh command that requires a passphrase in a new terminal you need to type

gpg-connect-agent updatestartuptty /bye

in the new terminal to update the agent's view of which tty or display to use.

meuh
  • 49,672
  • 2
  • 52
  • 114
  • 3
    This answer helped me fully congeal this realization: the people responsible for `gpg2` have no concept of what it's like to have a command-line-centric workflow/lifestyle. Somehow people whose *fundamental concept* of a a typical computer user experience starts and ends within the boundaries of GUI windows got to make decisions that effect a tool that previously had been comfortably usable on the command-line. – mtraceur Dec 15 '17 at 07:02
  • 2
    @mtraceur Not really, it's ssh-agent at fault here: in fact gpg2 will display the prompt on the right tty when unlocking a PGP key. It's those responsible of ssh-agent that possibly never thought of the switching to a different tty. – Rnhmjoj Mar 14 '18 at 00:40
  • 3
    @Rnhmjoj Should the SSH guys have supported a TTY-switching usecase that no command-line tool for most of Unix/Linux history wanted? Do you know how the design thought process and decisions for exactly which part of the workflow was handled by the command and which was handled by the agent was done? If you are, maybe you can help me see something I'm missing, because I just can't see a clear path to how the very *need* for the agent to "switch" TTYs would even arise unless the architecture was decided on without considering typical command-line use and workflows. – mtraceur Mar 14 '18 at 01:10
  • @mtraceur where’s the difference to gpg2? – Arne Babenhauserheide Dec 18 '18 at 07:18
  • 1
    @ArneBabenhauserheide The difference is that `gpg` can never ask for the passphrase on the wrong terminal, whereas `gpg2` easily can. The `gpg` command would always ask for the passphrase on the terminal you *executed the command from* because actually creating the passphrase was done from *that* process tree. But `gpg2` is coded such that it can't ensure that, because it has to ask a separate long-running agent process to prompt for the passphrase, and that agent might have originally started on a different terminal. `gpg2` and the agent could, but were not, coded to work around that. – mtraceur Dec 18 '18 at 16:56
  • 2
    @ArneBabenhauserheide Unless you're asking about the difference between SSH agent and gpg2? Because if so, then the difference is that SSH never required this perversion of other tooling having to proactively tell its agent specifically to switch terminals in the background (as far as I know - and if it did then I have the same criticisms for *it* too). The `gpg2` design only makes sense if implemented by people who don't grok the CLI-relevant aspects of how Linux/Unix works, and don't have a good sense of what makes interfaces and tooling good for composing in arbitrary combinations. – mtraceur Dec 18 '18 at 17:34
  • @mtraceur I meant the difference between ssh and gpg2, yes. So essentially it means that gpg2 allows re-using the cached password over multiple TTY's? I do not know the implementation details making problems with that. Do you know it deeply enough to estimate whether it’s likely that this is a temporary limitation? – Arne Babenhauserheide Dec 19 '18 at 11:00
  • I'm thinking that reusing cached passwords over multiple TTYs is a good way to assure that sessions inadvertently left open in remote locations and physically accessible to other persons will (in addition to first-level vulnerabilities) occasionally expose far more sensitive data unbeknownst to the authorized user. Does gpg-agent account for this? – Bill Michaelson Dec 11 '20 at 15:21
17

As per the upstream bug against openssh, the proper way to this is adding the following to your ~/.ssh/config:

Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye"

This has worked for me perfectly so far.

smaslennikov
  • 321
  • 2
  • 5