summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern Tropf <asymmail@googlemail.com>2009-08-22 11:17:03 +0200
committerBjoern Tropf <asymmail@googlemail.com>2009-08-22 11:17:03 +0200
commitbc703b78be5a3931af7ba3ac47c2002a23b940ad (patch)
tree65378792cdcec6ea6a7c219bd4669b67a2c7ab48
parentBreak lines after 79 characters (diff)
downloadkernel-check-bc703b78be5a3931af7ba3ac47c2002a23b940ad.tar.gz
kernel-check-bc703b78be5a3931af7ba3ac47c2002a23b940ad.tar.bz2
kernel-check-bc703b78be5a3931af7ba3ac47c2002a23b940ad.zip
Implement show bugid
Rework output Add beta message Remove sys.exit() Add debug arg (-d, --debug) Fix one exception
-rw-r--r--TODO40
-rwxr-xr-xcollector.py4
-rwxr-xr-xkernel-check.py178
-rwxr-xr-xkernellib.py22
4 files changed, 178 insertions, 66 deletions
diff --git a/TODO b/TODO
index cb65cfe..cc6e67e 100644
--- a/TODO
+++ b/TODO
@@ -1,19 +1,29 @@
-Todo
-====
-- Fix all inline TODO/FIXME markers
-- Find a solution for <ref source url/>
-- Use telling function- and variable names
-- Rework interval class and all interval functions (expand?)
-- Rework cves.refs
-- Use exeptions instead of debug()
+Implementation
+==============
+- Implement Report
+- Handle "best kernel not found"
- Add further error handling
-- [kernel +<version] -> [+kernel <version]
-- Ignore vserver whiteboard
-- Find a way to insert arch into bugzilla
- Implement find_cve() (return bugid)
-- Write a proper documentation
-- Implement DTD
+
+Cleanup and Rework
+==================
- Remove unused code and find better ways
- Check lookaround of 'grp_all'
-- Handle "best kernel not found"
-- Implement Show and Report
+- Rework interval class and all interval functions (expand?)
+- Rework cves.refs and find a solution for <ref source url/>
+
+Dokumentation
+=============
+- Use telling function- and variable names
+- Write a proper documentation
+- Implement DTD
+
+Whiteboard changes
+==================
+- Move arch into whiteboard e.g. {x86, amd64}
+- [kernel +<version] -> [+kernel <version]
+- Ignore vserver whiteboard
+
+Summary changes
+===============
+- Explicitly mention the CVSS score e.g. (CVSS-5.6)
diff --git a/collector.py b/collector.py
index d817024..8aed337 100755
--- a/collector.py
+++ b/collector.py
@@ -19,6 +19,7 @@ def main(argv):
['delay=', 'force', 'help', 'skip', 'verbose'])
except getopt.GetoptError:
usage()
+ return
for opt, arg in opts:
if opt in ('-d', '--delay'):
@@ -28,6 +29,7 @@ def main(argv):
lib.FORCE = True
elif opt in ('-h', '--help'):
usage()
+ return
elif opt in ('-s', '--skip'):
lib.SKIP = True
elif opt in ('-v', '--verbose'):
@@ -103,6 +105,7 @@ def main(argv):
print '\nCreated %i xml files!' % created_files
+
def usage():
'Prints the usage screen'
@@ -113,7 +116,6 @@ def usage():
print ' -h, --help display help information'
print ' -s, --skip skip update of prior nvd files'
print ' -v, --verbose display debugging information'
- sys.exit()
if __name__ == '__main__':
diff --git a/kernel-check.py b/kernel-check.py
index 62b519d..e5a0c70 100755
--- a/kernel-check.py
+++ b/kernel-check.py
@@ -10,32 +10,35 @@ import os
import kernellib as lib
+info = portage.output.EOutput().einfo
+warn = portage.output.EOutput().ewarn
+error = portage.output.EOutput().eerror
+color = portage.output.colorize
+term = portage.output.get_term_size()
def main(argv):
'Main function'
- info = portage.output.EOutput().einfo
- warn = portage.output.EOutput().ewarn
- error = portage.output.EOutput().eerror
- color = portage.output.colorize
- term = portage.output.get_term_size()
-
try:
- opts, args = getopt.getopt(argv, 'hnr:s:v',
- ['help', 'nocolor', 'report=', 'show=', 'verbose'])
+ opts, args = getopt.getopt(argv, 'dhnr:s:v',
+ ['debug', 'help', 'nocolor', 'report=', 'show=', 'verbose'])
except getopt.GetoptError:
usage()
+ return
for opt, arg in opts:
- if opt in ('-h', '--help'):
+ if opt in ('-d', '--debug'):
+ lib.DEBUG = True
+ elif opt in ('-h', '--help'):
usage()
+ return
elif opt in ('-n', '--nocolor'):
portage.output.nocolor()
elif opt in ('-r', '--report'):
error('--report not yet implemented')
return
elif opt in ('-s', '--show'):
- error('--show not yet implemented')
+ print_bug(arg)
return
elif opt in ('-v', '--verbose'):
lib.VERBOSE = True
@@ -53,9 +56,9 @@ def main(argv):
error('No kernel information found!')
sys.exit()
- info('Kernel version: %s' % (color('GOOD', '%s-%s' %
+ info('Kernel version : %s' % (color('GOOD', '%s-%s' %
(kernel.version, kernel.revision))))
- info('Kernel sources: %s' % color('GOOD', kernel.source))
+ info('Kernel source : %s' % color('GOOD', kernel.source))
best = lib.best_version(kernel.source)
if not best:
@@ -66,16 +69,16 @@ def main(argv):
genpatch = lib.get_genpatch(lib.read_genpatch_file(lib.FOLDER['out']),
kernel)
if genpatch is not None:
- info('Integrated genpatch: %s' % color('GOOD', '%s %s' %
+ info('Gen(too)patch : %s' % color('GOOD', '%s %s' %
(genpatch.version, repr(genpatch))))
- elif lib.VERBOSE:
- info('No genpatch information found.')
+ elif kernel.source == 'gentoo':
+ warn('No genpatch information found!')
arch = portage.settings['ARCH']
if arch:
- info('System architecture: %s' % color('GOOD', arch))
+ info('Architecture : %s' % color('GOOD', arch))
else:
- error('No system architecture found!')
+ error('No architecture found!')
sys.exit()
print '\n>>> Reading all kernel vulnerabilities'
@@ -89,38 +92,31 @@ def main(argv):
info('%s do not affect this system.' %
color('GOOD', str(schedule.fixed)))
- if len(schedule.canfix):
- error('%s can be fixed by upgrading.' %
- color('BAD', str(len(schedule.canfix))))
- else:
- info('No vulnerability can be fixed by upgrading.')
-
if len(schedule.notfix):
warn('%s have not been fixed yet.' %
color('WARN', str(len(schedule.notfix))))
+ if lib.VERBOSE:
+ print_summary(schedule.notfix)
+
else:
info('No vulnerabilities have not been fixed yet.')
+ if len(schedule.canfix):
+ error('%s can be fixed by upgrading.' %
+ color('BAD', str(len(schedule.canfix))))
+ else:
+ info('No vulnerability can be fixed by upgrading.')
+
else:
error('No vulnerability files found!')
sys.exit()
if len(schedule.canfix):
- print '\nThese could be fixed by upgrading:'
- for item in schedule.canfix:
- print '\n Bugid %s:' % item.bugid
- for cve in item.cves:
- print ' %s - %s\n "%s..."' % (cve.cve,
- cve.severity, cve.desc[:term[1]-14])
- print ''
- info('To print more information about a vulnerability try:')
- info('')
- info(' $ %s -s [bugid]' % sys.argv[0])
- info('')
+ print_summary(schedule.canfix)
info('It is recommended to upgrade your kernel to %s.' %
color('GOOD', best.version + '-' + best.revision))
else:
- info('')
+ print ""
if kernel == best:
info('Your kernel is up to date!')
else:
@@ -128,18 +124,118 @@ def main(argv):
color('GOOD', best.version + '-' + best.revision))
info('does not improve your security!')
+ if len(schedule.canfix) or (len(schedule.notfix) and lib.VERBOSE):
+ info('')
+ info('To print more information about a vulnerability try:')
+ info('')
+ info(' $ %s -s [bugid|cve]' % sys.argv[0])
+ info('')
+
+ print_beta()
+
+
+def print_summary(vullist):
+ 'Prints the vulnerability summary'
+
+ severity = str()
+
+ for item in vullist:
+ print '\nBugid %s' % item.bugid
+ for cve in item.cves:
+ if cve.severity == 'Low':
+ severity = 'GOOD'
+ elif cve.severity == 'Medium':
+ severity = 'WARN'
+ else:
+ severity = 'BAD'
+
+ print '%s - %s\n"%s..."' % (cve.cve,
+ color(severity, cve.severity + ' (' + cve.score + ')'),
+ cve.desc[:term[1]-6])
+ print ''
+
+
+def print_bug(bugid):
+ 'Prints information about a particular bugid'
+
+ if 'CVE' in bugid.upper():
+ #print_cve(bugid)
+ #TODO find_cve
+ return
+
+ whiteboard = str()
+ cves = str()
+ vul = lib.read_cve_file(lib.FOLDER['out'], bugid)
+
+ if vul == None:
+ error('Could not find bugid: %s' % bugid)
+ return
+
+ for i, interval in enumerate(vul.affected):
+ if i is not 0:
+ whiteboard += ' ' * 14
+ whiteboard += '[' + str(interval) + ']\n'
+
+
+ info('Bugid : ' + vul.bugid + ' - ' + vul.status.capitalize())
+ info('Reported : ' + vul.reporter + ' - ' + vul.reported[:-5])
+ info('Affected : ' + whiteboard[:-1])
+ #TODO arch = str()
+
+ for cve in vul.cves:
+ print ''
+ print_cve(cve)
+
+def print_cve(cve):
+ 'Prints information about a cve'
+
+ info('Cve : ' + cve.cve + ' - ' + cve.published)
+ info('Severity : ' + cve.severity + ' ' + cve.score + ' - ' + cve.vector)
+ info('Desc : ' + break_line('"' + cve.desc + '"', 14)[14:])
+ #TODO print cve.refs
+
+ return
+
+def break_line(string, indent):
+ 'Breaks the line at the last whitespace'
+
+ ret = str()
+ last_space = 0
+ p_last_space = 0;
+
+ for i, char in enumerate(string):
+ if char == ' ':
+ last_space = i;
+
+ if i % (term[1] - indent) is 0 and i is not 0:
+ ret += (' ' * indent) + string[p_last_space:last_space] + '\n'
+ p_last_space = last_space
+
+ if i == len(string) - 1: #FIXME why does 'is' not work?
+ ret += (' ' * indent) + string[p_last_space:len(string)]
+
+ return ret
+
+
+def print_beta():
+ print ''
+ error('%s You are using a very early version of kernel-check!' %
+ color('BAD', 'IMPORTANT'))
+ error('Please note that this tool might not operate as expected.')
+ error('Moreover the given information are most likely incorrect.')
+
def usage():
'Prints the usage screen'
print 'Usage: %s [OPTION]...' % sys.argv[0][:-3]
print 'Kernel security information %s\r\n' % lib.VERSION
- 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'
- sys.exit()
+ print ' -d, --debug display debugging information'
+ print ' -h, --help display help information'
+ print ' -n, --nocolor disable colors'
+ print ' -r, --report [file] create a security report'
+ print ' -s, --show [bugid|cve] display information about a bug or cve'
+ print ' -v, --verbose display debugging information'
if __name__ == '__main__':
diff --git a/kernellib.py b/kernellib.py
index d201ac8..921a37a 100755
--- a/kernellib.py
+++ b/kernellib.py
@@ -58,10 +58,11 @@ KERNEL_TYPES = [
'vserver', 'win4lin', 'wolk-dev', 'wolk', 'xbox', 'xen', 'xfs'
]
-VERSION = '0.5.5'
+VERSION = '0.5.6'
NOCVE = 'GENERIC-MAP-NOMATCH'
CVES = dict()
PORTDIR = portage.settings['PORTDIR']
+DEBUG = False
VERBOSE = False
FORCE = False
SKIP = False
@@ -74,13 +75,11 @@ FOLDER = {
'nvd' : os.path.join(FILEPATH, 'tmp', 'nvd')
}
- #TODO Deprecated
logging.basicConfig(format='%(levelname)-6s[%(asctime)s] : %(message)s',
datefmt='%H:%M:%S', level=logging.DEBUG)
- #TODO Deprecated
def debug(msg):
- if VERBOSE:
+ if DEBUG:
logging.debug(msg)
@@ -629,7 +628,9 @@ def parse_cve_files(directory, kernel, best, arch):
for item in os.listdir(directory):
try:
- files.append(read_cve_file(directory, item[:-4]))
+ cve_file = read_cve_file(directory, item[:-4])
+ if cve_file is not None:
+ files.append(cve_file)
except: #FIXME specify
pass
@@ -673,10 +674,13 @@ def read_cve_file(directory, bugid):
affected = list()
filename = os.path.join(directory, bugid + '.xml')
-
- with open(filename, 'r+') as xml_data:
- memory_map = mmap.mmap(xml_data.fileno(), 0)
- root = et.parse(memory_map).getroot()
+
+ try:
+ with open(filename, 'r+') as xml_data:
+ memory_map = mmap.mmap(xml_data.fileno(), 0)
+ root = et.parse(memory_map).getroot()
+ except IOError:
+ return None
bugroot = root.find('bug')