[Secure-testing-commits] r3129 - bin lib/python

Florian Weimer fw at costa.debian.org
Fri Dec 23 13:15:26 UTC 2005


Author: fw
Date: 2005-12-23 13:15:25 +0000 (Fri, 23 Dec 2005)
New Revision: 3129

Modified:
   bin/update-db
   lib/python/security_db.py
Log:
lib/python/security_db.py (DB.initSchema):
  Add index on package_notes(package) (no schema version bump needed).
(DB.calculateDebsecan0):
  Renamed from DB.calculateDebsecan.
(DB.calculateDebsecan1):
  New method which generates version 1 format (with pinning support
  wtc.).
(DB.calculateDebsecan):
  Invokes both the version 0 and version 1 methods.

bin/update-db:
  Adjust accordingly.


Modified: bin/update-db
===================================================================
--- bin/update-db	2005-12-23 13:11:59 UTC (rev 3128)
+++ bin/update-db	2005-12-23 13:15:25 UTC (rev 3129)
@@ -78,8 +78,7 @@
 
 # debsecan data
 
-for release in ('', 'woody', 'sarge', 'etch'):
-    db.calculateDebsecan(release)
+db.calculateDebsecan()
 
 # Everything worked well.
 

Modified: lib/python/security_db.py
===================================================================
--- lib/python/security_db.py	2005-12-23 13:11:59 UTC (rev 3128)
+++ lib/python/security_db.py	2005-12-23 13:15:25 UTC (rev 3129)
@@ -233,6 +233,9 @@
         cursor.execute(
             """CREATE UNIQUE INDEX package_notes_bug
             ON package_notes(bug_name, package, release)""")
+        cursor.execute(
+            """CREATE INDEX package_notes_package
+            ON package_notes(package)""")
 
         cursor.execute("""CREATE TABLE debian_bugs
         (bug INTEGER NOT NULL,
@@ -1229,8 +1232,8 @@
         VALUES (?, ?, ?, ?)""",
               (bug_name, suite, status, pkgs))
 
-    def calculateDebsecan(self, release):
-        """Create data for the debsecan tool."""
+    def calculateDebsecan0(self, release):
+        """Create data for the debsecan tool (VERSION 0 format)."""
 
         c = self.cursor()
 
@@ -1344,6 +1347,204 @@
 
         c.execute("DROP TABLE vulnlist")
 
