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

Contents of /bin/tracker_service.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3014 - (hide annotations) (download) (as text)
Mon Dec 12 15:28:39 2005 UTC (7 years, 5 months ago) by fw
File MIME type: text/script
File size: 41059 byte(s)
bin/tracker_service.py (TrackerService.page_status_release_unstable):
  Correct page title.
1 fw 2482 #!/usr/bin/python
2    
3     import sys
4     sys.path.insert(0,'../lib/python')
5    
6     if len(sys.argv) <> 3:
7     print "usage: python tracker_serivce.py SOCKET-PATH DATABASE-PATH"
8     sys.exit(1)
9     socket_name = sys.argv[1]
10     db_name = sys.argv[2]
11    
12     import bugs
13     import re
14     import security_db
15     from web_support import *
16    
17 fw 2491 class BugFilter:
18     def __init__(self, params):
19     self.hide_medium_urgency = int(params.get('hide_medium_urgency',
20     (0,))[0])
21     self.hide_non_remote = int(params.get('hide_non_remote',
22     (0,))[0])
23    
24     def actions(self, url):
25     """Returns a HTML snippet which can be used to change the filter."""
26     if self.hide_medium_urgency:
27     urg = A(url.updateParams(hide_medium_urgency=None),
28     'Show lower urgencies')
29     else:
30     urg = A(url.updateParams(hide_medium_urgency='1'),
31     'Hide lower urgencies')
32     if self.hide_non_remote:
33     rem = A(url.updateParams(hide_non_remote=None),
34     'Show local vulnerabilities')
35     else:
36     rem = A(url.updateParams(hide_non_remote='1'),
37     'Hide local vulnerabilities')
38     return P(urg, ' ', rem)
39    
40     def urgencyFiltered(self, urg):
41     """Returns True if the urgency urg is filtered."""
42     return self.hide_medium_urgency and urg not in ("high", "unknown", "")
43    
44     def remoteFiltered(self, remote):
45     """Returns True if the attack range is filtered."""
46     return remote is not None and self.hide_non_remote and not remote
47    
48 fw 2482 class TrackerService(WebService):
49     head_contents = compose(STYLE(
50     """h1 { font-size : 144%; }
51     h2 { font-size : 120%; }
52     h3 { font-size : 100%; }
53    
54     table { padding-left : 1.5em }
55     td, th { text-align : left;
56     padding-left : 0.25em;
57     padding-right : 0.25em; }
58     td { vertical-align: baseline }
59     span.red { color: red; }
60     span.dangerous { color: rgb(191,127,0); }
61     """), SCRIPT('''var old_query_value = "";
62    
63     function selectSearch() {
64     document.searchForm.query.focus();
65     }
66    
67     function onSearch(query) {
68     if (old_query_value == "") {
69     if (query.length > 5) {
70     old_query_value = query;
71     document.searchForm.submit();
72     } else {
73     old_query_value = query;
74     }
75     }
76     }
77     ''')).toHTML()
78    
79     def __init__(self, socket_name, db_name):
80     WebService.__init__(self, socket_name)
81     self.db = security_db.DB(db_name)
82     self.register('', self.page_home)
83     self.register('*', self.page_object)
84 fw 2485 self.register('redirect/*', self.page_redirect)
85 fw 2482 self.register('source-package/*', self.page_source_package)
86     self.register('binary-package/*', self.page_binary_package)
87     self.register('status/release/stable', self.page_status_release_stable)
88     self.register('status/release/testing',
89     self.page_status_release_testing)
90     self.register('status/release/unstable',
91     self.page_status_release_unstable)
92     self.register('status/dtsa-candidates',
93     self.page_status_dtsa_candidates)
94     self.register('status/todo', self.page_status_todo)
95     self.register('status/itp', self.page_status_itp)
96     self.register('data/unknown-packages', self.page_data_unknown_packages)
97     self.register('data/missing-epochs', self.page_data_missing_epochs)
98     self.register('data/releases', self.page_data_releases)
99     self.register('data/funny-versions', self.page_data_funny_versions)
100 fw 2554 self.register('data/fake-names', self.page_data_fake_names)
101 fw 2482
102     def page_home(self, path, params, url):
103     query = params.get('query', ('',))[0]
104     if query:
105     if '/' in query:
106     return self.page_not_found(url, query)
107     else:
108     return RedirectResult(url.scriptRelativeFull(query))
109    
110     return self.create_page(
111     url, 'Security Bug Tracker',
112     [P(
113     """This is the experimental issue tracker for Debian's testing
114     security team. Keep in mind that this is merely a prototype.
115     Please report any problems to """,
116     A("mailto:fw@deneb.enyo.de", "Florian Weimer"),
117     """.Note that some of the data presented here is known
118     to be wrong (see below), but the data for the testing suite
119     should be fine."""),
120     make_menu(
121     url.scriptRelative,
122     ('status/release/stable',
123     'Vulnerable packages in the stable suite'),
124     ('status/release/testing',
125     'Vulnerable packages in the testing suite'),
126     ('status/release/unstable',
127     'Vulnerable packages in the unstable suite'),
128     ('status/dtsa-candidates', "Candidates for DTSAs"),
129     ('status/todo', 'TODO items'),
130     ('status/itp', 'ITPs with potential security issues'),
131     ('data/unknown-packages',
132     'Packages names not found in the archive'),
133 fw 2554 ('data/fake-names', 'Tracked issues without a CVE name'),
134 fw 2482 ('data/missing-epochs',
135     'Package versions which might lack an epoch'),
136     ('data/funny-versions',
137     'Packages with strange version numbers'),
138     ('data/releases',
139     'Covered Debian releases and architectures (slow)'),
140     self.make_search_button(url)),
141 fw 2495 P("""(You can enter CVE names, Debian bug numbers and package
142 fw 2488 names in the search forms.)"""),
143 fw 2482
144 fw 2489 H2("Data sources"),
145 fw 2482 P("""Data in this tracker comes solely from the bug database
146     which is maintained by Debian's testing security team in their
147     Subversion repository. All external data (this includes
148     Debian bug reports and official Debian security advisories)
149     must be added to this database before it appears here, and there
150     can be some delay before this happens."""),
151     P("""At the moment, the database only contains information which is
152     relevant for tracking the security status of the stable, testing and
153 fw 2488 unstable suites. This means that data for oldstable is likely wrong."""),
154 fw 2489 P('Data marked "NVD" comes from the ',
155     A(url.absolute('http://nvd.nist.gov/'),
156     'National Vulnerability Database'),
157     ' maintained by NIST.'),
158 fw 2488
159     H2("External interfaces"),
160     P("""If you want to automatically open a relevant web page for
161     some object, use the """,
162     CODE(str(url.scriptRelative("redirect/")), EM("object")),
163     """ URL. If no information is contained in this database,
164     the browser is automatically redirected to the corresponding external
165     data source.""")],
166 fw 2482 search_in_page=True)
167    
168     def page_object(self, path, params, url):
169     obj = path[0]
170 fw 2485 return self.page_object_or_redirect(url, obj, False)
171 fw 2482
172 fw 2485 def page_redirect(self, path, params, url):
173     obj = path[0]
174     return self.page_object_or_redirect(url, obj, True)
175    
176     def page_object_or_redirect(self, url, obj, redirect):
177     c = self.db.cursor()
178    
179 fw 2482 if not obj:
180     # Redirect to start page.
181     return RedirectResult(url.scriptRelativeFull(""))
182    
183     if 'A' <= obj[0] <= 'Z':
184     # Bug names start with a capital letter.
185 fw 2485 return self.page_bug(url, obj, redirect)
186 fw 2482
187     bugnumber = 0
188     try:
189     bugnumber = int(obj)
190     except ValueError:
191     pass
192     if bugnumber:
193 fw 2485 buglist = list(self.db.getBugsFromDebianBug(c, bugnumber))
194     if buglist:
195     return self.page_debian_bug(url, bugnumber, buglist)
196     if redirect:
197     return RedirectResult(self.url_debian_bug(url, str(bugnumber)),
198     permanent=False)
199 fw 2482
200     if self.db.isSourcePackage(c, obj):
201     return RedirectResult(self.url_source_package(url, obj, full=True))
202     if self.db.isBinaryPackage(c, obj):
203     return RedirectResult(self.url_binary_package(url ,obj, full=True))
204    
205     return self.page_not_found(url, obj)
206    
207 fw 2485 def page_bug(self, url, name, redirect):
208 fw 2511 # FIXME: Normalize CAN-* to CVE-* when redirecting. Too many
209     # people still use CAN.
210     if redirect and name[0:4] == 'CAN-':
211     name = 'CVE-' + name[4:]
212    
213 fw 2482 cursor = self.db.cursor()
214     try:
215     bug = bugs.BugFromDB(cursor, name)
216     except ValueError:
217 fw 2485 if redirect:
218 fw 2495 if name[0:4] == 'CVE-':
219 fw 2485 return RedirectResult(self.url_cve(url, name),
220     permanent=False)
221 fw 2482 return self.page_not_found(url, name)
222 fw 2485 if bug.name <> name or redirect:
223 fw 2482 # Show the normalized bug name in the browser address bar.
224     return RedirectResult(url.scriptRelativeFull(bug.name))
225    
226     page = []
227    
228     def gen_header():
229     yield B("Name"), bug.name
230    
231     source = bug.name.split('-')[0]
232 fw 2495 if source == 'CVE':
233 fw 2488 source_xref = compose(self.make_cve_ref(url, bug.name, 'CVE'),
234     " (",
235     self.make_nvd_ref(url, bug.name,
236     'in NVD'),
237     ")")
238 fw 2482 elif source == 'DSA':
239     source_xref = self.make_dsa_ref(url, bug.name, 'Debian')
240     elif source == 'DTSA':
241     source_xref = 'Debian Testing Security Team'
242     elif source == 'FAKE':
243     source_xref = (
244     'Automatically generated temporary name. Not for external reference.')
245     else:
246     source_xref = None
247    
248     if source_xref:
249     yield B("Source"), source_xref
250    
251     if bug.description:
252     yield B("Description"), bug.description
253    
254     xref = list(self.db.getBugXrefs(cursor, bug.name))
255     if xref:
256     yield B("References"), self.make_xref_list(url, xref)
257 fw 2488
258     nvd = self.db.getNVD(cursor, bug.name)
259     if nvd:
260     if nvd.severity:
261     yield B("NVD severity"), nvd.severity.lower()
262     nvd_range = nvd.rangeString()
263     if nvd_range:
264     yield B("NVD attack range"), nvd_range
265 fw 2482
266     debian_bugs = bug.getDebianBugs(cursor)
267     if debian_bugs:
268     yield (B("Debian Bugs"),
269     self.make_debian_bug_list(url, debian_bugs))
270    
271     if not bug.not_for_us:
272     for (release, status, reason) in bug.getStatus(cursor):
273     if status <> 'fixed':
274     reason = self.make_red(reason)
275     yield B('Status of %s' % release), reason
276    
277     page.append(make_table(gen_header()))
278    
279     if bug.notes:
280     page.append(H2("Vulnerable and fixed packages"))
281    
282     def gen_source():
283     old_pkg = ''
284     for (package, release, version, vulnerable) \
285     in self.db.getSourcePackages(cursor, bug.name):
286     if package == old_pkg:
287     package = ''
288     else:
289     old_pkg = package
290     package = compose(
291     self.make_source_package_ref(url, package),
292     " (", self.make_pts_ref(url, package, 'PTS'), ")")
293     if vulnerable:
294     vuln = self.make_red('vulnerable')
295     version = self.make_red(version)
296     else:
297     vuln = 'fixed'
298    
299     yield package, ', '.join(release), version, vuln
300    
301     page.append(make_table(gen_source(),
302     caption=("Source Package", "Release", "Version", "Status"),
303     introduction=P('The table below lists information on source packages.')))
304    
305     def gen_binary():
306     old_pkg = ''
307     for (packages, releases, version, archs, vulnerable) \
308     in self.db.getBinaryPackages(cursor, bug.name):
309     pkg = ', '.join(packages)
310     if pkg == old_pkg:
311     packages = ''
312     else:
313     old_pkg = pkg
314     packages = self.make_binary_packages_ref(url, packages)
315    
316     if vulnerable:
317     vuln = self.make_red('vulnerable')
318     version = self.make_red(version)
319     else:
320     vuln = 'fixed'
321     yield (packages,
322     ', '.join(releases),
323     version, vuln,
324     ', '.join(archs))
325    
326     page.append(make_table(gen_binary(),
327     caption=("Binary Package", "Release", "Version", "Status",
328     "Architecures"),
329     introduction=P("The next table lists affected binary packages.")))
330    
331     def gen_data():
332     notes_sorted = bug.notes[:]
333     notes_sorted.sort(lambda a, b: cmp(a.package, b.package))
334     for n in notes_sorted:
335     if n.release:
336     rel = str(n.release)
337     else:
338     rel = '(unstable)'
339     urgency = str(n.urgency)
340     if n.fixed_version:
341     ver = str(n.fixed_version)
342     if ver == '0':
343     ver = '(not affected)'
344     urgency = ''
345     else:
346     ver = self.make_red('(unfixed)')
347    
348     pkg = n.package
349     pkg_kind = n.package_kind
350     if pkg_kind == 'source':
351     pkg = self.make_source_package_ref(url, pkg)
352     elif pkg_kind == 'binary':
353     pkg = self.make_binary_package_ref(url, pkg)
354     elif pkg_kind == 'itp':
355     pkg_kind = 'ITP'
356     rel = ''
357     ver = ''
358     urgency = ''
359    
360     bugs = n.bugs
361     bugs.sort()
362     bugs = make_list(
363     map(lambda x: self.make_debian_bug(url, x), bugs))
364     if n.bug_origin:
365     origin = self.make_xref(url, n.bug_origin)
366     else:
367     origin = ''
368     yield (pkg, pkg_kind, rel, ver, urgency, origin, bugs)
369    
370     page.append(
371     make_table(gen_data(),
372     caption=("Package", "Type", "Release", "Fixed Version",
373     "Urgency", "Origin", "Debian Bugs"),
374     introduction=P("The information above is based on the following data on fixed versions.")))
375    
376     if bug.comments:
377     page.append(H2("Notes"))
378     def gen_comments():
379     for (t, c) in bug.comments:
380     yield c
381     page.append(make_pre(gen_comments()))
382    
383     return self.create_page(url, bug.name, page)
384    
385 fw 2485 def page_debian_bug(self, url, bugnumber, buglist):
386     if len(buglist) == 1:
387     # Single issue, redirect.
388     return RedirectResult(url.scriptRelativeFull(buglist[0][0]))
389 fw 2482
390 fw 2485 def gen():
391     for (name, urgency, description) in buglist:
392     if urgency == "unknown":
393     urgency = ""
394     yield self.make_xref(url, name), urgency, description
395 fw 2482
396 fw 2485 return self.create_page(
397     url, "Information related to Debian bug #%d" % bugnumber,
398     [P("The following issues reference to Debian bug ",
399     self.make_debian_bug(url, bugnumber), ":"),
400     make_table(gen(),
401     caption=("Name", "Urgency", "Description"))])
402 fw 2482
403     def page_not_found(self, url, query):
404     return self.create_page(url, 'Not found',
405     [P('Your query ',
406     CODE(query),
407     ' matched no results.')],
408     status=404)
409    
410     def page_source_package(self, path, params, url):
411     pkg = path[0]
412    
413     def gen_versions():
414     for (releases, version) in self.db.getSourcePackageVersions(
415     self.db.cursor(), pkg):
416     yield ', '.join(releases), version
417     def gen_binary():
418     for (packages, releases, archs, version) \
419     in self.db.getBinaryPackagesForSource(
420     self.db.cursor(), pkg):
421     yield (self.make_binary_packages_ref(url, packages),
422     ', '.join(releases), version, ', '.join(archs))
423     def gen_bug_list(lst):
424     for (bug, description) in lst:
425     yield self.make_xref(url, bug), description
426    
427     return self.create_page(
428     url, "Information on source package " + pkg,
429     [make_menu(lambda x: x,
430     (self.url_pts(url, pkg),
431     pkg + ' in the Package Tracking System'),
432     (self.url_debian_bug_pkg(url, pkg),
433     pkg + ' in the Bug Tracking System'),
434     (self.url_testing_status(url, pkg),
435     pkg + ' in the testing migration checker')),
436     H2("Available versions"),
437     make_table(gen_versions(), caption=("Release", "Version")),
438    
439     H2("Available binary packages"),
440     make_table(gen_binary(),
441     caption=('Package', 'Release', 'Version', 'Architectures'),
442     replacement="""No binary packages are recorded in this database.
443     This probably means that the package is architecture-specific, and the
444     architecture is currently not tracked."""),
445    
446     H2("Open issues"),
447     make_table(gen_bug_list(self.db.getBugsForSourcePackage
448     (self.db.cursor(), pkg, True)),
449     caption=('Bug', 'Description'),
450     replacement='No known open issues.'),
451    
452     H2("Resolved issues"),
453     make_table(gen_bug_list(self.db.getBugsForSourcePackage
454     (self.db.cursor(), pkg, False)),
455     caption=('Bug', 'Description'),
456     replacement='No known resolved issues.')])
457    
458     def page_binary_package(self, path, params, url):
459     pkg = path[0]
460    
461     def gen_versions():
462     for (releases, source, version, archs) \
463     in self.db.getBinaryPackageVersions(self.db.cursor(), pkg):
464     yield (', '.join(releases),
465     self.make_source_package_ref(url, source),
466     version, ', '.join(archs))
467     def gen_bug_list(lst):
468     for (bug, description) in lst:
469     yield self.make_xref(url, bug), description
470    
471     return self.create_page(
472     url, "Information on binary package " + pkg,
473     [make_menu(lambda x: x,
474     (self.url_debian_bug_pkg(url, pkg),
475     pkg + ' in the Bug Tracking System')),
476     H2("Available versions"),
477     make_table(gen_versions(),
478     caption=("Release", "Source", "Version", "Architectures")),
479    
480     H2("Open issues"),
481     make_table(gen_bug_list(self.db.getBugsForBinaryPackage
482     (self.db.cursor(), pkg, True)),
483     caption=('Bug', 'Description'),
484     replacement='No known open issues.'),
485    
486     H2("Resolved issues"),
487     make_table(gen_bug_list(self.db.getBugsForBinaryPackage
488     (self.db.cursor(), pkg, False)),
489     caption=('Bug', 'Description'),
490     replacement='No known resolved issues.'),
491    
492     H2("Non-issues"),
493     make_table(gen_bug_list(self.db.getNonBugsForBinaryPackage
494     (self.db.cursor(), pkg)),
495     caption=('Bug', 'Description'),
496     replacement="""No known issues which do not affect
497     this package, but still reference it.""")])
498    
499     def page_status_release_stable(self, path, params, url):
500 fw 2491 bf = BugFilter(params)
501    
502 fw 2482 def gen():
503     old_pkg_name = ''
504 fw 2488 for (pkg_name, bug_name, archive, urgency, remote) in \
505 fw 2482 self.db.cursor().execute(
506 fw 2488 """SELECT package, bug, section, urgency, remote
507     FROM stable_status"""):
508 fw 2491 if bf.urgencyFiltered(urgency):
509     continue
510     if bf.remoteFiltered(remote):
511     continue
512    
513 fw 2482 if pkg_name == old_pkg_name:
514     pkg_name = ''
515     else:
516     old_pkg_name = pkg_name
517     if archive <> 'main':
518     pkg_name = "%s (%s)" % (pkg_name, archive)
519    
520 fw 2488 if remote is None:
521     remote = ''
522     elif remote:
523     remote = 'yes'
524     else:
525     remote = 'no'
526    
527 fw 2482 if urgency == 'unknown':
528     urgency = ''
529     elif urgency == 'high':
530     urgency = self.make_red(urgency)
531    
532 fw 2488 yield pkg_name, self.make_xref(url, bug_name), urgency, remote
533 fw 2482
534     return self.create_page(
535     url, 'Vulnerable source packages in the stable suite',
536 fw 2491 [bf.actions(url),
537     make_table(gen(), caption=("Package", "Bug", "Urgency",
538 fw 2488 "Remote"))])
539 fw 2482
540     def page_status_release_testing(self, path, params, url):
541 fw 2491 bf = BugFilter(params)
542    
543 fw 2482 def gen():
544     old_pkg_name = ''
545     for (pkg_name, bug_name, archive, urgency,
546 fw 2488 sid_vulnerable, ts_fixed, remote) in self.db.cursor().execute(
547 fw 2482 """SELECT package, bug, section, urgency, unstable_vulnerable,
548 fw 2488 testing_security_fixed, remote
549 fw 2482 FROM testing_status"""):
550 fw 2491 if bf.urgencyFiltered(urgency):
551     continue
552     if bf.remoteFiltered(remote):
553     continue
554    
555 fw 2482 if pkg_name == old_pkg_name:
556     pkg_name = ''
557     else:
558     old_pkg_name = pkg_name
559     if archive <> 'main':
560     pkg_name = "%s (%s)" % (pkg_name, archive)
561    
562 fw 2488 if remote is None:
563     remote = ''
564     elif remote:
565     remote = 'yes'
566     else:
567     remote = 'no'
568    
569 fw 2482 if ts_fixed:
570     status = 'fixed in testing-security'
571     else:
572     if sid_vulnerable:
573     status = self.make_red('unstable is vulnerable')
574     else:
575     status = self.make_dangerous('fixed in unstable')
576    
577     if urgency == 'unknown':
578     urgency = ''
579    
580     yield (pkg_name, self.make_xref(url, bug_name),
581 fw 2488 urgency, remote, status)
582 fw 2482
583     return self.create_page(
584     url, 'Vulnerable source packages in the testing suite',
585     [make_menu(url.scriptRelative,
586     ("status/dtsa-candidates", "Candidates for DTSAs")),
587 fw 2491 bf.actions(url),
588 fw 2488 make_table(gen(), caption=("Package", "Bug", "Urgency",
589     "Remote"))])
590 fw 2482
591     def page_status_release_unstable(self, path, params, url):
592 fw 2491 bf = BugFilter(params)
593    
594 fw 2482 def gen():
595     old_pkg_name = ''
596 fw 2491 for (pkg_name, bug_name, section, urgency, remote) \
597 fw 2482 in self.db.cursor().execute(
598     """SELECT DISTINCT sp.name, st.bug_name,
599 fw 2491 sp.archive, st.urgency,
600     (SELECT range_remote FROM nvd_data
601     WHERE cve_name = st.bug_name)
602 fw 2482 FROM source_package_status AS st, source_packages AS sp
603     WHERE st.vulnerable AND st.urgency <> 'unimportant'
604     AND sp.rowid = st.package AND sp.release = 'sid'
605     AND sp.subrelease = ''
606     ORDER BY sp.name, st.bug_name"""):
607 fw 2491 if bf.urgencyFiltered(urgency):
608     continue
609     if bf.remoteFiltered(remote):
610     continue
611    
612 fw 2482 if pkg_name == old_pkg_name:
613     pkg_name = ''
614     else:
615     old_pkg_name = pkg_name
616     if section <> 'main':
617     pkg_name = "%s (%s)" % (pkg_name, section)
618     else:
619     pkg_name = self.make_xref(url, pkg_name)
620    
621 fw 2491 if remote is None:
622     remote = ''
623     elif remote:
624     remote = 'yes'
625     else:
626     remote = 'no'
627    
628 fw 2482 if urgency == 'unknown':
629     urgency = ''
630     elif urgency == 'high':
631     urgency = self.make_red(urgency)
632    
633 fw 2491 yield pkg_name, self.make_xref(url, bug_name), urgency, remote
634 fw 2482
635    
636     return self.create_page(
637 fw 3014 url, 'Vulnerable source packages in the unstable suite',
638 fw 2482 [P("""Note that the list below is based on source packages.
639     This means that packages are not listed here once a new,
640     fixed source version has been uploaded to the archive, even
641     if there are still some vulnerably binary packages present
642     in the archive."""),
643 fw 2491 bf.actions(url),
644     make_table(gen(), caption=('Package', 'Bug', 'Urgency',
645     'Remote'))])
646 fw 2482
647     def page_status_dtsa_candidates(self, path, params, url):
648 fw 2491 bf = BugFilter(params)
649    
650 fw 2482 def gen():
651     old_pkg_name = ''
652 fw 2491 for (pkg_name, bug_name, archive, urgency, stable_later,
653     remote) \
654 fw 2482 in self.db.cursor().execute(
655     """SELECT package, bug, section, urgency,
656     (SELECT testing.version_id < stable.version_id
657     FROM source_packages AS testing, source_packages AS stable
658     WHERE testing.name = testing_status.package
659     AND testing.release = 'etch'
660     AND testing.subrelease = ''
661     AND testing.archive = testing_status.section
662     AND stable.name = testing_status.package
663     AND stable.release = 'sarge'
664     AND stable.subrelease = 'security'
665 fw 2491 AND stable.archive = testing_status.section),
666     (SELECT range_remote FROM nvd_data
667     WHERE cve_name = bug)
668 fw 2482 FROM testing_status
669     WHERE (NOT unstable_vulnerable)
670     AND (NOT testing_security_fixed)"""):
671 fw 2491 if bf.urgencyFiltered(urgency):
672     continue
673     if bf.remoteFiltered(remote):
674     continue
675    
676 fw 2482 if pkg_name == old_pkg_name:
677     pkg_name = ''
678     migration = ''
679     else:
680     old_pkg_name = pkg_name
681     migration = A(self.url_testing_status(url, pkg_name),
682     "check")
683     if archive <> 'main':
684     pkg_name = "%s (%s)" % (pkg_name, archive)
685     else:
686     pkg_name = self.make_source_package_ref(url, pkg_name)
687    
688 fw 2491 if remote is None:
689     remote = ''
690     elif remote:
691     remote = 'yes'
692     else:
693     remote = 'no'
694    
695 fw 2482 if urgency == 'unknown':
696     urgency = ''
697     elif urgency == 'high':
698     urgency = self.make_red(urgency)
699    
700     if stable_later:
701     notes = "(fixed in stable?)"
702     else:
703     notes = ''
704    
705     yield (pkg_name, migration, self.make_xref(url, bug_name),
706 fw 2491 urgency, remote, notes)
707 fw 2482
708     return self.create_page(
709     url, "Candidates for DTSAs",
710     [P("""The table below lists packages which are fixed
711     in unstable, but unfixed in testing. Use the testing migration
712 fw 2679 checker to find out why they have not entered testing yet."""),
713 fw 2482 make_menu(url.scriptRelative,
714     ("status/release/testing",
715     "List of vulnerable packages in testing")),
716 fw 2491 bf.actions(url),
717 fw 2482 make_table(gen(),
718 fw 2491 caption=("Package", "Migration", "Bug", "Urgency",
719     "Remote"))])
720 fw 2482
721     def page_status_todo(self, path, params, url):
722     def gen():
723     for (bug, description) in self.db.getTODOs():
724     yield self.make_xref(url, bug), description
725     return self.create_page(
726     url, "Bugs with TODO items",
727     [make_table(gen(),
728     caption=("Bug", "Description"))])
729    
730     def page_status_itp(self, path, params, url):
731     def gen():
732     old_pkg = ''
733     for pkg, bugs, debian_bugs in self.db.getITPs(self.db.cursor()):
734     if pkg == old_pkg:
735     pkg = ''
736     else:
737     old_pkg = pkg
738     yield (pkg, self.make_xref_list(url, bugs),
739     self.make_debian_bug_list(url, debian_bugs))
740     return self.create_page(
741     url, "ITPs with potential security issues",
742     [make_table(gen(), caption=("Package", "Issue", "Debian Bugs"),
743     replacement="No ITP bugs are currently known.")])
744    
745     def page_data_unknown_packages(self, path, params, url):
746     def gen():
747     for name, bugs in self.db.getUnknownPackages(self.db.cursor()):
748     yield name, self.make_xref_list(url, bugs)
749     return self.create_page(
750     url, "Unknown packages",
751     [P("""Sometimes, a package referenced in a bug report
752     cannot be found in the database. This can be the result of a spelling
753     return web_supporterror, or a historic entry refers to a
754     return web_supportpackage which is no longer in the archive."""),
755     make_table(gen(), caption=("Package", "Bugs"),
756     replacement="No unknown packages are referenced in the database.")])
757    
758     def page_data_missing_epochs(self, path, params, url):
759     def gen():
760     old_bug = ''
761     old_pkg = ''
762     for bug, pkg, ver1, ver2 in self.db.cursor().execute(
763     """SELECT DISTINCT bug_name, n.package,
764     n.fixed_version, sp.version
765     FROM package_notes AS n, source_packages AS sp
766     WHERE n.package_kind = 'source'
767     AND n.fixed_version NOT LIKE '%:%'
768     AND n.fixed_version <> '0'
769     AND n.bug_origin = ''
770     AND sp.name = n.package
771     AND sp.version LIKE '%:%'
772     ORDER BY bug_name, package"""):
773     if bug == old_bug:
774     bug = ''
775     else:
776     old_bug = bug
777     old_pkg = ''
778     bug = self.make_xref(url, bug)
779     if pkg == old_pkg:
780     pkg = ''
781     else:
782     old_pkg = pkg
783     pkg = self.make_source_package_ref(url, pkg)
784     yield bug, pkg, ver1, ver2
785    
786     return self.create_page(
787     url, "Missing epochs in package versions",
788     [make_table(gen(),
789     caption=("Bug", "Package", "Version 1", "Version 2"),
790     replacement="No source package version with missing epochs.")])
791    
792     def page_data_releases(self, path, params, url):
793     def gen():
794     for (rel, subrel, archive, sources, archs) \
795     in self.db.availableReleases():
796     if sources:
797     sources = 'yes'
798     else:
799     sources = 'no'
800     yield rel, subrel, archive, sources, make_list(archs)
801     return self.create_page(
802     url, "Available releases",
803     [P("""The security issue database is checked against
804     the Debian releases listed in the table below."""),
805     make_table(gen(),
806     caption=("Release", "Subrelease", "Archive",
807     "Sources", "Architectures"))])
808    
809     def page_data_funny_versions(self, path, params, url):
810     def gen():
811     for name, release, archive, version, source_version \
812     in self.db.getFunnyPackageVersions():
813     yield name, release, archive, source_version, version
814    
815     return self.create_page(
816     url, "Version conflicts between source/binary packages",
817     [P("""The table below lists source packages
818     which have a binary package of the same name, but with a different
819     version. This means that extra care is necessary to determine
820     the version of a package which has been fixed. (Note that
821     the bug tracker prefers source versions to binary versions
822     in this case.)"""),
823     make_table(gen(),
824     caption=("Package",
825     "Release",
826     "Archive",
827     "Source Version",
828     "Binary Version")),
829     P("""Technically speaking, these version numbering is fine,
830     but it makes version-based bug tracking quite difficult for these packages."""),
831     P("""There are many binary packages which are built from source
832     packages with different version numbering schemes. However, as
833     long as none of the binary packages carries the same name as the
834     source package, most confusion is avoided or can be easily
835     explained.""")])
836    
837 fw 2554 def page_data_fake_names(self, path, params, url):
838     def gen():
839     for (bug, description) in self.db.getFakeBugs():
840     yield self.make_xref(url, bug), description
841     return self.create_page(
842     url, "Automatically generated issue names",
843     [P("""Some issues have not been assigned CVE names, but are still
844     tracked by this database. In this case, the system automatically assigns
845     a unique name. These names are not stable and can change when the database
846     is updated, so they should not be used in external references."""),
847     P('''The automatically generated names come in two flavors:
848     the first kind starts with the string "''', CODE("FAKE-000000-"),
849     '''". This means that no Debian bug has been assigned to this
850     issue (or a bug has been created and is not recorded in this database).
851     In the second kind of names, there is a Debian bug for the issue, and the "''',
852     CODE("000000"), '''"part of the name is replaced with the
853     Debian bug number.'''),
854     make_table(gen(),
855     caption=("Bug", "Description"))])
856    
857 fw 2482 def create_page(self, url, title, body, search_in_page=False, status=200):
858     append = body.append
859     append(HR())
860     if not search_in_page:
861     append(self.make_search_button(url))
862     append(P(A(url.scriptRelative(""), "Home"),
863     " - ", A(url.absolute("http://secure-testing.debian.net/"),
864     "Testing Security Team"),
865     " - ", A(url.absolute("http://www.debian.org/security/"),
866     "Debian Security"),
867     " - ", A(url.absolute
868     ("http://www.enyo.de/fw/impressum.html"),
869     "Imprint")))
870     if search_in_page:
871     on_load = "selectSearch()"
872     else:
873     on_load = None
874     return HTMLResult(self.add_title(title, body,
875     head_contents=self.head_contents,
876     body_attribs={'onload': on_load}),
877     doctype=self.html_dtd(),
878     status=status)
879    
880     def make_search_button(self, url):
881     return FORM("Search for package or bug name: ",
882     INPUT(type='text', name='query',
883     onkeyup="onSearch(this.value)",
884     onmousemove="onSearch(this.value)"),
885     INPUT(type='submit', value='Go'),
886     method='get',
887     action=url.scriptRelative(''))
888    
889     def url_cve(self, url, name):
890     return url.absolute("http://cve.mitre.org/cgi-bin/cvename.cgi",
891     name=name)
892 fw 2488 def url_nvd(self, url, name):
893     return url.absolute("http://nvd.nist.gov/nvd.cfm",
894     cvename=name)
895    
896 fw 2482 def url_dsa(self, url, dsa, re_dsa=re.compile(r'^DSA-(\d+)(?:-\d+)?$')):
897     match = re_dsa.match(dsa)
898     if match:
899     # We must determine the year because there is no generic URL.
900     (number,) = match.groups()
901     for (date,) in self.db.cursor().execute(
902     "SELECT release_date FROM bugs WHERE name = ?", (dsa,)):
903     (y, m, d) = date.split('-')
904     return url.absolute("http://www.debian.org/security/%d/dsa-%d"
905     % (int(y), int(number)))
906     return None
907    
908     def url_debian_bug(self, url, debian):
909     return url.absolute("http://bugs.debian.org/cgi-bin/bugreport.cgi",
910     bug=str(debian))
911     def url_debian_bug_pkg(self, url, debian):
912     return url.absolute("http://bugs.debian.org/cgi-bin/pkgreport.cgi",
913     pkg=debian)
914     def url_pts(self, url, package):
915     return url.absolute("http://packages.qa.debian.org/common/index.html",
916     src=package)
917     def url_testing_status(self, url, package):
918     return url.absolute("http://bjorn.haxx.se/debian/testing.pl",
919     package=package)
920     def url_source_package(self, url, package, full=False):
921     if full:
922     return url.scriptRelativeFull("source-package/" + package)
923     else:
924     return url.scriptRelative("source-package/" + package)
925     def url_binary_package(self, url, package, full=False):
926     if full:
927     return url.scriptRelativeFull("binary-package/" + package)
928     else:
929     return url.scriptRelative("binary-package/" + package)
930    
931     def make_xref(self, url, name):
932     return A(url.scriptRelative(name), name)
933    
934     def make_xref_list(self, url, lst, separator=', '):
935     return make_list(map(lambda x: self.make_xref(url, x), lst), separator)
936    
937     def make_debian_bug(self, url, debian):
938     return A(self.url_debian_bug(url, debian), str(debian))
939     def make_debian_bug_list(self, url, lst):
940     return make_list(map(lambda x: self.make_debian_bug(url, x), lst))
941    
942     def make_cve_ref(self, url, cve, name=None):
943     if name is None:
944     name = cve
945     return A(self.url_cve(url, cve), name)
946    
947 fw 2488 def make_nvd_ref(self, url, cve, name=None):
948     if name is None:
949     name = cve
950     return A(self.url_nvd(url, cve), name)
951    
952 fw 2482 def make_dsa_ref(self, url, dsa, name=None):
953     if name is None:
954     name = dsa
955     u = self.url_dsa(url, dsa)
956     if u:
957     return A(u, name)
958     else:
959     return name
960    
961     def make_pts_ref(self, url, pkg, name=None):
962     if name is None:
963     name = pkg
964     return A(self.url_pts(url, pkg), name)
965    
966     def make_source_package_ref(self, url, pkg, title=None):
967     if title is None:
968     title = pkg
969     return A(self.url_source_package(url, pkg), title)
970     def make_binary_package_ref(self, url, pkg, title=None):
971     if title is None:
972     title = pkg
973     return A(self.url_binary_package(url, pkg), title)
974     def make_binary_packages_ref(self, url, lst):
975     assert type(lst) <> types.StringType
976     return make_list(map(lambda x: self.make_binary_package_ref(url, x),
977     lst))
978    
979     def make_red(self, contents):
980     return SPAN(contents, _class="red")
981    
982     def make_dangerous(self, contents):
983     return SPAN(contents, _class="dangerous")
984    
985     def pre_dispatch(self):
986     self.db.refresh()
987    
988     TrackerService(socket_name, db_name).run()

Properties

Name Value
svn:mime-type text/script

  ViewVC Help
Powered by ViewVC 1.1.5