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

Contents of /bin/tracker_service.py

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:mime-type text/script

  ViewVC Help
Powered by ViewVC 1.1.5