Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # vim:ts=4 sw=4 et:
- #
- # vulnerability_report.py
- #
- # dumps a vulnerability report, but will also do it based on full errata, not just what
- # is available in the clone channel a system is tied to.
- # This does assume satellite >= 5.4.0. I have no idea if 5.3 will work yet.
- import sys
- import xmlrpclib
- import pprint
- import ConfigParser
- from optparse import OptionParser
- def getArch(arch):
- '''
- This is a function because the API doesn't return good data.
- Specifically system.listPackages() returns AMD64 for the arch instead
- of x86_64. If you try to use the arch value directly in packages.findByNvrea()
- it will blow up in your face.
- '''
- if arch == 'AMD64':
- return 'x86_64'
- else:
- return arch
- parser = OptionParser()
- parser.add_option("-c", "--configfile", action="store", type="string",
- dest="configfile", help="Alternate config file to set defaults")
- parser.add_option("-d", "--debug", action="store_true", dest="debug", help="Turn on Debug mode")
- parser.add_option("-l", "--login", dest="login", help="Satellite Server Login Name")
- parser.add_option("-p", "--password", dest="password", help="Satellite Server Password")
- parser.add_option("-u", "--url", dest="url", help="URL of Satellite Server")
- parser.set_defaults(configfile=False)
- parser.set_defaults(debug=False)
- parser.set_defaults(url='http://localhost/rpc/api')
- (options, args) = parser.parse_args()
- if __name__ == '__main__':
- login = False
- password = False
- # Read config file for options
- if options.configfile:
- config = ConfigParser.ConfigParser()
- config.read(options.configfile)
- try:
- url = config.get('config','url')
- except ConfigParser.NoOptionError:
- pass
- except ConfigParser.NoSectionError:
- parser.print_help()
- print
- print >>sys.stderr, 'No config section found in your config file.'
- print >>sys.stderr, 'Please verify that %s exists and has the correct syntax.' % (options.configfile)
- sys.exit(1)
- try:
- login = config.get('config','login')
- except ConfigParser.NoOptionError:
- pass
- try:
- password = config.get('config','password')
- except ConfigParser.NoOptionError:
- pass
- url = options.url
- debug = options.debug
- if options.login:
- login = options.login
- if options.password:
- password = options.password
- # Various checks up front to save time
- if login and password:
- client = xmlrpclib.Server(url, verbose=0)
- authKey = client.auth.login(login, password)
- else:
- parser.print_help()
- parser.error("Login or Password have not been defined on the commandline or in a config file")
- # Establish which system arch types to look for
- rhel5_x64 = False
- rhel4_x64 = False
- rhel3_x64 = False
- rhel5_i386 = False
- rhel4_i386 = False
- rhel3_i386 = False
- # get a list of servers to iterate over
- if debug:
- print >>sys.stderr, "Starting collection of system names"
- active_systems = []
- if args:
- args.sort()
- for system in args:
- try:
- data = client.system.getId(authKey,system)[0]
- cpu = client.system.getCpu(authKey,data['id'])
- detail = client.system.getDetails(authKey,data['id'])
- if cpu['arch'] == 'x86_64':
- if detail['release'] == '5Server':
- rhel5_x64 = True
- if detail['release'] == '4AS':
- rhel4_x64 = True
- if detail['release'] == '3AS':
- rhel3_x64 = True
- if cpu['arch'] == 'i386' or cpu['arch'] == 'i686':
- if detail['release'] == '5Server':
- rhel5_i386 = True
- if detail['release'] == '4AS':
- rhel4_i386 = True
- if detail['release'] == '3AS':
- rhel3_i386 = True
- data['arch'] = cpu['arch']
- data['release'] = detail['release']
- active_systems.append(data)
- except:
- print >>sys.stderr, "ERROR: Could not identify servername: %s" % system
- else:
- systems = sorted(client.system.listActiveSystems(authKey), key=lambda k: k['name'])
- for system in systems:
- data = system
- cpu = client.system.getCpu(authKey,data['id'])
- detail = client.system.getDetails(authKey,data['id'])
- data['arch'] = cpu['arch']
- data['release'] = detail['release']
- active_systems.append(data)
- rhel5_x64 = True
- rhel4_x64 = True
- rhel3_x64 = True
- rhel5_i386 = True
- rhel4_i386 = True
- rhel3_i386 = True
- # ALL RHEL3-64 Packages
- if rhel3_x64:
- if debug:
- print >>sys.stderr, "Starting collection of RHEL3 64bit"
- rhel3 = client.channel.software.listAllPackages(authKey,'rhel-x86_64-as-3')
- rhel3_tools = client.channel.software.listAllPackages(authKey,'rhn-tools-rhel-3-as-x86_64')
- rhel3_x64_all = rhel3 + rhel3_tools
- # ALL RHEL3-32 Packages
- if rhel3_i386:
- if debug:
- print >>sys.stderr, "Starting collection of RHEL3 32bit"
- rhel3 = client.channel.software.listAllPackages(authKey,'rhel-i386-as-3')
- rhel3_tools = client.channel.software.listAllPackages(authKey,'rhn-tools-rhel-3-as-i386')
- rhel3_i386_all = rhel3 + rhel3_tools
- # ALL RHEL4-64 Packages
- if rhel4_x64:
- if debug:
- print >>sys.stderr, "Starting collection of RHEL4 64bit"
- rhel4 = client.channel.software.listAllPackages(authKey,'rhel-x86_64-as-4')
- rhel4_tools = client.channel.software.listAllPackages(authKey,'rhn-tools-rhel-4-as-x86_64')
- rhel4_cluster = client.channel.software.listAllPackages(authKey,'rhel-x86_64-as-4-cluster')
- rhel4_gfs = client.channel.software.listAllPackages(authKey,'rhel-x86_64-as-4-gfs-6.1')
- rhel4_proxy = client.channel.software.listAllPackages(authKey,'redhat-rhn-proxy-5.1-as-x86_64-4')
- rhel4_extras = client.channel.software.listAllPackages(authKey,'rhel-x86_64-as-4-extras')
- rhel4_x64_all = rhel4 + rhel4_tools + rhel4_cluster + rhel4_gfs + rhel4_proxy + rhel4_extras
- # ALL RHEL4-32 Packages
- if rhel4_i386:
- if debug:
- print >>sys.stderr, "Starting collection of RHEL4 32bit"
- rhel4 = client.channel.software.listAllPackages(authKey,'rhel-i386-as-4')
- rhel4_tools = client.channel.software.listAllPackages(authKey,'rhn-tools-rhel-4-as-i386')
- rhel4_cluster = client.channel.software.listAllPackages(authKey,'rhel-i386-as-4-cluster')
- rhel4_gfs = client.channel.software.listAllPackages(authKey,'rhel-i386-as-4-gfs-6.1')
- rhel4_proxy = client.channel.software.listAllPackages(authKey,'redhat-rhn-proxy-5.1-as-i386-4')
- rhel4_extras = client.channel.software.listAllPackages(authKey,'rhel-i386-as-4-extras')
- rhel4_i386_all = rhel4 + rhel4_tools + rhel4_cluster + rhel4_gfs + rhel4_proxy + rhel4_extras
- # ALL RHEL5-64 Packages
- if rhel5_x64:
- if debug:
- print >>sys.stderr, "Starting collection of RHEL5 64bit"
- rhel5 = client.channel.software.listAllPackages(authKey,'rhel-x86_64-server-5')
- rhel5_tools = client.channel.software.listAllPackages(authKey,'rhn-tools-rhel-x86_64-server-5')
- rhel5_cluster_storage = client.channel.software.listAllPackages(authKey,'rhel-x86_64-server-cluster-storage-5')
- rhel5_cluster = client.channel.software.listAllPackages(authKey,'rhel-x86_64-server-cluster-5')
- rhel5_prod = client.channel.software.listAllPackages(authKey,'rhel-x86_64-server-productivity-5')
- rhel5_supp = client.channel.software.listAllPackages(authKey,'rhel-x86_64-server-supplementary-5')
- rhel5_virt = client.channel.software.listAllPackages(authKey,'rhel-x86_64-server-vt-5')
- rhel5_x64_all = rhel5 + rhel5_tools + rhel5_cluster_storage + rhel5_cluster + rhel5_prod + rhel5_supp + rhel5_virt
- # ALL RHEL5-32 Packages
- if rhel5_i386:
- if debug:
- print >>sys.stderr, "Starting collection of RHEL5 32bit"
- rhel5 = client.channel.software.listAllPackages(authKey,'rhel-i386-server-5')
- rhel5_proxy = client.channel.software.listAllPackages(authKey,'redhat-rhn-proxy-5.3-server-i386-5')
- rhel5_tools = client.channel.software.listAllPackages(authKey,'rhn-tools-rhel-i386-server-5')
- rhel5_cluster_storage = client.channel.software.listAllPackages(authKey,'rhel-i386-server-cluster-storage-5')
- rhel5_cluster = client.channel.software.listAllPackages(authKey,'rhel-i386-server-cluster-5')
- rhel5_prod = client.channel.software.listAllPackages(authKey,'rhel-i386-server-productivity-5')
- rhel5_supp = client.channel.software.listAllPackages(authKey,'rhel-i386-server-supplementary-5')
- rhel5_i386_all = rhel5 + rhel5_proxy + rhel5_tools + rhel5_cluster_storage + rhel5_cluster + rhel5_prod + rhel5_supp
- for system in active_systems:
- # re-auth every system to avoid timeouts
- authKey = client.auth.login(login, password)
- system_package_list = client.system.listPackages(authKey,system['id'])
- package_dict = {}
- unmatched_packages = []
- try:
- if system['arch'] == 'x86_64':
- if system['release'] == '5Server':
- if debug:
- print >>sys.stderr, "RHEL5 64bit collected"
- base_package_list = rhel5_x64_all
- elif system['release'] == '4AS':
- if debug:
- print >>sys.stderr, "RHEL4 64bit collected"
- base_package_list = rhel4_x64_all
- else:
- if debug:
- print >>sys.stderr, "RHEL3 64bit collected"
- base_package_list = rhel3_x64_all
- if system['arch'] == 'i386' or system['arch'] == 'i686':
- if system['release'] == '5Server':
- if debug:
- print >>sys.stderr, "RHEL5 32bit collected"
- base_package_list = rhel5_i386_all
- elif system['release'] == '4AS':
- if debug:
- print >>sys.stderr, "RHEL4 32bit collected"
- base_package_list = rhel4_i386_all
- else:
- if debug:
- print >>sys.stderr, "RHEL3 32bit collected"
- base_package_list = rhel3_i386_all
- except:
- base_package_list = []
- print 'WARNING, Unable to find packages -- System: %s, Arch: %s, Release: %s' % (system['name'],
- system['arch'],
- system['release'],)
- continue
- for package in system_package_list:
- arch = getArch(package['arch'])
- matched = False
- for base_package in base_package_list:
- pname = package['name'] == base_package['name']
- parch = arch == base_package['arch_label']
- release = package['release'] == base_package['release']
- version = package['version'] == base_package['version']
- if pname:
- matched = True
- pkey = base_package['name']+base_package['arch_label']
- package_dict.setdefault(pkey,{})
- package_dict[pkey][base_package['id']] = {}
- package_dict[pkey][base_package['id']]['data'] = base_package
- if release and version:
- package_dict[pkey][base_package['id']]['current'] = True
- else:
- package_dict[pkey][base_package['id']]['current'] = False
- if not matched:
- unmatched_packages.append(package['name']+'.'+package['arch'])
- bugfix_list = {}
- security_list = {}
- enhancement_list = {}
- package_keys = package_dict.keys()
- package_keys.sort()
- for package in package_keys:
- get_advisory = False
- current = 0
- pkg = package_dict[package]
- pkg_keys = pkg.keys()
- pkg_keys.sort()
- for pkey in pkg_keys:
- if pkg[pkey]['current']:
- if not pkey == pkg_keys[-1]:
- get_advisory = True
- current = pkg[pkey]['data']['id']
- continue
- if get_advisory:
- advisories = client.packages.listProvidingErrata(authKey,pkg[pkey]['data']['id'])
- for advisory in advisories:
- if 'RH' in advisory['advisory']:
- if 'Bug Fix Advisory' in advisory['type']:
- try:
- bugfix_list[advisory['advisory']].append(pkg[pkey]['data'])
- except:
- bugfix_list[advisory['advisory']] = []
- bugfix_list[advisory['advisory']].append(pkg[pkey]['data'])
- if 'Security Advisory' in advisory['type']:
- try:
- security_list[advisory['advisory']].append(pkg[pkey]['data'])
- except:
- security_list[advisory['advisory']] = []
- security_list[advisory['advisory']].append(pkg[pkey]['data'])
- if 'Product Enhancement Advisory' in advisory['type']:
- try:
- enhancement_list[advisory['advisory']].append(pkg[pkey]['data'])
- except:
- enhancement_list[advisory['advisory']] = []
- enhancement_list[advisory['advisory']].append(pkg[pkey]['data'])
- #print 'ADVISORY ALERT %s:%s -- Package: %s %s %s, Base Package: %s %s %s' % (advisory['advisory'],
- # advisory['type'],
- # pkg[current]['data']['name'],
- # pkg[current]['data']['version'],
- # pkg[current]['data']['release'],
- # pkg[pkey]['data']['name'],
- # pkg[pkey]['data']['version'],
- # pkg[pkey]['data']['release'])
- print 'System: %s, Arch: %s, Release: %s, Bugfixes: %d, Security Fixes: %d, Enhancements: %d' % (system['name'],
- system['arch'],
- system['release'],
- len(bugfix_list),
- len(security_list),
- len(enhancement_list))
- if debug:
- print
- print 'UNMATCHED PACKAGES'
- pprint.pprint(unmatched_packages)
- print
- print 'BUGFIX LIST'
- pprint.pprint(bugfix_list)
- print
- print 'SECURITY LIST'
- pprint.pprint(security_list)
- print
- print 'ENHANCEMENT LIST'
- pprint.pprint(enhancement_list)
- sys.stdout.flush()
- client.auth.logout(authKey)
Advertisement
Add Comment
Please, Sign In to add comment