[elbe-devel] [PATCH] Replace gpgme with maintained gpg module

bage at linutronix.de bage at linutronix.de
Fri Feb 8 16:17:35 CET 2019


From: Bastian Germann <bage at linutronix.de>

The pygpgme project is abandoned for years and not
available in the upcoming Debian buster.

Replace pygpgme with the official gpgme Python wrapper
from GnuPG that is available as Debian's python-gpg.
Replace the package references in README and the Debian
build. Python 2 needs the absolute_import semantics to
import the right module.

With this change, elbe can be installed on Debian buster.
This closes issue #192.

Signed-off-by: Bastian Germann <bage at linutronix.de>
---
 README.adoc              |  2 +-
 debian/control           |  2 --
 elbepack/debinstaller.py | 14 ++++++++-----
 elbepack/finetuning.py   | 14 ++++++-------
 elbepack/gpg.py          | 53 +++++++++++++++++++-----------------------------
 5 files changed, 37 insertions(+), 48 deletions(-)

diff --git a/README.adoc b/README.adoc
index 397ba310..a28945dd 100644
--- a/README.adoc
+++ b/README.adoc
@@ -13,7 +13,7 @@ Software Dependencies
 ---------------------
 If using ELBE from git repository directly, you'll need following packages installed:
 
-    apt install python python-debian python-mako python-lxml python-apt python-gpgme python-pyme python-suds python-libvirt qemu-utils qemu-kvm p7zip-full make
+    apt install python python-debian python-mako python-lxml python-apt python-gpg python-suds python-libvirt qemu-utils qemu-kvm p7zip-full make
 
 
 Crash Course
diff --git a/debian/control b/debian/control
index a52a1305..f156e300 100644
--- a/debian/control
+++ b/debian/control
@@ -57,7 +57,6 @@ Depends: ${misc:Depends},
   python (>= 2.7~),
   python-lxml,
   python-apt,
-  python-gpgme,
   python-pyme|python-gpg,
   python-libvirt,
   wget,
@@ -73,7 +72,6 @@ Depends: ${misc:Depends},
   python3,
   python3-lxml,
   python3-apt,
-  python3-gpgme,
   python3-gpg,
   python3-libvirt,
   wget,
diff --git a/elbepack/debinstaller.py b/elbepack/debinstaller.py
index 0160f6dc..b52b960d 100644
--- a/elbepack/debinstaller.py
+++ b/elbepack/debinstaller.py
@@ -3,7 +3,7 @@
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
 
-from __future__ import print_function
+from __future__ import absolute_import, print_function
 
 import sys
 import os
@@ -23,8 +23,9 @@ except ImportError:
     import urllib2
     urlopen = urllib2.urlopen
 
+import gpg
+
 from shutil import copyfileobj, copyfile
-from gpgme import Context
 
 from elbepack.filesystem import TmpdirFilesystem
 from elbepack.gpg import OverallStatus, check_signature
@@ -127,7 +128,7 @@ def download_release(tmp, base_url):
     # setup gpg context, for verifying
     # the Release.gpg signature.
     os.environ['GNUPGHOME'] = tmp.fname('/')
-    ctx = Context()
+    ctx = gpg.Context()
 
     # download the Relase file to a tmp file,
     # because we need it 2 times
@@ -144,14 +145,17 @@ def download_release(tmp, base_url):
             overall_status = OverallStatus()
 
             # verify detached signature
-            sigs = ctx.verify(sig, signed, None)
+            _, vres = ctx.verify(signed, sig)
 
-            for s in sigs:
+            for s in vres.signatures:
                 status = check_signature(ctx, s)
                 overall_status.add(status)
 
             if overall_status.to_exitcode():
                 raise InvalidSignature('Failed to verify Release file')
+
+    except gpg.errors.BadSignatures:
+            raise InvalidSignature('Failed to verify Release file')
     finally:
         sig.close()
 
diff --git a/elbepack/finetuning.py b/elbepack/finetuning.py
index 324aebef..9e901a18 100644
--- a/elbepack/finetuning.py
+++ b/elbepack/finetuning.py
@@ -6,14 +6,13 @@
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
 
-from __future__ import print_function
+from __future__ import absolute_import, print_function
 
 import os
 
 from shutil import rmtree
-from io import BytesIO
 
-import gpgme
+import gpg
 
 from apt.package import FetchError
 
@@ -419,14 +418,13 @@ class UpdatedAction(FinetuningAction):
             log.printo("transfer gpg key to target: " + fp)
 
             os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
-            key = BytesIO()
-            ctx = gpgme.Context()
+            ctx = gpg.Context()
             ctx.armor = True
-            ctx.export(fp, key)
+            key = ctx.key_export(fp)
 
-            log.printo(str(key.getvalue()))
+            log.printo(key)
             with open((target.path + '/pub.key'), 'wb') as tkey:
-                tkey.write(key.getvalue())
+                tkey.write(key)
 
             target.mkdir_p("/var/cache/elbe/gnupg", mode=0o700)
             with target:
diff --git a/elbepack/gpg.py b/elbepack/gpg.py
index c56f22e5..d079d992 100644
--- a/elbepack/gpg.py
+++ b/elbepack/gpg.py
@@ -5,27 +5,14 @@
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
 
-from __future__ import print_function
+from __future__ import absolute_import, print_function
 
 import os
 
-import gpgme
+import gpg as gpgme
 
 from elbepack.filesystem import hostfs
 
-elbe_internal_key_param = """
-<GnupgKeyParms format="internal">
-  Key-Type: RSA
-  Key-Usage: sign
-  Key-Length: 2048
-  Name-Real: Elbe Internal Repo
-  Name-Comment: Automatically generated
-  Name-Email: root at elbe-daemon.de
-  Expire-Date: 0
-</GnupgKeyParms>
-"""
-
-
 class OverallStatus(object):
 
     def __init__(self):
