[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Proposed refactoring of the per-release tracker pages



On Sat, 9 Jan 2010 23:34:26 -0500 Michael Gilbert wrote:

> On Thu, 7 Jan 2010 23:02:59 -0500 Michael Gilbert wrote:
> 
> > Hi all,
> > 
> > In order to address some usability, clutter, and transparancy issues
> > with the tracker, I propose to make the following changes:
> [...]
> 
> Hi all,
> 
> Attached is a patch for the proposed refactoring (after taking into
> account feedback and discussion).  See attached.

Here is an additional patch that uses the NVD urgency when one has yet
to be assigned.  See attached file.  Should I go ahead and commit all of
this now?

Mike
diff --git a/bin/tracker_service.py b/bin/tracker_service.py
index 7c18888..d41e403 100644
--- a/bin/tracker_service.py
+++ b/bin/tracker_service.py
@@ -24,10 +24,11 @@ else:
     webservice_base_class = WebServiceHTTP
 
 class BugFilter:
-    default_action_list = [("show_high_urgency", "only high urgencies"),
-                           ("show_medium_urgency", "only medium and high urgencies"),
-                           ("show_remote_only", "only remote vulnerabilities"),
-                           ("show_undetermined_urgency", "undetermined and unimportant urgencies")]
+    default_action_list = [('show_high_urgency', 'only high urgencies'),
+                           ('show_medium_urgency', 'only medium and high urgencies'),
+                           ('show_undetermined_urgency', 'only issues that are not undetermined (purple urgencies)'),
+                           ('show_unimportant_urgency', 'unimportant issues'),
+                           ('show_remote_only', 'only remote vulnerabilities')]
     def __init__(self, params, action_list=None):
         if action_list is None:
             self.action_list = self.default_action_list
@@ -47,6 +48,8 @@ class BugFilter:
                     note = 'Restore lower than medium urgencies'
                 elif self.params['show_high_urgency'] and prop == 'show_high_urgency':
                     note = 'Restore lower than high urgencies'
+                elif self.params['show_undetermined_urgency'] and prop == 'show_undetermined_urgency':
+                    note = 'Restore undetermined issues'
                 else:
                     note = 'Hide ' + desc
                 l.append(TR(TD(A(url.updateParamsDict({prop : None}), note))))
@@ -59,16 +62,19 @@ class BugFilter:
     def urgencyFiltered(self, urg, vuln):
         """Returns True for urgencies that should be filtered."""
         filterlow = self.params['show_medium_urgency'] and \
-                    urg in ('low', 'unimportant', 'undetermined')
+                    urg in ('low', 'low**', 'unimportant', 
+                    'undetermined', 'not yet assigned')
         filtermed = self.params['show_high_urgency'] and \
-                    urg in ('medium', 'low', 'unimportant', 'undetermined')
-        filteruni = not self.params['show_undetermined_urgency'] \
-                    and vuln == 2 or urg == 'unimportant'
-        return filterlow or filtermed or filteruni
+                    urg in ('medium', 'medium**', 'low', 'low**',
+                    'unimportant', 'undetermined', 'not yet assigned')
+        filterund = self.params['show_undetermined_urgency'] and vuln == 2
+        filteruni = not self.params['show_unimportant_urgency'] \
+                    and urg == 'unimportant'
+        return filterlow or filtermed or filterund or filteruni
 
     def remoteFiltered(self, remote):
         """Returns True for only remote flaws if filtered."""
-        return remote is not None and not self.params['show_remote_only'] \
+        return remote is not None and self.params['show_remote_only'] \
                and not remote
 
 class BugFilterNoDSA(BugFilter):
@@ -112,6 +118,14 @@ function onSearch(query) {
 }
 ''')).toHTML()
     
+    nvd_text =  P('''If a "**" is included, the urgency field was automatically
+        assigned by the NVD (National Vulnerability Database). Note that this
+        rating is automatically derived from a set of known factors about the
+        issue (such as access complexity, confidentiality impact, exploitability,
+        remediation level, and others). Human intervention is involved in
+        determining the values of these factors, but the rating itself comes
+        from a fully automated formula.''')
+
     def __init__(self, socket_name, db_name):
         webservice_base_class.__init__(self, socket_name)
         self.db = security_db.DB(db_name)
@@ -658,11 +672,10 @@ this package, but still reference it.""")])
                 else:
                     remote = 'no'
 
-                if vulnerable == 2:
-                    urgency = self.make_purple(urgency)
-
-                if urgency == 'high':
+                if urgency.startswith('high'):
                     urgency = self.make_red(urgency)
+                elif vulnerable == 2:
+                    urgency = self.make_purple(urgency)
                 else:
                     if no_dsa:
                         urgency = urgency + '*'
@@ -672,10 +685,10 @@ this package, but still reference it.""")])
         return self.create_page(
             url, 'Vulnerable source packages in the %s suite' % release,
             [bf.actions(url), BR(),
-             make_table(gen(), caption=("Package", "Bug", "Urgency",
-                                        "Remote")),
-             P('''(If a "*" is included in the urgency field, no DSA is planned
-for this vulnerability.)''')])
+             make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote")),
+             P('''If a "*" is included in the urgency field, no DSA is planned
+                  for this vulnerability.'''),
+             self.nvd_text])
 
     def page_status_release_stable(self, path, params, url):
         return self.page_status_release_stable_oldstable('stable', params, url)
@@ -715,9 +728,6 @@ for this vulnerability.)''')])
                 else:
                     remote = 'no'
 
-                if sid_vulnerable == 2:
-                    urgency = self.make_purple(urgency)
-
                 if ts_fixed:
                     status = 'fixed in testing-security'
                 else:
@@ -726,6 +736,11 @@ for this vulnerability.)''')])
                     else:
                         status = self.make_dangerous('fixed in unstable')
 
+                if urgency.startswith('high'):
+                    urgency = self.make_red(urgency)
+                elif vulnerable == 2:
+                    urgency = self.make_purple(urgency)
+
                 yield (pkg_name, self.make_xref(url, bug_name),
                        urgency, remote, status)
 
@@ -734,8 +749,8 @@ for this vulnerability.)''')])
             [make_menu(url.scriptRelative,
                        ("status/dtsa-candidates", "Candidates for DTSAs")),
              bf.actions(url), BR(),
-             make_table(gen(), caption=("Package", "Bug", "Urgency",
-                                        "Remote"))])
+             make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote")),
+             self.nvd_text])
 
     def page_status_release_unstable_like(self, path, params, url,
                                           rel, title):
@@ -774,7 +789,7 @@ for this vulnerability.)''')])
                 else:
                     remote = 'no'
 
-                if urgency == 'high':
+                if urgency.startswith('high'):
                     urgency = self.make_red(urgency)
                 elif vulnerable == 2:
                     urgency = self.make_purple(urgency)
@@ -789,8 +804,8 @@ for this vulnerability.)''')])
             if there are still some vulnerably binary packages present
             in the archive."""),
              bf.actions(url), BR(),
-             make_table(gen(), caption=('Package', 'Bug', 'Urgency',
-                                        'Remote'))])
+             make_table(gen(), caption=('Package', 'Bug', 'Urgency', 'Remote')),
+             self.nvd_text])
 
     def page_status_release_unstable(self, path, params, url):
         return self.page_status_release_unstable_like(
@@ -858,8 +873,10 @@ for this vulnerability.)''')])
                 else:
                     remote = 'no'
 
-                if urgency == 'high':
+                if urgency.starstwith('high'):
                     urgency = self.make_red(urgency)
+                elif vulnerable == 2:
+                    urgency = self.make_purple(urgency)
 
                 if stable_later:
                     notes = "(fixed in stable?)"
diff --git a/bin/update-nvd b/bin/update-nvd
index 281c047..fb564c4 100644
--- a/bin/update-nvd
+++ b/bin/update-nvd
@@ -43,8 +43,5 @@ data = deduplicate.values()
 data.sort()
 
 cursor = db.writeTxn()
-if incremental:
-    db.updateNVD(cursor, data)
-else:
-    db.replaceNVD(cursor, data)
+db.updateNVD(cursor, data, incremental)
 db.commit(cursor)
diff --git a/lib/python/bugs.py b/lib/python/bugs.py
index 482149d..b3edb0b 100644
--- a/lib/python/bugs.py
+++ b/lib/python/bugs.py
@@ -23,7 +23,7 @@ class Urgency(debian_support.PseudoEnum): pass
 
 def listUrgencies():
     urgencies = {}
-    urgs = ("high", "medium", "low", "unimportant", "undetermined")
+    urgs = ('high', 'medium', 'low', 'unimportant', 'not yet assigned')
     for u in range(len(urgs)):
         urgencies[urgs[u]] = Urgency(urgs[u], -u)
     Urgency.urgencies = urgencies
@@ -140,10 +140,7 @@ class PackageNoteParsed(PackageNote):
 
     def __init__(self, package, version, notes, release=None):
         bugs = []
-        if version == 'undetermined':
-            urgency = 'undetermined'
-        else:
-            urgency = 'low'
+        urgency = 'not yet assigned'
         if notes is not None:
             for n in self.re_notes_split.split(notes):
                 u = internUrgency(n)
diff --git a/lib/python/security_db.py b/lib/python/security_db.py
index 919768d..864fff5 100644
--- a/lib/python/security_db.py
+++ b/lib/python/security_db.py
@@ -1308,7 +1308,7 @@ class DB:
         c.execute("""DELETE FROM vulnlist WHERE name LIKE 'TEMP-0000000-%'""")
 
         urgency_to_flag = {'low' : 'L', 'medium' : 'M', 'high' : 'H',
-                           'unknown' : ' ' , 'undetermined' : ' '}
+                           'not yet assigned' : ' '}
 
         result = ["VERSION 0\n"]
         for (name, package, fixed_version, kind, urgency, remote, description,
@@ -1442,7 +1442,7 @@ class DB:
         fill_bug_to_index()
 
         urgency_to_flag = {'low' : 'L', 'medium' : 'M', 'high' : 'H',
-                           'unknown' : ' ', 'undetermined' : ' '}
+                           'not yet assigned' : ' '}
 
         vuln_list = []
         source_packages = {}
@@ -1615,7 +1615,6 @@ class DB:
             self.calculateDebsecan0(release)
         self.calculateDebsecan1()
         
-
     def getDebsecan(self, name):
         """Returns the debsecan data item NAME."""
         for (data,) in self.cursor().execute(
@@ -1624,20 +1623,37 @@ class DB:
         else:
             return None
 
-    def replaceNVD(self, cursor, data):
-        """Replaces the stored NVD data."""
-        cursor.execute("DELETE FROM nvd_data");
-        cursor.executemany("INSERT INTO nvd_data VALUES (?"
-                           + (", ?" * (len(data[0]) - 1))
-                           + ")", data)
-
-    def updateNVD(self, cursor, data):
-        """Adds (and overwrites) NVD data stored in the database.
-        This can be used for incremental updates."""
+    def updateNVD(self, cursor, data, incremental):
+        """Adds (and overwrites) NVD data stored in the database.  This
+        can be used for incremental updates if incremental is True."""
+        if not incremental:
+            cursor.execute("DELETE FROM nvd_data");
         cursor.executemany("INSERT OR REPLACE INTO nvd_data VALUES (?"
                            + (", ?" * (len(data[0]) - 1))
                            + ")", data)
 
+        # assign nvd urgencies to those that have not yet been assigned
+        cursor.execute(
+            """REPLACE INTO source_package_status
+            SELECT s.bug_name, s.package, s.vulnerable, 
+            CASE WHEN n.severity == 'Medium' THEN 'medium**'
+            ELSE CASE WHEN n.severity == 'High' THEN 'high**'
+            ELSE CASE WHEN n.severity == 'Low' THEN 'low**'
+            ELSE 'not yet assigned' END END END
+            FROM nvd_data AS n, source_package_status AS s
+            WHERE s.bug_name == n.cve_name
+            AND s.urgency == 'not yet assigned'""")
+        cursor.execute(
+            """REPLACE INTO binary_package_status
+            SELECT s.bug_name, s.package, s.vulnerable, 
+            CASE WHEN n.severity == 'Medium' THEN 'medium**'
+            ELSE CASE WHEN n.severity == 'High' THEN 'high**'
+            ELSE CASE WHEN n.severity == 'Low' THEN 'low**'
+            ELSE 'not yet assigned' END END END
+            FROM nvd_data AS n, source_package_status AS s
+            WHERE s.bug_name == n.cve_name
+            AND s.urgency == 'not yet assigned'""")
+
     def getNVD(self, cursor, cve_name):
         """Returns a dictionary with NVD data corresponding to the CVE name,
         or None."""

Reply to: