--- pym/portage/sync/modules/rsync/rsync.py | 66 ++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 9 deletions(-)
diff --git a/pym/portage/sync/modules/rsync/rsync.py b/pym/portage/sync/modules/rsync/rsync.py index 6b0280032..f6e59e211 100644 --- a/pym/portage/sync/modules/rsync/rsync.py +++ b/pym/portage/sync/modules/rsync/rsync.py @@ -6,6 +6,7 @@ import logging import time import signal import socket +import io import re import random import tempfile @@ -25,6 +26,13 @@ from portage.sync.getaddrinfo_validate import getaddrinfo_validate from _emerge.UserQuery import UserQuery from portage.sync.syncbase import NewBase +try: + import gemato.exceptions + import gemato.openpgp + import gemato.recursiveloader +except ImportError: + gemato = None + if sys.hexversion >= 0x3000000: # pylint: disable=W0622 _unicode = str @@ -285,17 +293,57 @@ class RsyncSync(NewBase): # if synced successfully, verify now if exitcode == 0 and not local_state_unchanged and self.verify_metamanifest: - command = ['gemato', 'verify', '-s', self.repo.location] - if self.repo.openpgp_key_path is not None: - command += ['-K', self.repo.openpgp_key_path] - if self.verify_jobs is not None: - command += ['-j', str(self.verify_jobs)] - try: - exitcode = portage.process.spawn(command, **self.spawn_kwargs) - except CommandNotFound as e: - writemsg_level("!!! Command not found: %s\n" % (command[0],), + if gemato is None: + writemsg_level("!!! Unable to verify: gemato not found\n", level=logging.ERROR, noiselevel=-1) exitcode = 127 + else: + # Use isolated environment if key is specified, + # system environment otherwise + if self.repo.openpgp_key_path is not None: + openpgp_env_cls = gemato.openpgp.OpenPGPEnvironment + else: + openpgp_env_cls = gemato.openpgp.OpenPGPSystemEnvironment + + try: + with openpgp_env_cls() as openpgp_env: + if self.repo.openpgp_key_path is not None: + out.einfo('Using keys from %s' % (self.repo.openpgp_key_path,)) + with io.open(self.repo.openpgp_key_path, 'rb') as f: + openpgp_env.import_key(f) + out.ebegin('Refreshing keys from keyserver') + openpgp_env.refresh_keys() + out.eend(0) + + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.repo.location, 'Manifest'), + verify_openpgp=True, + openpgp_env=openpgp_env, + max_jobs=self.verify_jobs) + if not m.openpgp_signed: + raise RuntimeError('OpenPGP signature not found on Manifest') + + ts = m.find_timestamp() + if ts is None: + raise RuntimeError('Timestamp not found in Manifest') + + out.einfo('Manifest timestamp: %s UTC' % (ts.ts,)) + out.einfo('Valid OpenPGP signature found:') + out.einfo('- primary key: %s' % ( + m.openpgp_signature.primary_key_fingerprint)) + out.einfo('- subkey: %s' % ( + m.openpgp_signature.fingerprint)) + out.einfo('- timestamp: %s UTC' % ( + m.openpgp_signature.timestamp)) + + out.ebegin('Verifying %s' % (self.repo.location,)) + m.assert_directory_verifies() + out.eend(0) + except Exception as e: + writemsg_level("!!! Manifest verification failed:\n%s\n" + % (e,), + level=logging.ERROR, noiselevel=-1) + exitcode = 1 return (exitcode, updatecache_flg) -- 2.16.1