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: