[elbe-devel] [PATCH v4 2/2] Replace gpgme with maintained gpg module
bage at linutronix.de
bage at linutronix.de
Tue Feb 19 09:30:45 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. Use the low-level op_* functions to also target
the wrapper's predecessor pyme (Debian jessie).
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 | 16 ++++++---
elbepack/egpg.py | 85 ++++++++++++++++++++++++++----------------------
elbepack/finetuning.py | 22 ++++++++-----
5 files changed, 73 insertions(+), 54 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..6bd166ef 100644
--- a/elbepack/debinstaller.py
+++ b/elbepack/debinstaller.py
@@ -23,8 +23,12 @@ except ImportError:
import urllib2
urlopen = urllib2.urlopen
+try:
+ from gpg import core
+except ImportError:
+ from pyme import core
+
from shutil import copyfileobj, copyfile
-from gpgme import Context
from elbepack.filesystem import TmpdirFilesystem
from elbepack.egpg import OverallStatus, check_signature
@@ -127,7 +131,7 @@ def download_release(tmp, base_url):
# setup gpg context, for verifying
# the Release.gpg signature.
os.environ['GNUPGHOME'] = tmp.fname('/')
- ctx = Context()
+ ctx = core.Context()
# download the Relase file to a tmp file,
# because we need it 2 times
@@ -144,14 +148,18 @@ def download_release(tmp, base_url):
overall_status = OverallStatus()
# verify detached signature
- sigs = ctx.verify(sig, signed, None)
+ det_sign = core.Data(sig.read())
+ signed_data = core.Data(signed.read())
+ ctx.op_verify(det_sign, signed_data, None)
+ vres = ctx.op_verify_result()
- 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')
+
finally:
sig.close()
diff --git a/elbepack/egpg.py b/elbepack/egpg.py
index c56f22e5..019cdefa 100644
--- a/elbepack/egpg.py
+++ b/elbepack/egpg.py
@@ -9,7 +9,12 @@ from __future__ import print_function
import os
-import gpgme
+try:
+ from gpg import core
+ from gpg.constants import sigsum, sig
+except ImportError:
+ from pyme import core
+ from pyme.constants import sigsum, sig
from elbepack.filesystem import hostfs
@@ -34,7 +39,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 +47,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,15 +66,15 @@ class OverallStatus(object):
def check_signature(ctx, sig):
status = OverallStatus()
- if sig.summary & gpgme.SIGSUM_KEY_MISSING:
+ if sig.summary & sigsum.KEY_MISSING:
print("Signature with unknown key: %s" % sig.fpr)
status.key_missing = True
return status
# there should be a key
- key = ctx.get_key(sig.fpr)
+ key = ctx.get_key(sig.fpr, 0)
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 +84,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,19 +121,20 @@ def unsign_file(fname):
outfilename = fname[:len(fname) - 4]
os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
- ctx = gpgme.Context()
- ctx.armor = False
+ ctx = core.Context()
+ ctx.set_armor(False)
try:
overall_status = OverallStatus()
- with open(fname, 'r') as infile:
- with open(outfilename, 'w') as outfile:
+ with core.Data(file=fname) as infile:
+ with core.Data(file=outfilename) as outfile:
# obtain signature and write unsigned file
- sigs = ctx.verify(infile, None, outfile)
+ ctx.op_verify(infile, None, outfile)
+ vres = ctx.op_verify_result()
- for sig in sigs:
+ for sig in vres.signatures:
status = check_signature(ctx, sig)
overall_status.add(status)
@@ -148,19 +154,21 @@ def unsign_file(fname):
def sign(infile, outfile, fingerprint):
os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
- ctx = gpgme.Context()
+ ctx = core.Context()
key = None
try:
- key = ctx.get_key(fingerprint)
- except gpgme.GpgmeError as ex:
+ key = ctx.get_key(fingerprint, 0)
+ except Exception as ex:
print("no key with fingerprint %s: %s" % (fingerprint, ex.message))
- ctx.signers = [key]
- ctx.armor = False
+ ctx.signers_add(key)
+ ctx.set_armor(False)
try:
- ctx.sign(infile, outfile, gpgme.SIG_MODE_NORMAL)
+ indata = core.Data(file=infile)
+ outdata = core.Data(file=outfile)
+ ctx.op_sign(indata, outdata, sig.mode.NORMAL)
except Exception as ex:
print("Error signing file %s" % ex.message)
@@ -178,8 +186,8 @@ def sign_file(fname, fingerprint):
def get_fingerprints():
os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
- ctx = gpgme.Context()
- keys = ctx.keylist()
+ ctx = core.Context()
+ keys = ctx.op_keylist_all(None, False)
fingerprints = []
for k in keys:
fingerprints.append(k.subkeys[0].fpr)
@@ -189,19 +197,20 @@ def get_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 = core.Context()
+ ctx.op_genkey(elbe_internal_key_param, None, None)
+ key = ctx.op_genkey_result()
return key.fpr
def export_key(fingerprint, outfile):
os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
- ctx = gpgme.Context()
- ctx.armor = True
+ ctx = core.Context()
+ ctx.set_armor(True)
try:
- ctx.export(fingerprint, outfile)
+ ctx.op_export(fingerprint, 0, outfile)
except Exception:
print("Error exporting key %s" % (fingerprint))
diff --git a/elbepack/finetuning.py b/elbepack/finetuning.py
index 0d9a2824..14c57309 100644
--- a/elbepack/finetuning.py
+++ b/elbepack/finetuning.py
@@ -11,9 +11,11 @@ from __future__ import print_function
import os
from shutil import rmtree
-from io import BytesIO
-import gpgme
+try:
+ from gpg import core
+except ImportError:
+ from pyme import core
from apt.package import FetchError
@@ -421,14 +423,16 @@ class UpdatedAction(FinetuningAction):
log.printo("transfer gpg key to target: " + fp)
os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
- key = BytesIO()
- ctx = gpgme.Context()
- ctx.armor = True
- ctx.export(fp, key)
-
- log.printo(str(key.getvalue()))
+ gpgdata = core.Data()
+ ctx = core.Context()
+ ctx.set_armor(True)
+ ctx.op_export(fp, 0, gpgdata)
+ gpgdata.seek(0, os.SEEK_SET)
+ key = gpgdata.read()
+
+ log.printo(str(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.11.0
More information about the elbe-devel
mailing list