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

Contents of /bin/tracker_service.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 29230 - (show annotations) (download) (as text)
Fri Oct 3 07:39:03 2014 UTC (3 weeks ago) by holger
File MIME type: text/script
File size: 62210 byte(s)
Revert "Include squeeze- and wheezy-backports in issue and package views. (Closes: #664866)"

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

Properties

Name Value
svn:mime-type text/script

  ViewVC Help
Powered by ViewVC 1.1.5