Blob Blame Raw
diff --git a/test/gpg/key.pub b/test/gpg/key.pub
new file mode 100644
index 0000000..00b3220
--- /dev/null
+++ b/test/gpg/key.pub
@@ -0,0 +1,30 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBFl4tiQBCADax2HrOug4wNlLirwTIKjuCgWq8fGq161gE9X5NxsRK98lB1gi
+LcfruKXPwaB52ZC+K0iouSGpEO9ncPuzea3gXciYofW67JKnI7DnSDSxO64kwh2Z
+KMCwhzy4veyfdZqO4XZ4rLFesSCKK8ik0ynhS4ArPyZHDEEho3tyHc6tVcHd/WBB
+eCiNBX3S3qdAncg64SYmESvS5IQeljFabI9Z5QLGq6TFcArArd9dnBGQQgghzsV2
+ckpkubhwIPAxJN4iBGH5yD1eywXpKsgfIWDHUZ9XutM190sF2L9ExKqXDdEQ9CAf
+5lTD3wuYrCNWbb6D/yyTrpB20TbsjgzqYdCTABEBAAG0FUpvZSBEb2UgPGpvZUBk
+b2UuY29tPokBVAQTAQgAPhYhBEF6Dm5VVmp1W+fWjDi7G17VhlQXBQJZeLYkAhsD
+BQkDwmcABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEDi7G17VhlQXM8wIAM/9
+uScli1xOD70WpkP+O4oK2I2+TWti5crp0BOS1VG3EUrKyqFt3dUIJ78nzbtoJFei
+9VZJQyDfnsXdrjBdX29tbsa0ECmM/RLbYHaBSdsoR2EV/jfDERUISlg7wx1lhg+n
+RlbbGycdFQJXB3F110w5NRm+Yo0AbkLEWzuNeopKDokf1c1EI2+E1pLABePth6KN
+25VcC0Q6FyuB4+6JLURr7ia1MIJ6NsBiTY1LVbjlDBkUcGWGNhpu5rUGgUC4R6fS
+BIhpWUaWcaRIrjLE+GPq/QZQXsglUIReBcLiWFpfv7W/To3u7bh5p/YwvYnctzpi
+Pk1l10mCTCcuMwYfjp25AQ0EWXi2JAEIALMm4bWHD2ruDtKC9FNJVOwCz4bTzvyd
+TYIlerEgwJ7PhW8FrhCltqBgOOCIqLWWhEkCSC9E1xc+X9qwSc7UcMRqKsCPjave
+v5z+O6dGOVmpah/FZpSvYkRr6E6yKJ2k+VuFig/UOeW6/MMvf1e/mSa6jsGY4Wt5
+TXBoXULtyNu6z7o26Er8pkl1nqaI6IKNJv0ry2t/xI1mhSxvPRD756J8GTfbQLsv
+Ijjs+qBLA6pEcntXOQBug/Cj9diRYBLDUE8UmIZQEFTIvqle0FBEuZ8hZlC9WyJ4
+/9FxKrWA8VynMHTYHMj69XtMPPRJ3djIxWM4WDccYv8OwtbV3MfPpIEAEQEAAYkB
+PAQYAQgAJhYhBEF6Dm5VVmp1W+fWjDi7G17VhlQXBQJZeLYkAhsMBQkDwmcAAAoJ
+EDi7G17VhlQX3GkIAJzDJT5eb4/iutl0Rs/6zWcimCVYTUSquHMb/GkoOffsEwV+
+nkaUgqXtjFNKQ4SwhVnupeyfLpw+8YvieJMZifDbo7a/LxlXRyzUzr4gEiO71x+B
+YxgiEtQRPw8YgGXiIaphRudgTyYK1cVYzkU6ehaRPbMnsdcovZFHVCLHUcSuTiuh
+Ruq9l5+FvMoYWWZkZUUpGn79zVXfDQNRPVlSKM3mJuocPGS5kxfVn9pLKN00je3+
+SUIv2KtoARGaSVC5fIGOL2Pk7hj39qiMjF4eCAXxf9jAAy59FPZny+Yh4cK4haPz
+QjSEdU0DPh5K6uFuaz2DfHMMu4N0iVgtelwmorA=
+=MDgQ
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/test/gpg/repomd.xml b/test/gpg/repomd.xml
new file mode 100644
index 0000000..d7a8027
--- /dev/null
+++ b/test/gpg/repomd.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repomd xmlns="http://linux.duke.edu/metadata/repo" xmlns:rpm="http://linux.duke.edu/metadata/rpm">
+  <revision>1499286698</revision>
+  <data type="primary">
+    <checksum type="sha256">880055a50c05b20641530d09b23f64501a000b2f92fe252417c530178730a95e</checksum>
+    <open-checksum type="sha256">9d4a10310a4092bde6231253f62976337f4e4fa3ab5cdda001e141a156a9dffb</open-checksum>
+    <location href="repodata/880055a50c05b20641530d09b23f64501a000b2f92fe252417c530178730a95e-primary.xml.gz"/>
+    <timestamp>1499286654</timestamp>
+    <size>14750183</size>
+    <open-size>134514273</open-size>
+  </data>
+  <data type="filelists">
+    <checksum type="sha256">b429c60a20974912547de94994db64e87fd7ec20fe9acca47da30fc5ba42ce96</checksum>
+    <open-checksum type="sha256">af9579b55eba28eb19b98e763b7269e47de59645091b75dbb5cb3649afda0d1e</open-checksum>
+    <location href="repodata/b429c60a20974912547de94994db64e87fd7ec20fe9acca47da30fc5ba42ce96-filelists.xml.gz"/>
+    <timestamp>1499286654</timestamp>
+    <size>40663907</size>
+    <open-size>582650352</open-size>
+  </data>
+  <data type="other">
+    <checksum type="sha256">070edd188871859175cfae62fb963038f8ae0b108dec1445f71d620ea7f788c9</checksum>
+    <open-checksum type="sha256">ad63825978f1dcffbeeba4946e0dc0eb05c749ad57a89a1b938a06e82475f53c</open-checksum>
+    <location href="repodata/070edd188871859175cfae62fb963038f8ae0b108dec1445f71d620ea7f788c9-other.xml.gz"/>
+    <timestamp>1499286654</timestamp>
+    <size>7610619</size>
+    <open-size>100013004</open-size>
+  </data>
+  <data type="primary_db">
+    <checksum type="sha256">00bf6ab375bd31ddb0df2789417d17f38ac72a091ea39ec37d7ddeb64ccaffb2</checksum>
+    <open-checksum type="sha256">ed291593c267db9c0ff530b504acd00018afd080ceead5a709020014fe783fbf</open-checksum>
+    <location href="repodata/00bf6ab375bd31ddb0df2789417d17f38ac72a091ea39ec37d7ddeb64ccaffb2-primary.sqlite.bz2"/>
+    <timestamp>1499286679</timestamp>
+    <size>28398595</size>
+    <open-size>138588160</open-size>
+    <database_version>10</database_version>
+  </data>
+  <data type="filelists_db">
+    <checksum type="sha256">192a4d58517814a4130f009abb7fc0899e06d63f78bc55f8e2429250acea6457</checksum>
+    <open-checksum type="sha256">7c84685dff9dd1f3f7c9f81aad84ba57f97631822a6fd8d481df12e1b985b6e1</open-checksum>
+    <location href="repodata/192a4d58517814a4130f009abb7fc0899e06d63f78bc55f8e2429250acea6457-filelists.sqlite.bz2"/>
+    <timestamp>1499286698</timestamp>
+    <size>41798451</size>
+    <open-size>265166848</open-size>
+    <database_version>10</database_version>
+  </data>
+  <data type="other_db">
+    <checksum type="sha256">9e940b3015a8adef4956f3989ebb83c52268fdeabb00de3ebf30b1fd3a808335</checksum>
+    <open-checksum type="sha256">399d8fa532962c21d81a3b5d4245e7662b0a44362fe58b3d594eae9b33835891</open-checksum>
+    <location href="repodata/9e940b3015a8adef4956f3989ebb83c52268fdeabb00de3ebf30b1fd3a808335-other.sqlite.bz2"/>
+    <timestamp>1499286676</timestamp>
+    <size>11963226</size>
+    <open-size>85381120</open-size>
+    <database_version>10</database_version>
+  </data>
+  <data type="group">
+    <checksum type="sha256">e4d5d691a5a9b53222cd8e8c3d5c99f042fdec7a27e39570a08c866e90882ec4</checksum>
+    <location href="repodata/e4d5d691a5a9b53222cd8e8c3d5c99f042fdec7a27e39570a08c866e90882ec4-comps-Everything.x86_64.xml"/>
+    <timestamp>1499286608</timestamp>
+    <size>1895236</size>
+  </data>
+  <data type="group_gz">
+    <checksum type="sha256">9fa6d1959b8b0a97eb8827ee899bba8ebfdb197daa29e621815d73167b2eeb8e</checksum>
+    <open-checksum type="sha256">e4d5d691a5a9b53222cd8e8c3d5c99f042fdec7a27e39570a08c866e90882ec4</open-checksum>
+    <location href="repodata/9fa6d1959b8b0a97eb8827ee899bba8ebfdb197daa29e621815d73167b2eeb8e-comps-Everything.x86_64.xml.gz"/>
+    <timestamp>1499286654</timestamp>
+    <size>453974</size>
+    <open-size>1895236</open-size>
+  </data>
+</repomd>
diff --git a/test/gpg/repomd.xml.asc b/test/gpg/repomd.xml.asc
new file mode 100644
index 0000000..6ca7833
--- /dev/null
+++ b/test/gpg/repomd.xml.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEEQXoOblVWanVb59aMOLsbXtWGVBcFAll40LIACgkQOLsbXtWG
+VBddBwgAtqPnVmtcPBvOt4/ulA2KXMOz8g24xgNejn/oDAVAs+opIIZmOX4xQWXU
+jeujEw6IiagsW1pwP4lLyNRkH49hWzlU0q/5WPg7BaHzOk20nq6fKtQU4u+uKK8/
+ODCsaRzKwQkHAPL9oXkFZUEMRZ9y4+IiEbTwFgvIuueE9fz5gALzwSlU3SH9917C
+Mjxi7ofhP/0jmvMH4Bb795cQ/mxuCFT8zUCl/qZ+XQSJoVPA9oE9BToItU+Ib2AM
+l1N61Werbw9Q9y1gGUqIGKywZpZQTJuxAYtpIQOZGSgJBA7k4YdluXBS2cab6U1g
+WzAc8sn9PtxWULCsBjCkPDzTAlkZyA==
+=vgbx
+-----END PGP SIGNATURE-----
diff --git a/test/pubringtests.py b/test/pubringtests.py
new file mode 100644
index 0000000..271e573
--- /dev/null
+++ b/test/pubringtests.py
@@ -0,0 +1,43 @@
+import unittest
+import gpg
+import os
+import shutil
+import tempfile
+
+from yum import misc
+
+PWD = os.path.dirname(os.path.abspath(__file__))
+KEYDIR = '%s/gpg' % PWD
+KEYFILE = '%s/key.pub' % KEYDIR
+REPOMD = '%s/repomd.xml' % KEYDIR
+SIGFILE = '%s/repomd.xml.asc' % KEYDIR
+KEYID = '38BB1B5ED5865417'
+FPR = '417A0E6E55566A755BE7D68C38BB1B5ED5865417'
+
+class PubringTests(unittest.TestCase):
+    def setUp(self):
+        self.gpgdir = tempfile.mkdtemp()
+        with open(KEYFILE) as f:
+            info = misc.getgpgkeyinfo(f.read())
+        hexkeyid = misc.keyIdToRPMVer(info['keyid']).upper()
+        self.imported = misc.import_key_to_pubring(info['raw_key'], hexkeyid,
+                                                   gpgdir=self.gpgdir)
+        self.ctx = gpg.Context()
+
+    def tearDown(self):
+        shutil.rmtree(self.gpgdir)
+
+    def testImportKey(self):
+        self.assertTrue(self.imported)
+        key = list(self.ctx.keylist())[0].subkeys[0]
+        self.assertEqual(key.fpr, FPR)
+
+    def testKeyids(self):
+        ids = misc.return_keyids_from_pubring(self.gpgdir)
+        self.assertEqual(ids[0], KEYID)
+        self.assertTrue(len(ids) == 1)
+
+    def testValid(self):
+        with open(SIGFILE) as s, open(REPOMD) as r:
+            valid = misc.valid_detached_sig(s, r, self.gpgdir)
+        self.assertTrue(valid)
diff --git a/yum/misc.py b/yum/misc.py
index d61531e..57ddb58 100644
--- a/yum/misc.py
+++ b/yum/misc.py
@@ -18,6 +18,7 @@ import constants
 import pgpmsg
 import tempfile
 import glob
