131

Using gpg from a console-based environment such as ssh sessions fails because the GTK pinentry dialog cannot be shown in a SSH session.

I tried unset DISPLAY but it did not help. The GPG command line options do not include a switch for forcing the pinentry to console-mode.

Older GPG versions offered a text-based prompt that worked fine in SSH sessions but after the upgrade it just fails.

There is the --textmode command line switch but apparently, it does something else.

What would be the proper and clean way of getting plain-text pin entry for remote sessions?

1
  • 1
    DISPLAY="" gpg2 ... helped me, I also installed pinentry-curses + pinentry-tty beforehand, not sure if they are strictly necessary Commented May 10, 2018 at 21:45

15 Answers 15

18

On Ubuntu 18.04, with the default installation of gpg 2.2.4, I have

/usr/bin/pinentry
/usr/bin/pinentry-gnome3
/usr/bin/pinentry-gtk-2
/usr/bin/pinentry-x11

I was able to do the following to have a text-based PIN entry:

export GPG_TTY=$(tty)
gpg-connect-agent updatestartuptty /bye >/dev/null
4
  • 3
    That is the right solution and also the official one from man gpg-agent, ``` You should always add the following lines to your .bashrc or whatever initialization file is used for all shell invocations: GPG_TTY=$(tty) export GPG_TTY It is important that this environment variable always reflects the output of the tty command. ```
    – whhone
    Commented Apr 11, 2022 at 14:19
  • This is the right answer.
    – Felipe
    Commented Aug 13, 2023 at 1:58
  • It doesn't cover the case when GPG agent is forwarded via SSH. gpg-connect-agent: connection to agent is in restricted mode. Maybe correct, but not full answer :-)
    – 0andriy
    Commented Aug 23, 2023 at 12:10
  • 1
    In my case, I'm connecting to a screen session where there is a desktop session running. gpg-agent will refuse to connect to the tty, so you have to stop it with systemctl --user stop gpg-agent (and all the associated sockets), and then restart it from the command line with GPG_TTY set. Commented Aug 29, 2023 at 17:57
144

To change the pinentry permanently, append the following to your ~/.gnupg/gpg-agent.conf:

pinentry-program /usr/bin/pinentry-tty

(In older versions which lack pinentry-tty, use pinentry-curses for a 'full-terminal' dialog window.)

Tell the GPG agent to reload configuration:

gpg-connect-agent reloadagent /bye
18
  • 15
    It's not completely "sane". Normally, gpg-agent should itself detect the presence or lack of $DISPLAY and choose the apropriate pinentry... Commented Dec 19, 2012 at 15:00
  • 13
    The agent is most likely capable of detecting the presence of a running xorg. But having a DISPLAY defined does not necessarily mean I can or want to use it, for example, when connected over SSH.
    – ccpizza
    Commented Dec 19, 2012 at 17:34
  • 4
    @lfxgroove: the problem is that su does not change the ownership of your TTY, so you need to manually chown it. See this article.
    – Rufflewind
    Commented Oct 9, 2015 at 16:22
  • 2
    @Starx: You create one. Commented Dec 8, 2016 at 10:39
  • 4
    Another tip: to view all the available options, type ls /usr/bin | grep pinentry. I see pinentry, pinentry-curses, pinentry-emacs, pinentry-gnome3, pinentry-gtk2, pinentry-qt and pinentry-tty. This way you can choose the one that suits you better, if you don't have the lack of $DISPLAY issue. Commented Jan 10, 2017 at 12:56
34

On a debian box:

sudo apt install pinentry-tty
sudo update-alternatives --config pinentry

(and set it to pinentry-tty)

2
  • 1
    Thanks! It works also with pinentry-curses which was installed already.
    – Olivier
    Commented Mar 10, 2021 at 8:55
  • 1
    For me, pinentry-tty didn't work but pinentry-curses did, just replace tty with curses in both the steps above. Commented Nov 28, 2021 at 16:00
15

I'll copy my answer from over here...

