/[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 3014 by fw, Mon Dec 12 15:28:39 2005 UTC revision 14909 by geissert, Sun Jun 27 04:03:20 2010 UTC
# Line 2  Line 2 
2    
3  import sys  import sys
4  sys.path.insert(0,'../lib/python')  sys.path.insert(0,'../lib/python')
   
 if len(sys.argv) <> 3:  
     print "usage: python tracker_serivce.py SOCKET-PATH DATABASE-PATH"  
     sys.exit(1)  
 socket_name = sys.argv[1]  
 db_name = sys.argv[2]  
   
5  import bugs  import bugs
6  import re  import re
7  import security_db  import security_db
8  from web_support import *  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:  class BugFilter:
27      def __init__(self, params):      default_action_list = [('show_high_urgency', 'only high urgencies'),
28          self.hide_medium_urgency = int(params.get('hide_medium_urgency',                             ('show_medium_urgency', 'only medium and high urgencies'),
29                                                    (0,))[0])                             ('show_undetermined_urgency', 'issues that may be vulnerable but need to be checked (shown in purple)'),
30          self.hide_non_remote = int(params.get('hide_non_remote',                             ('show_unimportant_urgency', 'unimportant issues'),
31                                                (0,))[0])                             ('show_remote_only', 'only remote vulnerabilities')]
32        def __init__(self, params, action_list=None):
33            if action_list is None:
34                self.action_list = self.default_action_list
35            else:
36                self.action_list = action_list
37            self.params = {}
38            for (prop, desc) in self.action_list:
39                self.params[prop] = int(params.get(prop, (0,))[0])
40    
41      def actions(self, url):      def actions(self, url):
42          """Returns a HTML snippet which can be used to change the filter."""          """Returns a HTML snippet which can be used to change the filter."""
43          if self.hide_medium_urgency:  
44              urg = A(url.updateParams(hide_medium_urgency=None),          l = []
45                      'Show lower urgencies')          for (prop, desc) in self.action_list:
46          else:              if self.params[prop]:
47              urg = A(url.updateParams(hide_medium_urgency='1'),                  if self.params['show_medium_urgency'] and prop == 'show_medium_urgency':
48                      'Hide lower urgencies')                      note = 'Restore lower than medium urgencies'
49          if self.hide_non_remote:                  elif self.params['show_high_urgency'] and prop == 'show_high_urgency':
50              rem = A(url.updateParams(hide_non_remote=None),                      note = 'Restore lower than high urgencies'
51                      'Show local vulnerabilities')                  elif self.params['show_remote_only'] and prop == 'show_remote_only':
52          else:                      note = 'Restore local vulnerabilities'
53              rem = A(url.updateParams(hide_non_remote='1'),                  else:
54                      'Hide local vulnerabilities')                      note = 'Hide ' + desc
55          return P(urg, ' ', rem)                  l.append(TR(TD(A(url.updateParamsDict({prop : None}), note))))
56                else:
57      def urgencyFiltered(self, urg):                  note = 'Show ' + desc
58          """Returns True if the urgency urg is filtered."""                  l.append(TR(TD(A(url.updateParamsDict({prop : '1'}), note))))
59          return self.hide_medium_urgency and urg not in ("high", "unknown", "")  
60            return TABLE(l)
61    
62        def urgencyFiltered(self, urg, vuln):
63            """Returns True for urgencies that should be filtered."""
64            filterlow = self.params['show_medium_urgency'] and \
65                        urg in ('low', 'low**', 'unimportant',
66                        'undetermined', 'not yet assigned')
67            filtermed = self.params['show_high_urgency'] and \
68                        urg in ('medium', 'medium**', 'low', 'low**',
69                        'unimportant', 'undetermined', 'not yet assigned')
70            filterund = not self.params['show_undetermined_urgency'] and vuln == 2
71            filteruni = not self.params['show_unimportant_urgency'] \
72                        and urg == 'unimportant'
73            return filterlow or filtermed or filterund or filteruni
74    
75      def remoteFiltered(self, remote):      def remoteFiltered(self, remote):
76          """Returns True if the attack range is filtered."""          """Returns True for only remote flaws if filtered."""
77          return remote is not None and self.hide_non_remote and not remote          return self.params['show_remote_only'] and not remote and not remote is None
78    
79    class BugFilterNoDSA(BugFilter):
80        def __init__(self, params):
81            BugFilter.__init__(self, params, self.default_action_list
82                + [('show_nodsa', 'issues that are not severe enough to warrant a DSA')])
83    
84  class TrackerService(WebService):      def nodsaFiltered(self, nodsa):
85            """Returns True for no DSA issues if filtered."""
86            return nodsa and not self.params['show_nodsa']
87    
88    class TrackerService(webservice_base_class):
89      head_contents = compose(STYLE(      head_contents = compose(STYLE(
90          """h1 { font-size : 144%; }          """h1 { font-size : 144%; }
91  h2 { font-size : 120%; }  h2 { font-size : 120%; }
# Line 57  td, th { text-align : left; Line 97  td, th { text-align : left;
97           padding-right : 0.25em; }           padding-right : 0.25em; }
98  td { vertical-align: baseline }  td { vertical-align: baseline }
99  span.red { color: red; }  span.red { color: red; }
100    span.purple { color: purple; }
101  span.dangerous { color: rgb(191,127,0); }  span.dangerous { color: rgb(191,127,0); }
102  """), SCRIPT('''var old_query_value = "";  """), SCRIPT('''var old_query_value = "";
103    
# Line 76  function onSearch(query) { Line 117  function onSearch(query) {
117  }  }
118  ''')).toHTML()  ''')).toHTML()
119    
120        nvd_text =  P('''If a "**" is included, the urgency field was automatically
121            assigned by the NVD (National Vulnerability Database). Note that this
122            rating is automatically derived from a set of known factors about the
123            issue (such as access complexity, confidentiality impact, exploitability,
124            remediation level, and others). Human intervention is involved in
125            determining the values of these factors, but the rating itself comes
126            from a fully automated formula.''')
127    
128      def __init__(self, socket_name, db_name):      def __init__(self, socket_name, db_name):
129          WebService.__init__(self, socket_name)          webservice_base_class.__init__(self, socket_name)
130          self.db = security_db.DB(db_name)          self.db = security_db.DB(db_name)
131          self.register('', self.page_home)          self.register('', self.page_home)
132          self.register('*', self.page_object)          self.register('*', self.page_object)
133          self.register('redirect/*', self.page_redirect)          self.register('redirect/*', self.page_redirect)
134          self.register('source-package/*', self.page_source_package)          self.register('source-package/*', self.page_source_package)
135          self.register('binary-package/*', self.page_binary_package)          self.register('status/release/oldstable',
136                          self.page_status_release_oldstable)
137          self.register('status/release/stable', self.page_status_release_stable)          self.register('status/release/stable', self.page_status_release_stable)
138            self.register('status/release/stable-backports',
139                          self.page_status_release_stable_backports)
140            self.register('status/release/oldstable-backports',
141                          self.page_status_release_oldstable_backports)
142          self.register('status/release/testing',          self.register('status/release/testing',
143                        self.page_status_release_testing)                        self.page_status_release_testing)
144          self.register('status/release/unstable',          self.register('status/release/unstable',
# Line 92  function onSearch(query) { Line 146  function onSearch(query) {
146          self.register('status/dtsa-candidates',          self.register('status/dtsa-candidates',
147                        self.page_status_dtsa_candidates)                        self.page_status_dtsa_candidates)
148          self.register('status/todo', self.page_status_todo)          self.register('status/todo', self.page_status_todo)
149            self.register('status/undetermined', self.page_status_undetermined)
150            self.register('status/unimportant', self.page_status_unimportant)
151          self.register('status/itp', self.page_status_itp)          self.register('status/itp', self.page_status_itp)
152          self.register('data/unknown-packages', self.page_data_unknown_packages)          self.register('data/unknown-packages', self.page_data_unknown_packages)
153          self.register('data/missing-epochs', self.page_data_missing_epochs)          self.register('data/missing-epochs', self.page_data_missing_epochs)
154            self.register('data/latently-vulnerable',
155                          self.page_data_latently_vulnerable)
156          self.register('data/releases', self.page_data_releases)          self.register('data/releases', self.page_data_releases)
157          self.register('data/funny-versions', self.page_data_funny_versions)          self.register('data/funny-versions', self.page_data_funny_versions)
158          self.register('data/fake-names', self.page_data_fake_names)          self.register('data/fake-names', self.page_data_fake_names)
159            self.register('data/pts/1', self.page_data_pts)
160            self.register('debsecan/**', self.page_debsecan)
161            self.register('data/report', self.page_report)
162    
163      def page_home(self, path, params, url):      def page_home(self, path, params, url):
164          query = params.get('query', ('',))[0]          query = params.get('query', ('',))[0]
# Line 110  function onSearch(query) { Line 171  function onSearch(query) {
171          return self.create_page(          return self.create_page(
172              url, 'Security Bug Tracker',              url, 'Security Bug Tracker',
173              [P(              [P(
174              """This is the experimental issue tracker for Debian's testing              """The data in this tracker comes solely from the bug database maintained
175  security team.  Keep in mind that this is merely a prototype.  by Debian's security team located in the testing-security Subversion """,
176  Please report any problems to """,              A("http://svn.debian.org/wsvn/secure-testing/data/", "repository"),
177              A("mailto:fw@deneb.enyo.de", "Florian Weimer"),              """.  The data represented here is derived from: """,
178              """.Note that some of the data presented here is known              A("http://www.debian.org/security/#DSAS", "DSAs"),
179  to be wrong (see below), but the data for the testing suite              """ issued by the Security Team; issues tracked in the """,
180  should be fine."""),              A("http://cve.mitre.org/cve/", "CVE database"),
181                                   make_menu(              """, issues tracked in the """,
182                A("http://nvd.nist.gov/", "National Vulnerability Database"),
183                """ (NVD), maintained by NIST; and security issues
184    discovered in Debian packages as reported in the BTS."""),
185                 P("""All external data (including Debian bug reports and official Debian
186    security advisories) must be added to this database before it appears
187    here. Please help us keep this information up-to-date by """,
188                   A(url.scriptRelative("data/report"), "reporting"),
189                   """ any discrepancies or change of states that you are
190    aware of and/or help us improve the quality of this information by """,
191                   A(url.scriptRelative("data/report"), "participating"),
192                   "."),
193                make_menu(
194              url.scriptRelative,              url.scriptRelative,
             ('status/release/stable',  
              'Vulnerable packages in the stable suite'),  
             ('status/release/testing',  
              'Vulnerable packages in the testing suite'),  
195              ('status/release/unstable',              ('status/release/unstable',
196               'Vulnerable packages in the unstable suite'),               'Vulnerable packages in the unstable suite'),
197                ('status/release/testing',
198                 'Vulnerable packages in the testing suite'),
199                ('status/release/stable',
200                 'Vulnerable packages in the stable suite'),
201                ('status/release/oldstable',
202                 'Vulnerable packages in the old stable suite'),
203                ('status/release/stable-backports',
204                 'Vulnerable packages in backports for stable'),
205                ('status/release/oldstable-backports',
206                 'Vulnerable packages in backports for oldstable'),
207              ('status/dtsa-candidates', "Candidates for DTSAs"),              ('status/dtsa-candidates', "Candidates for DTSAs"),
208              ('status/todo', 'TODO items'),              ('status/todo', 'TODO items'),
209                ('status/undetermined', 'Packages that may be vulnerable but need to be checked (undetermined issues)'),
210                ('status/unimportant', 'Packages that have open unimportant issues'),
211              ('status/itp', 'ITPs with potential security issues'),              ('status/itp', 'ITPs with potential security issues'),
212              ('data/unknown-packages',              ('data/unknown-packages',
213               'Packages names not found in the archive'),               'Packages names not found in the archive'),
214              ('data/fake-names', 'Tracked issues without a CVE name'),              ('data/fake-names', 'Tracked issues without a CVE name'),
215              ('data/missing-epochs',              ('data/missing-epochs',
216               'Package versions which might lack an epoch'),               'Package versions which might lack an epoch'),
217                ('data/latently-vulnerable',
218                 'Packages which are latently vulnerable in unstable'),
219              ('data/funny-versions',              ('data/funny-versions',
220               'Packages with strange version numbers'),               'Packages with strange version numbers'),
221              ('data/releases',              ('data/releases',
# Line 141  should be fine."""), Line 224  should be fine."""),
224               P("""(You can enter CVE names, Debian bug numbers and package               P("""(You can enter CVE names, Debian bug numbers and package
225  names in the search forms.)"""),  names in the search forms.)"""),
226    
              H2("Data sources"),  
              P("""Data in this tracker comes solely from the bug database  
 which is maintained by Debian's testing security team in their  
 Subversion repository.  All external data (this includes  
 Debian bug reports and official Debian security advisories)  
 must be added to this database before it appears here, and there  
 can be some delay before this happens."""),  
              P("""At the moment, the database only contains information which is  
 relevant for tracking the security status of the stable, testing and  
 unstable suites.  This means that data for oldstable is likely wrong."""),  
              P('Data marked "NVD" comes from the ',  
                A(url.absolute('http://nvd.nist.gov/'),  
                  'National Vulnerability Database'),  
                ' maintained by NIST.'),  
   
227               H2("External interfaces"),               H2("External interfaces"),
228               P("""If you want to automatically open a relevant web page for               P("""If you want to automatically open a relevant web page for
229  some object, use the """,  some object, use the """,
# Line 170  data source.""")], Line 238  data source.""")],
238          return self.page_object_or_redirect(url, obj, False)          return self.page_object_or_redirect(url, obj, False)
239    
240      def page_redirect(self, path, params, url):      def page_redirect(self, path, params, url):
241          obj = path[0]          if path == ():
242                obj = ''
243            else:
244                obj = path[0]
245          return self.page_object_or_redirect(url, obj, True)          return self.page_object_or_redirect(url, obj, True)
246    
247      def page_object_or_redirect(self, url, obj, redirect):      def page_object_or_redirect(self, url, obj, redirect):
# Line 179  data source.""")], Line 250  data source.""")],
250          if not obj:          if not obj:
251              # Redirect to start page.              # Redirect to start page.
252              return RedirectResult(url.scriptRelativeFull(""))              return RedirectResult(url.scriptRelativeFull(""))
   
         if 'A' <= obj[0] <= 'Z':  
             # Bug names start with a capital letter.  
             return self.page_bug(url, obj, redirect)  
253    
254            # Attempt to decode a bug number.  TEMP-nnn bugs (but not
255            # TEMP-nnn-mmm bugs) are treated as bug references, too.
256          bugnumber = 0          bugnumber = 0
257            fake_bug = False
258          try:          try:
259              bugnumber = int(obj)              if obj[0:5] == 'FAKE-' or obj[0:5] == 'TEMP-':
260                    bugnumber = int(obj[5:])
261                    fake_bug = True
262                else:
263                    bugnumber = int(obj)
264          except ValueError:          except ValueError:
265              pass              pass
266          if bugnumber:          if bugnumber:
267              buglist = list(self.db.getBugsFromDebianBug(c, bugnumber))              buglist = list(self.db.getBugsFromDebianBug(c, bugnumber))
268              if buglist:              if buglist:
269                  return self.page_debian_bug(url, bugnumber, buglist)                  return self.page_debian_bug(url, bugnumber, buglist, fake_bug)
270              if redirect:              if redirect:
271                  return RedirectResult(self.url_debian_bug(url, str(bugnumber)),                  return RedirectResult(self.url_debian_bug(url, str(bugnumber)),
272                                        permanent=False)                                        permanent=False)
273    
274            if 'A' <= obj[0] <= 'Z':
275                # Bug names start with a capital letter.
276                return self.page_bug(url, obj, redirect)
277    
278          if self.db.isSourcePackage(c, obj):          if self.db.isSourcePackage(c, obj):
279              return RedirectResult(self.url_source_package(url, obj, full=True))              return RedirectResult(self.url_source_package(url, obj, full=True))
         if  self.db.isBinaryPackage(c, obj):  
             return RedirectResult(self.url_binary_package(url ,obj, full=True))  
280    
281          return self.page_not_found(url, obj)          return self.page_not_found(url, obj)
282    
# Line 231  data source.""")], Line 307  data source.""")],
307              source = bug.name.split('-')[0]              source = bug.name.split('-')[0]
308              if source == 'CVE':              if source == 'CVE':
309                  source_xref = compose(self.make_cve_ref(url, bug.name, 'CVE'),                  source_xref = compose(self.make_cve_ref(url, bug.name, 'CVE'),
310                                        " (",                                        " (at ",
311                                        self.make_nvd_ref(url, bug.name,                                        self.make_nvd_ref(url, bug.name,
312                                                          'in NVD'),                                                          'NVD'),
313                                          "; ",
314                                          self.make_rhbug_ref(url, bug.name,
315                                                            'RH'),
316                                        ")")                                        ")")
317              elif source == 'DSA':              elif source == 'DSA':
318                  source_xref = self.make_dsa_ref(url, bug.name, 'Debian')                  source_xref = self.make_dsa_ref(url, bug.name, 'Debian')
319              elif source == 'DTSA':              elif source == 'DTSA':
320                  source_xref = 'Debian Testing Security Team'                  source_xref = 'Debian Testing Security Team'
321              elif source == 'FAKE':              elif source == 'TEMP':
322                  source_xref = (                  source_xref = (
323          'Automatically generated temporary name.  Not for external reference.')          'Automatically generated temporary name.  Not for external reference.')
324              else:              else:
# Line 248  data source.""")], Line 327  data source.""")],
327              if source_xref:              if source_xref:
328                  yield B("Source"), source_xref                  yield B("Source"), source_xref
329    
330              if bug.description:              nvd = self.db.getNVD(cursor, bug.name)
331    
332                if nvd and nvd.cve_desc:
333                    yield B("Description"), nvd.cve_desc
334                elif bug.description:
335                  yield B("Description"), bug.description                  yield B("Description"), bug.description
336    
337              xref = list(self.db.getBugXrefs(cursor, bug.name))              xref = list(self.db.getBugXrefs(cursor, bug.name))
338              if xref:              if xref:
339                  yield B("References"), self.make_xref_list(url, xref)                  yield B("References"), self.make_xref_list(url, xref)
340    
             nvd = self.db.getNVD(cursor, bug.name)  
341              if nvd:              if nvd:
                 if nvd.severity:  
                     yield B("NVD severity"), nvd.severity.lower()  
342                  nvd_range = nvd.rangeString()                  nvd_range = nvd.rangeString()
343                  if nvd_range:                  if nvd.severity:
344                      yield B("NVD attack range"), nvd_range                      nvd_severity = nvd.severity.lower()
345                        if nvd_range:
346                            nvd_severity = "%s (attack range: %s)" \
347                                           % (nvd_severity, nvd_range)
348                        yield B("NVD severity"), nvd_severity
349    
350              debian_bugs = bug.getDebianBugs(cursor)              debian_bugs = bug.getDebianBugs(cursor)
351              if debian_bugs:              if debian_bugs:
# Line 270  data source.""")], Line 354  data source.""")],
354    
355              if not bug.not_for_us:              if not bug.not_for_us:
356                  for (release, status, reason) in bug.getStatus(cursor):                  for (release, status, reason) in bug.getStatus(cursor):
357                      if status <> 'fixed':                      if status == 'undetermined':
358                            reason = self.make_purple(reason)
359                        elif status <> 'fixed':
360                          reason = self.make_red(reason)                          reason = self.make_red(reason)
361                      yield B('Status of %s' % release), reason                      yield B('Debian/%s' % release), reason
362    
363          page.append(make_table(gen_header()))          page.append(make_table(gen_header()))
364    
# Line 290  data source.""")], Line 376  data source.""")],
376                          package = compose(                          package = compose(
377                              self.make_source_package_ref(url, package),                              self.make_source_package_ref(url, package),
378                              " (", self.make_pts_ref(url, package, 'PTS'), ")")                              " (", self.make_pts_ref(url, package, 'PTS'), ")")
379                      if vulnerable:                      if vulnerable == 1:
380                          vuln = self.make_red('vulnerable')                          vuln = self.make_red('vulnerable')
381                          version = self.make_red(version)                          version = self.make_red(version)
382                        elif vulnerable == 2:
383                            vuln = self.make_purple('undetermined')
384                            version = self.make_purple(version)
385                      else:                      else:
386                          vuln = 'fixed'                          vuln = 'fixed'
387    
# Line 302  data source.""")], Line 391  data source.""")],
391      caption=("Source Package", "Release", "Version", "Status"),      caption=("Source Package", "Release", "Version", "Status"),
392      introduction=P('The table below lists information on source packages.')))      introduction=P('The table below lists information on source packages.')))
393    
             def gen_binary():  
                 old_pkg = ''  
                 for (packages, releases, version, archs, vulnerable) \  
                     in self.db.getBinaryPackages(cursor, bug.name):  
                     pkg = ', '.join(packages)  
                     if pkg == old_pkg:  
                         packages = ''  
                     else:  
                         old_pkg = pkg  
                         packages = self.make_binary_packages_ref(url, packages)  
   
                     if vulnerable:  
                         vuln = self.make_red('vulnerable')  
                         version = self.make_red(version)  
                     else:  
                         vuln = 'fixed'  
                     yield (packages,  
                            ', '.join(releases),  
                            version, vuln,  
                            ', '.join(archs))  
   
             page.append(make_table(gen_binary(),  
         caption=("Binary Package", "Release", "Version", "Status",  
                  "Architecures"),  
         introduction=P("The next table lists affected binary packages.")))  
   
394              def gen_data():              def gen_data():
395                  notes_sorted = bug.notes[:]                  notes_sorted = bug.notes[:]
396                  notes_sorted.sort(lambda a, b: cmp(a.package, b.package))                  notes_sorted.sort(lambda a, b: cmp(a.package, b.package))
# Line 344  data source.""")], Line 407  data source.""")],
407                              urgency = ''                              urgency = ''
408                      else:                      else:
409                          ver = self.make_red('(unfixed)')                          ver = self.make_red('(unfixed)')
410                        if urgency == 'not yet assigned':
411                            urgency = ''
412    
413                      pkg = n.package                      pkg = n.package
414                      pkg_kind = n.package_kind                      pkg_kind = n.package_kind
415                      if pkg_kind == 'source':                      if pkg_kind == 'source':
416                          pkg = self.make_source_package_ref(url, pkg)                          pkg = self.make_source_package_ref(url, pkg)
                     elif pkg_kind == 'binary':  
                         pkg = self.make_binary_package_ref(url, pkg)  
417                      elif pkg_kind == 'itp':                      elif pkg_kind == 'itp':
418                          pkg_kind = 'ITP'                          pkg_kind = 'ITP'
419                          rel = ''                          rel = ''
# Line 382  data source.""")], Line 445  data source.""")],
445    
446          return self.create_page(url, bug.name, page)          return self.create_page(url, bug.name, page)
447    
448      def page_debian_bug(self, url, bugnumber, buglist):      def page_debian_bug(self, url, bugnumber, buglist, fake_bug):
449            if fake_bug:
450                new_buglist = []
451                for b in buglist:
452                    (bug_name, urgency, description) = b
453                    if bug_name[0:5] == 'FAKE-' or bug_name[0:5] == 'TEMP-':
454                        new_buglist.append(b)
455                if len(new_buglist) > 0:
456                    # Only replace the bug list if there are still fake
457                    # bug reports.
458                    buglist = new_buglist
459    
460          if len(buglist) == 1:          if len(buglist) == 1:
461              # Single issue, redirect.              # Single issue, redirect.
462              return RedirectResult(url.scriptRelativeFull(buglist[0][0]))              return RedirectResult(url.scriptRelativeFull(buglist[0][0]))
# Line 393  data source.""")], Line 467  data source.""")],
467                      urgency = ""                      urgency = ""
468                  yield self.make_xref(url, name), urgency, description                  yield self.make_xref(url, name), urgency, description
469    
470            if fake_bug:
471                intro = """The URL you used contained a non-stable name
472    based on a Debian bug number.  This name cannot be mapped to a specific
473    issue. """
474            else:
475                intro = ""
476    
477          return self.create_page(          return self.create_page(
478              url, "Information related to Debian bug #%d" % bugnumber,              url, "Information related to Debian bug #%d" % bugnumber,
479              [P("The following issues reference to Debian bug ",              [P(intro + "The following issues reference to Debian bug ",
480                 self.make_debian_bug(url, bugnumber), ":"),                 self.make_debian_bug(url, bugnumber), ":"),
481               make_table(gen(),               make_table(gen(),
482                          caption=("Name", "Urgency", "Description"))])                          caption=("Name", "Urgency", "Description"))])
# Line 407  data source.""")], Line 488  data source.""")],
488                                     ' matched no results.')],                                     ' matched no results.')],
489                                  status=404)                                  status=404)
490    
491        def page_report(self, path, params, url):
492            return self.create_page(
493                url, 'Reporting discrepancies in the data',
494                [P("""The data in this tracker is always in flux, as bugs are fixed and new
495    issues disclosed, the data contained herein is updated. We strive to
496    maintain complete and accurate state information, and appreciate any
497    updates in status, information or new issues."""),
498                 P("There are three ways that you can report updates to this information:"),
499                 make_numbered_list(
500                [P("""IRC: We can be found at """,
501                   CODE("irc.oftc.net"),
502                   ", ",
503                   CODE("#debian-security"),
504        """. If you have information to report, please go ahead and join
505    the channel and tell us.  Please feel free to state the issue,
506    regardless if there is someone who has acknowledged you. Many of us
507    idle on this channel and may not be around when you join, but we read
508    the backlog and will see what you have said. If you require a
509    response, do not forget to let us know how to get a hold of you."""),
510                 P("Mailing list: Our mailing list is: ",
511                   A("mailto:debian-security-tracker@lists.debian.org",
512                     "debian-security-tracker@lists.debian.org")),
513                 P("""Helping out: We welcome people who wish to join us in tracking
514    issues. The process is designed to be easy to learn and participate,
515    please read our """,
516                   A("http://svn.debian.org/wsvn/secure-testing/doc/narrative_introduction?op=file&rev=0&sc=0",
517                     "Introduction"),
518                   """ to get familiar with how things work.  Join us on
519    our mailing list, and on IRC and request to be added to the Alioth """,
520                   A("http://alioth.debian.org/projects/secure-testing/", "project"),
521                   """. We are really quite friendly. If you have a
522    question about how things work, don't be afraid to ask, we would like
523    to improve our documentation and procedures, so feedback is welcome.""")])])
524    
525      def page_source_package(self, path, params, url):      def page_source_package(self, path, params, url):
526          pkg = path[0]          pkg = path[0]
527    
# Line 414  data source.""")], Line 529  data source.""")],
529              for (releases, version) in self.db.getSourcePackageVersions(              for (releases, version) in self.db.getSourcePackageVersions(
530                  self.db.cursor(), pkg):                  self.db.cursor(), pkg):
531                  yield ', '.join(releases), version                  yield ', '.join(releases), version
         def gen_binary():  
             for (packages, releases, archs, version) \  
                     in self.db.getBinaryPackagesForSource(  
                 self.db.cursor(), pkg):  
                 yield (self.make_binary_packages_ref(url, packages),  
                        ', '.join(releases), version, ', '.join(archs))  
532          def gen_bug_list(lst):          def gen_bug_list(lst):
533              for (bug, description) in lst:              for (bug, description) in lst:
534                  yield self.make_xref(url, bug), description                  yield self.make_xref(url, bug), description
# Line 436  data source.""")], Line 545  data source.""")],
545               H2("Available versions"),               H2("Available versions"),
546               make_table(gen_versions(), caption=("Release", "Version")),               make_table(gen_versions(), caption=("Release", "Version")),
547    
              H2("Available binary packages"),  
              make_table(gen_binary(),  
             caption=('Package', 'Release', 'Version', 'Architectures'),  
             replacement="""No binary packages are recorded in this database.  
 This probably means that the package is architecture-specific, and the  
 architecture is currently not tracked."""),  
   
548               H2("Open issues"),               H2("Open issues"),
549               make_table(gen_bug_list(self.db.getBugsForSourcePackage               make_table(gen_bug_list(self.db.getBugsForSourcePackage
550                                       (self.db.cursor(), pkg, True)),                                       (self.db.cursor(), pkg, True)),
# Line 455  architecture is currently not tracked."" Line 557  architecture is currently not tracked.""
557                          caption=('Bug', 'Description'),                          caption=('Bug', 'Description'),
558                          replacement='No known resolved issues.')])                          replacement='No known resolved issues.')])
559    
560      def page_binary_package(self, path, params, url):      def page_status_release_stable_oldstable(self, release, params, url):
561          pkg = path[0]          assert release in ('stable', 'oldstable')
562    
563          def gen_versions():          bf = BugFilterNoDSA(params)
             for (releases, source, version, archs) \  
                     in self.db.getBinaryPackageVersions(self.db.cursor(), pkg):  
                 yield (', '.join(releases),  
                        self.make_source_package_ref(url, source),  
                        version, ', '.join(archs))  
         def gen_bug_list(lst):  
             for (bug, description) in lst:  
                 yield self.make_xref(url, bug), description  
   
         return self.create_page(  
             url, "Information on binary package " + pkg,  
             [make_menu(lambda x: x,  
                        (self.url_debian_bug_pkg(url, pkg),  
                         pkg + ' in the Bug Tracking System')),  
              H2("Available versions"),  
              make_table(gen_versions(),  
                 caption=("Release", "Source", "Version", "Architectures")),  
   
              H2("Open issues"),  
              make_table(gen_bug_list(self.db.getBugsForBinaryPackage  
                                      (self.db.cursor(), pkg, True)),  
                         caption=('Bug', 'Description'),  
                         replacement='No known open issues.'),  
   
              H2("Resolved issues"),  
              make_table(gen_bug_list(self.db.getBugsForBinaryPackage  
                                      (self.db.cursor(), pkg, False)),  
                         caption=('Bug', 'Description'),  
                         replacement='No known resolved issues.'),  
   
              H2("Non-issues"),  
                 make_table(gen_bug_list(self.db.getNonBugsForBinaryPackage  
                                         (self.db.cursor(), pkg)),  
                     caption=('Bug', 'Description'),  
                     replacement="""No known issues which do not affect  
 this package, but still reference it.""")])  
   
     def page_status_release_stable(self, path, params, url):  
         bf = BugFilter(params)  
564    
565          def gen():          def gen():
566              old_pkg_name = ''              old_pkg_name = ''
567              for (pkg_name, bug_name, archive, urgency, remote) in \              for (pkg_name, bug_name, archive, urgency, vulnerable, remote, no_dsa) in \
568                      self.db.cursor().execute(                      self.db.cursor().execute(
569                  """SELECT package, bug, section, urgency, remote                  """SELECT package, bug, section, urgency, vulnerable, remote, no_dsa
570                  FROM stable_status"""):                  FROM %s_status""" % release):
571                  if bf.urgencyFiltered(urgency):                  if bf.urgencyFiltered(urgency, vulnerable):
572                      continue                      continue
573                  if bf.remoteFiltered(remote):                  if bf.remoteFiltered(remote):
574                      continue                      continue
575                    if bf.nodsaFiltered(no_dsa):
576                        continue
577    
578                  if pkg_name == old_pkg_name:                  if pkg_name == old_pkg_name:
579                      pkg_name = ''                      pkg_name = ''
580                  else:                  else:
# Line 518  this package, but still reference it.""" Line 583  this package, but still reference it."""
583                          pkg_name = "%s (%s)" % (pkg_name, archive)                          pkg_name = "%s (%s)" % (pkg_name, archive)
584    
585                  if remote is None:                  if remote is None:
586                      remote = ''                      remote = '???'
587                  elif remote:                  elif remote:
588                      remote = 'yes'                      remote = 'yes'
589                  else:                  else:
590                      remote = 'no'                      remote = 'no'
591    
592                  if urgency == 'unknown':                  if urgency.startswith('high'):
                     urgency = ''  
                 elif urgency == 'high':  
593                      urgency = self.make_red(urgency)                      urgency = self.make_red(urgency)
594                    elif vulnerable == 2:
595                        urgency = self.make_purple(urgency)
596                    else:
597                        if no_dsa:
598                            urgency = urgency + '*'
599    
600                  yield pkg_name, self.make_xref(url, bug_name), urgency, remote                  yield pkg_name, self.make_xref(url, bug_name), urgency, remote
601    
602          return self.create_page(          return self.create_page(
603              url, 'Vulnerable source packages in the stable suite',              url, 'Vulnerable source packages in the %s suite' % release,
604              [bf.actions(url),              [bf.actions(url), BR(),
605               make_table(gen(), caption=("Package", "Bug", "Urgency",               make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote")),
606                                          "Remote"))])               P('''If a "*" is included in the urgency field, no DSA is planned
607                      for this vulnerability.'''),
608                 self.nvd_text])
609    
610        def page_status_release_stable(self, path, params, url):
611            return self.page_status_release_stable_oldstable('stable', params, url)
612        def page_status_release_oldstable(self, path, params, url):
613            return self.page_status_release_stable_oldstable('oldstable',
614                                                             params, url)
615    
616      def page_status_release_testing(self, path, params, url):      def page_status_release_testing(self, path, params, url):
617          bf = BugFilter(params)          bf = BugFilterNoDSA(params)
618    
619          def gen():          def gen():
620              old_pkg_name = ''              old_pkg_name = ''
621              for (pkg_name, bug_name, archive, urgency,              for (pkg_name, bug_name, archive, urgency, vulnerable,
622                   sid_vulnerable, ts_fixed, remote) in self.db.cursor().execute(                   sid_vulnerable, ts_fixed, remote, no_dsa) \
623                  """SELECT package, bug, section, urgency, unstable_vulnerable,                   in self.db.cursor().execute(
624                  testing_security_fixed, remote                  """SELECT package, bug, section, urgency, vulnerable,
625                    unstable_vulnerable, testing_security_fixed, remote, no_dsa
626                  FROM testing_status"""):                  FROM testing_status"""):
627                  if bf.urgencyFiltered(urgency):                  if bf.urgencyFiltered(urgency, vulnerable):
628                      continue                      continue
629                  if bf.remoteFiltered(remote):                  if bf.remoteFiltered(remote):
630                      continue                      continue
631                    if bf.nodsaFiltered(no_dsa):
632                        continue
633    
634                  if pkg_name == old_pkg_name:                  if pkg_name == old_pkg_name:
635                      pkg_name = ''                      pkg_name = ''
# Line 560  this package, but still reference it.""" Line 639  this package, but still reference it."""
639                          pkg_name = "%s (%s)" % (pkg_name, archive)                          pkg_name = "%s (%s)" % (pkg_name, archive)
640    
641                  if remote is None:                  if remote is None:
642                      remote = ''                      remote = '???'
643                  elif remote:                  elif remote:
644                      remote = 'yes'                      remote = 'yes'
645                  else:                  else:
# Line 574  this package, but still reference it.""" Line 653  this package, but still reference it."""
653                      else:                      else:
654                          status = self.make_dangerous('fixed in unstable')                          status = self.make_dangerous('fixed in unstable')
655    
656                  if urgency == 'unknown':                  if urgency.startswith('high'):
657                      urgency = ''                      urgency = self.make_red(urgency)
658                    elif vulnerable == 2:
659                        urgency = self.make_purple(urgency)
660    
661                  yield (pkg_name, self.make_xref(url, bug_name),                  yield (pkg_name, self.make_xref(url, bug_name),
662                         urgency, remote, status)                         urgency, remote, status)
# Line 584  this package, but still reference it.""" Line 665  this package, but still reference it."""
665              url, 'Vulnerable source packages in the testing suite',              url, 'Vulnerable source packages in the testing suite',
666              [make_menu(url.scriptRelative,              [make_menu(url.scriptRelative,
667                         ("status/dtsa-candidates", "Candidates for DTSAs")),                         ("status/dtsa-candidates", "Candidates for DTSAs")),
668               bf.actions(url),               bf.actions(url), BR(),
669               make_table(gen(), caption=("Package", "Bug", "Urgency",               make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote")),
670                                          "Remote"))])               self.nvd_text])
671    
672      def page_status_release_unstable(self, path, params, url):      def page_status_release_unstable_like(self, path, params, url,
673                                              rel, title):
674          bf = BugFilter(params)          bf = BugFilter(params)
675    
676          def gen():          def gen():
677              old_pkg_name = ''              old_pkg_name = ''
678              for (pkg_name, bug_name, section, urgency, remote) \              for (pkg_name, bug_name, section, urgency, vulnerable, remote) \
679                      in self.db.cursor().execute(                      in self.db.cursor().execute(
680                  """SELECT DISTINCT sp.name, st.bug_name,                  """SELECT DISTINCT sp.name, st.bug_name,
681                  sp.archive, st.urgency,                  sp.archive, st.urgency, st.vulnerable,
682                  (SELECT range_remote FROM nvd_data                  (SELECT range_remote FROM nvd_data
683                   WHERE cve_name = st.bug_name)                   WHERE cve_name = st.bug_name)
684                  FROM source_package_status AS st, source_packages AS sp                  FROM source_package_status AS st, source_packages AS sp
685                  WHERE st.vulnerable AND st.urgency <> 'unimportant'                  WHERE st.vulnerable AND sp.rowid = st.package
686                  AND sp.rowid = st.package AND sp.release = 'sid'                  AND sp.release = ?  AND sp.subrelease = ''
687                  AND sp.subrelease = ''                  ORDER BY sp.name, st.bug_name""", (rel,)):
688                  ORDER BY sp.name, st.bug_name"""):                  if bf.urgencyFiltered(urgency, vulnerable):
                 if bf.urgencyFiltered(urgency):  
689                      continue                      continue
690                  if bf.remoteFiltered(remote):                  if bf.remoteFiltered(remote):
691                      continue                      continue
# Line 619  this package, but still reference it.""" Line 700  this package, but still reference it."""
700                          pkg_name = self.make_xref(url, pkg_name)                          pkg_name = self.make_xref(url, pkg_name)
701    
702                  if remote is None:                  if remote is None:
703                      remote = ''                      remote = '???'
704                  elif remote:                  elif remote:
705                      remote = 'yes'                      remote = 'yes'
706                  else:                  else:
707                      remote = 'no'                      remote = 'no'
708    
709                  if urgency == 'unknown':                  if urgency.startswith('high'):
                     urgency = ''  
                 elif urgency == 'high':  
710                      urgency = self.make_red(urgency)                      urgency = self.make_red(urgency)
711                    elif vulnerable == 2:
712                        urgency = self.make_purple(urgency)
713    
714                  yield pkg_name, self.make_xref(url, bug_name), urgency, remote                  yield pkg_name, self.make_xref(url, bug_name), urgency, remote
715    
   
716          return self.create_page(          return self.create_page(
717              url, 'Vulnerable source packages in the unstable suite',              url, title,
718              [P("""Note that the list below is based on source packages.              [P("""Note that the list below is based on source packages.
719              This means that packages are not listed here once a new,              This means that packages are not listed here once a new,
720              fixed source version has been uploaded to the archive, even              fixed source version has been uploaded to the archive, even
721              if there are still some vulnerably binary packages present              if there are still some vulnerably binary packages present
722              in the archive."""),              in the archive."""),
723               bf.actions(url),               bf.actions(url), BR(),
724               make_table(gen(), caption=('Package', 'Bug', 'Urgency',               make_table(gen(), caption=('Package', 'Bug', 'Urgency', 'Remote')),
725                                          'Remote'))])               self.nvd_text])
726    
727        def page_status_release_unstable(self, path, params, url):
728            return self.page_status_release_unstable_like(
729                path, params, url,
730                title='Vulnerable source packages in the unstable suite',
731                rel='sid')
732    
733        def page_status_release_stable_backports(self, path, params, url):
734            return self.page_status_release_unstable_like(
735                path, params, url,
736                title='Vulnerable source packages among backports for stable',
737                rel='lenny-backports')
738    
739        def page_status_release_oldstable_backports(self, path, params, url):
740            return self.page_status_release_unstable_like(
741                path, params, url,
742                title='Vulnerable source packages among backports for oldstable',
743                rel='etch-backports')
744    
745      def page_status_dtsa_candidates(self, path, params, url):      def page_status_dtsa_candidates(self, path, params, url):
746          bf = BugFilter(params)          bf = BugFilter(params)
747    
748          def gen():          def gen():
749              old_pkg_name = ''              old_pkg_name = ''
750              for (pkg_name, bug_name, archive, urgency, stable_later,              for (pkg_name, bug_name, archive, urgency, vulnerable,
751                   remote) \                   stable_later, remote) \
752                      in self.db.cursor().execute(                      in self.db.cursor().execute(
753                  """SELECT package, bug, section, urgency,                  """SELECT package, bug, section, urgency, vulnerable,
754                  (SELECT testing.version_id < stable.version_id                  (SELECT testing.version_id < stable.version_id
755                   FROM source_packages AS testing, source_packages AS stable                   FROM source_packages AS testing, source_packages AS stable
756                   WHERE testing.name = testing_status.package                   WHERE testing.name = testing_status.package
757                   AND testing.release = 'etch'                   AND testing.release = 'squeeze'
758                   AND testing.subrelease = ''                   AND testing.subrelease = ''
759                   AND testing.archive = testing_status.section                   AND testing.archive = testing_status.section
760                   AND stable.name = testing_status.package                   AND stable.name = testing_status.package
761                   AND stable.release = 'sarge'                   AND stable.release = 'lenny'
762                   AND stable.subrelease = 'security'                   AND stable.subrelease = 'security'
763                   AND stable.archive = testing_status.section),                   AND stable.archive = testing_status.section),
764                  (SELECT range_remote FROM nvd_data                  (SELECT range_remote FROM nvd_data
# Line 668  this package, but still reference it.""" Line 766  this package, but still reference it."""
766                  FROM testing_status                  FROM testing_status
767                  WHERE (NOT unstable_vulnerable)                  WHERE (NOT unstable_vulnerable)
768                  AND (NOT testing_security_fixed)"""):                  AND (NOT testing_security_fixed)"""):
769                  if bf.urgencyFiltered(urgency):                  if bf.urgencyFiltered(urgency, vulnerable):
770                      continue                      continue
771                  if bf.remoteFiltered(remote):                  if bf.remoteFiltered(remote):
772                      continue                      continue
# Line 686  this package, but still reference it.""" Line 784  this package, but still reference it."""
784                          pkg_name = self.make_source_package_ref(url, pkg_name)                          pkg_name = self.make_source_package_ref(url, pkg_name)
785    
786                  if remote is None:                  if remote is None:
787                      remote = ''                      remote = '???'
788                  elif remote:                  elif remote:
789                      remote = 'yes'                      remote = 'yes'
790                  else:                  else:
791                      remote = 'no'                      remote = 'no'
792    
793                  if urgency == 'unknown':                  if urgency.startswith('high'):
                     urgency = ''  
                 elif urgency == 'high':  
794                      urgency = self.make_red(urgency)                      urgency = self.make_red(urgency)
795                    elif vulnerable == 2:
796                        urgency = self.make_purple(urgency)
797    
798                  if stable_later:                  if stable_later:
799                      notes = "(fixed in stable?)"                      notes = "(fixed in stable?)"
# Line 713  checker to find out why they have not en Line 811  checker to find out why they have not en
811               make_menu(url.scriptRelative,               make_menu(url.scriptRelative,
812                         ("status/release/testing",                         ("status/release/testing",
813                          "List of vulnerable packages in testing")),                          "List of vulnerable packages in testing")),
814               bf.actions(url),               bf.actions(url), BR(),
815               make_table(gen(),               make_table(gen(),
816                          caption=("Package", "Migration", "Bug", "Urgency",                          caption=("Package", "Migration", "Bug", "Urgency",
817                                   "Remote"))])                                   "Remote"))])
818    
819      def page_status_todo(self, path, params, url):      def page_status_todo(self, path, params, url):
820            hide_check = params.get('hide_check', False)
821            if hide_check:
822                flags = A(url.updateParamsDict({'hide_check' : None}),
823                          'Show "check" TODOs')
824            else:
825                flags = A(url.updateParamsDict({'hide_check' : '1'}),
826                      'Hide "check" TODOs')
827    
828          def gen():          def gen():
829              for (bug, description) in self.db.getTODOs():              for (bug, description) in self.db.getTODOs(hide_check=hide_check):
830                  yield self.make_xref(url, bug), description                  yield self.make_xref(url, bug), description
831          return self.create_page(          return self.create_page(
832              url, "Bugs with TODO items",              url, "Bugs with TODO items",
833              [make_table(gen(),              [P(flags), make_table(gen(), caption=("Bug", "Description"))])
834                          caption=("Bug", "Description"))])  
835        def page_status_undetermined(self, path, params, url):
836            def gen():
837                outrel = []
838                old_bug = ''
839                old_pkg = ''
840                old_dsc = ''
841                last_displayed = ''
842                releases = ('sid', 'squeeze', 'lenny', 'etch')
843                for (pkg_name, bug_name, release, desc) in self.db.cursor().execute(
844                        """SELECT DISTINCT sp.name, st.bug_name, sp.release,
845                        bugs.description
846                        FROM source_package_status AS st, source_packages AS sp, bugs
847                        WHERE st.vulnerable == 2 AND sp.rowid = st.package
848                        AND ( sp.release = ? OR sp.release = ? OR sp.release = ?
849                        OR sp.release = ? )
850                        AND sp.subrelease = '' AND st.bug_name == bugs.name
851                        ORDER BY sp.name, st.bug_name""", releases):
852    
853                    if old_bug == '':
854                        old_bug = bug_name
855                        old_pkg = pkg_name
856                        old_dsc = desc
857                    elif old_bug != bug_name:
858                        if old_pkg == last_displayed:
859                            to_display = ''
860                        else:
861                            to_display = old_pkg
862                        yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
863                        last_displayed = old_pkg
864                        old_bug = bug_name
865                        old_pkg = pkg_name
866                        old_dsc = desc
867                        outrel = []
868                    outrel.append( release )
869                yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
870    
871            return self.create_page(url, 'Packages that may be vulnerable but need to be checked      (undetermined issues)',
872                [P("""This page lists packages that may or may not be affected
873                by known issues.  This means that some additional work needs to
874                be done to determined whether the package is actually
875                vulnerable or not.  This list is a good area for new
876                contributors to make quick and meaningful contributions."""),
877                make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
878    
879        def page_status_unimportant(self, path, params, url):
880            def gen():
881                outrel = []
882                old_bug = ''
883                old_pkg = ''
884                old_dsc = ''
885                old_name = ''
886                last_displayed = ''
887                releases = ('sid', 'squeeze', 'lenny', 'etch')
888                for (pkg_name, bug_name, release, desc) in self.db.cursor().execute(
889                        """SELECT DISTINCT sp.name, st.bug_name, sp.release,
890                        bugs.description
891                        FROM source_package_status AS st, source_packages AS sp, bugs
892                        WHERE st.vulnerable > 0 AND sp.rowid = st.package
893                        AND ( sp.release = ? OR sp.release = ? OR sp.release = ?
894                        OR sp.release = ? ) AND st.urgency == 'unimportant'
895                        AND sp.subrelease = '' AND st.bug_name == bugs.name
896                        ORDER BY sp.name, st.bug_name""", releases):
897    
898                    if old_bug == '':
899                        old_bug = bug_name
900                        old_pkg = pkg_name
901                        old_dsc = desc
902                    elif old_bug != bug_name:
903                        if old_pkg == last_displayed:
904                            to_display = ''
905                        else:
906                            to_display = old_pkg
907                        yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
908                        last_displayed = old_pkg
909                        old_bug = bug_name
910                        old_pkg = pkg_name
911                        old_dsc = desc
912                        outrel = []
913                    outrel.append( release )
914                yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
915    
916            return self.create_page(url, 'Packages that have open unimportant issues',
917                [P("""This page lists packages that are affected by issues
918                that are considered unimportant from a security perspective.
919                These issues are thought to be unexploitable or uneffective
920                in most situations (for example, browser denial-of-services)."""),
921                make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
922    
923      def page_status_itp(self, path, params, url):      def page_status_itp(self, path, params, url):
924          def gen():          def gen():
# Line 750  checker to find out why they have not en Line 943  checker to find out why they have not en
943              url, "Unknown packages",              url, "Unknown packages",
944              [P("""Sometimes, a package referenced in a bug report              [P("""Sometimes, a package referenced in a bug report
945  cannot be found in the database.  This can be the result of a spelling  cannot be found in the database.  This can be the result of a spelling
946  return web_supporterror, or a historic entry refers to a  error, or a historic entry refers to a
947  return web_supportpackage which is no longer in the archive."""),  package which is no longer in the archive."""),
948               make_table(gen(), caption=("Package", "Bugs"),               make_table(gen(), caption=("Package", "Bugs"),
949          replacement="No unknown packages are referenced in the database.")])          replacement="No unknown packages are referenced in the database.")])
950    
# Line 789  return web_supportpackage which is no lo Line 982  return web_supportpackage which is no lo
982                  caption=("Bug", "Package", "Version 1", "Version 2"),                  caption=("Bug", "Package", "Version 1", "Version 2"),
983                  replacement="No source package version with missing epochs.")])                  replacement="No source package version with missing epochs.")])
984    
985        def page_data_latently_vulnerable(self, path, params, url):
986            def gen():
987                for pkg, bugs in self.db.cursor().execute(
988                    """SELECT package, string_set(bug_name)
989                    FROM package_notes AS p1
990                    WHERE release <> ''
991                    AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
992                    AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
993                                    WHERE p2.bug_name = p1.bug_name
994                                    AND p2.package = p1.package
995                                    AND release = '')
996                    AND EXISTS (SELECT 1 FROM source_packages
997                               WHERE name = p1.package AND release = 'sid')
998                    GROUP BY package
999                    ORDER BY package"""):
1000                    pkg = self.make_source_package_ref(url, pkg)
1001                    bugs = bugs.split(',')
1002                    yield pkg, self.make_xref_list(url, bugs)
1003    
1004            def gen_unimportant():
1005                for pkg, bugs in self.db.cursor().execute(
1006                    """SELECT package, string_set(bug_name)
1007                    FROM package_notes AS p1
1008                    WHERE release <> ''
1009                    AND urgency <> 'unimportant'
1010                    AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
1011                    AND EXISTS (SELECT 1 FROM package_notes AS p2
1012                                    WHERE p2.bug_name = p1.bug_name
1013                                    AND p2.package = p1.package
1014                                    AND release = '')
1015                    AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
1016                                    WHERE p2.bug_name = p1.bug_name
1017                                    AND p2.package = p1.package
1018                                    AND urgency <> 'unimportant'
1019                                    AND release = '')
1020                    AND EXISTS (SELECT 1 FROM source_packages
1021                               WHERE name = p1.package AND release = 'sid')
1022                    GROUP BY package
1023                    ORDER BY package"""):
1024                    pkg = self.make_source_package_ref(url, pkg)
1025                    bugs = bugs.split(',')
1026                    yield pkg, self.make_xref_list(url, bugs)
1027    
1028            return self.create_page(
1029                url, "Latently vulnerable packages in unstable",
1030                [P(
1031    """A package is latently vulnerable in unstable if it is vulnerable in
1032    any release, and there is no package note for the same vulnerability
1033    and package in unstable (and the package is still available in
1034    unstable, of course)."""),
1035                 make_table(gen(),
1036                    caption=("Package", "Bugs"),
1037                    replacement="No latently vulnerable packages were found."),
1038                 P(
1039    """The next table lists issues which are marked unimportant for
1040    unstable, but for which release-specific annotations exist which are
1041    not unimportant."""),
1042                 make_table(gen_unimportant(),
1043                    caption=("Package", "Bugs"),
1044                    replacement=
1045        "No packages with unimportant latent vulnerabilities were found."),
1046                ])
1047    
1048      def page_data_releases(self, path, params, url):      def page_data_releases(self, path, params, url):
1049          def gen():          def gen():
1050              for (rel, subrel, archive, sources, archs) \              for (rel, subrel, archive, sources, archs) \
# Line 845  tracked by this database.  In this case, Line 1101  tracked by this database.  In this case,
1101  a unique name.  These names are not stable and can change when the database  a unique name.  These names are not stable and can change when the database
1102  is updated, so they should not be used in external references."""),  is updated, so they should not be used in external references."""),
1103               P('''The automatically generated names come in two flavors:               P('''The automatically generated names come in two flavors:
1104  the first kind starts with the string "''', CODE("FAKE-000000-"),  the first kind starts with the string "''', CODE("TEMP-000000-"),
1105                 '''".  This means that no Debian bug has been assigned to this                 '''".  This means that no Debian bug has been assigned to this
1106  issue (or a bug has been created and is not recorded in this database).  issue (or a bug has been created and is not recorded in this database).
1107  In the second kind of names, there is a Debian bug for the issue, and the "''',  In the second kind of names, there is a Debian bug for the issue, and the "''',
# Line 854  Debian bug number.'''), Line 1110  Debian bug number.'''),
1110               make_table(gen(),               make_table(gen(),
1111                          caption=("Bug", "Description"))])                          caption=("Bug", "Description"))])
1112    
1113        def page_data_pts(self, path, params, url):
1114            data = []
1115            for pkg, bugs in self.db.cursor().execute(
1116                    """SELECT package, COUNT(DISTINCT bug) FROM
1117                    (SELECT package, bug, urgency FROM stable_status
1118                     UNION ALL SELECT package, bug, urgency FROM oldstable_status
1119                     UNION ALL SELECT DISTINCT sp.name, st.bug_name, st.urgency
1120                       FROM source_package_status AS st, source_packages AS sp
1121                       WHERE st.vulnerable AND st.urgency <> 'unimportant'
1122                       AND sp.rowid = st.package AND sp.release = 'sid'
1123                       AND sp.subrelease = '') x WHERE urgency <> 'unimportant'
1124                    GROUP BY package ORDER BY package"""):
1125                data.append(pkg)
1126                data.append(':')
1127                data.append(str(bugs))
1128                data.append('\n')
1129            return BinaryResult(''.join(data))
1130    
1131        def page_debsecan(self, path, params, url):
1132            obj = '/'.join(path)
1133            data = self.db.getDebsecan(obj)
1134            if data:
1135                return BinaryResult(data)
1136            else:
1137                return self.create_page(
1138                    url, "Object not found",
1139                    [P("The requested debsecan object has not been found.")],
1140                    status=404)
1141    
1142      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):
1143          append = body.append          append = body.append
1144          append(HR())          append(HR())
# Line 883  Debian bug number.'''), Line 1168  Debian bug number.'''),
1168                            onkeyup="onSearch(this.value)",                            onkeyup="onSearch(this.value)",
1169                            onmousemove="onSearch(this.value)"),                            onmousemove="onSearch(this.value)"),
1170                      INPUT(type='submit', value='Go'),                      INPUT(type='submit', value='Go'),
1171                        ' ',
1172                        A(url.scriptRelative("data/report"), "Reporting problems"),
1173                      method='get',                      method='get',
1174                      action=url.scriptRelative(''))                      action=url.scriptRelative(''))
1175    
# Line 890  Debian bug number.'''), Line 1177  Debian bug number.'''),
1177          return url.absolute("http://cve.mitre.org/cgi-bin/cvename.cgi",          return url.absolute("http://cve.mitre.org/cgi-bin/cvename.cgi",
1178                              name=name)                              name=name)
1179      def url_nvd(self, url, name):      def url_nvd(self, url, name):
1180          return url.absolute("http://nvd.nist.gov/nvd.cfm",          return url.absolute("http://web.nvd.nist.gov/view/vuln/detail",
1181                              cvename=name)                              vulnId=name)
1182        def url_rhbug(self, url, name):
1183            return url.absolute("https://bugzilla.redhat.com/show_bug.cgi",
1184                                id=name)
1185    
1186      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+)?$')):
1187          match = re_dsa.match(dsa)          match = re_dsa.match(dsa)
# Line 915  Debian bug number.'''), Line 1205  Debian bug number.'''),
1205          return url.absolute("http://packages.qa.debian.org/common/index.html",          return url.absolute("http://packages.qa.debian.org/common/index.html",
1206                              src=package)                              src=package)
1207      def url_testing_status(self, url, package):      def url_testing_status(self, url, package):
1208          return url.absolute("http://bjorn.haxx.se/debian/testing.pl",          return url.absolute("http://release.debian.org/migration/testing.pl",
1209                              package=package)                              package=package)
1210      def url_source_package(self, url, package, full=False):      def url_source_package(self, url, package, full=False):
1211          if full:          if full:
1212              return url.scriptRelativeFull("source-package/" + package)              return url.scriptRelativeFull("source-package/" + package)
1213          else:          else:
1214              return url.scriptRelative("source-package/" + package)              return url.scriptRelative("source-package/" + package)
     def url_binary_package(self, url, package, full=False):  
         if full:  
             return url.scriptRelativeFull("binary-package/" + package)  
         else:  
             return url.scriptRelative("binary-package/" + package)  
1215    
1216      def make_xref(self, url, name):      def make_xref(self, url, name):
1217          return A(url.scriptRelative(name), name)          return A(url.scriptRelative(name), name)
# Line 948  Debian bug number.'''), Line 1233  Debian bug number.'''),
1233          if name is None:          if name is None:
1234              name = cve              name = cve
1235          return A(self.url_nvd(url, cve), name)          return A(self.url_nvd(url, cve), name)
1236    
1237        def make_rhbug_ref(self, url, cve, name=None):
1238            if name is None:
1239                name = cve
1240            return A(self.url_rhbug(url, cve), name)
1241    
1242      def make_dsa_ref(self, url, dsa, name=None):      def make_dsa_ref(self, url, dsa, name=None):
1243          if name is None:          if name is None:
# Line 967  Debian bug number.'''), Line 1257  Debian bug number.'''),
1257          if title is None:          if title is None:
1258              title = pkg              title = pkg
1259          return A(self.url_source_package(url, pkg), title)          return A(self.url_source_package(url, pkg), title)
     def make_binary_package_ref(self, url, pkg, title=None):  
         if title is None:  
             title = pkg  
         return A(self.url_binary_package(url, pkg), title)  
     def make_binary_packages_ref(self, url, lst):  
         assert type(lst) <> types.StringType  
         return make_list(map(lambda x: self.make_binary_package_ref(url, x),  
                              lst))  
1260    
1261      def make_red(self, contents):      def make_red(self, contents):
1262          return SPAN(contents, _class="red")          return SPAN(contents, _class="red")
1263    
1264        def make_purple(self, contents):
1265            return SPAN(contents, _class="purple")
1266    
1267      def make_dangerous(self, contents):      def make_dangerous(self, contents):
1268          return SPAN(contents, _class="dangerous")          return SPAN(contents, _class="dangerous")

Legend:
Removed from v.3014  
changed lines
  Added in v.14909

  ViewVC Help
Powered by ViewVC 1.1.5