+import gpg
 import pwd
 import fnmatch
 import bz2
@@ -36,11 +37,6 @@ except ImportError:
 from rpmUtils.miscutils import stringToVersion, flagToString
 from stat import *
 try:
-    import gpgme
-    import gpgme.editutil
-except ImportError:
-    gpgme = None
-try:
     import hashlib
     _available_checksums = set(['md5', 'sha1', 'sha256', 'sha384', 'sha512'])
 except ImportError:
@@ -543,27 +539,22 @@ def keyInstalled(ts, keyid, timestamp):
 
 def import_key_to_pubring(rawkey, keyid, cachedir=None, gpgdir=None, make_ro_copy=True):
     # FIXME - cachedir can be removed from this method when we break api
-    if gpgme is None:
-        return False
     
     if not gpgdir:
         gpgdir = '%s/gpgdir' % cachedir
     
     if not os.path.exists(gpgdir):
+        if os.geteuid() != 0:
+            return False
         os.makedirs(gpgdir)
     
-    key_fo = StringIO(rawkey) 
     os.environ['GNUPGHOME'] = gpgdir
     # import the key
-    ctx = gpgme.Context()
     fp = open(os.path.join(gpgdir, 'gpg.conf'), 'wb')
     fp.write('')
     fp.close()
-    ctx.import_(key_fo)
-    key_fo.close()
-    # ultimately trust the key or pygpgme is definitionally stupid
-    k = ctx.get_key(keyid)
-    gpgme.editutil.edit_trust(ctx, k, gpgme.VALIDITY_ULTIMATE)
+    with gpg.Context() as ctx:
+        ctx.op_import(rawkey)
     
     if make_ro_copy:
 