Looking at man pinentry-gnome3, I see this:

   pinentry-gnome3  implements  a PIN entry dialog based on GNOME 3, which
   aims to follow the GNOME Human Interface Guidelines as closely as  pos‐
   sible.   If the X Window System is not active then an alternative text-
   mode dialog will be used.  There are other flavors that  implement  PIN
   entry dialogs using other tool kits.

Unfortunately, this text-mode fallback doesn't work for me. It seems others have the same issue. However, this comment spurred my to try a different GUI pin-entry program: pinentry-gtk2. You can switch like this:

> sudo update-alternatives --config pinentry
There are 3 choices for the alternative pinentry (providing /usr/bin/pinentry).

  Selection    Path                      Priority   Status
------------------------------------------------------------
* 0            /usr/bin/pinentry-gnome3   90        auto mode
  1            /usr/bin/pinentry-curses   50        manual mode
  2            /usr/bin/pinentry-gnome3   90        manual mode
  3            /usr/bin/pinentry-gtk-2    85        manual mode

Press <enter> to keep the current choice[*], or type selection number: 3
update-alternatives: using /usr/bin/pinentry-gtk-2 to provide /usr/bin/pinentry (pinentry) in manual mode

Once I switched, it worked perfectly for me! In a terminal on the desktop, it will use the GUI password entry, but when I ssh into my machine, it will use a text-mode password entry.

1
  • 2
    This is the right answer. The text fallback in pinentry-gnome3 is completely broken, because it'll open up on X11 if there's an X11 session running on the machine even when $DISPLAY is unset. pinentry-gtk2 behaves correctly: it falls back to pinentry-tty if $DISPLAY is unset. Commented Oct 12, 2021 at 18:50
11

I just had this problem on Ubuntu 16.04.3 when trying to generate/install a private key using gpg2 (2.1.11) on a system account without a password, and on a user account over ssh. Nothing worked giving:

gpg: key FE17AE6D/FE17AE6D: error sending to agent: Permission denied
gpg: error building skey array: Permission denied

I then found this which worked for me, so in brief:

pico ~/.gnupg/gpg-agent.conf
# add: allow-loopback-pinentry
gpg-connect-agent reloadagent /bye
gpg2 --pinentry-mode loopback --import private.key
1
  • This worked for me on Android using Termux. Commented May 30, 2021 at 18:09
7

If you don't have it, install pinentry-curses with yum or apt-get.

Then, run:

sudo update-alternatives --config pinentry

And select pinentry-curses from the list.

5

Not sure which version of GPG this question was originally about. I am using GPG v2.2.19 in (K)ubuntu 20.04 LTS Focal. All I had to add was just --pinentry-mode loopback and it started to ask for a password in TTY. I didn't have to install anything. For example:

gpg --pinentry-mode loopback --export-secret-keys -a | less
1
  • Thanks a lot, and +1. Worked for me immediately in debian Buster, and probably saved a lot of time and hassle compared to the other solutions.
    – Binarus
    Commented Jun 5, 2023 at 10:51
2

To prevent the pinentry popup you could ssh localhost. Optionally forcing X11 disabled, -x Disables X11 forwarding. See the full example below.

patrick@patrick-C504:~$ ssh localhost
patrick@localhost's password: 
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.13.0-68-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

Last login: Mon Nov 16 22:48:53 2015 from localhost
patrick@patrick-C504:~$ gpg --gen-key
gpg (GnuPG) 1.4.16; Copyright (C) 2013 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 
Key does not expire at all
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <[email protected]>"

Real name: Foo
Name must be at least 5 characters long
Real name: FooBar
Email address: [email protected]
Comment: 
You selected this USER-ID:
    "FooBar <[email protected]>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.

