From f0f117577aed7eba4bc2c28db9a10bd05f2b8c80 Mon Sep 17 00:00:00 2001 From: Bjoern Tropf Date: Wed, 26 Aug 2009 18:32:12 +0200 Subject: Output changes #1 --- kernel-check.py | 128 +++++++++++++++++++++++++++++--------------------------- kernellib.py | 86 ++++++++++++++++--------------------- 2 files changed, 102 insertions(+), 112 deletions(-) diff --git a/kernel-check.py b/kernel-check.py index 71ce470..1038b35 100755 --- a/kernel-check.py +++ b/kernel-check.py @@ -63,20 +63,17 @@ def main(argv): supported = list() for item in lib.SUPPORTED: - best = (lib.best_version(item)) + best = (lib.all_version(item)) if best and best is not None: - if item == 'gentoo': - best.genpatch = lib.get_genpatch(lib.read_genpatch_file( - lib.DIR['out']), best) - supported.append(best) + for i in best: + if item == 'gentoo': + i.genpatch = lib.get_genpatch(lib.read_genpatch_file( + lib.DIR['out']), i) + supported.append(i) kernel.genpatch = lib.get_genpatch(lib.read_genpatch_file(lib.DIR['out']), kernel) - - best_gp = lib.get_genpatch(lib.read_genpatch_file(lib.DIR['out']), - best) - if kernel.genpatch is not None: info('Gen(too)patch : %s' % color('GOOD', '%s %s' % (kernel.genpatch.version, repr(kernel.genpatch)))) @@ -88,67 +85,67 @@ def main(argv): info('Architecture : %s' % color('GOOD', arch)) else: error('No architecture found!') - sys.exit() + return print '\n>>> Reading all kernel vulnerabilities' kernel_eval = lib.eval_cve_files(lib.DIR['out'], kernel, arch) - for item in supported: - best_eval = lib.eval_cve_files(lib.DIR['out'], item, arch) - - bundle = lib.bundle_evaluation(kernel_eval, best_eval) - if bundle is not None: - info('%s vulnerabilities read.' % - color('GOOD', str(bundle.read))) - info('%s apply to this architecture.' % - color('GOOD', str(bundle.match))) - info('%s do not affect this system.' % - color('GOOD', str(bundle.fixed))) - - if len(bundle.notfix): - if not lib.VERBOSE: - warn('%s have not been fixed yet.' % - color('WARN', str(len(bundle.notfix)))) - else: - print '' - warn('%s have not been fixed yet:' % - color('WARN', str(len(bundle.notfix)))) - print_summary(bundle.notfix) - - else: - info('No vulnerabilities have not been fixed yet.') - - if len(bundle.canfix): - error('%s can be fixed by upgrading:' % - color('BAD', str(len(bundle.canfix)))) - else: - info('No vulnerability can be fixed by upgrading.') + info('%s vulnerabilities read.' % + color('GOOD', str(kernel_eval.read))) + info('%s apply to this architecture.' % + color('GOOD', str(kernel_eval.arch))) + info('%s do not affect this kernel.' % + color('GOOD', str(len(kernel_eval.unaffected)))) - else: - error('No vulnerability files found!') - return + if (len(kernel_eval.affected) is 0): + info('Your kernel is not affected by any known vulnerabilites!') + return - if len(bundle.canfix): - print_summary(bundle.canfix) - info('It is recommended to upgrade your kernel to %s.' % - color('GOOD', item.version + '-' + item.revision)) - else: - print "" - if kernel == item: - info('Your kernel is up to date!') - else: - info('Upgrading your kernel to %s ' % - color('GOOD', item.version + '-' + item.revision)) - info('does not improve your security!') - - if len(bundle.canfix) or (len(bundle.notfix) and lib.VERBOSE): - info('') - info('To print more information about a vulnerability try:') - info('') - info(' $ %s -s [bugid|cve]' % sys.argv[0]) - info('') + error('%s affect you kernel: ' % + color('BAD', str(len(kernel_eval.affected)))) + print_summary(kernel_eval.affected) + + info('You have the following choices: ') + print '' + info('[1] Recommended') + info('Keep your current kernel: %s' % color('BRACKET', + 'sys-kernel/%s-sources-%s-%s' % ( + kernel.source, kernel.version, kernel.revision))) + print '' + + choice = 1 + for item in supported: + supported_eval = lib.eval_cve_files(lib.DIR['out'], item, arch) + if kernel == item: + pass + #TODO + else: + comparison = lib.compare_evaluation(kernel_eval, supported_eval) + + if comparison is not None: + choice += 1; + score = 0 + for fix in comparison.fixed: + for cve in fix.cves: + score += float(cve.score) + + for new in comparison.new: + for cve in new.cves: + score -= float(cve.score) + + info('[%s] Recommended: (Score %s)' % (str(choice), score)) + info('Upgrade to this kernel: %s' % color('BRACKET', + 'sys-kernel/%s-sources-%s-%s' % ( + item.source, item.version, item.revision))) + info('which fixes %s of %s vulnerabilities and introduces %s' \ + ' new' % (color('GOOD', str(len(comparison.fixed))), + color('BAD', str(len(kernel_eval.affected))), + color('BAD', str(len(comparison.new))))) + print '' + + print_information() print_beta() @@ -248,6 +245,13 @@ def print_beta(): error('Please note that this tool might not operate as expected.') error('Moreover the given information are most likely incorrect.') +def print_information(): + 'Prints an information message' + + info('To print more information about a vulnerability try:') + info('') + info(' $ %s -s [bugid|cve]' % sys.argv[0]) + def usage(): 'Prints the usage screen' diff --git a/kernellib.py b/kernellib.py index d28323c..bbe8acb 100755 --- a/kernellib.py +++ b/kernellib.py @@ -105,9 +105,11 @@ class NvdEntryError(Exception): class Evaluation: """Evaluation class + + Provides information about the vulnerability of a kernel. """ - number = int() + read = int() arch = int() affected = list() unaffected = list() @@ -117,29 +119,16 @@ class Evaluation: self.unaffected = list() -class Bundle: - """Bundle class - - Provides information about the vulnerability of the current system. - There is only one instance of this class available. - - Attributes: - read: an integer count represeting the number of read files. - match: an integer count of bugs matching this system architecture. - fixed: an integer count of bugs being fixed in the current kernel. - canfix: a list of bugs that could be fixed by upgrading the kernel. - notfix: a list representing unresolved bugs in gentoo bugzilla. +class Comparison: + """Comparison class """ - read = int() - match = int() fixed = int() - canfix = list() - notfix = list() + new = list() def __init__(self): - self.canfix = list() - self.notfix = list() + self.fixed = list() + self.new = list() class Cve: @@ -680,7 +669,7 @@ def eval_cve_files(directory, kernel, arch): evaluation = Evaluation() for item in files: - evaluation.number += 1 + evaluation.read += 1 if item.arch not in ARCHES: BUG_ON('[Error] Wrong architecture %s in bugid: %s' % @@ -747,34 +736,24 @@ def is_affected(interval_list, kernel, item): #TODO Remove item return kernel_affected -def bundle_evaluation(kernel, best): - 'Creates a bundle out of two evaluation instances' +def compare_evaluation(kernel, compare): + 'Creates a comparison out of two evaluation instances' - bundle = Bundle() + comparison = Comparison() - if kernel.number == best.number: #FIXME why does 'is' not work - bundle.read = kernel.number - else: - BUG_ON('Numbers do not match: %s %s' % (kernel.number, best.number)) + if kernel.read != compare.read or kernel.arch != compare.arch: + BUG_ON('Kernels do not match: %s %s' % (kernel1.read, kernel2.read)) return - if kernel.arch == best.arch: #FIXME why does 'is' not work - bundle.match = kernel.arch - else: - BUG_ON('Numbers do not match: %s %s' % (kernel.arch, best.arch)) - return - - bundle.fixed = len(kernel.unaffected) - (kernel.number - kernel.arch) - for item in kernel.affected: - if item not in best.affected: - bundle.canfix.append(item) + if item not in compare.affected: + comparison.fixed.append(item) - for item in best.affected: - if item not in bundle.canfix: - bundle.notfix.append(item) + for item in compare.affected: + if item not in kernel.affected: + comparison.new.append(item) - return bundle + return comparison def read_cve_file(directory, bugid): @@ -980,21 +959,28 @@ def extract_version(release): return kernel -def best_version(source): +def all_version(source): """ Given a kernel source name (e.g. vanilla), returns a Kernel object for the latest revision in the tree, or None if none exists. """ + versions = list() + porttree = portage.db[portage.root]['porttree'] - bestmatch = porttree.dep_bestmatch('sys-kernel/%s-sources' % source) - best = portage.versions.catpkgsplit(bestmatch) - if not best: - return None + matches = porttree.dbapi.xmatch('match-all', + 'sys-kernel/%s-sources' % source) - kernel = Kernel(best[1].replace('-sources', '')) - kernel.version = best[2] - kernel.revision = best[3] + for item in matches: + best = portage.versions.catpkgsplit(item) + if not best: + continue - return kernel + kernel = Kernel(best[1].replace('-sources', '')) + kernel.version = best[2] + kernel.revision = best[3] + + versions.append(kernel) + + return versions #TODO Remove BUG_ON; use Exceptions -- cgit v1.2.3-65-gdbad