@@ -572,6 +563,10 @@ def import_key_to_pubring(rawkey, keyid, cachedir=None, gpgdir=None, make_ro_cop
             os.makedirs(rodir, mode=0755)
             for f in glob.glob(gpgdir + '/*'):
                 basename = os.path.basename(f)
+                # Skip the gpg-agent files
+                if (basename.startswith('private-keys-v') or
+                        basename == 'S.gpg-agent'):
+                    continue
                 ro_f = rodir + '/' + basename
                 shutil.copy(f, ro_f)
                 os.chmod(ro_f, 0755)
@@ -591,11 +586,11 @@ preserve-permissions
     return True
     
 def return_keyids_from_pubring(gpgdir):
-    if gpgme is None or not os.path.exists(gpgdir):
+    if not os.path.exists(gpgdir):
         return []
 
     os.environ['GNUPGHOME'] = gpgdir
-    ctx = gpgme.Context()
+    ctx = gpg.Context()
     keyids = []
     for k in ctx.keylist():
         for subkey in k.subkeys:
@@ -607,9 +602,6 @@ def return_keyids_from_pubring(gpgdir):
 def valid_detached_sig(sig_file, signed_file, gpghome=None):
     """takes signature , file that was signed and an optional gpghomedir"""
 
-    if gpgme is None:
-        return False
-
     if gpghome:
         if not os.path.exists(gpghome):
             return False
@@ -624,25 +616,14 @@ def valid_detached_sig(sig_file, signed_file, gpghome=None):
     else:
         signed_text = open(signed_file, 'r')
     plaintext = None
-    ctx = gpgme.Context()
+    ctx = gpg.Context()
 
     try:
-        sigs = ctx.verify(sig, signed_text, plaintext)
-    except gpgme.GpgmeError, e:
+        ctx.verify(signed_text, sig, plaintext)
+    except (gpg.errors.GPGMEError, gpg.errors.BadSignatures):
         return False
     else:
-        if not sigs:
-            return False
-        # is there ever a case where we care about a sig beyond the first one?
-        thissig = sigs[0]
-        if not thissig:
-            return False
-
-        if thissig.validity in (gpgme.VALIDITY_FULL, gpgme.VALIDITY_MARGINAL,
-                                gpgme.VALIDITY_ULTIMATE):
-            return True
-
-    return False
+        return True
 
 def getCacheDir(tmpdir='/var/tmp', reuse=True, prefix='yum-'):
     """return a path to a valid and safe cachedir - only used when not running
diff --git a/yum/yumRepo.py b/yum/yumRepo.py
index a663176..f99f5d1 100644
--- a/yum/yumRepo.py
+++ b/yum/yumRepo.py
@@ -1712,9 +1712,6 @@ Insufficient space in download directory %s
 
         if self.repo_gpgcheck and not self._override_sigchecks:
 
-            if misc.gpgme is None:
-                raise URLGrabError(-1, 'pygpgme is not working so repomd.xml can not be verified for %s' % (self))
-
             sigfile = self.cachedir + '/repomd.xml.asc'
             try:
                 result = self._getFile(relative='repodata/repomd.xml.asc',
diff --git a/yum/misc.py b/yum/misc.py
index cc617b3..06b368e 100644
--- a/yum/misc.py
+++ b/yum/misc.py
@@ -561,11 +561,12 @@ def import_key_to_pubring(rawkey, keyid, cachedir=None, gpgdir=None, make_ro_cop
         if not os.path.exists(rodir):
             os.makedirs(rodir, mode=0755)
             for f in glob.glob(gpgdir + '/*'):
-                basename = os.path.basename(f)
-                # Skip the gpg-agent files
-                if (basename.startswith('private-keys-v') or
-                        basename == 'S.gpg-agent'):
+                if not os.path.isfile(f):
+                    # This is needed as gpg-agent puts some dirs/sockets in the
+                    # gpgdir (we don't need to copy them anyway), see:
+                    # https://www.gnupg.org/faq/whats-new-in-2.1.html
                     continue
+                basename = os.path.basename(f)
                 ro_f = rodir + '/' + basename
                 shutil.copy(f, ro_f)
                 os.chmod(ro_f, 0755)