gpg: gpg-agent is not available in this session
Enter passphrase:
3
  • 3
    Which X11 features specifically should be disabled? I personally know the answer to my question, the author does not, so the answer seems incomplete without this information.
    – Ramhound
    Commented Nov 17, 2015 at 12:26
  • ssh'ing to local host was enough for me, but optionally -x Disables X11 forwarding. should prevent any X11 forwarding. Answer is updated.
    – PvdL
    Commented Nov 18, 2015 at 9:45
  • I prefer this solution, given that pinentry over -X doesn't show up – I'm normally physically at my laptop, where I want X pinentry (so I don't want to edit a conf file all the time), but if I happen to ssh -X into it I might still want a curses pinentry. Of course, ideally, the gtk pinentry would actually work over ssh -X :-/
    – unhammer
    Commented Jun 5, 2016 at 13:29
2

If you do export GPG_TTY=$(tty) and unset DISPLAY it will give a TLI dialog box asking for the passphrase. Typing in the correct passphrase makes it decrypt.

If you do NOT do the above export of GPG_TTY and unset of DISPLAY it expects to use X Windows. If you launched your session (such as PuTTY) from an MS-Windows system with X11 forwarding turned on it wants to send the X-Window dialog to your MS Windows system. You can use an X emulator such as Exceed or Cygwin/X on Windows to allow the X-Window prompt for passphrase to appear on your MS-Windows box.

However, you can eliminate the need to set GPG_TTY and unset DISPLAY and getting either the TLI or GUI by running the command line with --batch option and putting the passphrase in with the --passphrase option:

gpg --batch --passphrase "<passphrase>" -o "<decrypted output file name>" --decrypt "<encrypted input file name>"

All 3 methods worked for me today on RHEL6 running gnupg2.

3
  • 2
    According to Roc White’s answer, export GPG_TTY=$(tty) is sufficient.  Have you tried that?  Do you have a reference that says that unset DISPLAY is also necessary? P.S. People don’t like to put passphrases on the command line. Commented May 30, 2019 at 19:24
  • 3
    -1 Putting a password or passphrase as an argument to a command is never a good idea as it can be easily seen by other processes that monitor system activity and will likely get recorded into your command history where it will remain for some time..
    – SlySven
    Commented Jun 6, 2020 at 0:38
  • For me export  GPG_TTY=$(tty) only was not enough. System used gpg-agent and popped up a GUI window (pinentry-gtk-2 in my case).
    – reikred
    Commented Jan 21, 2022 at 19:46
1

I found the "full example" in PvdL's answer a bit confusing, here's what I do:

ssh -X machine
# work hack hack work until I need something from gpg
ssh -x localhost -p$port
gpg2 --decrypt file.gpg
# enter password to pinentry
exit
# now the key is unlocked in gpg-agent, and I can keep decrypting files
# from my X ssh session without being asked for the password
0

in CentOS 8 you can try :

yum -y install pinentry

0

Simply uninstall pinentry, it has many issues on cli programs. GPG will ask for password on terminal if pinentry is not installed.

0
0

For me, export GPG_TTY=$(tty) did nothing - I had to install pinentry-tty and uninstall pinentry-curses. This fixed it using GPG in mutt, in screen, using SSH on a remote VPS.

0

I use GPG on a remote machine via ssh as follows:

  • When logging into the remote host from my laptop, I used ssh -Y to log in, which forwards all graphical program screens to be displayed on the server onto my laptop instead (Secure X Forwarding).

On the ssh server:

  • For pinentry, I usually install the pinentry-fltk variant, which is the most lightweight in terms of dependencies among the graphical pinentry clients (apt search pinentry)
  • pinentry-curses is the usual default on debian derivatives, which I update to use pinentry-fltk by updating alternatives configuration using sudo update-alternatives --config pinentry
  • pinentry-tty and pinentry-curses are the terminal based prompt programs, both of which have given me issues with terminal multiplexing, for example with screen, byobu or remote terminals.

Note: This is specific to Debian 11 (Bullseye) and upwards, as of Nov, 2022 till March, 2024. The exact package names will vary across other distribution families.

0

I am a tmux user and usually GPG asks for the password in a different pane (I think the first one that interacted with GPG) when using pinentry-*. Whatever pinentry I set, the result was the same, and since I use WSL and also SSH, graphical options were out of the question. What I ended up doing was to set

pinentry-mode loopback'

to my $GNUPGHOME/gpg.conf and the password is always asked in the pane that was invoked. I post this as answer since the accepted answer did not work for me

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .