/[secure-testing]/bin/tracker_service.py
ViewVC logotype

Contents of /bin/tracker_service.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 14059 - (hide annotations) (download) (as text)
Sun Feb 7 22:10:57 2010 UTC (3 years, 4 months ago) by gilbert-guest
File MIME type: text/script
File size: 60373 byte(s)
new pages for undetermined and unimportant issues
1 fw 2482 #!/usr/bin/python
2    
3     import sys
4     sys.path.insert(0,'../lib/python')
5     import bugs
6     import re
7     import security_db
8     from web_support import *
9    
10 fw 12985 if len(sys.argv) not in (3, 5):
11     print "usage: python tracker_service.py SOCKET-PATH DATABASE-PATH"
12     print " python tracker_service.py URL HOST PORT DATABASE-PATH"
13     sys.exit(1)
14     if len(sys.argv) == 3:
15     socket_name = sys.argv[1]
16     db_name = sys.argv[2]
17     webservice_base_class = WebService
18     else:
19     server_base_url = sys.argv[1]
20     server_address = sys.argv[2]
21     server_port = int(sys.argv[3])
22     socket_name = (server_base_url, server_address, server_port)
23     db_name = sys.argv[4]
24     webservice_base_class = WebServiceHTTP
25    
26 fw 2491 class BugFilter:
27 gilbert-guest 14058 default_action_list = [('show_high_urgency', 'only high urgencies'),
28     ('show_medium_urgency', 'only medium and high urgencies'),
29     ('show_undetermined_urgency', 'issues that may be vulnerable but need to be checked (shown in purple)'),
30     ('show_unimportant_urgency', 'unimportant issues'),
31     ('show_remote_only', 'only remote vulnerabilities')]
32 fw 3859 def __init__(self, params, action_list=None):
33     if action_list is None:
34     self.action_list = self.default_action_list
35     else:
36     self.action_list = action_list
37     self.params = {}
38 fw 3902 for (prop, desc) in self.action_list:
39 fw 3859 self.params[prop] = int(params.get(prop, (0,))[0])
40 fw 2491
41     def actions(self, url):
42     """Returns a HTML snippet which can be used to change the filter."""
43    
44 fw 3859 l = []
45     for (prop, desc) in self.action_list:
46     if self.params[prop]:
47 gilbert-guest 14057 if self.params['show_medium_urgency'] and prop == 'show_medium_urgency':
48     note = 'Restore lower than medium urgencies'
49     elif self.params['show_high_urgency'] and prop == 'show_high_urgency':
50     note = 'Restore lower than high urgencies'
51     else:
52     note = 'Hide ' + desc
53     l.append(TR(TD(A(url.updateParamsDict({prop : None}), note))))
54 fw 3859 else:
55 gilbert-guest 14057 note = 'Show ' + desc
56     l.append(TR(TD(A(url.updateParamsDict({prop : '1'}), note))))
57 fw 3859
58 gilbert-guest 14057 return TABLE(l)
59 fw 3859
60 gilbert-guest 14057 def urgencyFiltered(self, urg, vuln):
61     """Returns True for urgencies that should be filtered."""
62     filterlow = self.params['show_medium_urgency'] and \
63 gilbert-guest 14058 urg in ('low', 'low**', 'unimportant',
64     'undetermined', 'not yet assigned')
65 gilbert-guest 14057 filtermed = self.params['show_high_urgency'] and \
66 gilbert-guest 14058 urg in ('medium', 'medium**', 'low', 'low**',
67     'unimportant', 'undetermined', 'not yet assigned')
68     filterund = not self.params['show_undetermined_urgency'] and vuln == 2
69     filteruni = not self.params['show_unimportant_urgency'] \
70     and urg == 'unimportant'
71     return filterlow or filtermed or filterund or filteruni
72 fw 2491
73     def remoteFiltered(self, remote):
74 gilbert-guest 14057 """Returns True for only remote flaws if filtered."""
75 gilbert-guest 14058 return remote is not None and self.params['show_remote_only'] \
76 fw 3859 and not remote
77 fw 2491
78 fw 3859 class BugFilterNoDSA(BugFilter):
79     def __init__(self, params):
80     BugFilter.__init__(self, params, self.default_action_list
81 gilbert-guest 14058 + [('show_nodsa', 'issues that are not severe enough to warrant a DSA')])
82 fw 3859
83     def nodsaFiltered(self, nodsa):
84 gilbert-guest 14057 """Returns True for no DSA issues if filtered."""
85     return nodsa and not self.params['show_nodsa']
86 fw 3859
87 fw 12985 class TrackerService(webservice_base_class):
88 fw 2482 head_contents = compose(STYLE(
89     """h1 { font-size : 144%; }
90     h2 { font-size : 120%; }
91     h3 { font-size : 100%; }
92    
93     table { padding-left : 1.5em }
94     td, th { text-align : left;
95     padding-left : 0.25em;
96     padding-right : 0.25em; }
97     td { vertical-align: baseline }
98     span.red { color: red; }
99 gilbert-guest 13694 span.purple { color: purple; }
100 fw 2482 span.dangerous { color: rgb(191,127,0); }
101     """), SCRIPT('''var old_query_value = "";
102    
103     function selectSearch() {
104     document.searchForm.query.focus();
105     }
106    
107     function onSearch(query) {
108     if (old_query_value == "") {
109     if (query.length > 5) {
110     old_query_value = query;
111     document.searchForm.submit();
112     } else {
113     old_query_value = query;
114     }
115     }
116     }
117     ''')).toHTML()
118    
119 gilbert-guest 14058 nvd_text = P('''If a "**" is included, the urgency field was automatically
120     assigned by the NVD (National Vulnerability Database). Note that this
121     rating is automatically derived from a set of known factors about the
122     issue (such as access complexity, confidentiality impact, exploitability,
123     remediation level, and others). Human intervention is involved in
124     determining the values of these factors, but the rating itself comes
125     from a fully automated formula.''')
126    
127 fw 2482 def __init__(self, socket_name, db_name):
128 fw 12985 webservice_base_class.__init__(self, socket_name)
129 fw 2482 self.db = security_db.DB(db_name)
130     self.register('', self.page_home)
131     self.register('*', self.page_object)
132 fw 2485 self.register('redirect/*', self.page_redirect)
133 fw 2482 self.register('source-package/*', self.page_source_package)
134     self.register('binary-package/*', self.page_binary_package)
135 thijs 11216 self.register('status/release/oldstable',
136     self.page_status_release_oldstable)
137 fw 2482 self.register('status/release/stable', self.page_status_release_stable)
138 fw 10607 self.register('status/release/stable-backports',
139     self.page_status_release_stable_backports)
140 fw 11223 self.register('status/release/oldstable-backports',
141     self.page_status_release_oldstable_backports)
142 fw 2482 self.register('status/release/testing',
143     self.page_status_release_testing)
144     self.register('status/release/unstable',
145     self.page_status_release_unstable)
146     self.register('status/dtsa-candidates',
147     self.page_status_dtsa_candidates)
148     self.register('status/todo', self.page_status_todo)
149 gilbert-guest 14059 self.register('status/undetermined', self.page_status_undetermined)
150     self.register('status/unimportant', self.page_status_unimportant)
151 fw 2482 self.register('status/itp', self.page_status_itp)
152     self.register('data/unknown-packages', self.page_data_unknown_packages)
153     self.register('data/missing-epochs', self.page_data_missing_epochs)
154 fw 3136 self.register('data/latently-vulnerable',
155     self.page_data_latently_vulnerable)
156 fw 2482 self.register('data/releases', self.page_data_releases)
157     self.register('data/funny-versions', self.page_data_funny_versions)
158 fw 2554 self.register('data/fake-names', self.page_data_fake_names)
159 fw 12999 self.register('data/pts/1', self.page_data_pts)
160 fw 3051 self.register('debsecan/**', self.page_debsecan)
161 fw 3594 self.register('data/report', self.page_report)
162 fw 2482
163     def page_home(self, path, params, url):
164     query = params.get('query', ('',))[0]
165     if query:
166     if '/' in query:
167     return self.page_not_found(url, query)
168     else:
169     return RedirectResult(url.scriptRelativeFull(query))
170    
171     return self.create_page(
172     url, 'Security Bug Tracker',
173     [P(
174 fw 3594 """The data in this tracker comes solely from the bug database maintained
175     by Debian's security team located in the testing-security Subversion """,
176 geissert 13517 A("http://svn.debian.org/wsvn/secure-testing/data/", "repository"),
177 fw 3594 """. The data represented here is derived from: """,
178     A("http://www.debian.org/security/#DSAS", "DSAs"),
179     """ issued by the Security Team; issues tracked in the """,
180 stef-guest 6467 A("http://cve.mitre.org/cve/", "CVE database"),
181 fw 3594 """, issues tracked in the """,
182     A("http://nvd.nist.gov/", "National Vulnerability Database"),
183     """ (NVD), maintained by NIST; and security issues
184     discovered in Debian packages as reported in the BTS."""),
185 stef-guest 4662 P("""All external data (including Debian bug reports and official Debian
186 fw 3594 security advisories) must be added to this database before it appears
187 fw 3595 here. Please help us keep this information up-to-date by """,
188 fw 3594 A(url.scriptRelative("data/report"), "reporting"),
189     """ any discrepancies or change of states that you are
190     aware of and/or help us improve the quality of this information by """,
191 seanius 4570 A(url.scriptRelative("data/report"), "participating"),
192 fw 3594 "."),
193     make_menu(
194 fw 2482 url.scriptRelative,
195 fw 3071 ('status/release/unstable',
196     'Vulnerable packages in the unstable suite'),
197     ('status/release/testing',
198     'Vulnerable packages in the testing suite'),
199 fw 2482 ('status/release/stable',
200     'Vulnerable packages in the stable suite'),
201 fw 11220 ('status/release/oldstable',
202     'Vulnerable packages in the old stable suite'),
203 fw 10607 ('status/release/stable-backports',
204     'Vulnerable packages in backports for stable'),
205 fw 11223 ('status/release/oldstable-backports',
206     'Vulnerable packages in backports for oldstable'),
207 fw 2482 ('status/dtsa-candidates', "Candidates for DTSAs"),
208     ('status/todo', 'TODO items'),
209 gilbert-guest 14059 ('status/undetermined', 'Packages that may be vulnerable but need to be checked (undetermined issues)'),
210     ('status/unimportant', 'Packages that have open unimportant issues'),
211 fw 2482 ('status/itp', 'ITPs with potential security issues'),
212     ('data/unknown-packages',
213     'Packages names not found in the archive'),
214 fw 2554 ('data/fake-names', 'Tracked issues without a CVE name'),
215 fw 2482 ('data/missing-epochs',
216     'Package versions which might lack an epoch'),
217 fw 3136 ('data/latently-vulnerable',
218     'Packages which are latently vulnerable in unstable'),
219 fw 2482 ('data/funny-versions',
220     'Packages with strange version numbers'),
221     ('data/releases',
222     'Covered Debian releases and architectures (slow)'),
223     self.make_search_button(url)),
224 fw 2495 P("""(You can enter CVE names, Debian bug numbers and package
225 fw 2488 names in the search forms.)"""),
226 fw 2482
227 fw 2488 H2("External interfaces"),
228     P("""If you want to automatically open a relevant web page for
229     some object, use the """,
230     CODE(str(url.scriptRelative("redirect/")), EM("object")),
231     """ URL. If no information is contained in this database,
232     the browser is automatically redirected to the corresponding external
233     data source.""")],
234 fw 2482 search_in_page=True)
235    
236     def page_object(self, path, params, url):
237     obj = path[0]
238 fw 2485 return self.page_object_or_redirect(url, obj, False)
239 fw 2482
240 fw 2485 def page_redirect(self, path, params, url):
241 fw 12993 if path == ():
242     obj = ''
243     else:
244     obj = path[0]
245 fw 2485 return self.page_object_or_redirect(url, obj, True)
246    
247     def page_object_or_redirect(self, url, obj, redirect):
248     c = self.db.cursor()
249    
250 fw 2482 if not obj:
251     # Redirect to start page.
252     return RedirectResult(url.scriptRelativeFull(""))
253    
254 fw 5103 # Attempt to decode a bug number. TEMP-nnn bugs (but not
255     # TEMP-nnn-mmm bugs) are treated as bug references, too.
256 fw 2482 bugnumber = 0
257 fw 3311 fake_bug = False
258 fw 2482 try:
259 fw 5103 if obj[0:5] == 'FAKE-' or obj[0:5] == 'TEMP-':
260 fw 3311 bugnumber = int(obj[5:])
261     fake_bug = True
262     else:
263     bugnumber = int(obj)
264 fw 2482 except ValueError:
265     pass
266     if bugnumber:
267 fw 2485 buglist = list(self.db.getBugsFromDebianBug(c, bugnumber))
268     if buglist:
269 fw 3311 return self.page_debian_bug(url, bugnumber, buglist, fake_bug)
270 fw 2485 if redirect:
271     return RedirectResult(self.url_debian_bug(url, str(bugnumber)),
272     permanent=False)
273 fw 2482
274 fw 3311 if 'A' <= obj[0] <= 'Z':
275     # Bug names start with a capital letter.
276     return self.page_bug(url, obj, redirect)
277    
278 fw 2482 if self.db.isSourcePackage(c, obj):
279     return RedirectResult(self.url_source_package(url, obj, full=True))
280     if self.db.isBinaryPackage(c, obj):
281     return RedirectResult(self.url_binary_package(url ,obj, full=True))
282    
283     return self.page_not_found(url, obj)
284    
285 fw 2485 def page_bug(self, url, name, redirect):
286 fw 2511 # FIXME: Normalize CAN-* to CVE-* when redirecting. Too many
287     # people still use CAN.
288     if redirect and name[0:4] == 'CAN-':
289     name = 'CVE-' + name[4:]
290    
291 fw 2482 cursor = self.db.cursor()
292     try:
293     bug = bugs.BugFromDB(cursor, name)
294     except ValueError:
295 fw 2485 if redirect:
296 fw 2495 if name[0:4] == 'CVE-':
297 fw 2485 return RedirectResult(self.url_cve(url, name),
298     permanent=False)
299 fw 2482 return self.page_not_found(url, name)
300 fw 2485 if bug.name <> name or redirect:
301 fw 2482 # Show the normalized bug name in the browser address bar.
302     return RedirectResult(url.scriptRelativeFull(bug.name))
303    
304     page = []
305    
306     def gen_header():
307     yield B("Name"), bug.name
308    
309     source = bug.name.split('-')[0]
310 fw 2495 if source == 'CVE':
311 fw 2488 source_xref = compose(self.make_cve_ref(url, bug.name, 'CVE'),
312 geissert 13767 " (at ",
313 fw 2488 self.make_nvd_ref(url, bug.name,
314 geissert 13767 'NVD'),
315     "; ",
316     self.make_rhbug_ref(url, bug.name,
317     'RH'),
318 fw 2488 ")")
319 fw 2482 elif source == 'DSA':
320     source_xref = self.make_dsa_ref(url, bug.name, 'Debian')
321     elif source == 'DTSA':
322     source_xref = 'Debian Testing Security Team'
323 fw 5103 elif source == 'TEMP':
324 fw 2482 source_xref = (
325     'Automatically generated temporary name. Not for external reference.')
326     else:
327     source_xref = None
328    
329     if source_xref:
330     yield B("Source"), source_xref
331    
332 fw 3078 nvd = self.db.getNVD(cursor, bug.name)
333    
334     if nvd and nvd.cve_desc:
335     yield B("Description"), nvd.cve_desc
336     elif bug.description:
337 fw 2482 yield B("Description"), bug.description
338    
339     xref = list(self.db.getBugXrefs(cursor, bug.name))
340     if xref:
341     yield B("References"), self.make_xref_list(url, xref)
342 fw 2488
343     if nvd:
344 fw 3079 nvd_range = nvd.rangeString()
345 fw 2488 if nvd.severity:
346 fw 3079 nvd_severity = nvd.severity.lower()
347     if nvd_range:
348     nvd_severity = "%s (attack range: %s)" \
349     % (nvd_severity, nvd_range)
350     yield B("NVD severity"), nvd_severity
351 fw 2482
352     debian_bugs = bug.getDebianBugs(cursor)
353     if debian_bugs:
354     yield (B("Debian Bugs"),
355     self.make_debian_bug_list(url, debian_bugs))
356    
357     if not bug.not_for_us:
358     for (release, status, reason) in bug.getStatus(cursor):
359 gilbert-guest 13694 if status == 'undetermined':
360     reason = self.make_purple(reason)
361     elif status <> 'fixed':
362 fw 2482 reason = self.make_red(reason)
363 fw 3080 yield B('Debian/%s' % release), reason
364 fw 2482
365     page.append(make_table(gen_header()))
366    
367     if bug.notes:
368     page.append(H2("Vulnerable and fixed packages"))
369    
370     def gen_source():
371     old_pkg = ''
372     for (package, release, version, vulnerable) \
373     in self.db.getSourcePackages(cursor, bug.name):
374     if package == old_pkg:
375     package = ''
376     else:
377     old_pkg = package
378     package = compose(
379     self.make_source_package_ref(url, package),
380     " (", self.make_pts_ref(url, package, 'PTS'), ")")
381 gilbert-guest 13694 if vulnerable == 1:
382 fw 2482 vuln = self.make_red('vulnerable')
383     version = self.make_red(version)
384 gilbert-guest 13694 elif vulnerable == 2:
385     vuln = self.make_purple('undetermined')
386     version = self.make_purple(version)
387 fw 2482 else:
388     vuln = 'fixed'
389    
390     yield package, ', '.join(release), version, vuln
391    
392     page.append(make_table(gen_source(),
393     caption=("Source Package", "Release", "Version", "Status"),
394     introduction=P('The table below lists information on source packages.')))
395    
396     def gen_binary():
397     old_pkg = ''
398     for (packages, releases, version, archs, vulnerable) \
399     in self.db.getBinaryPackages(cursor, bug.name):
400     pkg = ', '.join(packages)
401     if pkg == old_pkg:
402     packages = ''
403     else:
404     old_pkg = pkg
405     packages = self.make_binary_packages_ref(url, packages)
406    
407 gilbert-guest 13694 if vulnerable == 1:
408 fw 2482 vuln = self.make_red('vulnerable')
409     version = self.make_red(version)
410 gilbert-guest 13694 elif vulnerable == 2:
411     vuln = self.make_purple('undetermined')
412     version = self.make_purple(version)
413 fw 2482 else:
414     vuln = 'fixed'
415     yield (packages,
416     ', '.join(releases),
417     version, vuln,
418     ', '.join(archs))
419    
420     page.append(make_table(gen_binary(),
421     caption=("Binary Package", "Release", "Version", "Status",
422     "Architecures"),
423     introduction=P("The next table lists affected binary packages.")))
424    
425     def gen_data():
426     notes_sorted = bug.notes[:]
427     notes_sorted.sort(lambda a, b: cmp(a.package, b.package))
428     for n in notes_sorted:
429     if n.release:
430     rel = str(n.release)
431     else:
432     rel = '(unstable)'
433     urgency = str(n.urgency)
434     if n.fixed_version:
435     ver = str(n.fixed_version)
436     if ver == '0':
437     ver = '(not affected)'
438     urgency = ''
439     else:
440     ver = self.make_red('(unfixed)')
441 gilbert-guest 14058 if urgency == 'not yet assigned':
442     urgency = ''
443 fw 2482
444     pkg = n.package
445     pkg_kind = n.package_kind
446     if pkg_kind == 'source':
447     pkg = self.make_source_package_ref(url, pkg)
448     elif pkg_kind == 'binary':
449     pkg = self.make_binary_package_ref(url, pkg)
450     elif pkg_kind == 'itp':
451     pkg_kind = 'ITP'
452     rel = ''
453     ver = ''
454     urgency = ''
455    
456     bugs = n.bugs
457     bugs.sort()
458     bugs = make_list(
459     map(lambda x: self.make_debian_bug(url, x), bugs))
460     if n.bug_origin:
461     origin = self.make_xref(url, n.bug_origin)
462     else:
463     origin = ''
464     yield (pkg, pkg_kind, rel, ver, urgency, origin, bugs)
465    
466     page.append(
467     make_table(gen_data(),
468     caption=("Package", "Type", "Release", "Fixed Version",
469     "Urgency", "Origin", "Debian Bugs"),
470     introduction=P("The information above is based on the following data on fixed versions.")))
471    
472     if bug.comments:
473     page.append(H2("Notes"))
474     def gen_comments():
475     for (t, c) in bug.comments:
476     yield c
477 geissert 13785 page.append(make_pre(gen_comments()))
478 fw 2482
479     return self.create_page(url, bug.name, page)
480    
481 fw 3311 def page_debian_bug(self, url, bugnumber, buglist, fake_bug):
482     if fake_bug:
483     new_buglist = []
484     for b in buglist:
485     (bug_name, urgency, description) = b
486 fw 5103 if bug_name[0:5] == 'FAKE-' or bug_name[0:5] == 'TEMP-':
487 fw 3311 new_buglist.append(b)
488     if len(new_buglist) > 0:
489     # Only replace the bug list if there are still fake
490     # bug reports.
491     buglist = new_buglist
492    
493 fw 2485 if len(buglist) == 1:
494     # Single issue, redirect.
495     return RedirectResult(url.scriptRelativeFull(buglist[0][0]))
496 fw 2482
497 fw 2485 def gen():
498     for (name, urgency, description) in buglist:
499     if urgency == "unknown":
500     urgency = ""
501     yield self.make_xref(url, name), urgency, description
502 fw 2482
503 fw 3311 if fake_bug:
504     intro = """The URL you used contained a non-stable name
505     based on a Debian bug number. This name cannot be mapped to a specific
506     issue. """
507     else:
508     intro = ""
509    
510 fw 2485 return self.create_page(
511     url, "Information related to Debian bug #%d" % bugnumber,
512 fw 3311 [P(intro + "The following issues reference to Debian bug ",
513 fw 2485 self.make_debian_bug(url, bugnumber), ":"),
514     make_table(gen(),
515     caption=("Name", "Urgency", "Description"))])
516 fw 2482
517     def page_not_found(self, url, query):
518     return self.create_page(url, 'Not found',
519     [P('Your query ',
520     CODE(query),
521     ' matched no results.')],
522     status=404)
523    
524 fw 3594 def page_report(self, path, params, url):
525     return self.create_page(
526     url, 'Reporting discrepancies in the data',
527     [P("""The data in this tracker is always in flux, as bugs are fixed and new
528     issues disclosed, the data contained herein is updated. We strive to
529     maintain complete and accurate state information, and appreciate any
530     updates in status, information or new issues."""),
531     P("There are three ways that you can report updates to this information:"),
532     make_numbered_list(
533     [P("""IRC: We can be found at """,
534     CODE("irc.oftc.net"),
535     ", ",
536     CODE("#debian-security"),
537     """. If you have information to report, please go ahead and join
538     the channel and tell us. Please feel free to state the issue,
539     regardless if there is someone who has acknowledged you. Many of us
540     idle on this channel and may not be around when you join, but we read
541     the backlog and will see what you have said. If you require a
542     response, do not forget to let us know how to get a hold of you."""),
543     P("Mailing list: Our mailing list is: ",
544 stef-guest 6277 A("mailto:debian-security-tracker@lists.debian.org",
545     "debian-security-tracker@lists.debian.org")),
546 fw 3594 P("""Helping out: We welcome people who wish to join us in tracking
547     issues. The process is designed to be easy to learn and participate,
548     please read our """,
549 fw 3595 A("http://svn.debian.org/wsvn/secure-testing/doc/narrative_introduction?op=file&rev=0&sc=0",
550 fw 3594 "Introduction"),
551     """ to get familiar with how things work. Join us on
552     our mailing list, and on IRC and request to be added to the Alioth """,
553     A("http://alioth.debian.org/projects/secure-testing/", "project"),
554     """. We are really quite friendly. If you have a
555     question about how things work, don't be afraid to ask, we would like
556     to improve our documentation and procedures, so feedback is welcome.""")])])
557    
558 fw 2482 def page_source_package(self, path, params, url):
559     pkg = path[0]
560    
561     def gen_versions():
562     for (releases, version) in self.db.getSourcePackageVersions(
563     self.db.cursor(), pkg):
564     yield ', '.join(releases), version
565     def gen_binary():
566     for (packages, releases, archs, version) \
567     in self.db.getBinaryPackagesForSource(
568     self.db.cursor(), pkg):
569     yield (self.make_binary_packages_ref(url, packages),
570     ', '.join(releases), version, ', '.join(archs))
571     def gen_bug_list(lst):
572     for (bug, description) in lst:
573     yield self.make_xref(url, bug), description
574    
575     return self.create_page(
576     url, "Information on source package " + pkg,
577     [make_menu(lambda x: x,
578     (self.url_pts(url, pkg),
579     pkg + ' in the Package Tracking System'),
580     (self.url_debian_bug_pkg(url, pkg),
581     pkg + ' in the Bug Tracking System'),
582     (self.url_testing_status(url, pkg),
583     pkg + ' in the testing migration checker')),
584     H2("Available versions"),
585     make_table(gen_versions(), caption=("Release", "Version")),
586    
587     H2("Available binary packages"),
588     make_table(gen_binary(),
589     caption=('Package', 'Release', 'Version', 'Architectures'),
590     replacement="""No binary packages are recorded in this database.
591     This probably means that the package is architecture-specific, and the
592     architecture is currently not tracked."""),
593    
594     H2("Open issues"),
595     make_table(gen_bug_list(self.db.getBugsForSourcePackage
596     (self.db.cursor(), pkg, True)),
597     caption=('Bug', 'Description'),
598     replacement='No known open issues.'),
599    
600     H2("Resolved issues"),
601     make_table(gen_bug_list(self.db.getBugsForSourcePackage
602     (self.db.cursor(), pkg, False)),
603     caption=('Bug', 'Description'),
604     replacement='No known resolved issues.')])
605    
606     def page_binary_package(self, path, params, url):
607     pkg = path[0]
608    
609     def gen_versions():
610     for (releases, source, version, archs) \
611     in self.db.getBinaryPackageVersions(self.db.cursor(), pkg):
612     yield (', '.join(releases),
613     self.make_source_package_ref(url, source),
614     version, ', '.join(archs))
615     def gen_bug_list(lst):
616     for (bug, description) in lst:
617     yield self.make_xref(url, bug), description
618    
619     return self.create_page(
620     url, "Information on binary package " + pkg,
621     [make_menu(lambda x: x,
622     (self.url_debian_bug_pkg(url, pkg),
623     pkg + ' in the Bug Tracking System')),
624     H2("Available versions"),
625     make_table(gen_versions(),
626     caption=("Release", "Source", "Version", "Architectures")),
627    
628     H2("Open issues"),
629     make_table(gen_bug_list(self.db.getBugsForBinaryPackage
630     (self.db.cursor(), pkg, True)),
631     caption=('Bug', 'Description'),
632     replacement='No known open issues.'),
633    
634     H2("Resolved issues"),
635     make_table(gen_bug_list(self.db.getBugsForBinaryPackage
636     (self.db.cursor(), pkg, False)),
637     caption=('Bug', 'Description'),
638     replacement='No known resolved issues.'),
639    
640     H2("Non-issues"),
641     make_table(gen_bug_list(self.db.getNonBugsForBinaryPackage
642     (self.db.cursor(), pkg)),
643     caption=('Bug', 'Description'),
644     replacement="""No known issues which do not affect
645     this package, but still reference it.""")])
646    
647 fw 3069 def page_status_release_stable_oldstable(self, release, params, url):
648     assert release in ('stable', 'oldstable')
649    
650 fw 3859 bf = BugFilterNoDSA(params)
651 fw 2491
652 fw 2482 def gen():
653     old_pkg_name = ''
654 gilbert-guest 14057 for (pkg_name, bug_name, archive, urgency, vulnerable, remote, no_dsa) in \
655 fw 2482 self.db.cursor().execute(
656 gilbert-guest 14057 """SELECT package, bug, section, urgency, vulnerable, remote, no_dsa
657 fw 3069 FROM %s_status""" % release):
658 gilbert-guest 14057 if bf.urgencyFiltered(urgency, vulnerable):
659 fw 2491 continue
660     if bf.remoteFiltered(remote):
661     continue
662 fw 3859 if bf.nodsaFiltered(no_dsa):
663     continue
664 gilbert-guest 14057
665 fw 2482 if pkg_name == old_pkg_name:
666     pkg_name = ''
667     else:
668     old_pkg_name = pkg_name
669     if archive <> 'main':
670     pkg_name = "%s (%s)" % (pkg_name, archive)
671    
672 fw 2488 if remote is None:
673     remote = ''
674     elif remote:
675     remote = 'yes'
676     else:
677     remote = 'no'
678    
679 gilbert-guest 14058 if urgency.startswith('high'):
680     urgency = self.make_red(urgency)
681     elif vulnerable == 2:
682 gilbert-guest 14057 urgency = self.make_purple(urgency)
683 fw 3859 else:
684     if no_dsa:
685     urgency = urgency + '*'
686 fw 2482
687 fw 2488 yield pkg_name, self.make_xref(url, bug_name), urgency, remote
688 fw 2482
689     return self.create_page(
690 fw 3069 url, 'Vulnerable source packages in the %s suite' % release,
691 gilbert-guest 14057 [bf.actions(url), BR(),
692 gilbert-guest 14058 make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote")),
693     P('''If a "*" is included in the urgency field, no DSA is planned
694     for this vulnerability.'''),
695     self.nvd_text])
696 fw 3069
697     def page_status_release_stable(self, path, params, url):
698     return self.page_status_release_stable_oldstable('stable', params, url)
699 thijs 11216 def page_status_release_oldstable(self, path, params, url):
700     return self.page_status_release_stable_oldstable('oldstable',
701     params, url)
702 fw 2482
703     def page_status_release_testing(self, path, params, url):
704 fw 5100 bf = BugFilterNoDSA(params)
705 fw 2491
706 fw 2482 def gen():
707     old_pkg_name = ''
708 gilbert-guest 14057 for (pkg_name, bug_name, archive, urgency, vulnerable,
709 fw 5100 sid_vulnerable, ts_fixed, remote, no_dsa) \
710     in self.db.cursor().execute(
711 gilbert-guest 14057 """SELECT package, bug, section, urgency, vulnerable,
712     unstable_vulnerable, testing_security_fixed, remote, no_dsa
713 fw 2482 FROM testing_status"""):
714 gilbert-guest 14057 if bf.urgencyFiltered(urgency, vulnerable):
715 fw 2491 continue
716     if bf.remoteFiltered(remote):
717     continue
718 fw 5100 if bf.nodsaFiltered(no_dsa):
719     continue
720 fw 2491
721 fw 2482 if pkg_name == old_pkg_name:
722     pkg_name = ''
723     else:
724     old_pkg_name = pkg_name
725     if archive <> 'main':
726     pkg_name = "%s (%s)" % (pkg_name, archive)
727    
728 fw 2488 if remote is None:
729     remote = ''
730     elif remote:
731     remote = 'yes'
732     else:
733     remote = 'no'
734    
735 fw 2482 if ts_fixed:
736     status = 'fixed in testing-security'
737     else:
738     if sid_vulnerable:
739     status = self.make_red('unstable is vulnerable')
740     else:
741     status = self.make_dangerous('fixed in unstable')
742    
743 gilbert-guest 14058 if urgency.startswith('high'):
744     urgency = self.make_red(urgency)
745     elif vulnerable == 2:
746     urgency = self.make_purple(urgency)
747    
748 fw 2482 yield (pkg_name, self.make_xref(url, bug_name),
749 fw 2488 urgency, remote, status)
750 fw 2482
751     return self.create_page(
752     url, 'Vulnerable source packages in the testing suite',
753     [make_menu(url.scriptRelative,
754     ("status/dtsa-candidates", "Candidates for DTSAs")),
755 gilbert-guest 14057 bf.actions(url), BR(),
756 gilbert-guest 14058 make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote")),
757     self.nvd_text])
758 fw 2482
759 fw 10607 def page_status_release_unstable_like(self, path, params, url,
760     rel, title):
761 fw 2491 bf = BugFilter(params)
762    
763 fw 2482 def gen():
764     old_pkg_name = ''
765 gilbert-guest 14057 for (pkg_name, bug_name, section, urgency, vulnerable, remote) \
766 fw 2482 in self.db.cursor().execute(
767     """SELECT DISTINCT sp.name, st.bug_name,
768 gilbert-guest 14057 sp.archive, st.urgency, st.vulnerable,
769 fw 2491 (SELECT range_remote FROM nvd_data
770     WHERE cve_name = st.bug_name)
771 fw 2482 FROM source_package_status AS st, source_packages AS sp
772 gilbert-guest 14057 WHERE st.vulnerable AND sp.rowid = st.package
773     AND sp.release = ? AND sp.subrelease = ''
774 fw 10607 ORDER BY sp.name, st.bug_name""", (rel,)):
775 gilbert-guest 14057 if bf.urgencyFiltered(urgency, vulnerable):
776 fw 2491 continue
777     if bf.remoteFiltered(remote):
778     continue
779    
780 fw 2482 if pkg_name == old_pkg_name:
781     pkg_name = ''
782     else:
783     old_pkg_name = pkg_name
784     if section <> 'main':
785     pkg_name = "%s (%s)" % (pkg_name, section)
786     else:
787     pkg_name = self.make_xref(url, pkg_name)
788    
789 fw 2491 if remote is None:
790     remote = ''
791     elif remote:
792     remote = 'yes'
793     else:
794     remote = 'no'
795    
796 gilbert-guest 14058 if urgency.startswith('high'):
797 fw 2482 urgency = self.make_red(urgency)
798 gilbert-guest 14057 elif vulnerable == 2:
799 gilbert-guest 13694 urgency = self.make_purple(urgency)
800 fw 2482
801 fw 2491 yield pkg_name, self.make_xref(url, bug_name), urgency, remote
802 gilbert-guest 14057
803 fw 2482 return self.create_page(
804 fw 10607 url, title,
805 fw 2482 [P("""Note that the list below is based on source packages.
806     This means that packages are not listed here once a new,
807     fixed source version has been uploaded to the archive, even
808     if there are still some vulnerably binary packages present
809     in the archive."""),
810 gilbert-guest 14057 bf.actions(url), BR(),
811 gilbert-guest 14058 make_table(gen(), caption=('Package', 'Bug', 'Urgency', 'Remote')),
812     self.nvd_text])
813 fw 2482
814 fw 10607 def page_status_release_unstable(self, path, params, url):
815     return self.page_status_release_unstable_like(
816     path, params, url,
817     title='Vulnerable source packages in the unstable suite',
818     rel='sid')
819    
820     def page_status_release_stable_backports(self, path, params, url):
821     return self.page_status_release_unstable_like(
822     path, params, url,
823     title='Vulnerable source packages among backports for stable',
824 thijs 11215 rel='lenny-backports')
825 fw 10607
826 fw 11223 def page_status_release_oldstable_backports(self, path, params, url):
827     return self.page_status_release_unstable_like(
828     path, params, url,
829     title='Vulnerable source packages among backports for oldstable',
830     rel='etch-backports')
831    
832 fw 2482 def page_status_dtsa_candidates(self, path, params, url):
833 fw 2491 bf = BugFilter(params)
834    
835 fw 2482 def gen():
836     old_pkg_name = ''
837 gilbert-guest 14057 for (pkg_name, bug_name, archive, urgency, vulnerable,
838     stable_later, remote) \
839 fw 2482 in self.db.cursor().execute(
840 gilbert-guest 14057 """SELECT package, bug, section, urgency, vulnerable,
841 fw 2482 (SELECT testing.version_id < stable.version_id
842     FROM source_packages AS testing, source_packages AS stable
843     WHERE testing.name = testing_status.package
844 thijs 11215 AND testing.release = 'squeeze'
845 fw 2482 AND testing.subrelease = ''
846     AND testing.archive = testing_status.section
847     AND stable.name = testing_status.package
848 thijs 11215 AND stable.release = 'lenny'
849 fw 2482 AND stable.subrelease = 'security'
850 fw 2491 AND stable.archive = testing_status.section),
851     (SELECT range_remote FROM nvd_data
852     WHERE cve_name = bug)
853 fw 2482 FROM testing_status
854     WHERE (NOT unstable_vulnerable)
855     AND (NOT testing_security_fixed)"""):
856 gilbert-guest 14057 if bf.urgencyFiltered(urgency, vulnerable):
857 fw 2491 continue
858     if bf.remoteFiltered(remote):
859     continue
860    
861 fw 2482 if pkg_name == old_pkg_name:
862     pkg_name = ''
863     migration = ''
864     else:
865     old_pkg_name = pkg_name
866     migration = A(self.url_testing_status(url, pkg_name),
867     "check")
868     if archive <> 'main':
869     pkg_name = "%s (%s)" % (pkg_name, archive)
870     else:
871     pkg_name = self.make_source_package_ref(url, pkg_name)
872    
873 fw 2491 if remote is None:
874     remote = ''
875     elif remote:
876     remote = 'yes'
877     else:
878     remote = 'no'
879    
880 gilbert-guest 14058 if urgency.starstwith('high'):
881 fw 2482 urgency = self.make_red(urgency)
882 gilbert-guest 14058 elif vulnerable == 2:
883     urgency = self.make_purple(urgency)
884 fw 2482
885     if stable_later:
886     notes = "(fixed in stable?)"
887     else:
888     notes = ''
889    
890     yield (pkg_name, migration, self.make_xref(url, bug_name),
891 fw 2491 urgency, remote, notes)
892 fw 2482
893     return self.create_page(
894     url, "Candidates for DTSAs",
895     [P("""The table below lists packages which are fixed
896     in unstable, but unfixed in testing. Use the testing migration
897 fw 2679 checker to find out why they have not entered testing yet."""),
898 fw 2482 make_menu(url.scriptRelative,
899     ("status/release/testing",
900     "List of vulnerable packages in testing")),
901 gilbert-guest 14057 bf.actions(url), BR(),
902 fw 2482 make_table(gen(),
903 fw 2491 caption=("Package", "Migration", "Bug", "Urgency",
904     "Remote"))])
905 fw 2482
906     def page_status_todo(self, path, params, url):
907 fw 4005 hide_check = params.get('hide_check', False)
908     if hide_check:
909     flags = A(url.updateParamsDict({'hide_check' : None}),
910     'Show "check" TODOs')
911     else:
912     flags = A(url.updateParamsDict({'hide_check' : '1'}),
913     'Hide "check" TODOs')
914    
915 fw 2482 def gen():
916 fw 4005 for (bug, description) in self.db.getTODOs(hide_check=hide_check):
917 fw 2482 yield self.make_xref(url, bug), description
918     return self.create_page(
919     url, "Bugs with TODO items",
920 gilbert-guest 14059 [P(flags), make_table(gen(), caption=("Bug", "Description"))])
921 fw 2482
922 gilbert-guest 14059 def page_status_undetermined(self, path, params, url):
923     def gen():
924     outrel = []
925     old_bug = ''
926     old_pkg = ''
927     old_dsc = ''
928     last_displayed = ''
929     releases = ('sid', 'squeeze', 'lenny', 'etch')
930     for (pkg_name, bug_name, release, desc) in self.db.cursor().execute(
931     """SELECT DISTINCT sp.name, st.bug_name, sp.release,
932     bugs.description
933     FROM source_package_status AS st, source_packages AS sp, bugs
934     WHERE st.vulnerable == 2 AND sp.rowid = st.package
935     AND ( sp.release = ? OR sp.release = ? OR sp.release = ?
936     OR sp.release = ? )
937     AND sp.subrelease = '' AND st.bug_name == bugs.name
938     ORDER BY sp.name, st.bug_name""", releases):
939    
940     if old_bug == '':
941     old_bug = bug_name
942     old_pkg = pkg_name
943     old_dsc = desc
944     elif old_bug != bug_name:
945     if old_pkg == last_displayed:
946     to_display = ''
947     else:
948     to_display = old_pkg
949     yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
950     last_displayed = old_pkg
951     old_bug = bug_name
952     old_pkg = pkg_name
953     old_dsc = desc
954     outrel = []
955     outrel.append( release )
956     yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
957    
958     return self.create_page(url, 'Packages that may be vulnerable but need to be checked (undetermined issues)',
959     [P("""This page lists packages that may or may not be affected
960     by known issues. This means that some additional work needs to
961     be done to determined whether the package is actually
962     vulnerable or not. This list is a good area for new
963     contributors to make quick and meaningful contributions."""),
964     make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
965    
966     def page_status_unimportant(self, path, params, url):
967     def gen():
968     outrel = []
969     old_bug = ''
970     old_pkg = ''
971     old_dsc = ''
972     old_name = ''
973     last_displayed = ''
974     releases = ('sid', 'squeeze', 'lenny', 'etch')
975     for (pkg_name, bug_name, release, desc) in self.db.cursor().execute(
976     """SELECT DISTINCT sp.name, st.bug_name, sp.release,
977     bugs.description
978     FROM source_package_status AS st, source_packages AS sp, bugs
979     WHERE st.vulnerable > 0 AND sp.rowid = st.package
980     AND ( sp.release = ? OR sp.release = ? OR sp.release = ?
981     OR sp.release = ? ) AND st.urgency == 'unimportant'
982     AND sp.subrelease = '' AND st.bug_name == bugs.name
983     ORDER BY sp.name, st.bug_name""", releases):
984    
985     if old_bug == '':
986     old_bug = bug_name
987     old_pkg = pkg_name
988     old_dsc = desc
989     elif old_bug != bug_name:
990     if old_pkg == last_displayed:
991     to_display = ''
992     else:
993     to_display = old_pkg
994     yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
995     last_displayed = old_pkg
996     old_bug = bug_name
997     old_pkg = pkg_name
998     old_dsc = desc
999     outrel = []
1000     outrel.append( release )
1001     yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
1002    
1003     return self.create_page(url, 'Packages that have open unimportant issues',
1004     [P("""This page lists packages that are affected by issues
1005     that are considered unimportant from a security perspective.
1006     These issues are thought to be unexploitable or uneffective
1007     in most situations (for example, browser denial-of-services)."""),
1008     make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
1009    
1010 fw 2482 def page_status_itp(self, path, params, url):
1011     def gen():
1012     old_pkg = ''
1013     for pkg, bugs, debian_bugs in self.db.getITPs(self.db.cursor()):
1014     if pkg == old_pkg:
1015     pkg = ''
1016     else:
1017     old_pkg = pkg
1018     yield (pkg, self.make_xref_list(url, bugs),
1019     self.make_debian_bug_list(url, debian_bugs))
1020     return self.create_page(
1021     url, "ITPs with potential security issues",
1022     [make_table(gen(), caption=("Package", "Issue", "Debian Bugs"),
1023     replacement="No ITP bugs are currently known.")])
1024    
1025     def page_data_unknown_packages(self, path, params, url):
1026     def gen():
1027     for name, bugs in self.db.getUnknownPackages(self.db.cursor()):
1028     yield name, self.make_xref_list(url, bugs)
1029     return self.create_page(
1030     url, "Unknown packages",
1031     [P("""Sometimes, a package referenced in a bug report
1032     cannot be found in the database. This can be the result of a spelling
1033 thijs 6389 error, or a historic entry refers to a
1034     package which is no longer in the archive."""),
1035 fw 2482 make_table(gen(), caption=("Package", "Bugs"),
1036     replacement="No unknown packages are referenced in the database.")])
1037    
1038     def page_data_missing_epochs(self, path, params, url):
1039     def gen():
1040     old_bug = ''
1041     old_pkg = ''
1042     for bug, pkg, ver1, ver2 in self.db.cursor().execute(
1043     """SELECT DISTINCT bug_name, n.package,
1044     n.fixed_version, sp.version
1045     FROM package_notes AS n, source_packages AS sp
1046     WHERE n.package_kind = 'source'
1047     AND n.fixed_version NOT LIKE '%:%'
1048     AND n.fixed_version <> '0'
1049     AND n.bug_origin = ''
1050     AND sp.name = n.package
1051     AND sp.version LIKE '%:%'
1052     ORDER BY bug_name, package"""):
1053     if bug == old_bug:
1054     bug = ''
1055     else:
1056     old_bug = bug
1057     old_pkg = ''
1058     bug = self.make_xref(url, bug)
1059     if pkg == old_pkg:
1060     pkg = ''
1061     else:
1062     old_pkg = pkg
1063     pkg = self.make_source_package_ref(url, pkg)
1064     yield bug, pkg, ver1, ver2
1065    
1066     return self.create_page(
1067     url, "Missing epochs in package versions",
1068     [make_table(gen(),
1069     caption=("Bug", "Package", "Version 1", "Version 2"),
1070     replacement="No source package version with missing epochs.")])
1071    
1072 fw 3136 def page_data_latently_vulnerable(self, path, params, url):
1073     def gen():
1074     for pkg, bugs in self.db.cursor().execute(
1075     """SELECT package, string_set(bug_name)
1076     FROM package_notes AS p1
1077     WHERE release <> ''
1078 fw 5103 AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
1079 fw 3136 AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
1080     WHERE p2.bug_name = p1.bug_name
1081     AND p2.package = p1.package
1082     AND release = '')
1083     AND EXISTS (SELECT 1 FROM source_packages
1084     WHERE name = p1.package AND release = 'sid')
1085     GROUP BY package
1086     ORDER BY package"""):
1087     pkg = self.make_source_package_ref(url, pkg)
1088     bugs = bugs.split(',')
1089     yield pkg, self.make_xref_list(url, bugs)
1090    
1091 fw 3166 def gen_unimportant():
1092     for pkg, bugs in self.db.cursor().execute(
1093     """SELECT package, string_set(bug_name)
1094     FROM package_notes AS p1
1095     WHERE release <> ''
1096     AND urgency <> 'unimportant'
1097 fw 5103 AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
1098 fw 3166 AND EXISTS (SELECT 1 FROM package_notes AS p2
1099     WHERE p2.bug_name = p1.bug_name
1100     AND p2.package = p1.package
1101     AND release = '')
1102     AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
1103     WHERE p2.bug_name = p1.bug_name
1104     AND p2.package = p1.package
1105     AND urgency <> 'unimportant'
1106     AND release = '')
1107     AND EXISTS (SELECT 1 FROM source_packages
1108     WHERE name = p1.package AND release = 'sid')
1109     GROUP BY package
1110     ORDER BY package"""):
1111     pkg = self.make_source_package_ref(url, pkg)
1112     bugs = bugs.split(',')
1113     yield pkg, self.make_xref_list(url, bugs)
1114    
1115 fw 3136 return self.create_page(
1116     url, "Latently vulnerable packages in unstable",
1117     [P(
1118     """A package is latently vulnerable in unstable if it is vulnerable in
1119     any release, and there is no package note for the same vulnerability
1120     and package in unstable (and the package is still available in
1121     unstable, of course)."""),
1122     make_table(gen(),
1123     caption=("Package", "Bugs"),
1124 fw 3166 replacement="No latently vulnerable packages were found."),
1125     P(
1126     """The next table lists issues which are marked unimportant for
1127     unstable, but for which release-specific annotations exist which are
1128     not unimportant."""),
1129     make_table(gen_unimportant(),
1130     caption=("Package", "Bugs"),
1131     replacement=
1132     "No packages with unimportant latent vulnerabilities were found."),
1133     ])
1134 fw 3136
1135 fw 2482 def page_data_releases(self, path, params, url):
1136     def gen():
1137     for (rel, subrel, archive, sources, archs) \
1138     in self.db.availableReleases():
1139     if sources:
1140     sources = 'yes'
1141     else:
1142     sources = 'no'
1143     yield rel, subrel, archive, sources, make_list(archs)
1144     return self.create_page(
1145     url, "Available releases",
1146     [P("""The security issue database is checked against
1147     the Debian releases listed in the table below."""),
1148     make_table(gen(),
1149     caption=("Release", "Subrelease", "Archive",
1150     "Sources", "Architectures"))])
1151    
1152     def page_data_funny_versions(self, path, params, url):
1153     def gen():
1154     for name, release, archive, version, source_version \
1155     in self.db.getFunnyPackageVersions():
1156     yield name, release, archive, source_version, version
1157    
1158     return self.create_page(
1159     url, "Version conflicts between source/binary packages",
1160     [P("""The table below lists source packages
1161     which have a binary package of the same name, but with a different
1162     version. This means that extra care is necessary to determine
1163     the version of a package which has been fixed. (Note that
1164     the bug tracker prefers source versions to binary versions
1165     in this case.)"""),
1166     make_table(gen(),
1167     caption=("Package",
1168     "Release",
1169     "Archive",
1170     "Source Version",
1171     "Binary Version")),
1172     P("""Technically speaking, these version numbering is fine,
1173     but it makes version-based bug tracking quite difficult for these packages."""),
1174     P("""There are many binary packages which are built from source
1175     packages with different version numbering schemes. However, as
1176     long as none of the binary packages carries the same name as the
1177     source package, most confusion is avoided or can be easily
1178     explained.""")])
1179    
1180 fw 2554 def page_data_fake_names(self, path, params, url):
1181     def gen():
1182     for (bug, description) in self.db.getFakeBugs():
1183     yield self.make_xref(url, bug), description
1184     return self.create_page(
1185     url, "Automatically generated issue names",
1186     [P("""Some issues have not been assigned CVE names, but are still
1187     tracked by this database. In this case, the system automatically assigns
1188     a unique name. These names are not stable and can change when the database
1189     is updated, so they should not be used in external references."""),
1190     P('''The automatically generated names come in two flavors:
1191 fw 5103 the first kind starts with the string "''', CODE("TEMP-000000-"),
1192 fw 2554 '''". This means that no Debian bug has been assigned to this
1193     issue (or a bug has been created and is not recorded in this database).
1194     In the second kind of names, there is a Debian bug for the issue, and the "''',
1195     CODE("000000"), '''"part of the name is replaced with the
1196     Debian bug number.'''),
1197     make_table(gen(),
1198     caption=("Bug", "Description"))])
1199    
1200 fw 12999 def page_data_pts(self, path, params, url):
1201     data = []
1202     for pkg, bugs in self.db.cursor().execute(
1203     """SELECT package, COUNT(DISTINCT bug) FROM
1204     (SELECT package, bug FROM stable_status
1205     UNION ALL SELECT package, bug FROM oldstable_status
1206     UNION ALL SELECT DISTINCT sp.name, st.bug_name
1207     FROM source_package_status AS st, source_packages AS sp
1208     WHERE st.vulnerable AND st.urgency <> 'unimportant'
1209     AND sp.rowid = st.package AND sp.release = 'sid'
1210     AND sp.subrelease = '') x
1211     GROUP BY package ORDER BY package"""):
1212     data.append(pkg)
1213     data.append(':')
1214     data.append(str(bugs))
1215     data.append('\n')
1216     return BinaryResult(''.join(data))
1217    
1218 fw 3051 def page_debsecan(self, path, params, url):
1219     obj = '/'.join(path)
1220     data = self.db.getDebsecan(obj)
1221     if data:
1222     return BinaryResult(data)
1223     else:
1224     return self.create_page(
1225     url, "Object not found",
1226     [P("The requested debsecan object has not been found.")],
1227     status=404)
1228    
1229 fw 2482 def create_page(self, url, title, body, search_in_page=False, status=200):
1230     append = body.append
1231     append(HR())
1232     if not search_in_page:
1233     append(self.make_search_button(url))
1234     append(P(A(url.scriptRelative(""), "Home"),
1235     " - ", A(url.absolute("http://secure-testing.debian.net/"),
1236     "Testing Security Team"),
1237     " - ", A(url.absolute("http://www.debian.org/security/"),
1238     "Debian Security"),
1239     " - ", A(url.absolute
1240     ("http://www.enyo.de/fw/impressum.html"),
1241     "Imprint")))
1242     if search_in_page:
1243     on_load = "selectSearch()"
1244     else:
1245     on_load = None
1246     return HTMLResult(self.add_title(title, body,
1247     head_contents=self.head_contents,
1248     body_attribs={'onload': on_load}),
1249     doctype=self.html_dtd(),
1250     status=status)
1251    
1252     def make_search_button(self, url):
1253     return FORM("Search for package or bug name: ",
1254     INPUT(type='text', name='query',
1255     onkeyup="onSearch(this.value)",
1256     onmousemove="onSearch(this.value)"),
1257     INPUT(type='submit', value='Go'),
1258 fw 3597 ' ',
1259 fw 3596 A(url.scriptRelative("data/report"), "Reporting problems"),
1260 fw 2482 method='get',
1261     action=url.scriptRelative(''))
1262    
1263     def url_cve(self, url, name):
1264     return url.absolute("http://cve.mitre.org/cgi-bin/cvename.cgi",
1265     name=name)
1266 fw 2488 def url_nvd(self, url, name):
1267 thijs 9808 return url.absolute("http://web.nvd.nist.gov/view/vuln/detail",
1268     vulnId=name)
1269 geissert 13767 def url_rhbug(self, url, name):
1270     return url.absolute("https://bugzilla.redhat.com/show_bug.cgi",
1271     id=name)
1272 fw 2488
1273 fw 2482 def url_dsa(self, url, dsa, re_dsa=re.compile(r'^DSA-(\d+)(?:-\d+)?$')):
1274     match = re_dsa.match(dsa)
1275     if match:
1276     # We must determine the year because there is no generic URL.
1277     (number,) = match.groups()
1278     for (date,) in self.db.cursor().execute(
1279     "SELECT release_date FROM bugs WHERE name = ?", (dsa,)):
1280     (y, m, d) = date.split('-')
1281     return url.absolute("http://www.debian.org/security/%d/dsa-%d"
1282     % (int(y), int(number)))
1283     return None
1284    
1285     def url_debian_bug(self, url, debian):
1286     return url.absolute("http://bugs.debian.org/cgi-bin/bugreport.cgi",
1287     bug=str(debian))
1288     def url_debian_bug_pkg(self, url, debian):
1289     return url.absolute("http://bugs.debian.org/cgi-bin/pkgreport.cgi",
1290     pkg=debian)
1291     def url_pts(self, url, package):
1292     return url.absolute("http://packages.qa.debian.org/common/index.html",
1293     src=package)
1294     def url_testing_status(self, url, package):
1295 thijs 8112 return url.absolute("http://release.debian.org/migration/testing.pl",
1296 fw 2482 package=package)
1297     def url_source_package(self, url, package, full=False):
1298     if full:
1299     return url.scriptRelativeFull("source-package/" + package)
1300     else:
1301     return url.scriptRelative("source-package/" + package)
1302     def url_binary_package(self, url, package, full=False):
1303     if full:
1304     return url.scriptRelativeFull("binary-package/" + package)
1305     else:
1306     return url.scriptRelative("binary-package/" + package)
1307    
1308     def make_xref(self, url, name):
1309     return A(url.scriptRelative(name), name)
1310    
1311     def make_xref_list(self, url, lst, separator=', '):
1312     return make_list(map(lambda x: self.make_xref(url, x), lst), separator)
1313    
1314     def make_debian_bug(self, url, debian):
1315     return A(self.url_debian_bug(url, debian), str(debian))
1316     def make_debian_bug_list(self, url, lst):
1317     return make_list(map(lambda x: self.make_debian_bug(url, x), lst))
1318    
1319     def make_cve_ref(self, url, cve, name=None):
1320     if name is None:
1321     name = cve
1322     return A(self.url_cve(url, cve), name)
1323    
1324 fw 2488 def make_nvd_ref(self, url, cve, name=None):
1325     if name is None:
1326     name = cve
1327     return A(self.url_nvd(url, cve), name)
1328 geissert 13767
1329     def make_rhbug_ref(self, url, cve, name=None):
1330     if name is None:
1331     name = cve
1332     return A(self.url_rhbug(url, cve), name)
1333 fw 2488
1334 fw 2482 def make_dsa_ref(self, url, dsa, name=None):
1335     if name is None:
1336     name = dsa
1337     u = self.url_dsa(url, dsa)
1338     if u:
1339     return A(u, name)
1340     else:
1341     return name
1342    
1343     def make_pts_ref(self, url, pkg, name=None):
1344     if name is None:
1345     name = pkg
1346     return A(self.url_pts(url, pkg), name)
1347    
1348     def make_source_package_ref(self, url, pkg, title=None):
1349     if title is None:
1350     title = pkg
1351     return A(self.url_source_package(url, pkg), title)
1352     def make_binary_package_ref(self, url, pkg, title=None):
1353     if title is None:
1354     title = pkg
1355     return A(self.url_binary_package(url, pkg), title)
1356     def make_binary_packages_ref(self, url, lst):
1357     assert type(lst) <> types.StringType
1358     return make_list(map(lambda x: self.make_binary_package_ref(url, x),
1359     lst))
1360    
1361     def make_red(self, contents):
1362     return SPAN(contents, _class="red")
1363 gilbert-guest 13694
1364     def make_purple(self, contents):
1365     return SPAN(contents, _class="purple")
1366 fw 2482
1367     def make_dangerous(self, contents):
1368     return SPAN(contents, _class="dangerous")
1369    
1370     def pre_dispatch(self):
1371     self.db.refresh()
1372    
1373     TrackerService(socket_name, db_name).run()

Properties

Name Value
svn:mime-type text/script

  ViewVC Help
Powered by ViewVC 1.1.5