@@ -61,7 +48,8 @@ class OverallStatus(object):
 def check_signature(ctx, sig):
     status = OverallStatus()
 
-    if sig.summary & gpgme.SIGSUM_KEY_MISSING:
+    sigsum = gpgme.constants.sigsum
+    if sig.summary & sigsum.KEY_MISSING:
         print("Signature with unknown key: %s" % sig.fpr)
         status.key_missing = True
         return status
@@ -69,7 +57,7 @@ def check_signature(ctx, sig):
     # there should be a key
     key = ctx.get_key(sig.fpr)
     print("%s <%s> (%s):" % (key.uids[0].name, key.uids[0].email, sig.fpr))
-    if sig.summary & gpgme.SIGSUM_VALID == gpgme.SIGSUM_VALID:
+    if sig.summary & sigsum.VALID == sigsum.VALID:
         # signature fully valid and trusted
         print("VALID (Trusted)")
         return status
@@ -79,28 +67,28 @@ def check_signature(ctx, sig):
         # Signature is valid, but the key is not ultimately trusted,
         # see: http://www.gossamer-threads.com/lists/gnupg/users/52350
         print("VALID (Untrusted).")
-    if sig.summary & gpgme.SIGSUM_SIG_EXPIRED == gpgme.SIGSUM_SIG_EXPIRED:
+    if sig.summary & sigsum.SIG_EXPIRED == sigsum.SIG_EXPIRED:
         print("SIGNATURE EXPIRED!")
         status.sig_expired = True
-    if sig.summary & gpgme.SIGSUM_KEY_EXPIRED == gpgme.SIGSUM_KEY_EXPIRED:
+    if sig.summary & sigsum.KEY_EXPIRED == sigsum.KEY_EXPIRED:
         print("KEY EXPIRED!")
         status.key_expired = True
-    if sig.summary & gpgme.SIGSUM_KEY_REVOKED == gpgme.SIGSUM_KEY_REVOKED:
+    if sig.summary & sigsum.KEY_REVOKED == sigsum.KEY_REVOKED:
         print("KEY REVOKED!")
         status.key_revoked = True
-    if sig.summary & gpgme.SIGSUM_RED == gpgme.SIGSUM_RED:
+    if sig.summary & sigsum.RED == sigsum.RED:
         print("INVALID SIGNATURE!")
         status.invalid = True
-    if sig.summary & gpgme.SIGSUM_CRL_MISSING == gpgme.SIGSUM_CRL_MISSING:
+    if sig.summary & sigsum.CRL_MISSING == sigsum.CRL_MISSING:
         print("CRL MISSING!")
         status.gpgme_error = True
-    if sig.summary & gpgme.SIGSUM_CRL_TOO_OLD == gpgme.SIGSUM_CRL_TOO_OLD:
+    if sig.summary & sigsum.CRL_TOO_OLD == sigsum.CRL_TOO_OLD:
         print("CRL TOO OLD!")
         status.gpgme_error = True
-    if sig.summary & gpgme.SIGSUM_BAD_POLICY == gpgme.SIGSUM_BAD_POLICY:
+    if sig.summary & sigsum.BAD_POLICY == sigsum.BAD_POLICY:
         print("UNMET POLICY REQUIREMENT!")
         status.gpgme_error = True
-    if sig.summary & gpgme.SIGSUM_SYS_ERROR == gpgme.SIGSUM_SYS_ERROR:
+    if sig.summary & sigsum.SYS_ERROR == sigsum.SYS_ERROR:
         print("SYSTEM ERROR!'")
         status.gpgme_error = True
 
@@ -126,9 +114,9 @@ def unsign_file(fname):
             with open(outfilename, 'w') as outfile:
 
                 # obtain signature and write unsigned file
-                sigs = ctx.verify(infile, None, outfile)
+                _, vres = ctx.verify(infile, None, outfile)
 
-                for sig in sigs:
+                for sig in vres.signatures:
                     status = check_signature(ctx, sig)
                     overall_status.add(status)
 
@@ -153,14 +141,14 @@ def sign(infile, outfile, fingerprint):
 
     try:
         key = ctx.get_key(fingerprint)
-    except gpgme.GpgmeError as ex:
+    except Exception as ex:
         print("no key with fingerprint %s: %s" % (fingerprint, ex.message))
 
     ctx.signers = [key]
     ctx.armor = False
 
     try:
-        ctx.sign(infile, outfile, gpgme.SIG_MODE_NORMAL)
+        ctx.sign(infile.read(), outfile)
     except Exception as ex:
         print("Error signing file %s" % ex.message)
 
@@ -182,7 +170,7 @@ def get_fingerprints():
     keys = ctx.keylist()
     fingerprints = []
     for k in keys:
-        fingerprints.append(k.subkeys[0].fpr)
+        fingerprints.append(k.fpr)
     return fingerprints
 
 
@@ -190,7 +178,7 @@ def generate_elbe_internal_key():
     hostfs.mkdir_p("/var/cache/elbe/gnupg")
     os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
     ctx = gpgme.Context()
-    key = ctx.genkey(elbe_internal_key_param)
+    key = ctx.create_key('Elbe Internal Repo (Automatically generated) <root at elbe-daemon.de>', 'rsa2048', expires=False, sign=True)
 
     return key.fpr
 
@@ -201,7 +189,8 @@ def export_key(fingerprint, outfile):
     ctx.armor = True
 
     try:
-        ctx.export(fingerprint, outfile)
+        key = ctx.key_export(fingerprint)
+        outfile.write(key)
     except Exception:
         print("Error exporting key %s" % (fingerprint))
 
-- 
2.11.0




More information about the elbe-devel mailing list