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

Diff of /bin/tracker_service.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2482 by fw, Thu Oct 20 09:02:12 2005 UTC revision 2554 by fw, Mon Oct 24 14:43:04 2005 UTC
# Line 14  import re Line 14  import re
14  import security_db  import security_db
15  from web_support import *  from web_support import *
16    
17    class BugFilter:
18        def __init__(self, params):
19            self.hide_medium_urgency = int(params.get('hide_medium_urgency',
20                                                      (0,))[0])
21            self.hide_non_remote = int(params.get('hide_non_remote',
22                                                  (0,))[0])
23    
24        def actions(self, url):
25            """Returns a HTML snippet which can be used to change the filter."""
26            if self.hide_medium_urgency:
27                urg = A(url.updateParams(hide_medium_urgency=None),
28                        'Show lower urgencies')
29            else:
30                urg = A(url.updateParams(hide_medium_urgency='1'),
31                        'Hide lower urgencies')
32            if self.hide_non_remote:
33                rem = A(url.updateParams(hide_non_remote=None),
34                        'Show local vulnerabilities')
35            else:
36                rem = A(url.updateParams(hide_non_remote='1'),
37                        'Hide local vulnerabilities')
38            return P(urg, ' ', rem)
39    
40        def urgencyFiltered(self, urg):
41            """Returns True if the urgency urg is filtered."""
42            return self.hide_medium_urgency and urg not in ("high", "unknown", "")
43    
44        def remoteFiltered(self, remote):
45            """Returns True if the attack range is filtered."""
46            return remote is not None and self.hide_non_remote and not remote
47    
48  class TrackerService(WebService):  class TrackerService(WebService):
49      head_contents = compose(STYLE(      head_contents = compose(STYLE(
50          """h1 { font-size : 144%; }          """h1 { font-size : 144%; }
# Line 50  function onSearch(query) { Line 81  function onSearch(query) {
81          self.db = security_db.DB(db_name)          self.db = security_db.DB(db_name)
82          self.register('', self.page_home)          self.register('', self.page_home)
83          self.register('*', self.page_object)          self.register('*', self.page_object)
84            self.register('redirect/*', self.page_redirect)
85          self.register('source-package/*', self.page_source_package)          self.register('source-package/*', self.page_source_package)
86          self.register('binary-package/*', self.page_binary_package)          self.register('binary-package/*', self.page_binary_package)
87          self.register('status/release/stable', self.page_status_release_stable)          self.register('status/release/stable', self.page_status_release_stable)
# Line 65  function onSearch(query) { Line 97  function onSearch(query) {
97          self.register('data/missing-epochs', self.page_data_missing_epochs)          self.register('data/missing-epochs', self.page_data_missing_epochs)
98          self.register('data/releases', self.page_data_releases)          self.register('data/releases', self.page_data_releases)
99          self.register('data/funny-versions', self.page_data_funny_versions)          self.register('data/funny-versions', self.page_data_funny_versions)
100            self.register('data/fake-names', self.page_data_fake_names)
101    
102      def page_home(self, path, params, url):      def page_home(self, path, params, url):
103          query = params.get('query', ('',))[0]          query = params.get('query', ('',))[0]
# Line 97  should be fine."""), Line 130  should be fine."""),
130              ('status/itp', 'ITPs with potential security issues'),              ('status/itp', 'ITPs with potential security issues'),
131              ('data/unknown-packages',              ('data/unknown-packages',
132               'Packages names not found in the archive'),               'Packages names not found in the archive'),
133                ('data/fake-names', 'Tracked issues without a CVE name'),
134              ('data/missing-epochs',              ('data/missing-epochs',
135               'Package versions which might lack an epoch'),               'Package versions which might lack an epoch'),
136              ('data/funny-versions',              ('data/funny-versions',
# Line 104  should be fine."""), Line 138  should be fine."""),
138              ('data/releases',              ('data/releases',
139               'Covered Debian releases and architectures (slow)'),               'Covered Debian releases and architectures (slow)'),
140              self.make_search_button(url)),              self.make_search_button(url)),
141                 P("""(You can enter CVE names, Debian bug numbers and package
142    names in the search forms.)"""),
143    
144               H2("A few notes on data sources"),               H2("Data sources"),
145               P("""Data in this tracker comes solely from the bug database               P("""Data in this tracker comes solely from the bug database
146  which is maintained by Debian's testing security team in their  which is maintained by Debian's testing security team in their
147  Subversion repository.  All external data (this includes  Subversion repository.  All external data (this includes
# Line 114  must be added to this database before it Line 150  must be added to this database before it
150  can be some delay before this happens."""),  can be some delay before this happens."""),
151               P("""At the moment, the database only contains information which is               P("""At the moment, the database only contains information which is
152  relevant for tracking the security status of the stable, testing and  relevant for tracking the security status of the stable, testing and
153  unstable suites.  This means that data for oldstable is likely wrong.""")],  unstable suites.  This means that data for oldstable is likely wrong."""),
154                 P('Data marked "NVD" comes from the ',
155                   A(url.absolute('http://nvd.nist.gov/'),
156                     'National Vulnerability Database'),
157                   ' maintained by NIST.'),
158    
159                 H2("External interfaces"),
160                 P("""If you want to automatically open a relevant web page for
161    some object, use the """,
162                   CODE(str(url.scriptRelative("redirect/")), EM("object")),
163                   """ URL.  If no information is contained in this database,
164    the browser is automatically redirected to the corresponding external
165    data source.""")],
166              search_in_page=True)              search_in_page=True)
167    
168      def page_object(self, path, params, url):      def page_object(self, path, params, url):
169          obj = path[0]          obj = path[0]
170            return self.page_object_or_redirect(url, obj, False)
171    
172        def page_redirect(self, path, params, url):
173            obj = path[0]
174            return self.page_object_or_redirect(url, obj, True)
175    
176        def page_object_or_redirect(self, url, obj, redirect):
177            c = self.db.cursor()
178    
179          if not obj:          if not obj:
180              # Redirect to start page.              # Redirect to start page.
# Line 126  unstable suites.  This means that data f Line 182  unstable suites.  This means that data f
182    
183          if 'A' <= obj[0] <= 'Z':          if 'A' <= obj[0] <= 'Z':
184              # Bug names start with a capital letter.              # Bug names start with a capital letter.
185              return self.page_bug(url, obj)              return self.page_bug(url, obj, redirect)
186    
187          bugnumber = 0          bugnumber = 0
188          try:          try:
# Line 134  unstable suites.  This means that data f Line 190  unstable suites.  This means that data f
190          except ValueError:          except ValueError:
191              pass              pass
192          if bugnumber:          if bugnumber:
193              return self.page_debian_bug(url, bugnumber)              buglist = list(self.db.getBugsFromDebianBug(c, bugnumber))
194                if buglist:
195                    return self.page_debian_bug(url, bugnumber, buglist)
196                if redirect:
197                    return RedirectResult(self.url_debian_bug(url, str(bugnumber)),
198                                          permanent=False)
199    
         c = self.db.cursor()  
200          if self.db.isSourcePackage(c, obj):          if self.db.isSourcePackage(c, obj):
201              return RedirectResult(self.url_source_package(url, obj, full=True))              return RedirectResult(self.url_source_package(url, obj, full=True))
202          if  self.db.isBinaryPackage(c, obj):          if  self.db.isBinaryPackage(c, obj):
# Line 144  unstable suites.  This means that data f Line 204  unstable suites.  This means that data f
204    
205          return self.page_not_found(url, obj)          return self.page_not_found(url, obj)
206    
207      def page_bug(self, url, name):      def page_bug(self, url, name, redirect):
208            # FIXME: Normalize CAN-* to CVE-* when redirecting.  Too many
209            # people still use CAN.
210            if redirect and name[0:4] == 'CAN-':
211                name = 'CVE-' + name[4:]
212    
213          cursor = self.db.cursor()          cursor = self.db.cursor()
214          try:          try:
215              bug = bugs.BugFromDB(cursor, name)              bug = bugs.BugFromDB(cursor, name)
216          except ValueError:          except ValueError:
217                if redirect:
218                    if name[0:4] == 'CVE-':
219                        return RedirectResult(self.url_cve(url, name),
220                                              permanent=False)
221              return self.page_not_found(url, name)              return self.page_not_found(url, name)
222          if bug.name <> name:          if bug.name <> name or redirect:
223              # Show the normalized bug name in the browser address bar.              # Show the normalized bug name in the browser address bar.
224              return RedirectResult(url.scriptRelativeFull(bug.name))              return RedirectResult(url.scriptRelativeFull(bug.name))
225    
# Line 160  unstable suites.  This means that data f Line 229  unstable suites.  This means that data f
229              yield B("Name"), bug.name              yield B("Name"), bug.name
230    
231              source = bug.name.split('-')[0]              source = bug.name.split('-')[0]
232              if source in ('CAN', 'CVE'):              if source == 'CVE':
233                  source_xref = self.make_cve_ref(url, bug.name, 'CVE')                  source_xref = compose(self.make_cve_ref(url, bug.name, 'CVE'),
234                                          " (",
235                                          self.make_nvd_ref(url, bug.name,
236                                                            'in NVD'),
237                                          ")")
238              elif source == 'DSA':              elif source == 'DSA':
239                  source_xref = self.make_dsa_ref(url, bug.name, 'Debian')                  source_xref = self.make_dsa_ref(url, bug.name, 'Debian')
240              elif source == 'DTSA':              elif source == 'DTSA':
# Line 181  unstable suites.  This means that data f Line 254  unstable suites.  This means that data f
254              xref = list(self.db.getBugXrefs(cursor, bug.name))              xref = list(self.db.getBugXrefs(cursor, bug.name))
255              if xref:              if xref:
256                  yield B("References"), self.make_xref_list(url, xref)                  yield B("References"), self.make_xref_list(url, xref)
257    
258                nvd = self.db.getNVD(cursor, bug.name)
259                if nvd:
260                    if nvd.severity:
261                        yield B("NVD severity"), nvd.severity.lower()
262                    nvd_range = nvd.rangeString()
263                    if nvd_range:
264                        yield B("NVD attack range"), nvd_range
265    
266              debian_bugs = bug.getDebianBugs(cursor)              debian_bugs = bug.getDebianBugs(cursor)
267              if debian_bugs:              if debian_bugs:
# Line 301  unstable suites.  This means that data f Line 382  unstable suites.  This means that data f
382    
383          return self.create_page(url, bug.name, page)          return self.create_page(url, bug.name, page)
384    
385      def page_debian_bug(self, url, bugnumber):      def page_debian_bug(self, url, bugnumber, buglist):
386          buglist = list(self.db.getBugsFromDebianBug(self.db.cursor(),          if len(buglist) == 1:
387                                                      bugnumber))              # Single issue, redirect.
388          if buglist:              return RedirectResult(url.scriptRelativeFull(buglist[0][0]))
389              if len(buglist) == 1:  
390                  # Single issue, redirect.          def gen():
391                  return RedirectResult(url.scriptRelativeFull(buglist[0][0]))              for (name, urgency, description) in buglist:
392                    if urgency == "unknown":
393              def gen():                      urgency = ""
394                  for (name, urgency, description) in buglist:                  yield self.make_xref(url, name), urgency, description
395                      if urgency == "unknown":  
396                          urgency = ""          return self.create_page(
397                      yield self.make_xref(url, name), urgency, description              url, "Information related to Debian bug #%d" % bugnumber,
398                [P("The following issues reference to Debian bug ",
399              return self.create_page(                 self.make_debian_bug(url, bugnumber), ":"),
400                  url, "Information related to Debian bug #%d" % bugnumber,               make_table(gen(),
401                  [P("The following issues reference to Debian bug ",                          caption=("Name", "Urgency", "Description"))])
                    self.make_debian_bug(url, bugnumber), ":"),  
                  make_table(gen(),  
                             caption=("Name", "Urgency", "Description"))])  
   
         else:  
             return self.page_not_found(url, str(bugnumber))  
402    
403      def page_not_found(self, url, query):      def page_not_found(self, url, query):
404          return self.create_page(url, 'Not found',          return self.create_page(url, 'Not found',
# Line 422  architecture is currently not tracked."" Line 497  architecture is currently not tracked.""
497  this package, but still reference it.""")])  this package, but still reference it.""")])
498    
499      def page_status_release_stable(self, path, params, url):      def page_status_release_stable(self, path, params, url):
500            bf = BugFilter(params)
501    
502          def gen():          def gen():
503              old_pkg_name = ''              old_pkg_name = ''
504              for (pkg_name, bug_name, archive, urgency) in \              for (pkg_name, bug_name, archive, urgency, remote) in \
505                      self.db.cursor().execute(                      self.db.cursor().execute(
506                  """SELECT package, bug, section, urgency FROM stable_status"""):                  """SELECT package, bug, section, urgency, remote
507                    FROM stable_status"""):
508                    if bf.urgencyFiltered(urgency):
509                        continue
510                    if bf.remoteFiltered(remote):
511                        continue
512    
513                  if pkg_name == old_pkg_name:                  if pkg_name == old_pkg_name:
514                      pkg_name = ''                      pkg_name = ''
515                  else:                  else:
# Line 434  this package, but still reference it.""" Line 517  this package, but still reference it."""
517                      if archive <> 'main':                      if archive <> 'main':
518                          pkg_name = "%s (%s)" % (pkg_name, archive)                          pkg_name = "%s (%s)" % (pkg_name, archive)
519    
520                    if remote is None:
521                        remote = ''
522                    elif remote:
523                        remote = 'yes'
524                    else:
525                        remote = 'no'
526    
527                  if urgency == 'unknown':                  if urgency == 'unknown':
528                      urgency = ''                      urgency = ''
529                  elif urgency == 'high':                  elif urgency == 'high':
530                      urgency = self.make_red(urgency)                      urgency = self.make_red(urgency)
531    
532                  yield pkg_name, self.make_xref(url, bug_name), urgency                  yield pkg_name, self.make_xref(url, bug_name), urgency, remote
533    
534          return self.create_page(          return self.create_page(
535              url, 'Vulnerable source packages in the stable suite',              url, 'Vulnerable source packages in the stable suite',
536              [make_table(gen(), caption=("Package", "Bug", "Urgency"))])              [bf.actions(url),
537                 make_table(gen(), caption=("Package", "Bug", "Urgency",
538                                            "Remote"))])
539    
540      def page_status_release_testing(self, path, params, url):      def page_status_release_testing(self, path, params, url):
541            bf = BugFilter(params)
542    
543          def gen():          def gen():
544              old_pkg_name = ''              old_pkg_name = ''
545              for (pkg_name, bug_name, archive, urgency,              for (pkg_name, bug_name, archive, urgency,
546                   sid_vulnerable, ts_fixed) in self.db.cursor().execute(                   sid_vulnerable, ts_fixed, remote) in self.db.cursor().execute(
547                  """SELECT package, bug, section, urgency, unstable_vulnerable,                  """SELECT package, bug, section, urgency, unstable_vulnerable,
548                  testing_security_fixed                  testing_security_fixed, remote
549                  FROM testing_status"""):                  FROM testing_status"""):
550                    if bf.urgencyFiltered(urgency):
551                        continue
552                    if bf.remoteFiltered(remote):
553                        continue
554    
555                  if pkg_name == old_pkg_name:                  if pkg_name == old_pkg_name:
556                      pkg_name = ''                      pkg_name = ''
557                  else:                  else:
# Line 460  this package, but still reference it.""" Line 559  this package, but still reference it."""
559                      if archive <> 'main':                      if archive <> 'main':
560                          pkg_name = "%s (%s)" % (pkg_name, archive)                          pkg_name = "%s (%s)" % (pkg_name, archive)
561    
562                    if remote is None:
563                        remote = ''
564                    elif remote:
565                        remote = 'yes'
566                    else:
567                        remote = 'no'
568    
569                  if ts_fixed:                  if ts_fixed:
570                      status = 'fixed in testing-security'                      status = 'fixed in testing-security'
571                  else:                  else:
# Line 472  this package, but still reference it.""" Line 578  this package, but still reference it."""
578                      urgency = ''                      urgency = ''
579    
580                  yield (pkg_name, self.make_xref(url, bug_name),                  yield (pkg_name, self.make_xref(url, bug_name),
581                         urgency, status)                         urgency, remote, status)
582    
583          return self.create_page(          return self.create_page(
584              url, 'Vulnerable source packages in the testing suite',              url, 'Vulnerable source packages in the testing suite',
585              [make_menu(url.scriptRelative,              [make_menu(url.scriptRelative,
586                         ("status/dtsa-candidates", "Candidates for DTSAs")),                         ("status/dtsa-candidates", "Candidates for DTSAs")),
587               make_table(gen(), caption=("Package", "Bug"))])               bf.actions(url),
588                 make_table(gen(), caption=("Package", "Bug", "Urgency",
589                                            "Remote"))])
590    
591      def page_status_release_unstable(self, path, params, url):      def page_status_release_unstable(self, path, params, url):
592            bf = BugFilter(params)
593    
594          def gen():          def gen():
595              old_pkg_name = ''              old_pkg_name = ''
596              for (pkg_name, bug_name, section, urgency) \              for (pkg_name, bug_name, section, urgency, remote) \
597                      in self.db.cursor().execute(                      in self.db.cursor().execute(
598                  """SELECT DISTINCT sp.name, st.bug_name,                  """SELECT DISTINCT sp.name, st.bug_name,
599                  sp.archive, st.urgency                  sp.archive, st.urgency,
600                    (SELECT range_remote FROM nvd_data
601                     WHERE cve_name = st.bug_name)
602                  FROM source_package_status AS st, source_packages AS sp                  FROM source_package_status AS st, source_packages AS sp
603                  WHERE st.vulnerable AND st.urgency <> 'unimportant'                  WHERE st.vulnerable AND st.urgency <> 'unimportant'
604                  AND sp.rowid = st.package AND sp.release = 'sid'                  AND sp.rowid = st.package AND sp.release = 'sid'
605                  AND sp.subrelease = ''                  AND sp.subrelease = ''
606                  ORDER BY sp.name, st.bug_name"""):                  ORDER BY sp.name, st.bug_name"""):
607                    if bf.urgencyFiltered(urgency):
608                        continue
609                    if bf.remoteFiltered(remote):
610                        continue
611    
612                  if pkg_name == old_pkg_name:                  if pkg_name == old_pkg_name:
613                      pkg_name = ''                      pkg_name = ''
614                  else:                  else:
# Line 501  this package, but still reference it.""" Line 618  this package, but still reference it."""
618                      else:                      else:
619                          pkg_name = self.make_xref(url, pkg_name)                          pkg_name = self.make_xref(url, pkg_name)
620    
621                    if remote is None:
622                        remote = ''
623                    elif remote:
624                        remote = 'yes'
625                    else:
626                        remote = 'no'
627    
628                  if urgency == 'unknown':                  if urgency == 'unknown':
629                      urgency = ''                      urgency = ''
630                  elif urgency == 'high':                  elif urgency == 'high':
631                      urgency = self.make_red(urgency)                      urgency = self.make_red(urgency)
632    
633                  yield pkg_name, self.make_xref(url, bug_name), urgency                  yield pkg_name, self.make_xref(url, bug_name), urgency, remote
634    
635    
636          return self.create_page(          return self.create_page(
# Line 516  this package, but still reference it.""" Line 640  this package, but still reference it."""
640              fixed source version has been uploaded to the archive, even              fixed source version has been uploaded to the archive, even
641              if there are still some vulnerably binary packages present              if there are still some vulnerably binary packages present
642              in the archive."""),              in the archive."""),
643               make_table(gen(), caption=('Package', 'Bug', 'Urgency'))])               bf.actions(url),
644                 make_table(gen(), caption=('Package', 'Bug', 'Urgency',
645                                            'Remote'))])
646    
647      def page_status_dtsa_candidates(self, path, params, url):      def page_status_dtsa_candidates(self, path, params, url):
648            bf = BugFilter(params)
649    
650          def gen():          def gen():
651              old_pkg_name = ''              old_pkg_name = ''
652              for (pkg_name, bug_name, archive, urgency, stable_later) \              for (pkg_name, bug_name, archive, urgency, stable_later,
653                     remote) \
654                      in self.db.cursor().execute(                      in self.db.cursor().execute(
655                  """SELECT package, bug, section, urgency,                  """SELECT package, bug, section, urgency,
656                  (SELECT testing.version_id < stable.version_id                  (SELECT testing.version_id < stable.version_id
# Line 533  this package, but still reference it.""" Line 662  this package, but still reference it."""
662                   AND stable.name = testing_status.package                   AND stable.name = testing_status.package
663                   AND stable.release = 'sarge'                   AND stable.release = 'sarge'
664                   AND stable.subrelease = 'security'                   AND stable.subrelease = 'security'
665                   AND stable.archive = testing_status.section)                   AND stable.archive = testing_status.section),
666                    (SELECT range_remote FROM nvd_data
667                     WHERE cve_name = bug)
668                  FROM testing_status                  FROM testing_status
669                  WHERE (NOT unstable_vulnerable)                  WHERE (NOT unstable_vulnerable)
670                  AND (NOT testing_security_fixed)"""):                  AND (NOT testing_security_fixed)"""):
671                    if bf.urgencyFiltered(urgency):
672                        continue
673                    if bf.remoteFiltered(remote):
674                        continue
675    
676                  if pkg_name == old_pkg_name:                  if pkg_name == old_pkg_name:
677                      pkg_name = ''                      pkg_name = ''
678                      migration = ''                      migration = ''
# Line 549  this package, but still reference it.""" Line 685  this package, but still reference it."""
685                      else:                      else:
686                          pkg_name = self.make_source_package_ref(url, pkg_name)                          pkg_name = self.make_source_package_ref(url, pkg_name)
687    
688                    if remote is None:
689                        remote = ''
690                    elif remote:
691                        remote = 'yes'
692                    else:
693                        remote = 'no'
694    
695                  if urgency == 'unknown':                  if urgency == 'unknown':
696                      urgency = ''                      urgency = ''
697                  elif urgency == 'high':                  elif urgency == 'high':
# Line 560  this package, but still reference it.""" Line 703  this package, but still reference it."""
703                      notes = ''                      notes = ''
704    
705                  yield (pkg_name, migration, self.make_xref(url, bug_name),                  yield (pkg_name, migration, self.make_xref(url, bug_name),
706                         urgency, notes)                         urgency, remote, notes)
707    
708          return self.create_page(          return self.create_page(
709              url, "Candidates for DTSAs",              url, "Candidates for DTSAs",
# Line 571  return web_supporttesting yet."""), Line 714  return web_supporttesting yet."""),
714               make_menu(url.scriptRelative,               make_menu(url.scriptRelative,
715                         ("status/release/testing",                         ("status/release/testing",
716                          "List of vulnerable packages in testing")),                          "List of vulnerable packages in testing")),
717                 bf.actions(url),
718               make_table(gen(),               make_table(gen(),
719                          caption=("Package", "Migration", "Bug", "Urgency"))])                          caption=("Package", "Migration", "Bug", "Urgency",
720                                     "Remote"))])
721    
722      def page_status_todo(self, path, params, url):      def page_status_todo(self, path, params, url):
723          def gen():          def gen():
# Line 689  but it makes version-based bug tracking Line 834  but it makes version-based bug tracking
834               long as none of the binary packages carries the same name as the               long as none of the binary packages carries the same name as the
835               source package, most confusion is avoided or can be easily               source package, most confusion is avoided or can be easily
836               explained.""")])               explained.""")])
837    
838        def page_data_fake_names(self, path, params, url):
839            def gen():
840                for (bug, description) in self.db.getFakeBugs():
841                    yield self.make_xref(url, bug), description
842            return self.create_page(
843                url, "Automatically generated issue names",
844                [P("""Some issues have not been assigned CVE names, but are still
845    tracked by this database.  In this case, the system automatically assigns
846    a unique name.  These names are not stable and can change when the database
847    is updated, so they should not be used in external references."""),
848                 P('''The automatically generated names come in two flavors:
849    the first kind starts with the string "''', CODE("FAKE-000000-"),
850                   '''".  This means that no Debian bug has been assigned to this
851    issue (or a bug has been created and is not recorded in this database).
852    In the second kind of names, there is a Debian bug for the issue, and the "''',
853                   CODE("000000"), '''"part of the name is replaced with the
854    Debian bug number.'''),
855                 make_table(gen(),
856                            caption=("Bug", "Description"))])
857    
858      def create_page(self, url, title, body, search_in_page=False, status=200):      def create_page(self, url, title, body, search_in_page=False, status=200):
859          append = body.append          append = body.append
# Line 726  but it makes version-based bug tracking Line 890  but it makes version-based bug tracking
890      def url_cve(self, url, name):      def url_cve(self, url, name):
891          return url.absolute("http://cve.mitre.org/cgi-bin/cvename.cgi",          return url.absolute("http://cve.mitre.org/cgi-bin/cvename.cgi",
892                              name=name)                              name=name)
893        def url_nvd(self, url, name):
894            return url.absolute("http://nvd.nist.gov/nvd.cfm",
895                                cvename=name)
896    
897      def url_dsa(self, url, dsa, re_dsa=re.compile(r'^DSA-(\d+)(?:-\d+)?$')):      def url_dsa(self, url, dsa, re_dsa=re.compile(r'^DSA-(\d+)(?:-\d+)?$')):
898          match = re_dsa.match(dsa)          match = re_dsa.match(dsa)
899          if match:          if match:
# Line 777  but it makes version-based bug tracking Line 945  but it makes version-based bug tracking
945              name = cve              name = cve
946          return A(self.url_cve(url, cve), name)          return A(self.url_cve(url, cve), name)
947    
948        def make_nvd_ref(self, url, cve, name=None):
949            if name is None:
950                name = cve
951            return A(self.url_nvd(url, cve), name)
952    
953      def make_dsa_ref(self, url, dsa, name=None):      def make_dsa_ref(self, url, dsa, name=None):
954          if name is None:          if name is None:
955              name = dsa              name = dsa

Legend:
Removed from v.2482  
changed lines
  Added in v.2554

  ViewVC Help
Powered by ViewVC 1.1.5