From 81bb769828534a2afa19213771c38be30fef6ef3 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sun, 25 Mar 2012 21:30:47 +0200 Subject: [PATCH] Verify signatures when installing packages. --- python/pakfire/actions.py | 11 ++++++ python/pakfire/config.py | 4 +++ python/pakfire/errors.py | 4 +++ python/pakfire/transaction.py | 64 +++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+) diff --git a/python/pakfire/actions.py b/python/pakfire/actions.py index e508f135a..6f6f89a92 100644 --- a/python/pakfire/actions.py +++ b/python/pakfire/actions.py @@ -58,6 +58,17 @@ class Action(object): # This is just a dummy test that does nothing at all. return filelist + def verify(self): + # Check if there are any signatures at all. + if not self.pkg.signatures: + raise SignatureError, _("%s has got no signatures") % self.pkg.friendly_name + + # Run the verification process and save the result. + sigs = self.pkg.verify() + + if not sigs: + raise SignatureError, _("%s has got no valid signatures") % self.pkg.friendly_name + @property def needs_download(self): return self.type in ("install", "reinstall", "upgrade", "downgrade", "change",) \ diff --git a/python/pakfire/config.py b/python/pakfire/config.py index 0d3278424..7d2986ec5 100644 --- a/python/pakfire/config.py +++ b/python/pakfire/config.py @@ -44,6 +44,10 @@ class _Config(object): "mode" : "rotate", "rotation_threshold" : 10485760, }, + + "signatures" : { + "mode" : "strict", + }, } # A dict with default settings for this config class. diff --git a/python/pakfire/errors.py b/python/pakfire/errors.py index fa9df78c8..2017b65e7 100644 --- a/python/pakfire/errors.py +++ b/python/pakfire/errors.py @@ -86,5 +86,9 @@ class PakfireContainerError(Error): message = _("Running pakfire-build in a pakfire container?") +class SignatureError(Error): + pass + + class TransactionCheckError(Error): message = _("Transaction test was not successful") diff --git a/python/pakfire/transaction.py b/python/pakfire/transaction.py index 5270015f2..0ab7b8c77 100644 --- a/python/pakfire/transaction.py +++ b/python/pakfire/transaction.py @@ -426,6 +426,67 @@ class Transaction(object): raise TransactionCheckError, _("Transaction test was not successful") + def verify_signatures(self, logger): + """ + Check the downloaded files for valid signatures. + """ + mode = self.pakfire.config.get("signatures", "mode", "strict") + + # If this disabled, we do nothing. + if mode == "disabled": + return + + # Search for actions we need to process. + actions = [] + for action in self.actions: + # Skip scripts. + if isinstance(action, ActionScript): + continue + + actions.append(action) + + # Make a nice progressbar. + p = util.make_progress(_("Verifying signatures..."), len(actions)) + + # Collect all errors. + errors = [] + + try: + # Do the verification for every action. + i = 0 + for action in actions: + # Update the progressbar. + if p: + i += 1 + p.update(i) + + try: + action.verify() + + except SignatureError, e: + errors.append("%s" % e) + finally: + if p: p.finish() + + # If no errors were found everything is fine. + if not errors: + logger.info("") + return + + # Raise a SignatureError in strict mode. + if mode == "strict": + raise SignatureError, "\n".join(errors) + + elif mode == "permissive": + logger.warning(_("Found %s signature error(s)!") % len(errors)) + for error in errors: + logger.warning(" %s" % error) + logger.warning("") + + logger.warning(_("Going on because we are running in permissive mode.")) + logger.warning(_("This is dangerous!")) + logger.warning("") + def run(self, logger=None): assert not self.__need_sort, "Did you forget to sort the transaction?" @@ -437,6 +498,9 @@ class Transaction(object): # in the build logs on the build service) self.download() + # Verify signatures. + self.verify_signatures(logger=logger) + # Run the transaction test self.check(logger=logger) -- 2.39.5