[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)