[Pkg-privacy-commits] [torbrowser-launcher] 01/28: Check that GnuPG key import was successful.
Ulrike Uhlig
u-guest at moszumanska.debian.org
Sun Jul 10 21:18:15 UTC 2016
This is an automated email from the git hooks/post-receive script.
u-guest pushed a commit to branch debian/sid
in repository torbrowser-launcher.
commit b337b3de8aee9be537810d2d4f89810bedfa69cd
Author: Isis Lovecruft <isis at torproject.org>
Date: Mon Oct 27 21:16:51 2014 +0000
Check that GnuPG key import was successful.
Rather than checking the GnuPG process exit code, a more robust way to
handle determining whether or not a GnuPG process behaved as was
intended is to check GnuPG's status-fd output. [0]
In the case of key import, the particular status-fd flag we're looking
for is `IMPORT_OK` followed by a "reason", then the expected
fingerprint. [1] Because the "reason"s are integers which may be ORed,
and we are never expecting private keys to be within the file, we can
assume the reason to be `[0, 15]` inclusive.
While it's not strictly necessary to hardcode Erinn's key fingerprint
within the code because the keyfiles are safely distributed along with
the source code, doing so adds a simple defense-in-depth mechanism for
the unlikely case that a user's torbrowser-launcher package/source
download was compromised. As such, and because it was a trivial
addition which will also assist with checking that a signature was made
by the key with the expected fingerprint [2], I've gone ahead and added
a `common.fingerprints` dictionary whose keys match the names of the
`common.paths` keyfile for their respective key (i.e. the fingerprint
for `common.paths['erinn_key']` is stored at
`common.fingerprints['erinn_key']`) in order to facilitate extensibility
in the event that torbrowser-launcher should add new keyfiles in the
future. This may be removed, if undesirable.
* ADD `common.gnupg_import_ok_pattern`, a compiled regex for
determining if a key import was successful.
* ADD new class attribute, `common.Common.fingerprints` for storing
fingerprints.
* ADD new method, `common.Common.import_key_and_check_status()`, which
imports a GnuPG key, and then checks that the key was successfully
imported.
* CHANGE `common.Common.import_keys()` method to make adding
new/additional keys easier.
* FIXES https://github.com/micahflee/torbrowser-launcher/issues/137
[0]: http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/DETAILS;hb=HEAD#l323
[1]: http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/DETAILS;hb=HEAD#l713
[2]: https://github.com/micahflee/torbrowser-launcher/issues/147
---
torbrowser_launcher/common.py | 69 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 67 insertions(+), 2 deletions(-)
diff --git a/torbrowser_launcher/common.py b/torbrowser_launcher/common.py
index c58a6fe..510706e 100644
--- a/torbrowser_launcher/common.py
+++ b/torbrowser_launcher/common.py
@@ -26,7 +26,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
"""
-import os, sys, platform, subprocess, locale, pickle, psutil
+import os, sys, platform, subprocess, locale, pickle, psutil, re
import pygtk
pygtk.require('2.0')
@@ -40,6 +40,16 @@ gettext.install('torbrowser-launcher', os.path.join(SHARE, 'locale'))
from twisted.internet import gtk2reactor
gtk2reactor.install()
+
+# We're looking for output which:
+#
+# 1. The first portion must be `[GNUPG:] IMPORT_OK`
+# 2. The second must be an integer between [0, 15], inclusive
+# 3. The third must be an uppercased hex-encoded 160-bit fingerprint
+gnupg_import_ok_pattern = re.compile(
+ "(\[GNUPG\:\]) (IMPORT_OK) ([0-9]|[1]?[0-5]) ([A-F0-9]{40})")
+
+
class Common:
def __init__(self, tbl_version):
@@ -150,6 +160,12 @@ class Common:
},
}
+ self.fingerprints = {}
+
+ # Add the expected fingerprint for imported keys:
+ if self.paths['erinn_key']:
+ self.fingerprints['erinn_key'] = '8738A680B84B3031A630F2DB416F061063FEE659'
+
# create a directory
@staticmethod
def mkdir(path):
@@ -172,10 +188,59 @@ class Common:
self.mkdir(self.paths['gnupg_homedir'])
self.import_keys()
+ def import_key_and_check_status(self, key):
+ """Import a GnuPG key and check that the operation was successful.
+
+ :param str key: A string specifying the key's filepath from
+ ``Common.paths``, as well as its fingerprint in
+ ``Common.fingerprints``.
+ :rtype: bool
+ :returns: ``True`` if the key is now within the keyring (or was
+ previously and hasn't changed). ``False`` otherwise.
+ """
+ success = False
+
+ p = subprocess.Popen(['/usr/bin/gpg', '--status-fd', '2',
+ '--homedir', self.paths['gnupg_homedir'],
+ '--import', self.paths[key]],
+ stderr=subprocess.PIPE)
+ p.wait()
+
+ output = p.stderr.read()
+ match = gnupg_import_ok_pattern.match(output)
+ if match:
+ # The output must match everything in the
+ # ``gnupg_import_ok_pattern``, as well as the expected fingerprint:
+ if match.group().find(self.fingerprints[key]) >= 0:
+ success = True
+
+ return success
+
# import gpg keys
def import_keys(self):
+ """Import all GnuPG keys.
+
+ :rtype: bool
+ :returns: ``True`` if all keys were successfully imported; ``False``
+ otherwise.
+ """
+ keys = ['erinn_key',]
+ all_imports_succeeded = True
+
print _('Importing keys')
- subprocess.Popen(['/usr/bin/gpg', '--homedir', self.paths['gnupg_homedir'], '--import', self.paths['erinn_key']]).wait()
+ for key in keys:
+ imported = self.import_key_and_check_status(key)
+ if not imported:
+ print _('Could not import key with fingerprint: %s.'
+ % self.fingerprints[key])
+ all_imports_succeeded = False
+
+ if all_imports_succeeded:
+ print _('Successfully imported all keys.')
+ else:
+ print _('Not all keys were imported successfully!')
+
+ return all_imports_succeeded
# load mirrors
def load_mirrors(self):
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/torbrowser-launcher.git
More information about the Pkg-privacy-commits
mailing list