/[secure-testing]/bin/tracker.cgi
ViewVC logotype

Contents of /bin/tracker.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2240 - (hide annotations) (download)
Thu Sep 29 21:06:02 2005 UTC (7 years, 7 months ago) by fw
File size: 34722 byte(s)
Add tons of missing epochs in versions.

http://idssi.enyo.de/tracker/data/missing-epochs contains a list of
problematic source packages.  The remaining ones should be okay.
1 fw 2225 #!/usr/bin/python
2    
3     import cgi
4     import cgitb
5     cgitb.enable() # FIXME for production use
6    
7     import sys
8     sys.path.insert(0,'../lib/python')
9    
10     import os
11     import re
12     import string
13     import types
14     import urllib
15    
16     import security_db
17     import bugs
18    
19     def print_header(status):
20     print "Content-Type: text/html"
21     print "Status:", status
22     print ""
23    
24     def print_title(title, status=200, selectSearch=False):
25     print_header(status)
26     title = cgi.escape(title)
27     print '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
28     print '''<html><head>
29     <style type="text/css">
30     h1 { font-size : 144%; }
31     h2 { font-size : 120%; }
32     h3 { font-size : 100%; }
33    
34     table { padding-left : 1.5em }
35     td, th { text-align : left;
36     padding-left : 0.25em;
37     padding-right : 0.25em; }
38     td { vertical-align: baseline }
39     span.red { color: red; }
40     span.dangerous { color: rgb(191,127,0); }
41     </style>
42    
43     <script type="text/javascript" language="JavaScript">
44     var old_query_value = "";
45    
46     function onLoad() {
47     '''
48     if selectSearch:
49     print ' document.searchForm.query.focus();'
50    
51     print '''}
52    
53     function onSearch(query) {
54     if (old_query_value == "") {
55     if (query.length > 5) {
56     old_query_value = query;
57     document.searchForm.submit();
58     } else {
59     old_query_value = query;
60     }
61     }
62     }
63     </script>
64     '''
65     print '<title>%s</title></head><body onload="onLoad()"><h1>%s</h1>' \
66     % (title, title)
67    
68     def print_footer(withSearch=True):
69     print "<hr/>"
70     if withSearch:
71     print_paragraph(make_search())
72    
73     print_paragraph(make_a(url_from_rel(""), "Home"),
74     " - ", make_a("http://secure-testing.debian.net",
75     "Testing Security Team"),
76     " - ", make_a("http://www.debian.org/security/",
77     "Debian Security"),
78     " - ", make_a("http://www.enyo.de/fw/impressum.html",
79     "Imprint"))
80     print "</body></html>"
81    
82     class NoEscape:
83     """Prevent escaping of HTML text."""
84     def __init__(self, data):
85     self.data = data
86     def __repr__(self):
87     return "NoEscape(%s)" % `self.data`
88    
89     def escape(data):
90     if type(data) == types.StringType:
91     return cgi.escape(data)
92     assert type(data) == types.InstanceType, type(data)
93     assert data.__class__ == NoEscape, data.__class__
94     return data.data
95    
96     def print_error(msg):
97     msg = escape(msg)
98     print "<p><b>ERROR:</b> %s</p>" % msg
99     print '<p>Please contact <a href="mailto:fw@deneb.enyo.de">Florian Weimer</a> and report this problem.</p>'
100    
101     try:
102     path_info = os.environ['PATH_INFO']
103     except KeyError:
104     path_info = ''
105    
106     try:
107     server_name = os.environ['SERVER_NAME']
108     except KeyError:
109     server_name = 'localhost'
110    
111     try:
112     script_name = cgi.escape(os.environ['SCRIPT_NAME'])
113     except KeyError:
114     script_name = ''
115     while script_name[0:2] == '//':
116     script_name = script_name[1:]
117    
118     def print_no_results(query):
119     print_title("No results", status=404)
120     print_error(NoEscape('Your query "<code>%s</code>" matched no results.'
121     % cgi.escape(query)))
122     print_footer()
123    
124     def print_invalid_query():
125     print_title("Invalid query", status=404)
126     print_error("The URL you specified is incorrect for this application.")
127     print_footer()
128    
129     def print_table(gen, caption=(), replacement='', introduction='', style=None):
130     w = sys.stdout.write
131     if style:
132     style = ' class="%s"' % escape(style)
133     else:
134     style = ''
135    
136     first_row = True
137     for row in gen:
138     if first_row:
139     w(escape(introduction))
140     if style:
141     w('<table%s>' % style)
142     else:
143     w('<table>')
144     if caption:
145     w('<tr%s>' % style)
146     for c in caption:
147     w('<th%s>' % style)
148     w(escape(c))
149     w('</th>')
150     w('</tr>\n')
151     first_row = False
152     w("<tr>")
153     for col in row:
154     w("<td%s>" % style)
155     w(escape(col))
156     w("</td>")
157     w("</tr>\n")
158     if first_row:
159     if replacement:
160     w(escape(replacement))
161     else:
162     w("</table>\n")
163    
164     def print_escaped(*args):
165     for x in args:
166     sys.stdout.write(escape(x))
167     def print_paragraph(*args):
168     sys.stdout.write('<p>')
169     apply(print_escaped, args)
170     sys.stdout.write('</p>\n')
171    
172     def make_bold(s):
173     return NoEscape("<b>%s</b>" % escape(s))
174     def make_code(s):
175     return NoEscape("<code>%s</code>" % escape(s))
176     def make_red(s):
177     return NoEscape('<span class="red">%s</span>' % escape(s))
178     def make_dangerous(s):
179     return NoEscape('<span class="dangerous">%s</span>' % escape(s))
180     def url_from_rel(x, full=False):
181     if full:
182     return "http://%s%s/%s" % (server_name, script_name, x)
183     else:
184     return "%s/%s" % (script_name, x)
185     url_known_bug = url_from_rel
186    
187     def url_source_package(p, full=False):
188     return url_from_rel("source-package/" + p, full)
189     def url_binary_package(p, full=False):
190     return url_from_rel("binary-package/" + p, full)
191    
192     def make_xref(x):
193     url = escape(url_known_bug(x))
194     return NoEscape('<a href="%s">%s</a>' % (url, escape(x)))
195     def make_cve_xref(cve, name=None):
196     cve = escape(cve)
197     if name is None:
198     name = cve
199     else:
200     name = escape(name)
201     return NoEscape('<a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=%s">%s</a>' % (cve, name))
202    
203     def make_dsa_xref(cursor, dsa, name,
204     re_dsa=re.compile(r'^DSA-(\d+)(?:-\d+)?$')):
205     match = re_dsa.match(dsa)
206     if name is None:
207     name = dsa
208     else:
209     name = escape(name)
210     if match:
211     # We must determine the year because there is no generic URL.
212     (number,) = match.groups()
213     for (date,) in cursor.execute(
214     "SELECT release_date FROM bugs WHERE name = ?", (dsa,)):
215     (y, m, d) = date.split('-')
216     return NoEscape('<a href="http://www.debian.org/security/%d/dsa-%d">%s</a>'
217     % (int(y), int(number), name))
218    
219     return escape(dsa)
220    
221    
222     def url_debian_bug(bug):
223     return "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%d" % bug
224     def url_debian_bug_pkg(pkg):
225     return ("http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg="
226     + urllib.quote(pkg))
227    
228     def make_debian_bug(bug, internal=False):
229     if internal:
230     assert False
231     return NoEscape('<a href="%s">%d</a>' % (url_debian_bug(bug), bug))
232    
233     def url_pts(src):
234     return "http://packages.qa.debian.org/common/index.html?src=" \
235     + urllib.quote(src)
236    
237     def url_testing_status(src):
238     return "http://bjorn.haxx.se/debian/testing.pl?package=" \
239     + urllib.quote(src)
240    
241     def make_a(url, text):
242     return NoEscape('<a href="%s">%s</a>' % (escape(url), escape(text)))
243     def make_pts_ref(pkg, title=None):
244     if title is None:
245     title = pkg
246     return make_a(url_pts(pkg), title)
247    
248     def make_source_package_ref(pkg, title=None):
249     if title is None:
250     title = pkg
251     return make_a(url_source_package(pkg), title)
252     def make_binary_package_ref(pkg, title=None):
253     if title is None:
254     title = pkg
255     return make_a(url_binary_package(pkg), title)
256     def make_binary_packages_ref(lst):
257     assert type(lst) <> types.StringType
258     return make_list(map(make_binary_package_ref, lst))
259    
260     def make_list(lst, separator=NoEscape(", ")):
261     assert type(lst) <> types.StringType
262     return NoEscape(escape(separator).join(map(escape, lst)))
263    
264     def make_search():
265     return NoEscape(\
266     ('<form name="searchForm" method="get" action="%s">'
267     % escape(url_from_rel('search/')))
268     + 'Search for package or bug name: '
269     + '<input type="text" name="query" onkeyup="onSearch(this.value)"'
270     + 'onmousemove="onSearch(this.value)"> '
271     + '<input type="submit" value="Go"/></form>')
272    
273     def print_bug(bug, db):
274     print_title(bug.name)
275    
276     cursor = db.cursor()
277    
278     def gen_header():
279     yield make_bold("Name"), bug.name
280    
281     source = bug.name.split('-')[0]
282     if source in ('CAN', 'CVE'):
283     source_xref = make_cve_xref(bug.name, 'CVE')
284     elif source == 'DSA':
285     source_xref = make_dsa_xref(cursor, bug.name, 'Debian')
286     elif source == 'DTSA':
287     source_xref = 'Debian Testing Security Team'
288     elif source == 'FAKE':
289     source_xref = 'Automatically generated temporary name. Not for external reference.'
290     else:
291     source_xref = None
292    
293     if source_xref:
294     yield make_bold("Source"), source_xref
295    
296     if bug.description:
297     yield make_bold("Description"), bug.description
298    
299     xref = list(db.getBugXrefs(cursor, bug.name))
300     if xref:
301     yield make_bold("References"), make_list(map(make_xref, xref))
302    
303     debian_bugs = bug.getDebianBugs(cursor)
304     if debian_bugs:
305     yield (make_bold("Debian Bugs"),
306     make_list(map(make_debian_bug, debian_bugs)))
307    
308     if bug.not_for_us:
309     yield make_bold("Status"), "Debian is not affected"
310     else:
311     for (release, status, reason) in bug.getStatus(cursor):
312     if status <> 'fixed':
313     reason = make_red(reason)
314     yield make_bold('Status of %s' % release), reason
315    
316     print_table(gen_header())
317    
318     if bug.notes:
319     print """<h2>Vulnerable and fixed packages</h2>
320     <p>The table below lists information on <em>source packages</em>.</p>
321     """
322    
323     def gen_source():
324     yield (make_bold("Source Package"),
325     make_bold("Release"),
326     make_bold("Version"),
327     make_bold("Status"))
328    
329     old_pkg = ''
330     for (package, release, version, vulnerable) \
331     in db.getSourcePackages(cursor, bug.name):
332     if package == old_pkg:
333     package = ''
334     else:
335     old_pkg = package
336     package = NoEscape("%s (%s)"
337     % (escape(make_source_package_ref(package)),
338     escape(make_pts_ref(package, 'PTS'))))
339     if vulnerable:
340     vuln = make_red('vulnerable')
341     version = make_red(version)
342     else:
343     vuln = 'fixed'
344    
345     yield package, ', '.join(release), version, vuln
346    
347     print_table(gen_source())
348    
349     print "<p>The next table lists affected <em>binary packages</em>.<p>"
350    
351     def gen_binary():
352     yield (make_bold("Binary Package"),
353     make_bold("Release"),
354     make_bold("Version"),
355     make_bold("Status"),
356     make_bold("Arch"))
357    
358     old_pkg = ''
359     for (packages, releases, version, archs, vulnerable) \
360     in db.getBinaryPackages(cursor, bug.name):
361     pkg = ', '.join(packages)
362     if pkg == old_pkg:
363     packages = ''
364     else:
365     old_pkg = pkg
366     packages = make_binary_packages_ref(packages)
367    
368     if vulnerable:
369     vuln = make_red('vulnerable')
370     version = make_red(version)
371     else:
372     vuln = 'fixed'
373     yield (packages,
374     ', '.join(releases),
375     version, vuln,
376     ', '.join(archs))
377    
378     print_table(gen_binary())
379    
380    
381     print """<p>The information above is based on the following
382     data on fixed versions.</p>"""
383    
384     def gen_data():
385     yield ()
386    
387     notes_sorted = bug.notes[:]
388     notes_sorted.sort(lambda a, b: cmp(a.package, b.package))
389     for n in notes_sorted:
390     if n.release:
391     rel = str(n.release)
392     else:
393     rel = '(unstable)'
394     urgency = str(n.urgency)
395     if n.fixed_version:
396     ver = str(n.fixed_version)
397     if ver == '0':
398     ver = '(not affected)'
399     urgency = ''
400     else:
401     ver = make_red('(unfixed)')
402    
403     pkg = n.package
404     pkg_kind = n.package_kind
405     if pkg_kind == 'source':
406     pkg = make_source_package_ref(pkg)
407     elif pkg_kind == 'binary':
408     pkg = make_binary_package_ref(pkg)
409     elif pkg_kind == 'itp':
410     pkg_kind = 'ITP'
411     rel = ''
412     ver = ''
413     urgency = ''
414    
415     bugs = n.bugs
416     bugs.sort()
417     bugs = make_list(map(make_debian_bug, bugs))
418     if n.bug_origin:
419     origin = make_xref(n.bug_origin)
420     else:
421     origin = ''
422     yield (pkg, pkg_kind, rel, ver, urgency, origin, bugs)
423    
424     print_table(gen_data(),
425     caption=("Package", "Type", "Release", "Fixed Version",
426     "Urgency", "Origin", "Debian Bugs"))
427    
428     if bug.comments:
429     print "<h2>Notes</h2>"
430     print "<pre>"
431     for (t, c) in bug.comments:
432     print escape(c)
433     print "</pre>"
434    
435     print_footer()
436    
437     def print_debian_bug(db, bug, buglist):
438     print_title("Information related to Debian Bug #%d" % bug)
439    
440     print_paragraph("The following issues reference to Debian bug ",
441     make_debian_bug(bug), ":")
442    
443     def gen():
444     yield make_bold("Name"), make_bold("Urgency"), make_bold("Description")
445    
446     for (name, urgency, description) in buglist:
447     yield make_xref(name), urgency, description
448    
449     print_table(gen())
450     print_footer()
451    
452     def handle_simple_search(query):
453     db = security_db.DB('../data/security.db')
454     c = db.cursor()
455     if 'A' <= query[0] <= 'Z':
456     try:
457     bug = bugs.BugFromDB(c, query)
458     except ValueError:
459     print_no_results(query)
460     return
461    
462     if bug.name <> query:
463     # Bug name was normalized, perform redirect so that the
464     # browser sees the normalized URL.
465     print "Location:", url_from_rel(bug.name, full=True)
466     print
467     return
468    
469     print_bug(bug, db)
470     return
471    
472     elif db.isSourcePackage(c, query):
473     print "Location:", url_source_package(query, full=True)
474     print
475     return
476    
477     elif db.isBinaryPackage(c, query):
478     print "Location:", url_binary_package(query, full=True)
479     print
480     return
481    
482     elif '0' <= query[0] <= '9':
483     # Debian bug number.
484     if query[-6:] == '_REDIR':
485     query = query[:-6]
486     redirect = True
487     else:
488     redirect = False
489    
490     bugnumber = 0
491     try:
492     bugnumber = int(query)
493     except ValueError:
494     pass
495     if bugnumber:
496     buglist = list(db.getBugsFromDebianBug(c, bugnumber))
497     if buglist:
498     if len(buglist) == 1:
499     # Single issue, redirect.
500     print "Location:", url_known_bug(buglist[0][0], full=True)
501     print
502     return
503     else:
504     print_debian_bug(c, bugnumber, buglist)
505     return
506     elif redirect:
507     print "Location:", url_debian_bug(bugnumber)
508     print
509     return
510     print_no_results(query)
511    
512     def print_source_package(pkg):
513     db = security_db.DB('../data/security.db')
514     c = db.cursor()
515    
516     print_title("Information on source package " + pkg)
517    
518     print_menu([(url_pts(pkg),
519     pkg + ' in the Package Tracking System'),
520     (url_debian_bug_pkg(pkg),
521     pkg + ' in the Bug Tracking System'),
522     (url_testing_status(pkg),
523     pkg + ' in the testing migration checker')],
524     relative=False)
525    
526     print "<h2>Available versions</h2>"
527    
528     def gen_versions():
529     yield make_bold("Release"), make_bold("Version")
530     for (releases, version) in db.getSourcePackageVersions(c, pkg):
531     yield ', '.join(releases), version
532     print_table(gen_versions())
533    
534     print "<h2>Available binary packages</h2>"
535    
536     def gen_binary():
537     for (packages, releases, archs, version) \
538     in db.getBinaryPackagesForSource(c, pkg):
539     yield (make_binary_packages_ref(packages),
540     ', '.join(releases), version, ', '.join(archs))
541     print_table(gen_binary(),
542     caption=('Package', 'Release', 'Version', 'Architectures'),
543     replacement=('No binary packages are recorded in this database. '
544     + 'This probably means that the package is '
545     + 'architecture-specific, and the architecture '
546     + 'is currently not tracked.'))
547    
548     print "<h2>Open issues</h2>"
549    
550     def gen_bug_list(lst):
551     for (bug, description) in lst:
552     yield make_xref(bug), description
553     print_table(gen_bug_list(db.getBugsForSourcePackage(c, pkg, True)),
554     caption=('Bug', 'Description'),
555     replacement='No known open issues.')
556    
557     print "<h2>Resolved issues</h2>"
558    
559     print_table(gen_bug_list(db.getBugsForSourcePackage(c, pkg, False)),
560     caption=('Bug', 'Description'),
561     replacement='No known resolved issues.')
562    
563     print_footer()
564    
565     def print_binary_package(pkg):
566     db = security_db.DB('../data/security.db')
567     c = db.cursor()
568    
569     print_title("Information on binary package " + pkg)
570    
571     print_menu([(url_debian_bug_pkg(pkg),
572     pkg + ' in the Bug Tracking System')],
573     relative=False)
574     print "<h2>Available versions</h2>"
575    
576     def gen_versions():
577     # FIXME: We should include the source package name in this list.
578     yield ()
579     for (releases, source, version, archs) \
580     in db.getBinaryPackageVersions(c, pkg):
581     yield (', '.join(releases), make_source_package_ref(source),
582     version, ', '.join(archs))
583     print_table(gen_versions(),
584     caption=("Release", "Source", "Version", "Architectures"))
585    
586     print "<h2>Open issues</h2>"
587    
588     def gen_bug_list(lst):
589     for (bug, description) in lst:
590     yield make_xref(bug), description
591     print_table(gen_bug_list(db.getBugsForBinaryPackage(c, pkg, True)),
592     caption=('Bug', 'Description'),
593     replacement='No known open issues.')
594    
595     print "<h2>Resolved issues</h2>"
596    
597     print_table(gen_bug_list(db.getBugsForBinaryPackage(c, pkg, False)),
598     caption=('Bug', 'Description'),
599     replacement='No known resolved issues.')
600    
601     print "<h2>Non-issues</h2>"
602    
603     print_table(gen_bug_list(db.getNonBugsForBinaryPackage(c, pkg)),
604     caption=('Bug', 'Description'),
605     replacement=('No known issues which do not affect '
606     + 'this package.'))
607    
608     print_footer()
609    
610     def print_todo():
611     db = security_db.DB('../data/security.db')
612     print_title("Bugs with TODO items")
613    
614     def gen():
615     yield make_bold("Bug"), make_bold("Description")
616     for (bug, description) in db.getTODOs():
617     yield make_xref(bug), description
618     print_table(gen())
619    
620     print_footer()
621    
622     def print_menu(entries,relative=True):
623     w = sys.stdout.write
624     w("<ul>")
625     for e in entries:
626     w("<li>")
627     if type(e) == types.TupleType:
628     (relurl, label) = e
629     if relative:
630     relurl = url_from_rel(relurl)
631     sys.stdout.write(escape(make_a(relurl, label)))
632     else:
633     w(escape(e))
634     w("</li>\n")
635     w("</ul>\n")
636    
637     def print_overview():
638     print_title("Security issue tracker", selectSearch=True)
639    
640     print """<p>This is the experimental issue tracker for Debian's testing
641     security team. Keep in mind that this is merely a prototype.
642     Please report any problems to <a href="mailto:fw@deneb.enyo.de">Florian
643     Weimer</a>. Note that some of the data presented here is known
644     to be wrong (see below), but the data for the testing suite
645     should be fine.
646     </p>
647    
648     <h2>Starting points</h2>
649     """
650    
651     print_menu([('status/release/testing',
652     'Vulnerable packages in the testing suite'),
653     ('status/release/unstable',
654     'Vulnerable packages in the unstable suite'),
655     ('status/dtsa-candidates', "Candidates for DTSAs"),
656     ('status/todo', 'TODO items'),
657     ('status/itp', 'ITPs with potential security issues'),
658     ('data/unknown-packages',
659     'Packages names not found in the archive'),
660 fw 2240 ('data/missing-epochs',
661     'Package versions which might lack an epoch'),
662 fw 2225 ('data/funny-versions',
663     'Packages with strange version numbers'),
664     ('data/releases',
665     'Covered Debian releases and architectures (slow)'),
666     make_search()])
667    
668     print """<h2>A few notes on data sources</h2>
669    
670     <p>Data in this tracker comes solely from the bug database
671     which is maintained by Debian's testing security team in their
672     Subversion repository. All external data (this includes
673     Debian bug reports and official Debian security advisories)
674     must be added to this database before it appears here, and there
675     can be some delay before this happens.
676     </p>
677    
678     <p>At the moment, the database only contains information which is
679     relevant for tracking the security status of the testing suite.
680     This means that data for stable or oldstable is likely wrong.
681     The unstable suite should be covered pretty well, though,
682     because it is relevant to the status of testing.
683     </p>
684     """
685     print_footer(withSearch = False)
686    
687     def handle_cmd(cmd, arg):
688     if cmd == 'source-package':
689     print_source_package(arg)
690     sys.exit(0)
691     elif cmd == 'binary-package':
692     print_binary_package(arg)
693     sys.exit(0)
694    
695     if path_info in ('', '/'):
696     print_overview()
697     sys.exit(0)
698    
699     re_query = re.compile(r'^/([a-zA-Z0-9_.-]+)$')
700     match = re_query.match(path_info)
701     if match is None:
702     cmd_list = path_info.split('/')
703     if len(cmd_list) == 3:
704     handle_cmd(cmd_list[1], cmd_list[2])
705     # fall-through if not handled
706    
707     def print_releases():
708     db = security_db.DB('../data/security.db')
709    
710     print_title("Available releases")
711    
712     print """<p>The security issue database is checked against
713     the Debian releases listed in the table below. Currently, space
714     and processing resources are limited, so the list of architectures
715     is incomplete.
716     </p>"""
717    
718     def gen():
719     yield (make_bold("Release"),
720     make_bold("Subrelease"),
721     make_bold("Archive"),
722     make_bold("Sources"),
723     make_bold("Architectures"))
724     for (rel, subrel, archive, sources, archs) \
725     in db.availableReleases():
726     if sources:
727     sources = 'yes'
728     else:
729     sources = 'no'
730     yield rel, subrel, archive, sources, make_list(archs)
731    
732     print_table(gen())
733     print_footer()
734    
735     def print_funny_versions():
736     db = security_db.DB('../data/security.db')
737     print_title("Version conflicts between source/binary packages")
738    
739     print """<p>The table below lists source packages
740     which have a binary package of the same name, but with a different
741     version. This means that extra care is necessary to determine
742     the version of a package which has been fixed. (Note that
743     the bug tracker prefers source versions to binary versions
744     in this case.)
745     </p>"""
746     def gen():
747     yield (make_bold("Package"),
748     make_bold("Release"),
749     make_bold("Archive"),
750     make_bold("Source Version"),
751     make_bold("Binary Version"))
752    
753     for name, release, archive, version, source_version \
754     in db.getFunnyPackageVersions():
755     yield name, release, archive, source_version, version
756    
757     print_table(gen())
758    
759     print """<p>Technically speaking, these version numbering is fine,
760     but it makes version-based bug tracking quite difficult for these packages.
761     </p>
762    
763     <p>There are many binary packages which are built from source packages
764     with different version numbering schemes. However, as long as none of
765     the binary packages carries the same name as the source package, most
766     confusion is avoided or can be easily explained.</p>"""
767    
768     print_footer()
769    
770 fw 2240 def print_missing_epochs():
771     db = security_db.DB('../data/security.db')
772     print_title("Missing epochs in package versions")
773    
774     def gen():
775     old_bug = ''
776     old_pkg = ''
777     for bug, pkg, ver1, ver2 in db.cursor().execute(
778     """SELECT DISTINCT bug_name, n.package,
779     n.fixed_version, sp.version
780     FROM package_notes AS n, source_packages AS sp
781     WHERE n.package_kind = 'source'
782     AND n.fixed_version NOT LIKE '%:%'
783     AND n.fixed_version <> '0'
784     AND n.bug_origin = ''
785     AND sp.name = n.package
786     AND sp.version LIKE '%:%'
787     ORDER BY bug_name, package"""):
788     if bug == old_bug:
789     bug = ''
790     else:
791     old_bug = bug
792     old_pkg = ''
793     bug = make_xref(bug)
794     if pkg == old_pkg:
795     pkg = ''
796     else:
797     old_pkg = pkg
798     pkg = make_source_package_ref(pkg)
799     yield bug, pkg, ver1, ver2
800    
801     print_table(gen(),
802     caption=("Bug", "Package", "Version 1", "Version 2"),
803     replacement="No source package version with missing epochs.")
804    
805     print_footer()
806    
807 fw 2225 def print_unknown_packages():
808     db = security_db.DB('../data/security.db')
809     print_title("Unknown packages")
810    
811     print_paragraph("Sometimes, a package referenced in a bug report ",
812     "cannot be found in the database. This can be ",
813     "the result of a spelling error, or a historic ",
814     "entry refers to a package which is no longer in ",
815     "the archive.")
816    
817     def gen():
818     for name, bugs in db.getUnknownPackages(db.cursor()):
819     yield name, make_list(map(make_xref, bugs))
820    
821     print_table(gen(), caption=("Package", "Bugs"),
822     replacement="No unknown packages are referenced in the database.")
823    
824     print_footer()
825    
826     def print_itp():
827     db = security_db.DB('../data/security.db')
828     print_title("ITPs with potential security issues")
829    
830     def gen():
831     old_pkg = ''
832     for pkg, bugs, debian_bugs in db.getITPs(db.cursor()):
833     if pkg == old_pkg:
834     pkg = ''
835     else:
836     old_pkg = pkg
837     yield (pkg,
838     make_list(map(make_xref, bugs)),
839     make_list(map(make_debian_bug, debian_bugs)))
840    
841     print_table(gen(), caption=("Package", "Issue", "Debian Bugs"),
842     replacement="No ITPs are currently known.")
843    
844     print_footer()
845    
846     def print_testing_status():
847     db = security_db.DB('../data/security.db')
848    
849     print_title("Vulnerable source packages in testing")
850    
851     print_menu([("status/dtsa-candidates", "Candidates for DTSAs")])
852    
853     def gen():
854     yield (make_bold("Package"),
855     make_bold("Bug"))
856    
857     c = db.cursor()
858    
859     old_pkg_name = ''
860     for (pkg_name, bug_name, archive, urgency,
861     sid_vulnerable, ts_fixed) in db.cursor().execute(
862     """SELECT package, bug, section, urgency, unstable_vulnerable,
863     testing_security_fixed
864     FROM testing_status"""):
865     if pkg_name == old_pkg_name:
866     pkg_name = ''
867     else:
868     old_pkg_name = pkg_name
869     if archive <> 'main':
870     pkg_name = "%s (%s)" % (pkg_name, archive)
871    
872     if ts_fixed:
873     status = 'fixed in testing-security'
874     else:
875     if sid_vulnerable:
876     status = make_red('unstable is vulnerable')
877     else:
878     status = make_dangerous('fixed in unstable')
879    
880     if urgency == 'unknown':
881     urgency = ''
882    
883     yield pkg_name, make_xref(bug_name), urgency, status
884    
885     print_table(gen())
886    
887     print_footer()
888    
889     def print_dtsa_candidates():
890     db = security_db.DB('../data/security.db')
891    
892     print_title("Candidates for DTSAs")
893    
894     print_paragraph("The table below lists packages which are fixed ",
895     "in unstable, but unfixed in testing. ",
896     "Use the testing migration tracker to find out ",
897     "why they have not entered testing yet.")
898    
899     print_menu([("status/release/testing",
900     "List of vulnerable packages in testing")])
901    
902     def gen():
903     old_pkg_name = ''
904     for (pkg_name, bug_name, archive, urgency, stable_later) \
905     in db.cursor().execute(
906     """SELECT package, bug, section, urgency,
907     (SELECT testing.version_id < stable.version_id
908     FROM source_packages AS testing, source_packages AS stable
909     WHERE testing.name = testing_status.package
910     AND testing.release = 'etch'
911     AND testing.subrelease = ''
912     AND testing.archive = testing_status.section
913     AND stable.name = testing_status.package
914     AND stable.release = 'sarge'
915     AND stable.subrelease = 'security'
916     AND stable.archive = testing_status.section)
917     FROM testing_status
918     WHERE (NOT unstable_vulnerable)
919     AND (NOT testing_security_fixed)"""):
920     if pkg_name == old_pkg_name:
921     pkg_name = ''
922     migration = ''
923     else:
924     old_pkg_name = pkg_name
925     migration = make_a(url_testing_status(pkg_name),
926     "check")
927     if archive <> 'main':
928     pkg_name = "%s (%s)" % (pkg_name, archive)
929     else:
930     pkg_name = make_source_package_ref(pkg_name)
931    
932     if urgency == 'unknown':
933     urgency = ''
934     elif urgency == 'high':
935     urgency = make_red(urgency)
936    
937     if stable_later:
938     notes = "(fixed in stable?)"
939     else:
940     notes = ''
941    
942     yield pkg_name, migration, make_xref(bug_name), urgency, notes
943    
944     print_table(gen(),
945     caption=("Package", "Migration", "Bug", "Urgency"))
946    
947     print_footer()
948    
949     def print_unstable_status():
950     db = security_db.DB('../data/security.db')
951    
952     print_title("Vulnerable source packages in unstable")
953    
954     print_paragraph(
955     "Note that the list below is based on source packages. ",
956     "This means that packages are not listed here once a new, ",
957     "fixed source version has been uploaded to the archive, even ",
958     "if there are still some vulnerably binary packages present ",
959     "in the archive.")
960    
961     def gen():
962     c = db.cursor()
963    
964     old_pkg_name = ''
965     for (pkg_name, bug_name, section, urgency) in db.cursor().execute(
966     """SELECT DISTINCT sp.name, st.bug_name,
967     sp.archive, st.urgency
968     FROM source_package_status AS st, source_packages AS sp
969     WHERE st.vulnerable AND st.urgency <> 'unimportant'
970     AND sp.rowid = st.package AND sp.release = 'sid'
971     AND sp.subrelease = ''
972     ORDER BY sp.name, st.bug_name"""):
973     if pkg_name == old_pkg_name:
974     pkg_name = ''
975     else:
976     old_pkg_name = pkg_name
977     if section <> 'main':
978     pkg_name = "%s (%s)" % (pkg_name, section)
979     else:
980     pkg_name = make_xref(pkg_name)
981    
982     if urgency == 'unknown':
983     urgency = ''
984     elif urgency == 'high':
985     urgency = make_red(urgency)
986    
987     yield pkg_name, make_xref(bug_name), urgency
988    
989     print_table(gen(), caption=('Package', 'Bug', 'Urgency'))
990    
991     print_footer()
992    
993     def do_search():
994     form = cgi.FieldStorage()
995     query = form.getfirst("query", None)
996     if query is None:
997     # redirect to start page
998     print "Location:", url_from_rel("", full=True)
999     print
1000     else:
1001     re_simple_query = re.compile(r'^[A-Za-z0-9_.-]+$')
1002     if re_simple_query.match(query):
1003     print "Location:", url_from_rel(query, full=True)
1004     print
1005     else:
1006     print_invalid_query()
1007    
1008     commands = {'/data/releases' : print_releases,
1009     '/data/funny-versions' : print_funny_versions,
1010 fw 2240 '/data/missing-epochs' : print_missing_epochs,
1011 fw 2225 '/data/unknown-packages' : print_unknown_packages,
1012     '/status/release/testing' : print_testing_status,
1013     '/status/release/unstable' : print_unstable_status,
1014     '/status/todo' : print_todo,
1015     '/status/dtsa-candidates' : print_dtsa_candidates,
1016     '/status/itp' : print_itp,
1017     '/search/' : do_search}
1018     try:
1019     cmd = commands[path_info]
1020     except KeyError:
1021     print_invalid_query()
1022     cmd = None
1023     if cmd:
1024     cmd()
1025     else:
1026     handle_simple_search(match.group(1))

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.5