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

Contents of /bin/tracker_service.py

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:mime-type text/script

  ViewVC Help
Powered by ViewVC 1.1.5