]> git.ipfire.org Git - pakfire.git/commitdiff
Verify signatures when installing packages.
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 25 Mar 2012 19:30:47 +0000 (21:30 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 25 Mar 2012 19:30:47 +0000 (21:30 +0200)
python/pakfire/actions.py
python/pakfire/config.py
python/pakfire/errors.py
python/pakfire/transaction.py

index e508f135a56ba96c37780b8c22f9890b1218d865..6f6f89a92b65b1999bfb0d2a88c5591a69de5d4c 100644 (file)
@@ -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",) \
index 0d3278424c91c88d45ae049a4c74d90ad83ed5cd..7d2986ec5de75018378c504dc7e7537ec9e4a6fe 100644 (file)
@@ -44,6 +44,10 @@ class _Config(object):
                        "mode"  : "rotate",
                        "rotation_threshold" : 10485760,
                },
+
+               "signatures" : {
+                       "mode" : "strict",
+               },
        }
 
        # A dict with default settings for this config class.
index fa9df78c84a55fe641c02d99a855e65c2432e0c2..2017b65e719bb6ad29e99c8c04d6a308c45f4f2e 100644 (file)
@@ -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")
index 5270015f2b9c6085f0f8540137f74020f4d0bc07..0ab7b8c77e8bd177211f7349585da20ebc86164c 100644 (file)
@@ -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)