[Secure-testing-commits] r2225 - bin

Florian Weimer fw at costa.debian.org
Thu Sep 29 12:40:29 UTC 2005


Author: fw
Date: 2005-09-29 12:40:28 +0000 (Thu, 29 Sep 2005)
New Revision: 2225

Added:
   bin/tracker.cgi
Log:
Commit the tracker.cgi Python script.

Sorry, this script is a complete mess. 8-(


Added: bin/tracker.cgi
===================================================================
--- bin/tracker.cgi	2005-09-29 12:39:03 UTC (rev 2224)
+++ bin/tracker.cgi	2005-09-29 12:40:28 UTC (rev 2225)
@@ -0,0 +1,986 @@
+#!/usr/bin/python
+
+import cgi
+import cgitb
+cgitb.enable()                          # FIXME for production use
+
+import sys
+sys.path.insert(0,'../lib/python')
+
+import os
+import re
+import string
+import types
+import urllib
+
+import security_db
+import bugs
+
+def print_header(status):
+    print "Content-Type: text/html"
+    print "Status:", status
+    print ""
+
+def print_title(title, status=200, selectSearch=False):
+    print_header(status)
+    title = cgi.escape(title)
+    print '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
+    print '''<html><head>
+<style type="text/css">
+h1 { font-size : 144%; }
+h2 { font-size : 120%; }
+h3 { font-size : 100%; }
+
+table { padding-left : 1.5em }
+td, th { text-align : left; 
+	 padding-left : 0.25em;
+         padding-right : 0.25em; }
+td { vertical-align: baseline }
+span.red { color: red; }
+span.dangerous { color: rgb(191,127,0); }
+</style>
+
+<script type="text/javascript" language="JavaScript">
+var old_query_value = "";
+
+function onLoad() {
+'''
+    if selectSearch:
+        print ' document.searchForm.query.focus();'
+
+    print '''}
+
+function onSearch(query) {
+  if (old_query_value == "") {
+    if (query.length > 5) {
+      old_query_value = query;
+      document.searchForm.submit();
+    } else {
+      old_query_value = query;
+    }
+  }
+}
+</script>
+'''
+    print '<title>%s</title></head><body onload="onLoad()"><h1>%s</h1>' \
+          % (title, title)
+
+def print_footer(withSearch=True):
+    print "<hr/>"
+    if withSearch:
+        print_paragraph(make_search())
+
+    print_paragraph(make_a(url_from_rel(""), "Home"),
+                    " - ", make_a("http://secure-testing.debian.net",
+                                  "Testing Security Team"),
+                    " - ", make_a("http://www.debian.org/security/",
+                                  "Debian Security"),
+                    " - ", make_a("http://www.enyo.de/fw/impressum.html",
+                                  "Imprint"))
+    print "</body></html>"
+
+class NoEscape:
+    """Prevent escaping of HTML text."""
+    def __init__(self, data):
+        self.data = data
+    def __repr__(self):
+        return "NoEscape(%s)" % `self.data`
+
+def escape(data):
+    if type(data) == types.StringType:
+        return cgi.escape(data)
+    assert type(data) == types.InstanceType, type(data)
+    assert data.__class__ == NoEscape, data.__class__
+    return data.data
+
+def print_error(msg):
+    msg = escape(msg)
+    print "<p><b>ERROR:</b> %s</p>" % msg
+    print '<p>Please contact <a href="mailto:fw at deneb.enyo.de">Florian Weimer</a> and report this problem.</p>'
+
+try:
+    path_info = os.environ['PATH_INFO']
+except KeyError:
+    path_info = ''
+
+try:
+    server_name = os.environ['SERVER_NAME']
+except KeyError:
+    server_name = 'localhost'
+
+try:
+    script_name = cgi.escape(os.environ['SCRIPT_NAME'])
+except KeyError:
+    script_name = ''
+while script_name[0:2] == '//':
+    script_name = script_name[1:]
+
+def print_no_results(query):
+    print_title("No results", status=404)
+    print_error(NoEscape('Your query "<code>%s</code>" matched no results.'
+                         % cgi.escape(query)))
+    print_footer()
+
+def print_invalid_query():
+    print_title("Invalid query", status=404)
+    print_error("The URL you specified is incorrect for this application.")
+    print_footer()
+
+def print_table(gen, caption=(), replacement='', introduction='', style=None):
+    w = sys.stdout.write
+    if style:
+        style = ' class="%s"' % escape(style)
+    else:
+        style = ''
+
+    first_row = True
+    for row in gen:
+        if first_row:
+            w(escape(introduction))
+            if style:
+                w('<table%s>' % style)
+            else:
+                w('<table>')
+            if caption:
+                w('<tr%s>' % style)
+                for c in caption:
+                    w('<th%s>' % style)
+                    w(escape(c))
+                    w('</th>')
+                w('</tr>\n')
+            first_row = False
+        w("<tr>")
+        for col in row:
+            w("<td%s>" % style)
+            w(escape(col))
+            w("</td>")
+        w("</tr>\n")
+    if first_row:
+        if replacement:
+            w(escape(replacement))
+    else:
+        w("</table>\n")
+
+def print_escaped(*args):
+    for x in args:
+        sys.stdout.write(escape(x))
+def print_paragraph(*args):
+    sys.stdout.write('<p>')
+    apply(print_escaped, args)
+    sys.stdout.write('</p>\n')
+
+def make_bold(s):
+    return NoEscape("<b>%s</b>" % escape(s))
+def make_code(s):
+    return NoEscape("<code>%s</code>" % escape(s))
+def make_red(s):
+    return NoEscape('<span class="red">%s</span>' % escape(s))
+def make_dangerous(s):
+    return NoEscape('<span class="dangerous">%s</span>' % escape(s))
+def url_from_rel(x, full=False):
+    if full:
+        return "http://%s%s/%s" % (server_name, script_name, x)
+    else:
+        return "%s/%s" % (script_name, x)
+url_known_bug = url_from_rel
+    
+def url_source_package(p, full=False):
+    return url_from_rel("source-package/" + p, full)
+def url_binary_package(p, full=False):
+    return url_from_rel("binary-package/" + p, full)
+
+def make_xref(x):
+    url = escape(url_known_bug(x))
+    return NoEscape('<a href="%s">%s</a>' % (url, escape(x)))
+def make_cve_xref(cve, name=None):
+    cve = escape(cve)
+    if name is None:
+        name = cve
+    else:
+        name = escape(name)
+    return NoEscape('<a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=%s">%s</a>' % (cve, name))
+
+def make_dsa_xref(cursor, dsa, name,
+                  re_dsa=re.compile(r'^DSA-(\d+)(?:-\d+)?$')):
+    match = re_dsa.match(dsa)
+    if name is None:
+        name = dsa
+    else:
+        name = escape(name)
+    if match:
+        # We must determine the year because there is no generic URL.
+        (number,) = match.groups()
+        for (date,) in cursor.execute(
+            "SELECT release_date FROM bugs WHERE name = ?", (dsa,)):
+            (y, m, d) = date.split('-')
+            return NoEscape('<a href="http://www.debian.org/security/%d/dsa-%d">%s</a>'
+                            % (int(y), int(number), name))
+
+    return escape(dsa)
+    
+    
+def url_debian_bug(bug):
+    return "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%d" % bug
+def url_debian_bug_pkg(pkg):
+    return ("http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg="
+            + urllib.quote(pkg))
+
+def make_debian_bug(bug, internal=False):
+    if internal:
+        assert False
+    return NoEscape('<a href="%s">%d</a>' % (url_debian_bug(bug), bug))
+
+def url_pts(src):
+    return "http://packages.qa.debian.org/common/index.html?src=" \
+           + urllib.quote(src)
+
+def url_testing_status(src):
+    return "http://bjorn.haxx.se/debian/testing.pl?package=" \
+           + urllib.quote(src)
+
+def make_a(url, text):
+    return NoEscape('<a href="%s">%s</a>' % (escape(url), escape(text)))
+def make_pts_ref(pkg, title=None):
+    if title is None:
+        title = pkg
+    return make_a(url_pts(pkg), title)
+
+def make_source_package_ref(pkg, title=None):
+    if title is None:
+        title = pkg
+    return make_a(url_source_package(pkg), title)
+def make_binary_package_ref(pkg, title=None):
+    if title is None:
+        title = pkg
+    return make_a(url_binary_package(pkg), title)
+def make_binary_packages_ref(lst):
+    assert type(lst) <> types.StringType
+    return make_list(map(make_binary_package_ref, lst))
+
+def make_list(lst, separator=NoEscape(", ")):
+    assert type(lst) <> types.StringType
+    return NoEscape(escape(separator).join(map(escape, lst)))
+
+def make_search():
+    return NoEscape(\
+        ('<form name="searchForm" method="get" action="%s">'
+         % escape(url_from_rel('search/')))
+        + 'Search for package or bug name: '
+        + '<input type="text" name="query" onkeyup="onSearch(this.value)"'
+        + 'onmousemove="onSearch(this.value)"> '
+        + '<input type="submit" value="Go"/></form>')
+    
+def print_bug(bug, db):
+    print_title(bug.name)
+
+    cursor = db.cursor()
+
+    def gen_header():
+        yield make_bold("Name"), bug.name
+
+        source = bug.name.split('-')[0]
+        if source in ('CAN', 'CVE'):
+            source_xref = make_cve_xref(bug.name, 'CVE')
+        elif source == 'DSA':
+            source_xref = make_dsa_xref(cursor, bug.name, 'Debian')
+        elif source == 'DTSA':
+            source_xref = 'Debian Testing Security Team'
+        elif source == 'FAKE':
+            source_xref = 'Automatically generated temporary name.  Not for external reference.'
+        else:
+            source_xref = None
+
+        if source_xref:
+            yield make_bold("Source"), source_xref
+        
+        if bug.description:
+            yield make_bold("Description"), bug.description
+
+        xref = list(db.getBugXrefs(cursor, bug.name))
+        if xref:
+            yield make_bold("References"), make_list(map(make_xref, xref))
+            
+        debian_bugs = bug.getDebianBugs(cursor)
+        if debian_bugs:
+            yield (make_bold("Debian Bugs"),
+                   make_list(map(make_debian_bug, debian_bugs)))
+
+        if bug.not_for_us:
+            yield make_bold("Status"), "Debian is not affected"
+        else:
+            for (release, status, reason) in bug.getStatus(cursor):
+                if status <> 'fixed':
+                    reason = make_red(reason)
+                yield make_bold('Status of %s' % release), reason
+
+    print_table(gen_header())
+
+    if bug.notes:
+        print """<h2>Vulnerable and fixed packages</h2>
+<p>The table below lists information on <em>source packages</em>.</p>
+"""
+
+        def gen_source():
+            yield (make_bold("Source Package"),
+                   make_bold("Release"),
+                   make_bold("Version"),
+                   make_bold("Status"))
+
+            old_pkg = ''
+            for (package, release, version, vulnerable) \
+                    in db.getSourcePackages(cursor, bug.name):
+                if package == old_pkg:
+                    package = ''
+                else:
+                    old_pkg = package
+                    package = NoEscape("%s (%s)"
+                        % (escape(make_source_package_ref(package)),
+                           escape(make_pts_ref(package, 'PTS'))))
+                if vulnerable:
+                    vuln = make_red('vulnerable')
+                    version = make_red(version)
+                else:
+                    vuln = 'fixed'
+                    
+                yield package, ', '.join(release), version, vuln
+                
+        print_table(gen_source())
+
+        print "<p>The next table lists affected <em>binary packages</em>.<p>"
+
+        def gen_binary():
+            yield (make_bold("Binary Package"),
+                   make_bold("Release"),
+                   make_bold("Version"),
+                   make_bold("Status"),
+                   make_bold("Arch"))
+
+            old_pkg = ''
+            for (packages, releases, version, archs, vulnerable) \
+                in db.getBinaryPackages(cursor, bug.name):
+                pkg = ', '.join(packages)
+                if pkg == old_pkg:
+                    packages = ''
+                else:
+                    old_pkg = pkg
+                    packages = make_binary_packages_ref(packages)
+                    
+                if vulnerable:
+                    vuln = make_red('vulnerable')
+                    version = make_red(version)
+                else:
+                    vuln = 'fixed'
+                yield (packages,
+                       ', '.join(releases),
+                       version, vuln,
+                       ', '.join(archs))
+
+        print_table(gen_binary())
+            
+
+        print """<p>The information above is based on the following
+data on fixed versions.</p>"""
+
+        def gen_data():
+            yield ()
+
+            notes_sorted = bug.notes[:]
+            notes_sorted.sort(lambda a, b: cmp(a.package, b.package))
+            for n in notes_sorted:
+                if n.release:
+                    rel = str(n.release)
+                else:
+                    rel = '(unstable)'
+                urgency = str(n.urgency)
+                if n.fixed_version:
+                    ver = str(n.fixed_version)
+                    if ver == '0':
+                        ver = '(not affected)'
+                        urgency = ''
+                else:
+                    ver = make_red('(unfixed)')
+
+                pkg = n.package
+                pkg_kind = n.package_kind
+                if pkg_kind == 'source':
+                    pkg = make_source_package_ref(pkg)
+                elif pkg_kind == 'binary':
+                    pkg = make_binary_package_ref(pkg)
+                elif pkg_kind == 'itp':
+                    pkg_kind = 'ITP'
+                    rel = ''
+                    ver = ''
+                    urgency = ''
+                
+                bugs = n.bugs
+                bugs.sort()
+                bugs = make_list(map(make_debian_bug, bugs))
+                if n.bug_origin:
+                    origin = make_xref(n.bug_origin)
+                else:
+                    origin = ''
+                yield (pkg, pkg_kind, rel, ver, urgency, origin, bugs)
+
+        print_table(gen_data(),
+                    caption=("Package", "Type", "Release", "Fixed Version",
+                             "Urgency", "Origin", "Debian Bugs"))
+
+    if bug.comments:
+        print "<h2>Notes</h2>"
+        print "<pre>"
+        for (t, c) in bug.comments:
+            print escape(c)
+        print "</pre>"
+
+    print_footer()
+
+def print_debian_bug(db, bug, buglist):
+    print_title("Information related to Debian Bug #%d" % bug)
+
+    print_paragraph("The following issues reference to Debian bug ",
+                    make_debian_bug(bug), ":")
+
+    def gen():
+        yield make_bold("Name"), make_bold("Urgency"), make_bold("Description")
+
+        for (name, urgency, description) in buglist:
+            yield make_xref(name), urgency, description
+
+    print_table(gen())
+    print_footer()
+
+def handle_simple_search(query):
+    db = security_db.DB('../data/security.db')
+    c = db.cursor()
+    if 'A' <= query[0] <= 'Z':
+        try:
+            bug = bugs.BugFromDB(c, query)
+        except ValueError:
+            print_no_results(query)
+            return
+
+        if bug.name <> query:
+            # Bug name was normalized, perform redirect so that the
+            # browser sees the normalized URL.
+            print "Location:", url_from_rel(bug.name, full=True)
+            print
+            return
+        
+        print_bug(bug, db)
+        return
+    
+    elif db.isSourcePackage(c, query):
+        print "Location:", url_source_package(query, full=True)
+        print
+        return
+
+    elif db.isBinaryPackage(c, query):
+        print "Location:", url_binary_package(query, full=True)
+        print
+        return
+        
+    elif '0' <= query[0] <= '9':
+        # Debian bug number.
+        if query[-6:] == '_REDIR':
+            query = query[:-6]
+            redirect = True
+        else:
+            redirect = False
+
+        bugnumber = 0
+        try:
+            bugnumber = int(query)
+        except ValueError:
+            pass
+        if bugnumber:
+            buglist = list(db.getBugsFromDebianBug(c, bugnumber))
+            if buglist:
+                if len(buglist) == 1:
+                    # Single issue, redirect.
+                    print "Location:", url_known_bug(buglist[0][0], full=True)
+                    print
+                    return
+                else:
+                    print_debian_bug(c, bugnumber, buglist)
+                    return
+            elif redirect:
+                print "Location:", url_debian_bug(bugnumber)
+                print
+                return
+    print_no_results(query)
+
+def print_source_package(pkg):
+    db = security_db.DB('../data/security.db')
+    c = db.cursor()
+
+    print_title("Information on source package " + pkg)
+
+    print_menu([(url_pts(pkg),
+                 pkg + ' in the Package Tracking System'),
+                (url_debian_bug_pkg(pkg),
+                 pkg + ' in the Bug Tracking System'),
+                (url_testing_status(pkg),
+                 pkg + ' in the testing migration checker')],
+               relative=False)
+
+    print "<h2>Available versions</h2>"
+
+    def gen_versions():
+        yield make_bold("Release"), make_bold("Version")
+        for (releases, version) in db.getSourcePackageVersions(c, pkg):
+            yield ', '.join(releases), version
+    print_table(gen_versions())
+
+    print "<h2>Available binary packages</h2>"
+    
+    def gen_binary():
+        for (packages, releases, archs, version) \
+                in db.getBinaryPackagesForSource(c, pkg):
+            yield (make_binary_packages_ref(packages),
+                   ', '.join(releases), version, ', '.join(archs))
+    print_table(gen_binary(),
+        caption=('Package', 'Release', 'Version', 'Architectures'),
+        replacement=('No binary packages are recorded in this database. '
+                     + 'This probably means that the package is '
+                     + 'architecture-specific, and the architecture '
+                     + 'is currently not tracked.'))
+
+    print "<h2>Open issues</h2>"
+
+    def gen_bug_list(lst):
+        for (bug, description) in lst:
+            yield make_xref(bug), description
+    print_table(gen_bug_list(db.getBugsForSourcePackage(c, pkg, True)),
+                caption=('Bug', 'Description'),
+                replacement='No known open issues.')
+            
+    print "<h2>Resolved issues</h2>"
+
+    print_table(gen_bug_list(db.getBugsForSourcePackage(c, pkg, False)),
+                caption=('Bug', 'Description'),
+                replacement='No known resolved issues.')
+
+    print_footer()
+
+def print_binary_package(pkg):
+    db = security_db.DB('../data/security.db')
+    c = db.cursor()
+
+    print_title("Information on binary package " + pkg)
+
+    print_menu([(url_debian_bug_pkg(pkg),
+                 pkg + ' in the Bug Tracking System')],
+               relative=False)
+    print "<h2>Available versions</h2>"
+
+    def gen_versions():
+        # FIXME: We should include the source package name in this list.
+        yield ()
+        for (releases, source, version, archs) \
+                in db.getBinaryPackageVersions(c, pkg):
+            yield (', '.join(releases), make_source_package_ref(source),
+                   version, ', '.join(archs))
+    print_table(gen_versions(),
+                caption=("Release", "Source", "Version", "Architectures"))
+
+    print "<h2>Open issues</h2>"
+
+    def gen_bug_list(lst):
+        for (bug, description) in lst:
+            yield make_xref(bug), description
+    print_table(gen_bug_list(db.getBugsForBinaryPackage(c, pkg, True)),
+                caption=('Bug', 'Description'),
+                replacement='No known open issues.')
+            
+    print "<h2>Resolved issues</h2>"
+
+    print_table(gen_bug_list(db.getBugsForBinaryPackage(c, pkg, False)),
+                caption=('Bug', 'Description'),
+                replacement='No known resolved issues.')
+
+    print "<h2>Non-issues</h2>"
+
+    print_table(gen_bug_list(db.getNonBugsForBinaryPackage(c, pkg)),
+                 caption=('Bug', 'Description'),
+                 replacement=('No known issues which do not affect '
+                              + 'this package.'))
+    
+    print_footer()
+
+def print_todo():
+    db = security_db.DB('../data/security.db')
+    print_title("Bugs with TODO items")
+
+    def gen():
+        yield make_bold("Bug"), make_bold("Description")
+        for (bug, description) in db.getTODOs():
+            yield make_xref(bug), description
+    print_table(gen())
+
+    print_footer()
+
+def print_menu(entries,relative=True):
+    w = sys.stdout.write
+    w("<ul>")
+    for e in entries:
+        w("<li>")
+        if type(e) == types.TupleType:
+            (relurl, label) = e
+            if relative:
+                relurl = url_from_rel(relurl)
+            sys.stdout.write(escape(make_a(relurl, label)))
+        else:
+            w(escape(e))
+        w("</li>\n")
+    w("</ul>\n")
+
+def print_overview():
+    print_title("Security issue tracker", selectSearch=True)
+
+    print """<p>This is the experimental issue tracker for Debian's testing
+security team.  Keep in mind that this is merely a prototype.
+Please report any problems to <a href="mailto:fw at deneb.enyo.de">Florian
+Weimer</a>.  Note that some of the data presented here is known
+to be wrong (see below), but the data for the testing suite
+should be fine.
+</p>
+
+<h2>Starting points</h2>
+"""
+
+    print_menu([('status/release/testing',
+                 'Vulnerable packages in the testing suite'),
+                ('status/release/unstable',
+                 'Vulnerable packages in the unstable suite'),
+                ('status/dtsa-candidates', "Candidates for DTSAs"),
+                ('status/todo', 'TODO items'),
+                ('status/itp', 'ITPs with potential security issues'),
+                ('data/unknown-packages',
+                 'Packages names not found in the archive'),
+                ('data/funny-versions',
+                 'Packages with strange version numbers'),
+                ('data/releases',
+                 'Covered Debian releases and architectures (slow)'),
+                make_search()])
+
+    print """<h2>A few notes on data sources</h2>
+
+<p>Data in this tracker comes solely from the bug database
+which is maintained by Debian's testing security team in their
+Subversion repository.  All external data (this includes
+Debian bug reports and official Debian security advisories)
+must be added to this database before it appears here, and there
+can be some delay before this happens.
+</p>
+
+<p>At the moment, the database only contains information which is
+relevant for tracking the security status of the testing suite.
+This means that data for stable or oldstable is likely wrong.
+The unstable suite should be covered pretty well, though,
+because it is relevant to the status of testing.
+</p>
+"""
+    print_footer(withSearch = False)
+
+def handle_cmd(cmd, arg):
+    if cmd == 'source-package':
+        print_source_package(arg)
+        sys.exit(0)
+    elif cmd == 'binary-package':
+        print_binary_package(arg)
+        sys.exit(0)
+
+if path_info in ('', '/'):
+    print_overview()
+    sys.exit(0)
+
+re_query = re.compile(r'^/([a-zA-Z0-9_.-]+)$')
+match = re_query.match(path_info)
+if match is None:
+    cmd_list = path_info.split('/')
+    if len(cmd_list) == 3:
+        handle_cmd(cmd_list[1], cmd_list[2])
+        # fall-through if not handled
+    
+    def print_releases():
+        db = security_db.DB('../data/security.db')
+        
+        print_title("Available releases")
+
+        print """<p>The security issue database is checked against
+the Debian releases listed in the table below.  Currently, space
+and processing resources are limited, so the list of architectures
+is incomplete.
+</p>"""
+
+        def gen():
+            yield (make_bold("Release"),
+                   make_bold("Subrelease"),
+                   make_bold("Archive"),
+                   make_bold("Sources"),
+                   make_bold("Architectures"))
+            for (rel, subrel, archive, sources, archs) \
+                    in db.availableReleases():
+                if sources:
+                    sources = 'yes'
+                else:
+                    sources = 'no'
+                yield rel, subrel, archive, sources, make_list(archs)
+
+        print_table(gen())
+        print_footer()
+
+    def print_funny_versions():
+        db = security_db.DB('../data/security.db')
+        print_title("Version conflicts between source/binary packages")
+        
+        print """<p>The table below lists source packages
+which have a binary package of the same name, but with a different
+version.  This means that extra care is necessary to determine
+the version of a package which has been fixed.  (Note that
+the bug tracker prefers source versions to binary versions
+in this case.)
+</p>"""
+        def gen():
+            yield (make_bold("Package"),
+                   make_bold("Release"), 
+                   make_bold("Archive"),
+                   make_bold("Source Version"),
+                   make_bold("Binary Version"))
+
+            for name, release, archive, version, source_version \
+                in db.getFunnyPackageVersions():
+                yield name, release, archive, source_version, version
+
+        print_table(gen())
+
+        print """<p>Technically speaking, these version numbering is fine,
+but it makes version-based bug tracking quite difficult for these packages.
+</p>
+
+<p>There are many binary packages which are built from source packages
+with different version numbering schemes.  However, as long as none of
+the binary packages carries the same name as the source package, most
+confusion is avoided or can be easily explained.</p>"""        
+        
+        print_footer()
+
+    def print_unknown_packages():
+        db = security_db.DB('../data/security.db')
+        print_title("Unknown packages")
+
+        print_paragraph("Sometimes, a package referenced in a bug report ",
+                        "cannot be found in the database.  This can be ",
+                        "the result of a spelling error, or a historic ",
+                        "entry refers to a package which is no longer in ",
+                        "the archive.")
+                        
+        def gen():
+            for name, bugs in db.getUnknownPackages(db.cursor()):
+                yield name, make_list(map(make_xref, bugs))
+
+        print_table(gen(), caption=("Package", "Bugs"),
+            replacement="No unknown packages are referenced in the database.")
+
+        print_footer()
+
+    def print_itp():
+        db = security_db.DB('../data/security.db')
+        print_title("ITPs with potential security issues")
+
+        def gen():
+            old_pkg = ''
+            for pkg, bugs, debian_bugs in db.getITPs(db.cursor()):
+                if pkg == old_pkg:
+                    pkg = ''
+                else:
+                    old_pkg = pkg
+                yield (pkg,
+                       make_list(map(make_xref, bugs)),
+                       make_list(map(make_debian_bug, debian_bugs)))
+
+        print_table(gen(), caption=("Package", "Issue", "Debian Bugs"),
+            replacement="No ITPs are currently known.")
+
+        print_footer()
+
+    def print_testing_status():
+        db = security_db.DB('../data/security.db')
+
+        print_title("Vulnerable source packages in testing")
+
+        print_menu([("status/dtsa-candidates", "Candidates for DTSAs")])
+
+        def gen():
+            yield (make_bold("Package"),
+                   make_bold("Bug"))
+
+            c = db.cursor()
+
+            old_pkg_name = ''
+            for (pkg_name, bug_name, archive, urgency,
+                 sid_vulnerable, ts_fixed) in db.cursor().execute(
+                """SELECT package, bug, section, urgency, unstable_vulnerable,
+                testing_security_fixed
+                FROM testing_status"""):
+                if pkg_name == old_pkg_name:
+                    pkg_name = ''
+                else:
+                    old_pkg_name = pkg_name
+                    if archive <> 'main':
+                        pkg_name = "%s (%s)" % (pkg_name, archive)
+
+                if ts_fixed:
+                    status = 'fixed in testing-security'
+                else:
+                    if sid_vulnerable:
+                        status = make_red('unstable is vulnerable')
+                    else:
+                        status = make_dangerous('fixed in unstable')
+
+                if urgency == 'unknown':
+                    urgency = ''
+
+                yield pkg_name, make_xref(bug_name), urgency, status
+
+        print_table(gen())
+        
+        print_footer()
+    
+    def print_dtsa_candidates():
+        db = security_db.DB('../data/security.db')
+
+        print_title("Candidates for DTSAs")
+
+        print_paragraph("The table below lists packages which are fixed ",
+                        "in unstable, but unfixed in testing. ",
+                        "Use the testing migration tracker to find out ",
+                        "why they have not entered testing yet.")
+
+        print_menu([("status/release/testing",
+                     "List of vulnerable packages in testing")])
+
+        def gen():
+            old_pkg_name = ''
+            for (pkg_name, bug_name, archive, urgency, stable_later) \
+                    in db.cursor().execute(
+                """SELECT package, bug, section, urgency,
+                (SELECT testing.version_id < stable.version_id
+                 FROM source_packages AS testing, source_packages AS stable
+                 WHERE testing.name = testing_status.package
+                 AND testing.release = 'etch'
+                 AND testing.subrelease = ''
+                 AND testing.archive = testing_status.section
+                 AND stable.name = testing_status.package
+                 AND stable.release = 'sarge'
+                 AND stable.subrelease = 'security'
+                 AND stable.archive = testing_status.section)
+                FROM testing_status
+                WHERE (NOT unstable_vulnerable)
+                AND (NOT testing_security_fixed)"""):
+                if pkg_name == old_pkg_name:
+                    pkg_name = ''
+                    migration = ''
+                else:
+                    old_pkg_name = pkg_name
+                    migration = make_a(url_testing_status(pkg_name),
+                                       "check")
+                    if archive <> 'main':
+                        pkg_name = "%s (%s)" % (pkg_name, archive)
+                    else:
+                        pkg_name = make_source_package_ref(pkg_name)
+
+                if urgency == 'unknown':
+                    urgency = ''
+                elif urgency == 'high':
+                    urgency = make_red(urgency)
+
+                if stable_later:
+                    notes = "(fixed in stable?)"
+                else:
+                    notes = ''
+
+                yield pkg_name, migration, make_xref(bug_name), urgency, notes
+
+        print_table(gen(),
+                    caption=("Package", "Migration", "Bug", "Urgency"))
+        
+        print_footer()
+
+    def print_unstable_status():
+        db = security_db.DB('../data/security.db')
+
+        print_title("Vulnerable source packages in unstable")
+
+        print_paragraph(
+            "Note that the list below is based on source packages. ",
+            "This means that packages are not listed here once a new, ",
+            "fixed source version has been uploaded to the archive, even ",
+            "if there are still some vulnerably binary packages present ",
+            "in the archive.")
+
+        def gen():
+            c = db.cursor()
+
+            old_pkg_name = ''
+            for (pkg_name, bug_name, section, urgency) in db.cursor().execute(
+                """SELECT DISTINCT sp.name, st.bug_name,
+                sp.archive, st.urgency
+                FROM source_package_status AS st, source_packages AS sp
+                WHERE st.vulnerable AND st.urgency <> 'unimportant'
+                AND sp.rowid = st.package AND sp.release = 'sid'
+                AND sp.subrelease = ''
+                ORDER BY sp.name, st.bug_name"""):
+                if pkg_name == old_pkg_name:
+                    pkg_name = ''
+                else:
+                    old_pkg_name = pkg_name
+                    if section <> 'main':
+                        pkg_name = "%s (%s)" % (pkg_name, section)
+                    else:
+                        pkg_name = make_xref(pkg_name)
+
+                if urgency == 'unknown':
+                    urgency = ''
+                elif urgency == 'high':
+                    urgency = make_red(urgency)
+
+                yield pkg_name, make_xref(bug_name), urgency
+
+        print_table(gen(), caption=('Package', 'Bug', 'Urgency'))
+        
+        print_footer()
+    
+    def do_search():
+        form = cgi.FieldStorage()
+        query = form.getfirst("query", None)
+        if query is None:
+            # redirect to start page
+            print "Location:", url_from_rel("", full=True)
+            print
+        else:
+            re_simple_query = re.compile(r'^[A-Za-z0-9_.-]+$')
+            if re_simple_query.match(query):
+                print "Location:", url_from_rel(query, full=True)
+                print
+            else:
+                print_invalid_query()
+
+    commands = {'/data/releases' : print_releases,
+                '/data/funny-versions' : print_funny_versions,
+                '/data/unknown-packages' : print_unknown_packages,
+                '/status/release/testing' : print_testing_status,
+                '/status/release/unstable' : print_unstable_status,
+                '/status/todo' : print_todo,
+                '/status/dtsa-candidates' : print_dtsa_candidates,
+                '/status/itp' : print_itp,
+                '/search/' : do_search}
+    try:
+        cmd = commands[path_info]
+    except KeyError:
+        print_invalid_query()
+        cmd = None
+    if cmd:
+        cmd()
+else:
+    handle_simple_search(match.group(1))


Property changes on: bin/tracker.cgi
___________________________________________________________________
Name: svn:executable
   + *




More information about the Secure-testing-commits mailing list