diff options
author | Florian Weimer <fw@deneb.enyo.de> | 2005-12-15 11:37:40 +0000 |
---|---|---|
committer | Florian Weimer <fw@deneb.enyo.de> | 2005-12-15 11:37:40 +0000 |
commit | 6e7dd85627d85a0e545cbba99698d3a000daf8af (patch) | |
tree | 3b5224f58b2a846f0ab83004f6c30f0dfe9d7180 | |
parent | fcae623dfaf7f5c469d3ca89e9b9cbb34b37045c (diff) |
lib/python/security_db.py (DB):
Bump schema version.
(DB.initSchema):
Add debsecan_data table.
(DB.calculateDebsecan, DB.getDebsecan):
New methods.
bin/update-db:
Invoke calculateDebsecan.
bin/tracker_service.py (TrackerService):
Add support for debsecan/* pages.
(TrackerService.page_debsecan):
New method.
git-svn-id: svn+ssh://svn.debian.org/svn/secure-testing@3051 e39458fd-73e7-0310-bf30-c45bca0a0e42
-rw-r--r-- | bin/tracker_service.py | 12 | ||||
-rwxr-xr-x | bin/update-db | 7 | ||||
-rw-r--r-- | lib/python/security_db.py | 136 |
3 files changed, 153 insertions, 2 deletions
diff --git a/bin/tracker_service.py b/bin/tracker_service.py index 00c1c81ca9..44d8210c35 100644 --- a/bin/tracker_service.py +++ b/bin/tracker_service.py @@ -98,6 +98,7 @@ function onSearch(query) { self.register('data/releases', self.page_data_releases) self.register('data/funny-versions', self.page_data_funny_versions) self.register('data/fake-names', self.page_data_fake_names) + self.register('debsecan/**', self.page_debsecan) def page_home(self, path, params, url): query = params.get('query', ('',))[0] @@ -854,6 +855,17 @@ Debian bug number.'''), make_table(gen(), caption=("Bug", "Description"))]) + def page_debsecan(self, path, params, url): + obj = '/'.join(path) + data = self.db.getDebsecan(obj) + if data: + return BinaryResult(data) + else: + return self.create_page( + url, "Object not found", + [P("The requested debsecan object has not been found.")], + status=404) + def create_page(self, url, title, body, search_in_page=False, status=200): append = body.append append(HR()) diff --git a/bin/update-db b/bin/update-db index 8d22f696fc..71b79e457b 100755 --- a/bin/update-db +++ b/bin/update-db @@ -75,6 +75,11 @@ if warnings: print x sys.exit(1) +# debsecan data + +for release in ('', 'woody', 'sarge', 'etch'): + db.calculateDebsecan(release) + # Everything worked well. - + db.commit(cursor) diff --git a/lib/python/security_db.py b/lib/python/security_db.py index 4be0974173..af60d48017 100644 --- a/lib/python/security_db.py +++ b/lib/python/security_db.py @@ -27,6 +27,7 @@ FIXME: Document the database schema once it is finished. """ import apsw +import base64 import bugs import cPickle import cStringIO @@ -37,6 +38,7 @@ import os.path import re import sys import types +import zlib class InsertError(Exception): """Class for capturing insert errors. @@ -111,7 +113,7 @@ class DB: self.db = apsw.Connection(name) self.verbose = verbose - self.schema_version = 17 + self.schema_version = 18 self._initFunctions() c = self.cursor() @@ -309,6 +311,11 @@ class DB: loss_sec_prot_other INTEGER NOT NULL)""") cursor.execute( + """CREATE TABLE debsecan_data + (name TEXT NOT NULL PRIMARY KEY, + data TEXT NOT NULL)""") + + cursor.execute( """CREATE VIEW testing_status AS SELECT DISTINCT sp.name AS package, st.bug_name AS bug, sp.archive AS section, st.urgency AS urgency, @@ -1219,6 +1226,133 @@ class DB: VALUES (?, ?, ?, ?)""", (bug_name, suite, status, pkgs)) + def calculateDebsecan(self, release): + """Create data for the debsecan tool.""" + + c = self.cursor() + + c.execute("""CREATE TEMPORARY TABLE vulnlist ( + name TEXT NOT NULL, + package TEXT NOT NULL, + note INTEGER NOT NULL, + PRIMARY KEY (name, package) + )""") + + # Populate the table with the unstable vulnerabilities; + # override them with the release-specific status. + + c.execute("""INSERT INTO vulnlist + SELECT bug_name, package, id FROM package_notes WHERE release = ''""") + + if release: + c.execute("""INSERT OR REPLACE INTO vulnlist + SELECT bug_name, package, id FROM package_notes + WHERE release = ?""", (release,)) + + c.execute("""DELETE FROM vulnlist WHERE name LIKE 'FAKE-0000000-%'""") + + urgency_to_flag = {'low' : 'L', 'medium' : 'M', 'high' : 'H', + 'unknown' : ' '} + + result = ["VERSION 0\n"] + for (name, package, fixed_version, kind, urgency, remote, description, + note_id) in list(c.execute("""SELECT + vulnlist.name, vulnlist.package, + COALESCE(n.fixed_version, ''), + n.package_kind, n.urgency, + (SELECT range_remote FROM nvd_data + WHERE cve_name = vulnlist.name) AS remote, + bugs.description, + n.id + FROM vulnlist, bugs, package_notes AS n + WHERE bugs.name = vulnlist.name + AND n.id = vulnlist.note + ORDER BY vulnlist.package""")): + if fixed_version == '0' or urgency == 'unimportant' \ + or kind not in ('source', 'binary', 'unknown'): + continue + + # Normalize FAKE-* names a bit. The line number (which + # makes the name unique) is completely useless for the + # client. + + if name[0:5] == "FAKE-": + name = '-'.join(name.split('-')[0:2]) + + # Determine if a fix is available for the specific + # release. + + fix_available = ' ' + if release: + fix_available = ' ' + if kind == 'source': + fix_available_sql = """SELECT st.vulnerable + FROM source_packages AS p, source_package_status AS st + WHERE p.name = ? + AND p.release = ? + AND p.subrelease IN ('', 'security') + AND st.bug_name = ? + AND st.package = p.rowid + ORDER BY p.version COLLATE version DESC""" + elif kind == 'binary': + fix_available_sql = """SELECT st.vulnerable + FROM binary_packages AS p, binary_package_status AS st + WHERE p.name = ? + AND p.release = ? + AND p.subrelease IN ('', 'security') + AND st.bug_name = ? + AND st.package = p.rowid + ORDER BY p.version COLLATE version DESC""" + else: + fix_available_sql = '' + + if fix_available_sql: + for (v,) in c.execute(fix_available_sql, + (package, release, name)): + assert v is not None + if not v: + fix_available = 'F' + break + elif fixed_version <> '': + fix_available = 'F' + + if kind == 'source': + kind = 'S' + elif kind == 'binary': + kind = 'B' + else: + kind = ' ' + + if remote is None: + remote = '?' + elif remote: + remote = 'R' + else: + remote = ' ' + + result.append("%s,%c%c%c%c,%s,%s,%s\n" + % (name, + kind, urgency_to_flag[urgency], remote, + fix_available, + package, fixed_version, description)) + result = base64.encodestring(zlib.compress(''.join(result), 9)) + + if not release: + release = 'sid' + c.execute( + "INSERT OR REPLACE INTO debsecan_data (name, data) VALUES (?, ?)", + ('release/' + release, result)) + + c.execute("DROP TABLE vulnlist") + + def getDebsecan(self, name): + """Returns the debsecan data item NAME.""" + for (data,) in self.cursor().execute( + "SELECT data FROM debsecan_data WHERE name = ?", (name,)): + return base64.decodestring(data) + else: + return None + def replaceNVD(self, cursor, data): """Replaces the stored NVD data.""" cursor.execute("DELETE FROM nvd_data"); |