+    def calculateDebsecan1(self):
+        """Calculates debsecan data (release-independent, VERSION 1)."""
+
+        c = self.cursor()
+
+        result_start = ['VERSION 1']
+        bug_to_index = {}
+        bug_to_remote_flag = {}
+
+        def fill_bug_to_index():
+            index = 0
+            for (bug, desc, remote) in c.execute(
+                """SELECT DISTINCT p.bug_name, b.description,
+                (SELECT range_remote FROM nvd_data
+                 WHERE cve_name = p.bug_name)
+                FROM package_notes AS p, bugs AS b
+                WHERE p.urgency <> 'unimportant'
+                AND name NOT LIKE 'FAKE-0000000-%'
+                AND b.name = p.bug_name
+                AND p.package_kind IN ('source', 'binary', 'unknown')
+                ORDER BY p.bug_name"""):
+                if remote is None:
+                    remote = '?'
+                elif remote:
+                    remote = 'R'
+                else:
+                    remote = ' '
+
+                # Normalize FAKE-* names a bit.  The line number (which
+                # makes the name unique) is completely useless for the
+                # client.
+
+                if bug[0:5] == "FAKE-":
+                    name = '-'.join(bug.split('-')[0:2])
+                else:
+                    name = bug
+
+                result_start.append("%s,,%s" % (name, desc))
+                bug_to_index[bug] = index
+                bug_to_remote_flag[bug] = remote
+                index += 1
+            result_start.append('')
+        fill_bug_to_index()
+
+        urgency_to_flag = {'low' : 'L', 'medium' : 'M', 'high' : 'H',
+                           'unknown' : ' '}
+
+        vuln_list = []
+        source_packages = {}
+        def fill_vuln_list(source_packages=source_packages):
+            for (bug, package) in list(c.execute(
+                """SELECT DISTINCT bug_name, package
+                FROM package_notes
+                WHERE bug_name NOT LIKE 'FAKE-0000000-%'
+                AND package_kind IN ('source', 'binary', 'unknown')
+                GROUP BY package, bug_name
+                ORDER BY package, bug_name""")):
+
+                unstable_fixed = '0'
+                total_urgency = ''
+                other_versions = {}
+                is_binary = False
+                is_unknown = False
+                fixed_releases = {}
+                for (release, kind, urgency, version) in list(c.execute(
+                    """SELECT release, package_kind, urgency, fixed_version
+                    FROM package_notes WHERE bug_name = ? AND package = ?""",
+                    (bug, package))):
+                    if total_urgency:
+                        if urgency == 'unknown':
+                            total_urgency = urgency
+                        elif total_urgency <> 'unknown' \
+                                 and bugs.internUrgency(urgency) \
+                                 > bugs.internUrgency(total_urgency):
+                            total_urgency = urgency
+                    else:
+                        total_urgency = urgency
+
+                    if kind == 'binary':
+                        is_binary = True
+                    elif kind == 'source':
+                        source_packages[package] = True
+                    else:
+                        is_unknown = True
+
+                    if release == '':
+                        unstable_fixed = version
+                        if version:
+                            v_ref = debian_support.Version(version)
+                            for (v,) in c.execute("""SELECT version
+                            FROM source_packages WHERE name = ?
+                            AND release = 'sid' AND subrelease = ''""",
+                                                  (package,)):
+                                if debian_support.Version(v) > v_ref:
+                                    fixed_releases['sid'] = True
+                                    break
+                    elif version is not None:
+                        fixed_releases[release] = True
+
+                        # Collect newer versions in the same release
+                        # (which are supposed to fix the same bug).
+
+                        v_ref = debian_support.Version(version)
+                        for (v,) in c.execute("""SELECT fixed_version
+                        FROM package_notes
+                        WHERE package = ? AND release = ?""",
+                                              (package, release)):
+                            if v is None:
+                                continue
+                            if debian_support.Version(v) > v_ref:
+                                other_versions[v] = True
+
+                        for (v,) in c.execute("""SELECT version
+                        FROM source_packages WHERE name = ?
+                        AND release = ? AND subrelease IN ('', 'security')""",
+                                              (package, release)):
+                            if debian_support.Version(v) > v_ref:
+                                other_versions[v] = True
+
+                # Check if the issue does not actually mark any packages
+                # as vulnerable.
+                if total_urgency == 'unimportant' \
+                       or (unstable_fixed == '0' and len(other_versions) == 0):
+                    continue
+
+                if unstable_fixed is None:
+                    unstable_fixed = ''
+                bs_flag = 'S'
+                if is_binary:
+                    assert not is_unknown
+                    bs_flag = 'B'
+                elif is_unknown:
+                    bs_flag = ' '
+
+                other_versions = other_versions.keys()
+                other_versions.sort()
+                other_versions = ' '.join(other_versions)
+
+                vuln_list.append(("%s,%d,%c%c%c"
+                                  % (package, bug_to_index[bug],
+                                     bs_flag, urgency_to_flag[total_urgency],
+                                     bug_to_remote_flag[bug]),
+                                  fixed_releases.keys(),
+                                  ",%s,%s"
+                                  % (unstable_fixed, other_versions)))
+        fill_vuln_list()
+        source_packages = source_packages.keys()
+        source_packages.sort()
+
+        def store_value(name, value):
+            value = base64.encodestring(zlib.compress(value, 9))
+            c.execute("""INSERT OR REPLACE INTO debsecan_data
+            VALUES (?, ?)""", (name, value))
+                       
+        def gen_release(release):
+            result = result_start[:]
+
+            for (prefix, releases, suffix) in vuln_list:
+                if release in releases:
+                    fixed = 'F'
+                else:
+                    fixed = ' '
+                result.append(prefix + fixed + suffix)
+            result.append('')
+
+            for sp in source_packages:
+                bp_list = []
+                for (bp,) in c.execute("""SELECT name FROM binary_packages
+                WHERE source = ? AND release = ? AND subrelease = ''
+                ORDER BY name""",
+                                       (sp, release)):
+                    bp_list.append(bp)
+                if bp_list <> [sp]:
+                    # We intentionally store the empty list, it means
+                    # that the source package is obsolete as a whole.
+                    result.append("%s,%s" % (sp, ' '.join(bp_list)))
+            result.append('')
+
+            store_value('release/1/' + release, '\n'.join(result))
+
+        for release in ('sid', 'etch', 'sarge', 'woody'):
+            gen_release(release)
+
+        result = result_start
+        for (prefix, release, suffix) in vuln_list:
+            result.append(prefix + ' ' + suffix)
+        result.append('')
+        result.append('')            
+        result.append('')
+        store_value ('release/1/GENERIC', '\n'.join(result))
+                
+    def calculateDebsecan(self):
+        """Calculate all debsecan data."""
+        for release in ('', 'woody', 'sarge', 'etch'):
+            self.calculateDebsecan0(release)
+        self.calculateDebsecan1()
+        
+
     def getDebsecan(self, name):
         """Returns the debsecan data item NAME."""
         for (data,) in self.cursor().execute(




More information about the Secure-testing-commits mailing list