File gnome-keysign-gpg-2.1-returncode.patch of Package gnome-keysign
From c01552eb9f15e39e7458ed2ab233385357e2f139 Mon Sep 17 00:00:00 2001
From: Tobias Mueller <muelli@cryptobitch.de>
Date: Thu, 7 Jul 2016 20:24:12 +0200
Subject: [PATCH] gpg: Checking for the return code when signing
It seems that gpg2.1 does not necessarily send GOOD_PASSPHRASE when the
agent has a cached passphrase.
In fact, I can't produce two signatures because of the following
exception:
File "/tmp/gks-foo-install/local/lib/python2.7/site-
packages/gnome_keysign-0.6-py2.7.egg/monkeysign/gpg.py", line 510, in
sign_key
raise GpgRuntimeError(self.context.returncode, _('unable to prompt
for passphrase, is gpg-agent running?'))
monkeysign.gpg.GpgRuntimeError: [Errno 0] unable to prompt for
passphrase, is gpg-agent running?
We can see the Errno 0. According to the man page, that's no problem,
though. The modification appears to work with both, gpg1.4 and gpg2.1.
I haven't checked 2.0, though.
---
monkeysign/gpg.py | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/monkeysign/gpg.py b/monkeysign/gpg.py
index 56d21a1..8260cb2 100644
--- a/monkeysign/gpg.py
+++ b/monkeysign/gpg.py
@@ -498,10 +498,19 @@ class Keyring():
self.context.expect(proc.stderr, 'GOT_IT')
# expect the passphrase confirmation
# we seek because i have seen a USERID_HINT <keyid> <uid> in some cases
- try:
- self.context.seek(proc.stderr, 'GOOD_PASSPHRASE')
- except GpgProtocolError:
- raise GpgRuntimeError(self.context.returncode, _('unable to prompt for passphrase, is gpg-agent running?'))
+
+ # The GnuPG (1.4 and 2.1) man page states that all is fine
+ # if gpg exits with 0. So let's assume that once we see
+ # 0, we're good.
+ # We have seen instances in which the GOOD_PASSPHRASE
+ # is not sent with GnuPG 2.1, maybe because the agent
+ # cached the passphrase.
+ if self.context.returncode != 0:
+ try:
+ self.context.seek(proc.stderr, 'GOOD_PASSPHRASE')
+ except GpgProtocolError:
+ raise GpgRuntimeError(self.context.returncode,
+ _('unable to prompt for passphrase, is gpg-agent running?'))
return proc.wait() == 0
# don't sign all uids
@@ -540,11 +549,12 @@ class Keyring():
raise GpgRuntimeError(self.context.returncode, _('key is expired, cannot sign'))
else:
raise GpgRuntimeError(self.context.returncode, _('unable to signing a single key: %s') % e.found().decode('utf-8') + proc.stderr.read())
- # expect the passphrase confirmation
- try:
- self.context.seek(proc.stderr, 'GOOD_PASSPHRASE')
- except GpgProtocolError:
- raise GpgRuntimeError(self.context.returncode, _('password confirmation failed'))
+ # expect the passphrase confirmation if return code indicates problems
+ if self.context.returncode != 0:
+ try:
+ self.context.seek(proc.stderr, 'GOOD_PASSPHRASE')
+ except GpgProtocolError:
+ raise GpgRuntimeError(self.context.returncode, _('password confirmation failed'))
if multiuid:
# we save the resulting key in uid selection mode
self.context.expect(proc.stderr, 'GET_LINE keyedit.prompt')
--
2.7.4