<<< Date Index >>>     <<< Thread Index >>>

[PATCH] Re: Bug#316388: still prompts for passphrase with gpg-agent unless GPG_TTY is set



tag 316388 patch
thanks

Hello,

  this is about Debian Bug#316388, in which Joey Hess (CC'ed) argues
  that Mutt should not be requiring GPG_TTY to be set in order to accept
  using gnupg-agent. I think he has a point; I will now explain what I
  understand the current situation is, and how I think it could be
  improved.

> Marco d'Itri wrote:
> > On Jun 30, Joey Hess <joeyh@xxxxxxxxxx> wrote:

> > > gpg-agent 1.9.15-6 does not set a GPG_TTY variable. I tried setting
> > > this variable and mutt began using the agent properly.
> > I understand that this is a feature. Feel free to argue against it with
> > the upstream developers.

> current versions of gpg and pinentry work perfectly well, even
> at the console, without GPG_TTY being set. gpg falls back to using
> ttyname() and other methods to get the tty to pass to pinentry.

  Yes, this paragraph is true. If you invoke gpg at the console without
  GPG_TTY set, it'll figure out there's a tty involved and will tell
  pinentry that; so it'll work.

  However, this is not the case if it's Mutt who invokes gpg, since then
  the stdin, stdout, and stderr of the gpg process will be pipes, and
  gpg will not be able to figure out there's a tty involved; so it'll
  fail.

  Obviously, when in X11 and using pinentry-qt or pinentry-gtk, the
  above does not apply.

  So, we have that:

    (a) either at the console, or in X11 but with gnupg-agent configured
        to use pinentry-curses, it is _required_ that GPG_TTY is set for
        gpg calls to succeed, and Mutt takes care of enforcing that.

    (b) when in X11 with gnupg-agent configured to use a pinentry-x11,
        GPG_TTY is not needed at all, yet Mutt does require it.

  The current behavior of the code with respect to this is to just
  always (*) require GPG_TTY to be set, but this is not documented at
  all. 

    (*) Of course, it's impossible for Mutt to distinguish beteween (a)
        and (b).

                                 * * *

  _If_ we accept Joey's point that Mutt has no business enforcing the
  presence of GPG_TTY, since there are cases when it is not needed, I
  see two possible solutions (with #2 being my prefered option, since it
  just makes things work):

    1. remove the check for GPG_TTY, and add to the documentation of
       $pgp_use_gpg_agent that some pinentry agents will need it to
       work. Attached gpg_tty.patch1 which does this.

    2. remove the check for GPG_TTY, and make the pgp_use_gpg_agent
       function add it to the environment if it's not present. Attached
       gpg_tty.patch2 does this, which I'm considering adding to the
       Debian package (though I'd welcome comments first).

  Cheers,

-- 
Adeodato Simó
    EM: asp16 [ykwim] alu.ua.es | PK: DA6AE621
 
The easy way is the wrong way, and the hard way is the stupid way. Pick one.
--- pgp.c~
+++ pgp.c
@@ -106,7 +106,7 @@
 
 int pgp_use_gpg_agent (void)
 {
-  return option (OPTUSEGPGAGENT) && getenv ("GPG_TTY") && getenv 
("GPG_AGENT_INFO");
+  return option (OPTUSEGPGAGENT) && getenv ("GPG_AGENT_INFO");
 }
 
 char *pgp_keyid(pgp_key_t k)
--- init.h~
+++ init.h
@@ -1434,7 +1434,9 @@
   { "pgp_use_gpg_agent", DT_BOOL, R_NONE, OPTUSEGPGAGENT, 0},
   /*
   ** .pp
-  ** If set, mutt will use a possibly-running gpg-agent process.
+  ** If set, mutt will use a possibly-running gpg-agent process. Note
+  ** that some pinentry agents, notably pinentry-curses, will require
+  ** the GPG_TTY environment variable to be set in order to be functional.
   ** (PGP only)
   */
   { "pgp_verify_sig",   DT_SYN,  R_NONE, UL "crypt_verify_sig", 0},
--- pgp.c~
+++ pgp.c
@@ -106,7 +106,15 @@
 
 int pgp_use_gpg_agent (void)
 {
-  return option (OPTUSEGPGAGENT) && getenv ("GPG_TTY") && getenv 
("GPG_AGENT_INFO");
+  char *tty;
+
+  if (!option (OPTUSEGPGAGENT) || !getenv ("GPG_AGENT_INFO"))
+    return 0;
+
+  if ((tty = ttyname(0)))
+    setenv("GPG_TTY", tty, 0);
+
+  return 1;
 }
 
 char *pgp_keyid(pgp_key_t k)