[Secure-testing-commits] r2062 - lib/python
Florian Weimer
fw at costa.debian.org
Wed Sep 21 06:08:53 UTC 2005
Author: fw
Date: 2005-09-21 06:08:51 +0000 (Wed, 21 Sep 2005)
New Revision: 2062
Modified:
lib/python/security_db.py
Log:
lib/python/security_db.py (DB.calculateVulnerabilities):
Factor out testing and unstable code.
(DB._calcUnstable):
New. Mostly unchanged from the verison in calculateVulnerabilities.
(DB._calcTesting):
Rewritten from scratch. Now works on source packages. Should be
more reliable.
Modified: lib/python/security_db.py
===================================================================
--- lib/python/security_db.py 2005-09-21 04:03:03 UTC (rev 2061)
+++ lib/python/security_db.py 2005-09-21 06:08:51 UTC (rev 2062)
@@ -1030,184 +1030,104 @@
for (bug_name,) in cursor.execute(
"SELECT name FROM bugs WHERE NOT not_for_us"):
- # Calculate status for unstable. Only source package
- # status is relevant here.
+ self._calcUnstable(c, bug_name)
+ self._calcTesting(c, bug_name)
- def handle_unstable():
- unstable_packages = []
- for (package,) in c.execute(
- """SELECT DISTINCT sp.name
- FROM package_notes AS n,
- source_package_status AS st, source_packages AS sp
- WHERE n.bug_name = ? AND n.urgency <> 'unimportant'
- AND n.release = ''
- AND st.note = n.id AND st.vulnerable
- AND sp.rowid = st.package AND sp.release = 'sid'
- ORDER BY sp.name""",
- (bug_name,)):
- unstable_packages.append(package)
+ return result
- if unstable_packages:
- if len(unstable_packages) == 1:
- pkgs = ("package %s is vulnerable"
- % unstable_packages[0])
- else:
- pkgs = ("packages %s are vulnerable"
- % ', '.join(unstable_packages))
- c.execute("""INSERT INTO bug_status
- (bug_name, release, status, reason)
- VALUES (?, 'unstable', 'vulnerable', ?)""",
- (bug_name, pkgs))
- else:
- c.execute("""INSERT INTO bug_status
- (bug_name, release, status, reason)
- VALUES (?, 'unstable', 'fixed',
- 'not known to be vulnerable')""",
- (bug_name,))
- handle_unstable()
+ def _calcUnstable(self, cursor, bug_name):
+ """Update bug_status with bug_name for unstable."""
+
+ vulnerable_packages = []
+ for (package,) in cursor.execute(
+ """SELECT DISTINCT sp.name
+ FROM package_notes AS n,
+ source_package_status AS st, source_packages AS sp
+ WHERE n.bug_name = ? AND n.urgency <> 'unimportant'
+ AND n.release = ''
+ AND st.note = n.id AND st.vulnerable
+ AND sp.rowid = st.package AND sp.release = 'sid'
+ ORDER BY sp.name""",
+ (bug_name,)):
+ vulnerable_packages.append(package)
- # The algorith below roughly proceeds as follows:
- #
- # For each package:
- # Is this package in testing/unstable? If not, exit.
- #
- # Differentiate between the following cases:
- # For all architectures with security support, the
- # package in testing is not vulnerable (fully fixed)
- #
- # For all architectures with security support, the
- # package is not vulnerable in testing or
- # testing-security, and there exists a package (on a
- # security support architecture) which is vulnerable
- # in testing (partially fixed)
- #
- # There exists an architecture with security support
- # where the package is fixed in testing, and there
- # exists a non-vulnerable architecture in testing
- # (should not happen, partially-fixed)
- #
- # Same as the preceding case, but including
- # test-security; this can actually happen
- # (partially-fixed, secure-testing is out-of-date on
- # some architectures)
- #
- # There exists an architecture with security support
- # where the package is fixed in unstable, and all
- # packages in testing are vulnerable, and the
- # package is in testing (fixed in unstable)
- #
- # For some supported architecture the package is in
- # testing, and vulnerable. It is
- #
- # The package is not in testing on any supported
- # architecture,
- #
- # At least this is the plan. The code below probably does
- # something slightly different. 8-(
+ if vulnerable_packages:
+ if len(vulnerable_packages) == 1:
+ pkgs = "package %s is vulnerable" % vulnerable_packages[0]
+ else:
+ pkgs = ("packages %s are vulnerable"
+ % ', '.join(vulnerable_packages))
+ cursor.execute("""INSERT INTO bug_status
+ (bug_name, release, status, reason)
+ VALUES (?, 'unstable', 'vulnerable', ?)""",
+ (bug_name, pkgs))
+ else:
+ cursor.execute("""INSERT INTO bug_status
+ (bug_name, release, status, reason)
+ VALUES (?, 'unstable', 'fixed',
+ 'not known to be vulnerable')""",
+ (bug_name,))
- available_archs = {}
- vulnerable_in_other = {}
- vulnerable_in_testing = {}
- fixed_in_testing = {}
- fixed_in_security = {}
+ def _calcTesting(self, cursor, bug_name):
+ """Update bug_status with bug_name for unstable."""
- def record_archs_per_package(dict, pkg, archs):
- if not dict.has_key(pkg):
- dict[pkg] = {}
- for arch in archs.split(','):
- dict[pkg][arch] = True
-
- for (pkg_name, release, subrelease, archs, vulnerable) \
- in c.execute(
- """SELECT DISTINCT
- p.name, p.release, p.subrelease, p.archs, vulnerable
- FROM binary_package_status AS s, binary_packages AS p
- WHERE s.bug_name = ? AND p.rowid = s.package""", (bug_name,)):
- if not binary_packages_in_testing.has_key(pkg_name):
- continue
+ # Note that there is at most one source package per
+ # note/release/subrelease triple, but we should check that
+ # here. (A separate test is needed.)
- record_archs_per_package(available_archs, pkg_name, archs)
+ status = {'' : {}, 'security' : {}}
+ for (package, note, subrelease, vulnerable) in cursor.execute(
+ """SELECT DISTINCT sp.name, n.id, sp.subrelease,
+ st.vulnerable
+ FROM package_notes AS n,
+ source_package_status AS st, source_packages AS sp
+ WHERE n.bug_name = ? AND n.urgency <> 'unimportant'
+ AND st.note = n.id
+ AND sp.rowid = st.package AND sp.release = 'etch'
+ AND sp.subrelease IN ('', 'security')
+ ORDER BY sp.name""",
+ (bug_name,)):
+ status[subrelease][(package, note)] = vulnerable
- if release == 'etch':
- if vulnerable:
- record_archs_per_package(vulnerable_in_testing,
- pkg_name, archs)
- else:
- if subrelease == '':
- record_archs_per_package(fixed_in_testing,
- pkg_name, archs)
- record_archs_per_package(fixed_in_security,
- pkg_name, archs)
- elif subrelease == 'security':
- record_archs_per_package(fixed_in_security,
- pkg_name, archs)
- elif vulnerable:
- record_archs_per_package(vulnerable_in_other,
- pkg_name, archs)
+ # Check if any packages in plain testing are vulnerable, and
+ # if all of those have been fixed in the security archive.
+ fixed_in_security = True
+ pkgs = {}
+ for ((package, note), vulnerable) in status[''].items():
+ if vulnerable:
+ pkgs[package] = True
+ if status['security'].get((package, note), True):
+ fixed_in_security = False
- def record(status, reason):
- if status <> 'vulnerable':
- ((has_todo,),) = c.execute(
- """SELECT EXISTS (SELECT * FROM bugs_notes
- WHERE bug_name = ? AND typ = 'TODO')""",
- (bug_name,))
- if has_todo:
- status = 'todo'
- reason = 'see notes below'
-
- c.execute(
- """INSERT INTO bug_status
- (bug_name, release, status, reason)
- VALUES (?, 'testing', ?, ?)""",
- (bug_name, status, reason))
+ pkgs = pkgs.keys()
+ pkgs.sort()
+ if len(pkgs) == 0:
+ if len(status[''].keys()) == 0:
+ msg = "not known to be vulnerable"
+ else:
+ msg = "not vulnerable"
+ cursor.execute("""INSERT INTO bug_status
+ (bug_name, release, status, reason)
+ VALUES (?, 'testing', 'fixed', ?)""",
+ (bug_name, msg))
+ return
- if len(available_archs.keys()) == 0:
- record('fixed',
- 'package(s) neither in testing nor in unstable')
- continue
+ if len(pkgs) == 1:
+ pkgs = "package " + pkgs[0] + " is "
+ else:
+ pkgs = "packages " + ", ".join(pkgs) + " are "
+ if fixed_in_security:
+ pkgs += "fixed in testing-security"
+ status = "partially-fixed"
+ else:
+ pkgs += "vulnerable"
+ status = "vulnerable"
- totally_unfixed_packages = []
- testing_missing_archs = {}
- security_missing_archs = {}
- for (pkg_name, archs) in vulnerable_in_other.items():
- fixed_somewhere = False
- for arch in archs.keys():
- if fixed_in_testing.get(pkg_name, {}).has_key(arch):
- fixed_somewhere = True
- else:
- testing_missing_archs[arch] = True
- if fixed_in_security.get(pkg_name, {}).has_key(arch):
- fixed_somewhere = True
- else:
- security_missing_archs[arch] = True
- if not fixed_somewhere:
- totally_unfixed_packages.append(pkg_name)
-
- if totally_unfixed_packages:
- totally_unfixed_packages.sort()
- if len(totally_unfixed_packages) == 1:
- record('vulnerable', 'package %s is vulnerable'
- % totally_unfixed_packages[0])
- else:
- record('vulnerable', 'packages %s are vulnerable'
- % ', '.join(totally_unfixed_packages))
- continue
+ cursor.execute("""INSERT INTO bug_status
+ (bug_name, release, status, reason)
+ VALUES (?, 'testing', ?, ?)""",
+ (bug_name, status, pkgs))
- if security_missing_archs.keys():
- record('partially-fixed',
- 'fixed via testing-security, '
- + 'but architectures out of date: '
- + ', '.join(security_missing_archs.keys()))
- continue
-
- if testing_missing_archs.keys():
- record('partially-fixed', 'fixed in testing-security')
- continue
-
- record('fixed', 'packages are not vulnerable')
-
- return result
-
def getSourcePackageVersions(self, cursor, pkg):
"""A generator which returns tuples (RELEASE-LIST, VERSION),
the available versions of the source package pkg."""
More information about the Secure-testing-commits
mailing list