GnuPGv2 & 'pinentry' on Linux w/ remote access

Peter Lebbing peter at
Wed Mar 29 12:20:02 CEST 2017


On 22/03/17 15:46, Sander Smeenk via Gnupg-users wrote:
> I'm on Linux and i am not using Unity/Gnome/whatever, so i start X by
> calling 'startx' and it invokes my .xsession that has ...
> | GPG_TTY=$(tty)
> | export GPG_TTY
> | eval $(gpg-agent --daemon)

This is the style for GnuPG 2.0, not for 2.1. 2.1 uses a standard socket
location and the OpenPGP part of the agent will Just Work(tm). You still need
something for the SSH part, and for GnuPG v1 if you want to have that use the agent.

The following is a variation on the Debian GnuPG v2.1 Xsession script.

If you need the agent for GnuPG v1, include the following snippet:

agent_sock=$(gpgconf --list-dirs agent-socket)
export GPG_AGENT_INFO=${agent_sock}:0:1

However, note that the way the agent is used is fundamentally different. GnuPG
v1 uses it as a passphrase cache and retrieves the password to decrypt the
private key in secring.gpg on its own. GnuPG v2.1 delegates all private key
operations to the agent entirely, and the agent stores its private keys in
private-keys-v1.d. I'd advise against mixing use of GnuPG v1 and v2.1 at all. If
you don't want GnuPG v1 with use-agent, just omit the snippet.

For SSH, you can use the following snippet:
if [ -n "$(gpgconf --list-options gpg-agent | \
      awk -F: '/^enable-ssh-support:/{ print $10 }')" ]; then
    export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
    # Launch the agent if it is not already running
    gpgconf --launch gpg-agent

Note that the agent survives the user session, so if you logout and log back in,
the agent will already be running. gpgconf will not launch it again. And your
keys will still be unlocked if the time to live hasn't expired.

Finally, there is the TTY issue. gpg will pass the TTY (or DISPLAY) it is
running on to the agent, so the pinentry pops up on the TTY/DISPLAY where the
invoking gpg was running. Unfortunately, SSH has no facility for that, so the
pinentry pops up on the "startup TTY". When I'm using SSH from a terminal
running on my graphical X session, it turns out just fine: pinentry-gtk-2 pops
up on my X screen. When I'm connecting remotely, it goes wrong. Personally,
before I SSH from a remote session[1], I run:

gpg-connect-agent updatestartuptty /bye

You could put that in a shell script with a shorter name...

As long as I don't forget to run the gpg-connect-agent command, it always works
fine for me.

> ... where ssh-agent used to be, just before starting the window manager.
> Then i have this gpg-agent.conf:
> | enable-ssh-support
> | pinentry-program /usr/bin/pinentry-curses
> | default-cache-ttl 300
> | max-cache-ttl 999999

If you use a graphical pinentry and it needs to pop up on a text terminal
instead, it will automatically fall back to the curses based pinentry. So if you
want a graphical pinentry, you can use that as well. I don't think a curses
pinentry would actually work if some graphical program invoked gpg? Where would
it pop up? :-)

Furthermore, note that the ttl entries are only for OpenPGP. SSH keys have their
own entries, ending in -ssh.

> With this config, trying to decrypt a GPG-file, everything stalls
> and undescriptive errors appear after staring at a blinking cursor
> for quite some time.

When using gpg? I only have it with SSH, perhaps you really should switch to a
graphical pinentry. I can imagine gpg telling the agent "I'm running on
$DISPLAY", and then the pinentry cannot work with that. If gpg is not also
telling it on what TTY it is running...

> Then, when i then ^C the ssh command that is seemingly hanging because
> a pinentry popped up on some other workspace's terminal, the pinentry
> program on the unrelated terminal completely messes up said terminal.
> Sometimes resulting in *'s being displayed while typing, or letters
> disappearing from the input altogether. In such situations it turns out
> pinentry-curses was still running, even though my shell was also
> interactive.

Yes, this is also what I experience when I forget updatestartuptty and the last
updatestartuptty was on a text terminal.

I also see some of the letters I'm typing, as they are actually passed to the
shell running on the text terminal. I think every other character goes to the
terminal, with the messed up pinentry-curses getting half of the keystrokes and
the others going to your shell. It's a great way to get half of your password in
.bash_history if you just keep on typing. You could at least prevent that last
bit by immediately doing:
$ unset HISTFILE
But it will still end up in swappable memory. So just stop typing your
passphrase already! :-)

> And i haven't even started looking at "how can u use a gpg-agent that
> is already running on a box that i am logging in remotely" yet, sort of
> what 'keychain' can do with ssh-agent.

This for me is actually the only situation where it goes wrong by default at
all. But if you switch between multiple X and/or Linux VT sessions, it'll also
happen. I do sometimes have a Linux VT open during an X session, but I never use
it for SSH (or GnuPG).

I hope this helps you further along.



[1] I don't usually nest SSH terminal sessions. However, I /do/ use git remotely
every now and then. And git often uses... SSH. So that's still a remote SSH running.

I use the GNU Privacy Guard (GnuPG) in combination with Enigmail.
You can send me encrypted mail if you want some privacy.
My key is available at <>

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: </pipermail/attachments/20170329/b492eddf/attachment.sig>

More information about the Gnupg-users mailing list