Page MenuHome GnuPG

pinentry-gnome3 requires DBUS_SESSION_BUS_ADDRESS to be updated
Closed, ResolvedPublic


pinentry-gnome3 is not working for me, because I am using a separate DBUS
session (via eval "$(dbus-launch)"), and pinentry-gnome3 will use the main
DBUS session:

dbus-daemon[1178]: [session uid=1000 pid=1178] Activating service name='org.gnome.keyring.SystemPrompter' requested by ':1.19' (uid=1000 pid=3259 comm="pinentry-gnome3 --display :1 ")
org.gnome.keyring.SystemPrompter[1178]: Unable to init server: Could not connect: Connection refused

This started to happen recently for me because of a change in Arch Linux'
pinentry package, which prefers pinentry-gnome3 now instead of pinentry-gtk-2

The following patch fixes this, by also adding "DBUS_SESSION_BUS_ADDRESS" (from
the session) to the copied startup env:

diff --git i/agent/gpg-agent.c w/agent/gpg-agent.c
index bd9a471e8..8502e31b8 100644
--- i/agent/gpg-agent.c
+++ w/agent/gpg-agent.c
@@ -1980,7 +1980,7 @@ gpg_error_t
 agent_copy_startup_env (ctrl_t ctrl)
   static const char *names[] =
   gpg_error_t err = 0;
   int idx;
   const char *value;

Maybe this should handle all/more variables from stdenvnames though, assuming
that this is the correct fix.

"DBUS_SESSION_BUS_ADDRESS" is included in stdenvnames, which gets used in the
at_fork callback in agent/call-pinentry.c:213:

static void
atfork_cb (void *opaque, int where)
  ctrl_t ctrl = opaque;

  if (!where)
      int iterator = 0;
      const char *name, *assname, *value;

      gcry_control (GCRYCTL_TERM_SECMEM);

      while ((name = session_env_list_stdenvnames (&iterator, &assname)))
          /* For all new envvars (!ASSNAME) and the two medium old
             ones which do have an assuan name but are conveyed using
             environment variables, update the environment of the
             forked process.  */
          if (!assname
              || !strcmp (name, "XAUTHORITY")
              || !strcmp (name, "PINENTRY_USER_DATA"))
              value = session_env_getenv (ctrl->session_env, name);
              if (value)
                gnupg_setenv (name, value, 1);

For reference: I am using gpg-connect-agent UPDATESTARTUPTTY /bye to update
the envvars, of course.

Stack trace to start_pinentry:

#0  start_pinentry (ctrl=0x5555557d6fd0) at call-pinentry.c:278
#1  0x00005555555733ba in agent_askpin (ctrl=0x5555557d6fd0, 
    desc_text=0x7ffff0009310 "Please enter the passphrase for the ssh key …", prompt_text=0x0, 
    initial_errtext=0x0, pininfo=0x7ffff7fef2b0, keyinfo=0x7ffff6cbd940 "A648BB3BFD9B2779D1F79783A6A95D39ECB83437", cache_mode=CACHE_MODE_SSH) at call-pinentry.c:1015
#2  0x00005555555771f5 in unprotect (ctrl=0x5555557d6fd0, cache_nonce=0x0, 
    desc_text=0x7ffff0009310 "Please enter the passphrase for the ssh key …", keybuf=0x7ffff6cbda00, 
    grip=0x5555557d7060 "\246H\273;\375\233'y\321\367\227\203\246\251]9\354\270\064\067\001", cache_mode=CACHE_MODE_SSH, lookup_ttl=0x55555556c3cd <ttl_from_sshcontrol>, r_passphrase=0x0)
    at findkey.c:634
#3  0x0000555555577d97 in agent_key_from_file (ctrl=0x5555557d6fd0, cache_nonce=0x0, desc_text=0x5555555b0e58 "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)", 
    grip=0x5555557d7060 "\246H\273;\375\233'y\321\367\227\203\246\251]9\354\270\064\067\001", shadow_info=0x7ffff6cbdb18, cache_mode=CACHE_MODE_SSH, 
    lookup_ttl=0x55555556c3cd <ttl_from_sshcontrol>, result=0x7ffff6cbdaf8, r_passphrase=0x0) at findkey.c:926
#4  0x0000555555579eea in agent_pksign_do (ctrl=0x5555557d6fd0, cache_nonce=0x0, desc_text=0x5555555b0e58 "Please enter the passphrase for the ssh key%%0A  %F%%0A  (%c)", 
    signature_sexp=0x7ffff6cbdbe0, cache_mode=CACHE_MODE_SSH, lookup_ttl=0x55555556c3cd <ttl_from_sshcontrol>, overridedata=0x0, overridedatalen=0) at pksign.c:312
#5  0x000055555556f838 in data_sign (ctrl=0x5555557d6fd0, spec=0x7ffff6cbdce0, hash=0x0, hashlen=0, r_sig=0x7ffff6cbdcd0, r_siglen=0x7ffff6cbdcd8) at command-ssh.c:2815
#6  0x000055555556fd6d in ssh_handler_sign_request (ctrl=0x5555557d6fd0, request=0x7ffff000af50, response=0x7ffff000c720) at command-ssh.c:2965
#7  0x0000555555570cf8 in ssh_request_process (ctrl=0x5555557d6fd0, stream_sock=0x7ffff0000b90) at command-ssh.c:3550
#8  0x00005555555710d8 in start_command_handler_ssh (ctrl=0x5555557d6fd0, sock_client=9) at command-ssh.c:3734
#9  0x0000555555562816 in start_connection_thread_ssh (arg=0x5555557d6fd0) at gpg-agent.c:2796
#10 0x00007ffff7486bec in ?? () from /usr/lib/
#11 0x00007ffff726e0bc in start_thread () from /usr/lib/
#12 0x00007ffff6fa32ff in clone () from /usr/lib/

To summarize:

The agent is supervised by systemd --user, and this has its own bus (the one
you get by default), but I am using eval "$(dbus-launch)" then, because I
have multiple X sessions, and an own DBUS session bus helps with separating
The problem is that pinentry is getting launched by the supervised agent, not
the gnupg cli, and therefore uses the wrong/old DBUS_SESSION_BUS_ADDRESS.

  1. I've also noted that the following patch seems to never have been applied to the master branch?!
It looks relevant in this context, but agent_send_all_options does not seem to
be involved in my use case(s) at least.