[elbe-devel] [PATCH v2 2/2] Replace gpgme with maintained gpg module
Manuel Traut
manut at linutronix.de
Fri Feb 8 17:44:01 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>
Signed-off-by: Manuel Traut <manut at linutronix.de>
---
README.adoc | 2 +-
debian/control | 2 --
elbepack/debinstaller.py | 12 ++++---
elbepack/egpg.py | 75 +++++++++++++++++-----------------------
elbepack/finetuning.py | 12 +++----
5 files changed, 46 insertions(+), 57 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 1a46b353..b6d65b37 100644
--- a/elbepack/debinstaller.py
+++ b/elbepack/debinstaller.py
@@ -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.egpg 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/egpg.py b/elbepack/egpg.py
index c56f22e5..4e8543f4 100644
--- a/elbepack/egpg.py
+++ b/elbepack/egpg.py
@@ -9,23 +9,10 @@ from __future__ import print_function
import os
-import gpgme
+import gpg
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):
@@ -34,7 +21,7 @@ class OverallStatus(object):
self.sig_expired = False
self.key_revoked = False
self.key_missing = False
- self.gpgme_error = False
+ self.gpg_error = False
def add(self, to_add):
self.invalid = self.invalid or to_add.invalid
@@ -42,10 +29,10 @@ class OverallStatus(object):
self.sig_expired = self.sig_expired or to_add.sig_expired
self.key_revoked = self.key_revoked or to_add.key_revoked
self.key_missing = self.key_missing or to_add.key_missing
- self.gpgme_error = self.gpgme_error or to_add.gpgme_error
+ self.gpg_error = self.gpg_error or to_add.gpg_error
def to_exitcode(self):
- if self.gpgme_error: # critical GPG error
+ if self.gpg_error: # critical GPG error
return 20
if self.invalid: # invalid signature
return 1
@@ -61,7 +48,8 @@ class OverallStatus(object):
def check_signature(ctx, sig):
status = OverallStatus()
- if sig.summary & gpgme.SIGSUM_KEY_MISSING:
+ sigsum = gpg.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,30 +67,30 @@ 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:
+ status.gpg_error = True
+ 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:
+ status.gpg_error = True
+ 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:
+ status.gpg_error = True
+ if sig.summary & sigsum.SYS_ERROR == sigsum.SYS_ERROR:
print("SYSTEM ERROR!'")
- status.gpgme_error = True
+ status.gpg_error = True
return status
@@ -116,7 +104,7 @@ def unsign_file(fname):
outfilename = fname[:len(fname) - 4]
os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
- ctx = gpgme.Context()
+ ctx = gpg.Context()
ctx.armor = False
try:
@@ -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)
@@ -148,19 +136,19 @@ def unsign_file(fname):
def sign(infile, outfile, fingerprint):
os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
- ctx = gpgme.Context()
+ ctx = gpg.Context()
key = None
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)
@@ -178,30 +166,31 @@ def sign_file(fname, fingerprint):
def get_fingerprints():
os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
- ctx = gpgme.Context()
+ ctx = gpg.Context()
keys = ctx.keylist()
fingerprints = []
for k in keys:
- fingerprints.append(k.subkeys[0].fpr)
+ fingerprints.append(k.fpr)
return fingerprints
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)
+ ctx = gpg.Context()
+ key = ctx.create_key('Elbe Internal Repo (Automatically generated) <root at elbe-daemon.de>', 'rsa2048', expires=False, sign=True)
return key.fpr
def export_key(fingerprint, outfile):
os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
- ctx = gpgme.Context()
+ ctx = gpg.Context()
ctx.armor = True
try:
- ctx.export(fingerprint, outfile)
+ key = ctx.key_export(fingerprint)
+ outfile.write(key)
except Exception:
print("Error exporting key %s" % (fingerprint))
diff --git a/elbepack/finetuning.py b/elbepack/finetuning.py
index 0d9a2824..70b9793b 100644
--- a/elbepack/finetuning.py
+++ b/elbepack/finetuning.py
@@ -11,9 +11,8 @@ from __future__ import print_function
import os
from shutil import rmtree
-from io import BytesIO
-import gpgme
+import gpg
from apt.package import FetchError
@@ -421,14 +420,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:
--
2.20.1
More information about the elbe-devel
mailing list