[Python-modules-commits] [python-gnupg] 06/08: merge patched into master
Elena Grandi
valhalla-guest at moszumanska.debian.org
Sat Apr 8 06:44:44 UTC 2017
This is an automated email from the git hooks/post-receive script.
valhalla-guest pushed a commit to branch gpg2
in repository python-gnupg.
commit baa7448e13c6498610d618cc4a62702bb46a8fc4
Merge: 1ec436f 9bb7af6
Author: Elena Grandi <valhalla-d at trueelena.org>
Date: Tue Feb 28 15:36:01 2017 +0100
merge patched into master
debian/.git-dpm | 4 +-
.../0002-Default-on-using-gpg1-as-gpgbinary.patch | 36 ------
...inentry-mode-loopback-for-2.1.x-and-later.patch | 26 ++++
...oid-exceptions-on-unknown-status-keywords.patch | 141 +++++++++++++++++++++
...fixed-list-mode-and-batch-and-with-colons.patch | 87 +++++++++++++
...risky-scan_keys-operation-on-modern-GnuPG.patch | 38 ++++++
...ous-test-suite-failures-due-to-socket-rem.patch | 110 ++++++++++++++++
debian/patches/series | 6 +-
gnupg.py | 88 +++++--------
test_gnupg.py | 8 +-
10 files changed, 443 insertions(+), 101 deletions(-)
diff --cc debian/.git-dpm
index b12a216,0000000..3edc140
mode 100644,000000..100644
--- a/debian/.git-dpm
+++ b/debian/.git-dpm
@@@ -1,11 -1,0 +1,11 @@@
+# see git-dpm(1) from git-dpm package
- 09a1f18cf9864dba35db34744200f7e40b401d6f
- 09a1f18cf9864dba35db34744200f7e40b401d6f
++9bb7af658e91c2228183d8d1fbc759299116e629
++9bb7af658e91c2228183d8d1fbc759299116e629
+53585fde665095b170b0706129af9238b168becf
+53585fde665095b170b0706129af9238b168becf
+python-gnupg_0.3.9.orig.tar.gz
+75fd5ed615edfaf5b3e5ef0af0d14f0e3c6cd0b1
+42260
+debianTag="debian/%e%v"
+patchedTag="patched/%e%v"
+upstreamTag="upstream/%e%u"
diff --cc debian/patches/0002-use-pinentry-mode-loopback-for-2.1.x-and-later.patch
index 0000000,0000000..0f82430
new file mode 100644
--- /dev/null
+++ b/debian/patches/0002-use-pinentry-mode-loopback-for-2.1.x-and-later.patch
@@@ -1,0 -1,0 +1,26 @@@
++From 9f3c15b8990970e91aa33779ba03a26fdd94b115 Mon Sep 17 00:00:00 2001
++From: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
++Date: Fri, 17 Feb 2017 17:23:04 -0500
++Subject: use --pinentry-mode loopback for 2.1.x and later
++
++If the user specifies an explicit passphrase rather than relying on
++the gpg-agent for granting access, then we should try to pass the
++passphrase to the agent. In 2.1.x, passing a passphrase to the agent
++is done with "--pinentry-mode loopback", so we add that here.
++---
++ gnupg.py | 2 ++
++ 1 file changed, 2 insertions(+)
++
++diff --git a/gnupg.py b/gnupg.py
++index 2a08d96..0412531 100644
++--- a/gnupg.py
+++++ b/gnupg.py
++@@ -783,6 +783,8 @@ class GPG(object):
++ cmd.extend(['--secret-keyring', no_quote(fn)])
++ if passphrase:
++ cmd.extend(['--batch', '--passphrase-fd', '0'])
+++ if self.version >= (2,1):
+++ cmd.extend(['--pinentry-mode', 'loopback'])
++ if self.use_agent: # pragma: no cover
++ cmd.append('--use-agent')
++ if self.options:
diff --cc debian/patches/0003-Avoid-exceptions-on-unknown-status-keywords.patch
index 0000000,0000000..eb9737d
new file mode 100644
--- /dev/null
+++ b/debian/patches/0003-Avoid-exceptions-on-unknown-status-keywords.patch
@@@ -1,0 -1,0 +1,141 @@@
++From 6787db516ce3896d8e566ecc8343bc5d98d74795 Mon Sep 17 00:00:00 2001
++From: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
++Date: Fri, 17 Feb 2017 17:23:05 -0500
++Subject: Avoid exceptions on unknown status keywords
++
++in upstream GnuPG, doc/DETAILS says:
++
++---------
++* Format of the --status-fd output
++
++ Every line is prefixed with "[GNUPG:] ", followed by a keyword with
++ the type of the status line and some arguments depending on the type
++ (maybe none); an application should always be willing to ignore
++ unknown keywords that may be emitted by future versions of GnuPG.
++ Also, new versions of GnuPG may add arguments to existing keywords.
++ Any additional arguments should be ignored for forward-compatibility.
++---------
++
++This set of changes ensures that any time we're looking for status
++messages it is only to look for them positively -- if we encounter an
++unknown or other status message, we'll just let it slide by without an
++error.
++---
++ gnupg.py | 47 ++++-------------------------------------------
++ 1 file changed, 4 insertions(+), 43 deletions(-)
++
++diff --git a/gnupg.py b/gnupg.py
++index 0412531..7ff9f11 100644
++--- a/gnupg.py
+++++ b/gnupg.py
++@@ -240,14 +240,6 @@ class Verify(object):
++ if key in self.TRUST_LEVELS:
++ self.trust_text = key
++ self.trust_level = self.TRUST_LEVELS[key]
++- elif key in ("RSA_OR_IDEA", "NODATA", "IMPORT_RES", "PLAINTEXT",
++- "PLAINTEXT_LENGTH", "POLICY_URL", "DECRYPTION_INFO",
++- "DECRYPTION_OKAY", "INV_SGNR", "FILE_START", "FILE_ERROR",
++- "FILE_DONE", "PKA_TRUST_GOOD", "PKA_TRUST_BAD", "BADMDC",
++- "GOODMDC", "NO_SGNR", "NOTATION_NAME", "NOTATION_DATA",
++- "PROGRESS", "PINENTRY_LAUNCHED", "NEWSIG",
++- "KEY_CONSIDERED"):
++- pass
++ elif key == "BADSIG": # pragma: no cover
++ self.valid = False
++ self.status = 'signature bad'
++@@ -286,12 +278,6 @@ class Verify(object):
++ self.valid = False
++ self.key_id = value
++ self.status = 'no public key'
++- elif key in ("KEYEXPIRED", "SIGEXPIRED", "KEYREVOKED"): # pragma: no cover
++- # these are useless in verify, since they are spit out for any
++- # pub/subkeys on the key, not just the one doing the signing.
++- # if we want to check for signatures with expired key,
++- # the relevant flag is EXPKEYSIG or REVKEYSIG.
++- pass
++ elif key in ("EXPKEYSIG", "REVKEYSIG"): # pragma: no cover
++ # signed with expired or revoked key
++ self.valid = False
++@@ -309,8 +295,6 @@ class Verify(object):
++ else:
++ # N.B. there might be other reasons
++ self.status = 'incorrect passphrase'
++- else:
++- raise ValueError("Unknown status message: %r" % key)
++
++ class ImportResult(object):
++ "Handle status messages for --import"
++@@ -385,8 +369,6 @@ class ImportResult(object):
++ elif key == "SIGEXPIRED": # pragma: no cover
++ self.results.append({'fingerprint': None,
++ 'problem': '0', 'text': 'Signature expired'})
++- else: # pragma: no cover
++- raise ValueError("Unknown status message: %r" % key)
++
++ def summary(self):
++ l = []
++@@ -552,14 +534,8 @@ class Crypt(Verify, TextHandler):
++ __bool__ = __nonzero__
++
++ def handle_status(self, key, value):
++- if key in ("ENC_TO", "USERID_HINT", "GOODMDC", "END_DECRYPTION",
++- "BEGIN_SIGNING", "NO_SECKEY", "ERROR", "NODATA", "PROGRESS",
++- "CARDCTRL", "BADMDC", "SC_OP_FAILURE", "SC_OP_SUCCESS",
++- "PINENTRY_LAUNCHED"):
++- # in the case of ERROR, this is because a more specific error
++- # message will have come first
++- if key == "NODATA":
++- self.status = "no data was provided"
+++ if key == "NODATA":
+++ self.status = "no data was provided"
++ elif key in ("NEED_PASSPHRASE", "BAD_PASSPHRASE", "GOOD_PASSPHRASE",
++ "MISSING_PASSPHRASE", "DECRYPTION_FAILED",
++ "KEY_NOT_CREATED", "NEED_PASSPHRASE_PIN"):
++@@ -604,13 +580,8 @@ class GenKey(object):
++ return self.fingerprint or ''
++
++ def handle_status(self, key, value):
++- if key in ("PROGRESS", "GOOD_PASSPHRASE", "NODATA", "KEY_NOT_CREATED",
++- "PINENTRY_LAUNCHED"):
++- pass
++- elif key == "KEY_CREATED":
+++ if key == "KEY_CREATED":
++ (self.type,self.fingerprint) = value.split()
++- else:
++- raise ValueError("Unknown status message: %r" % key)
++
++ class ExportResult(GenKey):
++ """Handle status messages for --export[-secret-key].
++@@ -643,8 +614,6 @@ class DeleteResult(object):
++ if key == "DELETE_PROBLEM": # pragma: no cover
++ self.status = self.problem_reason.get(value,
++ "Unknown error: %r" % value)
++- else: # pragma: no cover
++- raise ValueError("Unknown status message: %r" % key)
++
++ def __nonzero__(self):
++ return self.status == 'ok'
++@@ -666,13 +635,7 @@ class Sign(TextHandler):
++ __bool__ = __nonzero__
++
++ def handle_status(self, key, value):
++- if key in ("USERID_HINT", "NEED_PASSPHRASE", "BAD_PASSPHRASE",
++- "GOOD_PASSPHRASE", "BEGIN_SIGNING", "CARDCTRL", "INV_SGNR",
++- "NO_SGNR", "MISSING_PASSPHRASE", "NEED_PASSPHRASE_PIN",
++- "SC_OP_FAILURE", "SC_OP_SUCCESS", "PROGRESS",
++- "PINENTRY_LAUNCHED"):
++- pass
++- elif key in ("KEYEXPIRED", "SIGEXPIRED"): # pragma: no cover
+++ if key in ("KEYEXPIRED", "SIGEXPIRED"): # pragma: no cover
++ self.status = 'key expired'
++ elif key == "KEYREVOKED": # pragma: no cover
++ self.status = 'key revoked'
++@@ -681,8 +644,6 @@ class Sign(TextHandler):
++ algo, self.hash_algo, cls,
++ self.timestamp, self.fingerprint
++ ) = value.split()
++- else: # pragma: no cover
++- raise ValueError("Unknown status message: %r" % key)
++
++ VERSION_RE = re.compile(r'gpg \(GnuPG\) (\d+(\.\d+)*)'.encode('ascii'), re.I)
++ HEX_DIGITS_RE = re.compile(r'[0-9a-f]+$', re.I)
diff --cc debian/patches/0004-always-use-fixed-list-mode-and-batch-and-with-colons.patch
index 0000000,0000000..97757ee
new file mode 100644
--- /dev/null
+++ b/debian/patches/0004-always-use-fixed-list-mode-and-batch-and-with-colons.patch
@@@ -1,0 -1,0 +1,87 @@@
++From e9c796033ca3489f24468475694f6fad008c9c0b Mon Sep 17 00:00:00 2001
++From: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
++Date: Fri, 17 Feb 2017 17:23:06 -0500
++Subject: always use --fixed-list-mode and --batch and --with-colons
++
++gpg is being invoked programmatically, so it should always use
++--batch.
++
++--fixed-list-mode is also the standard, since we have no intention of
++ever using the non-fixed mode and modern versions of GnuPG don't even
++have the option of doing so.
++
++we also want --with-colons: for any output, are going to be parsing it
++directly, so we don't want the human-readable form.
++---
++ gnupg.py | 16 ++++++++--------
++ 1 file changed, 8 insertions(+), 8 deletions(-)
++
++diff --git a/gnupg.py b/gnupg.py
++index 7ff9f11..9090599 100644
++--- a/gnupg.py
+++++ b/gnupg.py
++@@ -733,6 +733,7 @@ class GPG(object):
++ a passphrase will be sent to GPG, else False.
++ """
++ cmd = [self.gpgbinary, '--status-fd', '2', '--no-tty']
+++ cmd.extend(['--fixed-list-mode', '--batch', '--with-colons'])
++ if self.gnupghome:
++ cmd.extend(['--homedir', no_quote(self.gnupghome)])
++ if self.keyring:
++@@ -743,7 +744,7 @@ class GPG(object):
++ for fn in self.secret_keyring:
++ cmd.extend(['--secret-keyring', no_quote(fn)])
++ if passphrase:
++- cmd.extend(['--batch', '--passphrase-fd', '0'])
+++ cmd.extend(['--passphrase-fd', '0'])
++ if self.version >= (2,1):
++ cmd.extend(['--pinentry-mode', 'loopback'])
++ if self.use_agent: # pragma: no cover
++@@ -874,7 +875,7 @@ class GPG(object):
++ "If writing to a file which exists, avoid a confirmation message."
++ if os.path.exists(output):
++ # We need to avoid an overwrite confirmation message
++- args.extend(['--batch', '--yes'])
+++ args.extend(['--yes'])
++ args.extend(['--output', no_quote(output)])
++
++ def sign_file(self, file, keyid=None, passphrase=None, clearsign=True,
++@@ -1069,7 +1070,7 @@ class GPG(object):
++ fingerprints = [no_quote(s) for s in fingerprints]
++ else:
++ fingerprints = [no_quote(fingerprints)]
++- args = ['--batch', '--delete-%s' % which]
+++ args = ['--delete-%s' % which]
++ args.extend(fingerprints)
++ result = self.result_map['delete'](self)
++ p = self._open_subprocess(args)
++@@ -1148,9 +1149,8 @@ class GPG(object):
++ which='keys'
++ if secret:
++ which='secret-keys'
++- args = ['--list-%s' % which, '--fixed-list-mode',
++- '--fingerprint', '--fingerprint', # get subkey FPs, too
++- '--with-colons']
+++ args = ['--list-%s' % which,
+++ '--fingerprint', '--fingerprint'] # get subkey FPs, too
++ if keys:
++ if isinstance(keys, string_types):
++ keys = [keys]
++@@ -1188,7 +1188,7 @@ class GPG(object):
++ query = query.strip()
++ if HEX_DIGITS_RE.match(query):
++ query = '0x' + query
++- args = ['--fixed-list-mode', '--fingerprint', '--with-colons',
+++ args = ['--fingerprint',
++ '--keyserver', no_quote(keyserver), '--search-keys',
++ no_quote(query)]
++ p = self._open_subprocess(args)
++@@ -1225,7 +1225,7 @@ class GPG(object):
++ >>> assert not result
++
++ """
++- args = ["--gen-key", "--batch"]
+++ args = ["--gen-key"]
++ result = self.result_map['generate'](self)
++ f = _make_binary_stream(input, self.encoding)
++ self._handle_io(args, f, result, binary=True)
diff --cc debian/patches/0005-Avoid-risky-scan_keys-operation-on-modern-GnuPG.patch
index 0000000,0000000..6c43d98
new file mode 100644
--- /dev/null
+++ b/debian/patches/0005-Avoid-risky-scan_keys-operation-on-modern-GnuPG.patch
@@@ -1,0 -1,0 +1,38 @@@
++From 7963728cccb72bbac3f9afdd5f9bc64f37549f19 Mon Sep 17 00:00:00 2001
++From: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
++Date: Fri, 17 Feb 2017 17:23:07 -0500
++Subject: Avoid risky scan_keys() operation on modern GnuPG.
++
++Please see comments from Werner Koch at:
++
++https://bugs.gnupg.org/gnupg/issue2942
++---
++ gnupg.py | 13 +++++++++++--
++ 1 file changed, 11 insertions(+), 2 deletions(-)
++
++diff --git a/gnupg.py b/gnupg.py
++index 9090599..137a6b0 100644
++--- a/gnupg.py
+++++ b/gnupg.py
++@@ -1163,10 +1163,19 @@ class GPG(object):
++ List details of an ascii armored or binary key file
++ without first importing it to the local keyring.
++
++- The function achieves this by running:
+++ The function achieves this on modern GnuPG by running:
+++
+++ $ gpg --dry-run --import-options import-show --import
+++
+++ On older versions, it does the *much* riskier:
+++
++ $ gpg --with-fingerprint --with-colons filename
++ """
++- args = ['--with-fingerprint', '--with-colons']
+++ if self.version >= (2, 1, 14):
+++ args = ['--dry-run', '--import-options', 'import-show', '--import']
+++ else:
+++ logger.warning('Warning! trying to list packets, but if the file is not a keyring, might accidentally decrypt')
+++ args = ['--with-fingerprint']
++ args.append(no_quote(filename))
++ p = self._open_subprocess(args)
++ return self._get_list_output(p, 'scan')
diff --cc debian/patches/0006-Avoid-spurious-test-suite-failures-due-to-socket-rem.patch
index 0000000,0000000..9f57f1a
new file mode 100644
--- /dev/null
+++ b/debian/patches/0006-Avoid-spurious-test-suite-failures-due-to-socket-rem.patch
@@@ -1,0 -1,0 +1,110 @@@
++From 9bb7af658e91c2228183d8d1fbc759299116e629 Mon Sep 17 00:00:00 2001
++From: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
++Date: Fri, 17 Feb 2017 17:23:08 -0500
++Subject: Avoid spurious test suite failures due to socket removal race.
++
++When gpg-agent notices that its primary socket has been removed, it
++shuts down. When it shuts down, it closes and unlinks its other
++sockets as well.
++
++These rmtree invocations look like they might be getting the list of
++files to delete and then unlinking them one at a time.
++
++The result is a lot of errors like:
++
++File "/home/dkg/src/python-gnupg/python-gnupg/gnupg.py", line 1157, in gnupg.GPG.list_keys
++Failed example:
++ shutil.rmtree("keys")
++Exception raised:
++ Traceback (most recent call last):
++ File "/usr/lib/python3.5/doctest.py", line 1321, in __run
++ compileflags, 1), test.globs)
++ File "<doctest gnupg.GPG.list_keys[1]>", line 1, in <module>
++ shutil.rmtree("keys")
++ File "/usr/lib/python3.5/shutil.py", line 480, in rmtree
++ _rmtree_safe_fd(fd, path, onerror)
++ File "/usr/lib/python3.5/shutil.py", line 438, in _rmtree_safe_fd
++ onerror(os.unlink, fullname, sys.exc_info())
++ File "/usr/lib/python3.5/shutil.py", line 436, in _rmtree_safe_fd
++ os.unlink(name, dir_fd=topfd)
++ FileNotFoundError: [Errno 2] No such file or directory: 'S.gpg-agent.extra'
++
++Simply making rmtree ignore errors (as this patch does) is enough to
++make the tests pass cleanly with GnuPG 2.1.18-6 and Python 3.5.3-1 on
++Debian stretch (testing).
++---
++ gnupg.py | 8 ++++----
++ test_gnupg.py | 6 +++---
++ 2 files changed, 7 insertions(+), 7 deletions(-)
++
++diff --git a/gnupg.py b/gnupg.py
++index 137a6b0..aad114b 100644
++--- a/gnupg.py
+++++ b/gnupg.py
++@@ -1027,7 +1027,7 @@ class GPG(object):
++ """Import a key from a keyserver
++
++ >>> import shutil
++- >>> shutil.rmtree("keys")
+++ >>> shutil.rmtree("keys", ignore_errors=True)
++ >>> gpg = GPG(gnupghome="keys")
++ >>> os.chmod('keys', 0x1C0)
++ >>> result = gpg.recv_keys('keyserver.ubuntu.com', '92905378') # doctest: +SKIP
++@@ -1130,7 +1130,7 @@ class GPG(object):
++ """ list the keys currently in the keyring
++
++ >>> import shutil
++- >>> shutil.rmtree("keys")
+++ >>> shutil.rmtree("keys", ignore_errors=True)
++ >>> gpg = GPG(gnupghome="keys")
++ >>> input = gpg.gen_key_input()
++ >>> result = gpg.gen_key(input)
++@@ -1184,7 +1184,7 @@ class GPG(object):
++ """ search keyserver by query (using --search-keys option)
++
++ >>> import shutil
++- >>> shutil.rmtree('keys')
+++ >>> shutil.rmtree('keys', ignore_errors=True)
++ >>> gpg = GPG(gnupghome='keys')
++ >>> os.chmod('keys', 0x1C0)
++ >>> result = gpg.search_keys('<vinay_sajip at hotmail.com>') # doctest: +SKIP
++@@ -1329,7 +1329,7 @@ class GPG(object):
++
++ >>> import shutil
++ >>> if os.path.exists("keys"):
++- ... shutil.rmtree("keys")
+++ ... shutil.rmtree("keys", ignore_errors=True)
++ >>> gpg = GPG(gnupghome="keys")
++ >>> input = gpg.gen_key_input(passphrase='foo')
++ >>> result = gpg.gen_key(input)
++diff --git a/test_gnupg.py b/test_gnupg.py
++index 3559e62..1633b39 100644
++--- a/test_gnupg.py
+++++ b/test_gnupg.py
++@@ -153,7 +153,7 @@ class GPGTestCase(unittest.TestCase):
++ if os.path.exists(hd):
++ self.assertTrue(os.path.isdir(hd),
++ "Not a directory: %s" % hd)
++- shutil.rmtree(hd)
+++ shutil.rmtree(hd, ignore_errors=True)
++ self.homedir = hd
++ self.gpg = gpg = gnupg.GPG(gnupghome=hd, gpgbinary=GPGBINARY)
++ v = gpg.version
++@@ -691,7 +691,7 @@ class GPGTestCase(unittest.TestCase):
++ decfname = os.path.join(d, 'decrypted file')
++ self.do_file_encryption_and_decryption(encfname, decfname)
++ finally:
++- shutil.rmtree(d)
+++ shutil.rmtree(d, ignore_errors=True)
++ logger.debug("test_filename_with_spaces ends")
++
++ @unittest.skip('requires network')
++@@ -727,7 +727,7 @@ class GPGTestCase(unittest.TestCase):
++ files = os.listdir(workdir)
++ self.assertEqual(files, ["'ab?'"])
++ finally:
++- shutil.rmtree(workdir)
+++ shutil.rmtree(workdir, ignore_errors=True)
++
++ def disabled_test_signing_with_uid(self): # pragma: no cover
++ "Test that signing with uids works. On hold for now."
diff --cc debian/patches/series
index ec45f72,0000000..465fe30
mode 100644,000000..100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@@ -1,2 -1,0 +1,6 @@@
+skip_network_needing_test.patch
- 0002-Default-on-using-gpg1-as-gpgbinary.patch
++0002-use-pinentry-mode-loopback-for-2.1.x-and-later.patch
++0003-Avoid-exceptions-on-unknown-status-keywords.patch
++0004-always-use-fixed-list-mode-and-batch-and-with-colons.patch
++0005-Avoid-risky-scan_keys-operation-on-modern-GnuPG.patch
++0006-Avoid-spurious-test-suite-failures-due-to-socket-rem.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-gnupg.git
More information about the Python-modules-commits
mailing list