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

Contents of /bin/tracker_service.py

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:mime-type text/script

  ViewVC Help
Powered by ViewVC 1.1.5