]> git.decadent.org.uk Git - dak.git/blobdiff - dak/process_unchecked.py
make mirrorsplit keep non-i386 oldstable (sarge) rather than non-i386 for stable...
[dak.git] / dak / process_unchecked.py
index 1cf2234ecd2f10a4a0f6b132980e25e40f175f67..aac33d234662ac6831bc89219169740490467d67 100755 (executable)
@@ -39,10 +39,11 @@ from types import *
 
 ################################################################################
 
-re_valid_version = re.compile(r"^([0-9]+:)?[0-9A-Za-z\.\-\+:]+$")
+re_valid_version = re.compile(r"^([0-9]+:)?[0-9A-Za-z\.\-\+:~]+$")
 re_valid_pkg_name = re.compile(r"^[\dA-Za-z][\dA-Za-z\+\-\.]+$")
 re_changelog_versions = re.compile(r"^\w[-+0-9a-z.]+ \([^\(\) \t]+\)")
 re_strip_revision = re.compile(r"-([^-]+)$")
+re_strip_srcver = re.compile(r"\s+\(\S+\)$")
 
 ################################################################################
 
@@ -202,6 +203,14 @@ def check_changes():
             reject("%s: Missing mandatory field `%s'." % (filename, i))
             return 0    # Avoid <undef> errors during later tests
 
+    # Strip a source version in brackets from the source field
+    if re_strip_srcver.search(changes["source"]):
+       changes["source"] = re_strip_srcver.sub('', changes["source"])
+
+    # Ensure the source field is a valid package name.
+    if not re_valid_pkg_name.match(changes["source"]):
+        reject("%s: invalid source name '%s'." % (filename, changes["source"]))
+
     # Split multi-value fields into a lower-level dictionary
     for i in ("architecture", "distribution", "binary", "closes"):
         o = changes.get(i, "")
@@ -529,8 +538,15 @@ def check_files():
                         files[file]["byhand"] = 1
                     elif os.path.exists(Cnf["Dir::Queue::New"] + '/' + dsc_filename):
                         files[file]["new"] = 1
-                    elif not os.path.exists(Cnf["Dir::Queue::Accepted"] + '/' + dsc_filename):
-                        reject("no source found for %s %s (%s)." % (source_package, source_version, file))
+                    else:
+                       dsc_file_exists = 0
+                        for myq in ["Accepted", "Embargoed", "Unembargoed", "ProposedUpdates"]:
+                           if Cnf.has_key("Dir::Queue::%s" % (myq)):
+                               if os.path.exists(Cnf["Dir::Queue::"+myq] + '/' + dsc_filename):
+                                   dsc_file_exists = 1
+                                   break
+                       if not dsc_file_exists:
+                            reject("no source found for %s %s (%s)." % (source_package, source_version, file))
             # Check the version and for file overwrites
             reject(Upload.check_binary_against_db(file),"")
 
@@ -971,7 +987,7 @@ def check_timestamps():
                     apt_inst.debExtract(deb_file,tar.callback,"data.tar.gz")
                 except SystemError, e:
                     # If we can't find a data.tar.gz, look for data.tar.bz2 instead.
-                    if not re.match(r"Cannot f[ui]nd chunk data.tar.gz$", str(e)):
+                    if not re.search(r"Cannot f[ui]nd chunk data.tar.gz$", str(e)):
                         raise
                     deb_file.seek(0)
                     apt_inst.debExtract(deb_file,tar.callback,"data.tar.bz2")
@@ -997,6 +1013,48 @@ def check_timestamps():
             except:
                 reject("%s: deb contents timestamp check failed [%s: %s]" % (filename, sys.exc_type, sys.exc_value))
 
+################################################################################
+
+def check_signed_by_key():
+    """Ensure the .changes is signed by an authorized uploader."""
+
+    # We only check binary-only uploads right now
+    if changes["architecture"].has_key("source"):
+        return
+
+    if not Cnf.Exists("Binary-Upload-Restrictions"):
+        return
+
+    restrictions = Cnf.SubTree("Binary-Upload-Restrictions")
+
+    # If the restrictions only apply to certain components make sure
+    # that the upload is actual targeted there.
+    if restrictions.Exists("Components"):
+        restricted_components = restrictions.SubTree("Components").ValueList()
+        is_restricted = False
+        for file in files:
+            if files[file]["component"] in restricted_components:
+                is_restricted = True
+                break
+        if not is_restricted:
+            return
+
+    # Assuming binary only upload restrictions are in place we then
+    # iterate over suite and architecture checking the key is in the
+    # allowed list.  If no allowed list exists for a given suite or
+    # architecture it's assumed to be open to anyone.
+    for suite in changes["distribution"].keys():
+        if not restrictions.Exists(suite):
+            continue
+        for arch in changes["architecture"].keys():
+            if not restrictions.SubTree(suite).Exists(arch):
+                continue
+            allowed_keys = restrictions.SubTree("%s::%s" % (suite, arch)).ValueList()
+            if changes["fingerprint"] not in allowed_keys:
+                base_filename = os.path.basename(pkg.changes_file)
+                reject("%s: not signed by authorised uploader for %s/%s"
+                       % (base_filename, suite, arch))
+
 ################################################################################
 ################################################################################
 
@@ -1134,7 +1192,12 @@ def is_unembargo ():
     if ql:
         return 1
 
-    if pkg.directory == Cnf["Dir::Queue::Disembargo"].rstrip("/"):
+    oldcwd = os.getcwd()
+    os.chdir(Cnf["Dir::Queue::Disembargo"])
+    disdir = os.getcwd()
+    os.chdir(oldcwd)
+
+    if pkg.directory == disdir:
         if changes["architecture"].has_key("source"):
             if Options["No-Action"]: return 1
 
@@ -1177,9 +1240,20 @@ def queue_embargo (summary):
 ################################################################################
 
 def is_stableupdate ():
-    if changes["distribution"].has_key("proposed-updates"):
-       return 1
-    return 0
+    if not changes["distribution"].has_key("proposed-updates"):
+       return 0
+
+    if not changes["architecture"].has_key("source"):
+        pusuite = daklib.database.get_suite_id("proposed-updates")
+        q = Upload.projectB.query(
+          "SELECT S.source FROM source s JOIN src_associations sa ON (s.id = sa.source) WHERE s.source = '%s' AND s.version = '%s' AND sa.suite = %d" % 
+          (changes["source"], changes["version"], pusuite))
+        ql = q.getresult()
+        if ql:
+            # source is already in proposed-updates
+            return 0
+
+    return 1
 
 def do_stableupdate (summary):
     print "Moving to PROPOSED-UPDATES holding area."
@@ -1288,6 +1362,7 @@ def process_it (changes_file):
                 check_md5sums()
                 check_urgency()
                 check_timestamps()
+                check_signed_by_key()
         Upload.update_subst(reject_message)
         action()
     except SystemExit: