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

Contents of /bin/tracker_service.py

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:mime-type text/script

  ViewVC Help
Powered by ViewVC 1.1.5