summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern Tropf <asymmail@googlemail.com>2009-06-08 00:03:46 +0200
committerBjoern Tropf <asymmail@googlemail.com>2009-06-08 00:03:46 +0200
commit478c95410e4b1c9862e501474faa3cf582768af6 (patch)
tree8e10db5ca0e0bda643bec4ebd6454774c16b9e19
parentMove is_in_interval() to kernellib.py; Use dict for genpatches (diff)
downloadkernel-check-478c95410e4b1c9862e501474faa3cf582768af6.tar.gz
kernel-check-478c95410e4b1c9862e501474faa3cf582768af6.tar.bz2
kernel-check-478c95410e4b1c9862e501474faa3cf582768af6.zip
Add cve/vulnerability class, change lots of code
-rw-r--r--TODO2
-rwxr-xr-xcollector.py9
-rwxr-xr-xkernel-check.py53
-rwxr-xr-xkernellib.py143
4 files changed, 117 insertions, 90 deletions
diff --git a/TODO b/TODO
index 0ff31d5..36b8884 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,7 @@
Todo
====
- Fix all TODO markers
-- Create a vulnerability class
+- Find a solution for <ref source url/>
Clean code
==========
diff --git a/collector.py b/collector.py
index 5951e95..cd214ef 100755
--- a/collector.py
+++ b/collector.py
@@ -101,15 +101,16 @@ def main(argv):
print('Creating the xml files...')
for item in buglist:
lib.receive_bugzilla_bug(folder['bug'], item)
- bug_dict = lib.parse_bugzilla_dict(folder['bug'], item)
- lib.write_cve_file(folder['out'], item, bug_dict, nvd_dict)
+ vul = lib.parse_bugzilla_dict(folder['bug'], item)
+ vul = lib.search_nvd_dict(nvd_dict, vul)
+ lib.write_cve_file(folder['out'], vul)
time.sleep(DELAY)
def usage():
'Prints the usage screen'
- print 'Usage: ' + sys.argv[0][:-3] + ' [OPTION]...'
+ print 'Usage: %s [OPTION]...' % sys.argv[0][:-3]
print 'Kernel security information\r\n'
print ' -d, --delay [ticks] add delay to xml file creation'
print ' -f, --force force update of xml files'
@@ -117,7 +118,7 @@ def usage():
print ' -t, --tree [dir] set the portage path'
print ' -s, --skip skip update of earlier xml files'
print ' -v, --verbose display debugging information'
- print '\r\nVersion: 0.3'
+ print '\r\nVersion: %s' % lib.VERSION
print 'Copyright (C) 2009 Bjoern Tropf <asymmail@googemail.com>'
print 'Copyright (C) 2009 Robert Buchholz <rbu@gentoo.org>'
sys.exit()
diff --git a/kernel-check.py b/kernel-check.py
index c8f2019..1bce717 100755
--- a/kernel-check.py
+++ b/kernel-check.py
@@ -25,13 +25,6 @@ import kernellib as lib
def main(argv):
'Main function'
- KERNEL = lib.extract_version(os.uname()[2])
-
- ARCH = os.uname()[4]
- BEST = lib.best_version(KERNEL['source'])
- CVE = [345, 284, 274, 0, 4] #TODO: Implement + use dict!
- GENPATCH = lib.get_genpatch(lib.read_genpatch_file('out'), KERNEL)
-
info = portage.output.EOutput().einfo
warn = portage.output.EOutput().ewarn
error = portage.output.EOutput().eerror
@@ -54,42 +47,46 @@ def main(argv):
return
# TODO: show_bugid(arg)
elif opt in ('-v', '--verbose'):
- lib.verbose = True
+ lib.VERBOSE = True
print '>>> Gathering system information'
- if KERNEL:
- info('Kernel version: ' + color('GOOD', KERNEL['version'] + '-' + KERNEL['revision']))
- info('Kernel sources: ' + color('GOOD', KERNEL['source']))
+ kernel = lib.extract_version(os.uname()[2])
+ if kernel:
+ info('Kernel version: ' + color('GOOD', kernel['version'] + '-' + kernel['revision']))
+ info('Kernel sources: ' + color('GOOD', kernel['source']))
else:
error('No kernel information found!')
sys.exit()
- if GENPATCH:
- info('Integrated genpatch: ' + color('GOOD', GENPATCH['version'] + ' ' + GENPATCH['want']))
+ genpatch = lib.get_genpatch(lib.read_genpatch_file('out'), kernel)
+ if genpatch:
+ info('Integrated genpatch: ' + color('GOOD', genpatch['version'] + ' ' + genpatch['want']))
else:
warn('No genpatch information found!')
- if ARCH:
- info('System architecture: ' + color('GOOD', ARCH))
+ arch = os.uname()[4]
+ if arch:
+ info('System architecture: ' + color('GOOD', arch))
else:
error('No system architecture found!')
sys.exit()
print '\n>>> Reading kernel vulnerabilities'
- if CVE:
- info(color('GOOD', str(CVE[0])) + ' files read')
- info(color('GOOD', str(CVE[1])) + ' match this system')
- info(color('GOOD', str(CVE[2])) + ' haven been fixed')
+ cve = [345, 284, 274, 0, 4] #TODO: Implement + use dict!
+ if cve:
+ info(color('GOOD', str(cve[0])) + ' files read')
+ info(color('GOOD', str(cve[1])) + ' match this system')
+ info(color('GOOD', str(cve[2])) + ' haven been fixed')
- if CVE[3]:
- warn(str(CVE[3]) + ' could be fixed by upgrading')
+ if cve[3]:
+ warn(str(cve[3]) + ' could be fixed by upgrading')
else:
info('No vulnerability could be fixed by upgrading')
- if CVE[4]:
- warn(str(CVE[4]) + ' have not been fixed yet')
+ if cve[4]:
+ warn(str(cve[4]) + ' have not been fixed yet')
else:
info('No vulnerability have not been fixed yet')
@@ -97,7 +94,9 @@ def main(argv):
error('No vulnerability files found!')
sys.exit()
- if not CVE[3]:
+
+ if not cve[3]:
+ best = lib.best_version(kernel['source'])
info('')
info('These could be fixed by upgrading:')
info('')
@@ -108,7 +107,7 @@ def main(argv):
info('$ ' + sys.argv[0] + ' -i [id]')
info('')
info('Upgrading to the latest version')
- info('[' + color('GOOD', BEST) + ']')
+ info('[' + color('GOOD', best) + ']')
info('is recommended!')
else:
info('')
@@ -118,14 +117,14 @@ def main(argv):
def usage():
'Prints the usage screen'
- print 'Usage: ' + sys.argv[0][:-3] + ' [OPTION]...'
+ print 'Usage: %s [OPTION]...' % sys.argv[0][:-3]
print 'Kernel security information\r\n'
print ' -h, --help display help information'
print ' -n, --nocolor disable colors'
print ' -r, --report [file] create a security report'
print ' -s, --show [bugid] display information about a bug'
print ' -v, --verbose display debugging information'
- print '\r\nVersion: 0.3'
+ print '\r\nVersion: %s' % lib.VERSION
print 'Copyright (C) 2009 Bjoern Tropf <asymmail@googemail.com>'
print 'Copyright (C) 2009 Robert Buchholz <rbu@gentoo.org>'
sys.exit()
diff --git a/kernellib.py b/kernellib.py
index 317142b..be95a70 100755
--- a/kernellib.py
+++ b/kernellib.py
@@ -57,6 +57,7 @@ GENERAL_KERNEL_TYPES = ['aa', 'acpi', 'ac', 'alpha', 'arm', 'as', 'cell', 'ck',
GENTOO_KERNEL_TYPES = ['cell', 'mips', 'tuxonice', 'mm', 'usermode', 'gentoo', 'vanilla', 'git',
'openvz', 'vserver', 'hardened', 'sh', 'xbox', 'sparc', 'xen']
+VERSION = '0.4'
VERBOSE = False
FORCE = False
@@ -244,29 +245,55 @@ def parse_bugzilla_list(filename):
return buglist
+#TODO: Short Code, use Vulnerability directly instead of dic
def parse_bugzilla_dict(directory, bugid):
- 'Returns a dictionary containing information about a kernel vulnerability'
+ 'Returns a vulnerability containing information about a kernel vulnerability' #FIXME: Sounds strange
bugfilename = os.path.join(directory, bugid)
root = et.parse(open(bugfilename, 'r')).getroot()[0]
- elements = ['bug_id', 'creation_ts', 'reporter', 'status_whiteboard', 'short_desc', 'rep_platform']
+ elem = ['bug_id', 'reporter', 'creation_ts', 'rep_platform', 'status_whiteboard', 'short_desc']
dic = dict()
- for i in elements:
- if i == 'short_desc':
- cves = extract_cves(root.find(i).text)
+ for item in elem:
+ if item == 'short_desc':
+ cves = extract_cves(root.find(item).text)
if len(cves) > 0:
dic['cves'] = cves
else:
error('Invalid cve for bugid [%s]' % root.find('bug_id').text)
- error('-> ' + root.find(i).text)
+ error('-> ' + root.find(item).text)
try:
- dic[i] = root.find(i).text
+ dic[item] = root.find(item).text
except AttributeError:
- dic[i] = None
+ dic[item] = None
- return dic
+ interval = from_whiteboard(dic['status_whiteboard'])
+ vul = Vulnerability(dic['cves'], dic[elem[0]], dic[elem[1]], dic[elem[2]], dic[elem[3]], interval)
+
+ return vul
+
+
+def search_nvd_dict(dic, vul): #TODO: Rename
+ #TODO: Description
+
+ cves = list()
+
+ for item in vul.cvelist:
+ cve = Cve(item,
+ dic[item]['published'],
+ dic[item]['desc'],
+ dic[item]['severity'],
+ dic[item]['CVSS_vector'],
+ dic[item]['CVSS_score'],
+ dic[item]['refs'])
+ #TODO: bugref.set('url', 'https://bugs.gentoo.org/show_bug.cgi?id=' + bug_dict['bug_id'])
+ #TODO: bugref.text = 'Gentoo bug #%s' % (bug_dict['bug_id'],)
+
+ cves.append(cve)
+ vul.cves = cves
+
+ return vul
def parse_nvd_dict(directory):
@@ -299,7 +326,7 @@ def parse_nvd_dict(directory):
reftree.tag = reftree.tag.replace(namespace, '')
for elem in reftree.findall('.//*'):
elem.tag = elem.tag.replace(namespace, '')
- dic['refs'] = reftree
+ dic['refs'] = reftree #TODO: Rework! Use dict instead
desc = tree.find(''.join(namespace + tag + '/' for tag in ('desc', 'descript')))
if desc != None:
@@ -348,73 +375,44 @@ def read_cve_file():
return
-#TODO: Deprecated, create a vulnerability class
-def write_cve_file(directory, bugid, bug_dict, nvd_dict):
+def write_cve_file(directory, vul):
'Write a bug file containing all important information for kernel-check'
- filename = os.path.join(directory, bugid + '.xml')
+ filename = os.path.join(directory, vul.bugid + '.xml')
- bug_order = ['id', 'reporter', 'reported', 'arch', 'affected']
- cve_order = ['id', 'published', 'desc', 'severity', 'vector', 'score', 'refs']
+ bug_order = ['bugid', 'reporter', 'reported', 'arch', 'affected'] #FIXME
+ cve_order = ['published', 'desc', 'severity', 'vector', 'score', 'refs'] #FIXME
root = et.Element('vulnerability')
-
- try:
- cves = bug_dict['cves']
-
- xml_bug_dict = {
- 'arch' : bug_dict['rep_platform'],
- 'id' : bug_dict['bug_id'],
- 'reporter' : bug_dict['reporter'],
- 'reported' : bug_dict['creation_ts']
- }
-
- except KeyError:
- return
-
bugroot = et.SubElement(root, 'bug')
for element in bug_order:
if element == 'affected':
affectedroot = et.SubElement(bugroot, 'affected')
- intervals = from_whiteboard(bug_dict['status_whiteboard'])
- if intervals:
- for item in intervals:
+ if vul.interval:
+ for item in vul.interval:
item.to_xml(affectedroot)
else:
- error('Whiteboard for bugid [%s]' % bug_dict['bug_id'])
- error('-> %s' % bug_dict['status_whiteboard'])
+ error('Whiteboard for bugid [%s]' % vul.bugid)
+ error('-> %s' % vul.interval)
else:
node = et.SubElement(bugroot, element)
- node.text = xml_bug_dict[element]
-
- for enum, cve in enumerate(cves):
- try:
- xml_cve_dic = {
- 'desc' : nvd_dict[cve]['desc'],
- 'id' : cve,
- 'published' : nvd_dict[cve]['published'],
- 'severity' : nvd_dict[cve]['severity'],
- 'score' : nvd_dict[cve]['CVSS_score'],
- 'refs' : nvd_dict[cve]['refs'],
- 'vector' : nvd_dict[cve]['CVSS_vector']
- }
-
- except KeyError:
- break
+ node.text = getattr(vul, element)
+ for cve in vul.cves:
cveroot = et.SubElement(root, 'cve')
for element in cve_order:
if element == 'refs':
- reftree = xml_cve_dic[element]
- cveroot.append(xml_cve_dic[element])
- bugref = et.SubElement(reftree, 'ref')
- bugref.set('url', 'https://bugs.gentoo.org/show_bug.cgi?id=' + bug_dict['bug_id'])
- bugref.text = 'Gentoo bug #%s' % (bug_dict['bug_id'],)
+ reftree = cve.refs
+ cveroot.append(cve.refs)
+ bugref = et.SubElement(reftree, 'ref') #FIXME: Add this information earlier
+ bugref.set('url', 'https://bugs.gentoo.org/show_bug.cgi?id=%s' % vul.bugid)
+ bugref.set('source', 'GENTOO')
+ bugref.text = 'Gentoo bug #%s' % vul.bugid
else:
node = et.SubElement(cveroot, element)
- node.text = xml_cve_dic[element]
+ node.text = getattr(cve, element)
write_xml(root, filename)
@@ -430,7 +428,36 @@ def write_xml(root, filename):
doc.write(xmlout, encoding='utf-8')
-class IntervalEntry:
+class Vulnerability:
+ #TODO: Description
+
+ def __init__(self, cvelist, bugid, reporter, reported, arch, interval, cves = None):
+ #TODO: Description
+
+ self.cvelist = cvelist
+ self.bugid = bugid
+ self.reporter = reporter
+ self.reported = reported
+ self.arch = arch
+ self.interval = interval
+ self.cves = cves
+
+
+class Cve:
+ #TODO: Description
+
+ def __init__(self, cve, published, desc, severity, vector, score, refs):
+ #TODO: Description
+ self.cve = cve
+ self.published = published
+ self.desc = desc
+ self.severity = severity
+ self.vector = vector
+ self.score = score
+ self.refs = refs
+
+
+class Interval:
'Defines an interval for kernel ebuilds'
def __init__(self, name, lower, upper, lower_inclusive, upper_inclusive, expand):
@@ -591,7 +618,7 @@ def from_whiteboard(whiteboard):
if version and not REGEX['wb_version'].match(version):
return False
- affected.append(IntervalEntry(name, wb['lower'], wb['upper'], wb['lower_inc'], wb['upper_inc'], wb['expand']))
+ affected.append(Interval(name, wb['lower'], wb['upper'], wb['lower_inc'], wb['upper_inc'], wb['expand']))
whiteboard = match.group(7)
return affected