Hi, both on Tails 3.0.1 (Stretch) and current Debian sid (GNOME), if /usr/bin/pinentry-gtk-2 is configured as the pinentry tool with update-alternatives (or pinentry-program in gpg-agent.conf), then importing a passphrase-protected secret key from Seahorse fails. Seahorse says: Import failed: key 0x...: public key "uid <email>" imported And the Journal says: gpg-agent[11835]: starting a new PIN Entry gpg-agent[11835]: DBG: connection to PIN entry established gpg-agent[11835]: DBG: chan_6 -> INQUIRE PINENTRY_LAUNCHED 11914 gtk2:curses 1.0.0 ? ? ? gpg-agent[11835]: DBG: chan_6 <- END gpg-agent[11835]: DBG: error calling pinentry: Inappropriate ioctl for device <Pinentry> gpg-agent[11835]: command 'IMPORT_KEY' failed: Inappropriate ioctl for device <Pinentry> gpg-agent[11835]: DBG: chan_6 -> ERR 83918950 Inappropriate ioctl for device <Pinentry> gpg-agent[11835]: DBG: chan_6 <- [eof] Note that: * This problem doesn't happen when using pinentry-gnome3. The difference I see in gpg-agent's debug log is that when using pinentry-gnome3, I see a number of OPTION commands sent to gpg-agent, e.g. OPTION display=:1, while I see no such thing when using pinentry-gtk-2. I'm not sure who's responsible for sending these options. * Importing the same key with gpg on the command line in GNOME Terminal works just fine: the expected pinentry-gtk2 dialog is displayed and the key is imported as a result. * This might be a bug in Seahorse, or in some underlying plumbing it uses, or in pinentry-gtk2. Details and some initial research: https://labs.riseup.net/code/issues/12733 Anything else I should try?
Hello, intrigeri@debian.org writes: I guess that pinentry is invoked with no DISPLAY and no GPG_TTY. It failed to open window, and then, it failed at isatty (3), then return ENOTTY (its error string: "Inappropriate ioctl for device"). When DISPLAY is there for gpgme, gpgme sends "OPTION display=:1" to gpg-agent. Does Seahorse have DISPLAY env var? I think that gpg has DISPLAY env var under GNOME Terminal.
Hi! Thanks for your fast answer! My replies are inline below. NIIBE Yutaka: OK, this makes sense :) Apparently yes: $ tr '\0' '\n' < /proc/$(pgrep seahorse)/environ | grep -E '^(GPG|DISPLAY)' DISPLAY=:1 GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1 Anything else I should try? Something about $GPG_TTY, or starting Seahorse from GNOME Terminal (instead of the GNOME Overview), perhaps? Cheers,
Thanks for your reply.
intrigeri <intrigeri@debian.org> wrote:
It seems that the most likely case is the following scenario:
(1) Upon login, gpg-agent is invoked with no DISPLAY.
(2) While Sheahorse has DISPLAY and invokes gpg by gpgme,
gpg connects to existing gpg-agent.
(3) Because gpg-agent has no DISPLAY, when gpg-agent invokes
pinentry, it fails at isatty(3).
Could you please try this?
$ gpg-connect-agent updatestartuptty /bye
It should be done from your GNOME Terminal, before importing key by
Seahorse. It updates variables of DISPLAY and TTY in gpg-agent.
Hi again! NIIBE & I just spent some time debugging this. After some strace & shell wrapping fun, we identified that for some reason, gpg-agent runs pinentry-gtk2 without $DISPLAY set in its environment, although it (gpg-agent) does have $DISPLAY in its own environment according to /proc/$(pgrep gpg-agent)/environ. Pointing pinentry-program to a shell wrapper that exports DISPLAY=:0 before exec'ing pinentry-gtk-2 works around the problem. So I'm reassigning this to gnupg-agent, where the root cause of the problem seems to live. Thanks a lot :)
Hi, NIIBE Yutaka: This doesn't seem to be the case: # tr '\0' '\n' < /proc/$(pgrep gpg-agent)/environ | grep -E '^(GPG|DISPLAY|TTY)' DISPLAY=:0 I've verified that this gpg-agent is the one running as the desktop user (/usr/bin/gpg-agent --supervised). This might invalidate the next steps of this hypothesis i.e.: I've tried. But then I see no relevant change to gpg-agent's environment: # tr '\0' '\n' < /proc/$(pgrep gpg-agent)/environ | grep -E '^(GPG|DISPLAY|TTY)' DISPLAY=:0 debug-all: Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 -> OK Pleased to meet you, process 2130 Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 <- RESET Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 -> OK Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 <- OPTION ttyname=/dev/pts/2 Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 -> OK Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 <- OPTION ttytype=xterm-256color Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 -> OK Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 <- OPTION display=:0 Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 -> OK Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 <- OPTION putenv=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 -> OK Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 <- OPTION lc-ctype=fr_FR.UTF-8 Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 -> OK Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 <- OPTION lc-messages=fr_FR.UTF-8 Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 -> OK Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 <- updatestartuptty Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 -> OK Aug 11 22:47:34 gpg-agent[2069]: DBG: chan_8 <- [eof] … and then the key importation fails in the exact same way as before: I'm not asked for the passphrase and the debug-all logs are the same :( FWIW I've tried both on GNOME/X.Org and GNOME/Wayland (up-to-date sid). Cheers,
intrigeri <intrigeri@debian.org> wrote:
It seems for me that gpg-agent can not do anything for this bug.
I tried to locate the invocation of "gpg" from seahorse. I figured out
that when this issue occurred (replacing gpg by shell script), it was
invoked by something like
gpg --status-fd 20 --import
and environment variables are only LOCALE and PWD. This is the cause of
the problem; Environment variables (like GPG_TTY, DISPLAY) should be
provided by the parent process.
Also, I ran "seahorse" with the setting of:
export GPGME_DEBUG=9:/tmp/gpgme.log
... and I realized that the invocation of gpg --import is not through
gpgme.
Then, I found: in seahorse/src/seahorse-import-dialog.c, there is a call
to function gcr_import_button_new. I think that this is the function to
create the "Import" button in the particular dialog.
Now, I guess that the problem is in the implementaiton of libgcr library.
While I'm reading gcr-3.20.0/gcr/gcr-gnupg-process.c, getting the source
by apt source libgcr-base-3-1, I suspect the function
_gcr_gnupg_process_run_async, which doesn't provide GPG_TTY and/or
DISPLAY to "gpg" process.
NIIBE Yutaka <gniibe@fsij.org> wrote: Attached is a patch for gcr to fix this issue. When I apply this patch to build libgcr-base-3-1 package (and install), the problem of seahorse has gone. I also created a ticket for GnuPG upstream to improve its documentation: https://dev.gnupg.org/T3353 I put the patch in public domain, or it may be distributed under the licence of LGPL-2.1+.
NIIBE Yutaka: Amazing, thanks! I'm going to forward this bug report + your patch upstream. Cheers,
Hi NIIBE! intrigeri: The upstream maintainer says that adding a dependency on GTK+ is not a option, and suggests another (probably simpler) approach: https://bugzilla.gnome.org/show_bug.cgi?id=787543#c1 Can you please take a look, and maybe attach an updated patch? Also, I can act as a proxy between you/Debian and Stef/GNOME if you want, but it would be simpler if you could reply directly on the GNOME bugzilla, so please consider adding yourself to the CC list there :) Cheers,
intrigeri <intrigeri@debian.org> wrote: OK. Attached is updated patch for gcr to fix this issue, by simply supplying parent's environ untouched, intended to be put under debian/patches/. While this patch fixes the particular issue, I think that more clean up will be needed, perhaps. The function g_spawn_async_with_pipes let inherit child process parent's environ when envp=NULL. By the change, _gcr_gnupg_process_run_async does so for its envp, when GCR_GNUPG_PROCESS_RESPECT_LOCALE is specified. I put the patch in public domain, or it may be distributed under the licence of LGPL-2.1+. It is tested by seahorse and pinentry-gtk-2.
Hi, NIIBE Yutaka (2017-09-27): Thanks! I noticed, a few years later, that this patch had not been proposed upstream, so I added it to https://gitlab.gnome.org/GNOME/gcr/-/issues/80. Cheers,