]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/checks.py
checks: Fix a syntax error in ExternalHashCheck
[dak.git] / daklib / checks.py
index 81bd629e481e171991d1ddf0da8d3b4dce282c12..e7afda55340fd811ab40c4bff169485d1f64d055 100644 (file)
@@ -45,6 +45,12 @@ class Reject(Exception):
     """exception raised by failing checks"""
     pass
 
+class RejectStupidMaintainerException(Exception):
+    """exception raised by failing the external hashes check"""
+
+    def __str__(self):
+        return "'%s' has mismatching %s from the external files db ('%s' [current] vs '%s' [external])" % self.args[:4]
+
 class Check(object):
     """base class for checks
 
@@ -167,6 +173,43 @@ class HashesCheck(Check):
             for f in source.files.itervalues():
                 f.check(upload.directory)
 
+class ExternalHashesCheck(Check):
+    """Checks hashes in .changes and .dsc against an external database."""
+    def check_single(self, session, f):
+        q = session.execute("SELECT size, md5sum, sha1sum, sha256sum FROM external_files WHERE filename LIKE '%%/%s'" % f.filename)
+        (ext_size, ext_md5sum, ext_sha1sum, ext_sha256sum) = q.fetchone() or (None, None, None, None)
+
+        if not ext_size:
+            return
+
+        if ext_size != f.size:
+            raise RejectStupidMaintainerException(f.filename, 'size', f.size, ext_size)
+
+        if ext_md5sum != f.md5sum:
+            raise RejectStupidMaintainerException(f.filename, 'md5sum', f.md5sum, ext_md5sum)
+
+        if ext_sha1sum != f.sha1sum:
+            raise RejectStupidMaintainerException(f.filename, 'sha1sum', f.sha1sum, ext_sha1sum)
+
+        if ext_sha256sum != f.sha256sum:
+            raise RejectStupidMaintainerException(f.filename, 'sha256sum', f.sha256sum, ext_sha256sum)
+
+    def check(self, upload):
+        cnf = Config()
+
+        if not cnf.use_extfiles:
+            return
+
+        session = upload.session
+        changes = upload.changes
+
+        for f in changes.files.itervalues():
+            self.check_single(session, f)
+        source = changes.source
+        if source is not None:
+            for f in source.files.itervalues():
+                self.check_single(session, f)
+
 class BinaryCheck(Check):
     """Check binary packages for syntax errors."""
     def check(self, upload):
@@ -354,6 +397,10 @@ class ACLCheck(Check):
     """Check the uploader is allowed to upload the packages in .changes"""
 
     def _does_hijack(self, session, upload, suite):
+        # Try to catch hijacks.
+        # This doesn't work correctly. Uploads to experimental can still
+        # "hijack" binaries from unstable. Also one can hijack packages
+        # via buildds (but people who try this should not be DMs).
         for binary_name in upload.changes.binary_names:
             binaries = session.query(DBBinary).join(DBBinary.source) \
                 .filter(DBBinary.suites.contains(suite)) \
@@ -389,9 +436,9 @@ class ACLCheck(Check):
                 uploaded_arches = set(upload.changes.architectures)
                 uploaded_arches.discard('source')
                 allowed_arches = set(a.arch_string for a in acl.architectures)
-                for a in uploaded_arches:
-                    if a not in allowed_arches:
-                        return False, "uploads for architecture {0} are not allowed".format(a)
+                forbidden_arches = uploaded_arches - allowed_arches
+                if len(forbidden_arches) != 0:
+                    return False, "uploads for architecture(s) {0} are not allowed".format(", ".join(forbidden_arches))
         if not acl.allow_hijack:
             for suite in upload.final_suites:
                 does_hijack, hijacked_binary, hijacked_from = self._does_hijack(session, upload, suite)
@@ -401,6 +448,7 @@ class ACLCheck(Check):
         acl_per_source = session.query(ACLPerSource).filter_by(acl=acl, fingerprint=upload.fingerprint, source=source_name).first()
         if acl.allow_per_source:
             # XXX: Drop DMUA part here and switch to new implementation.
+            # XXX: Send warning mail once users can set the new DMUA flag
             dmua_status, dmua_reason = self._check_dmua(upload)
             if not dmua_status:
                 return False, dmua_reason
@@ -590,7 +638,7 @@ class LintianCheck(Check):
         except yaml.YAMLError as msg:
             raise Exception('Could not read lintian tags file {0}, YAML error: {1}'.format(tagfile, msg))
 
-        fd, temp_filename = utils.temp_filename()
+        fd, temp_filename = utils.temp_filename(mode=0o644)
         temptagfile = os.fdopen(fd, 'w')
         for tags in lintiantags.itervalues():
             for tag in tags:
@@ -599,8 +647,10 @@ class LintianCheck(Check):
 
         changespath = os.path.join(upload.directory, changes.filename)
         try:
-            # FIXME: no shell
-            cmd = "lintian --show-overrides --tags-from-file {0} {1}".format(temp_filename, changespath)
+            if cnf.unprivgroup:
+                cmd = "sudo -H -u {0} -- /usr/bin/lintian --show-overrides --tags-from-file {1} {2}".format(cnf.unprivgroup, temp_filename, changespath)
+            else:
+                cmd = "/usr/bin/lintian --show-overrides --tags-from-file {0} {1}".format(temp_filename, changespath)
             result, output = commands.getstatusoutput(cmd)
         finally:
             os.unlink(temp_filename)