class Doctor: ''' Class Doctor. Main class. ''' def __init__(self): self.__options = {} self.__config = {} self.__plugin_list = [] self.__plugin_dir = '' self.__category_list = [] self.__alienvault_config = {} self.__successful_config = {} self.__system_summary = [] self.__summary = {} self.__in_strike_zone = True self.__ignore_dummy_platform = False self.__output_file = '' self.__rc = 0 # Start the actual process. def run(self): # Parse command line options. parser = OptionParser(description='Save the world, one Alien at a time', version=default.version_string) parser.add_option("-v", "--verbose", dest="verbose", default=default.verbose, action="count", help="More meaningful warnings [default: %default]. Maximum verbosity depth is 2 (-vv)") parser.add_option("-l", "--plugin-list", dest="plugin_list", default=default.plugin_list, help="A list of plugins you want to run, separated by commas [default: run all plugins]") parser.add_option("-c", "--category_list", dest="category_list", default=default.category_list, help="A list of plugin categories you want to run [default: run all plugins]") parser.add_option("-s", "--severity_list", dest="severity_list", default=default.severity_list, help="A list of check severities you want to run [default: run all checks]") parser.add_option("-a", "--appliance_type", dest="appliance_type_list", default=default.appliance_type_list, help="Appliance whose checks you want to run [default: run checks for current appliance] ") parser.add_option("-P", "--plugin-dir", dest="plugin_dir", default=default.plugin_dir, help="Directory where plugins are stored [default: %default]") parser.add_option("-k", "--ko", dest="ko_only", default=default.ko, action="store_true", help=SUPPRESS_HELP) parser.add_option("-i", "--ignore-dummy", dest="ignore_dummy", default=default.ignore_dummy, action="store_true", help=SUPPRESS_HELP) output_group = OptionGroup(parser, 'Output options') output_group.add_option('-o', '--output-type', dest='output_type', type='choice', choices=default.valid_output_types, default=default.output_type, help='Output type [default: %default]') output_group.add_option('-p', '--output-path', dest='output_path', default=default.output_path, help='Output file path [default: %default]') output_group.add_option('-f', '--output-file-prefix', dest='output_file_prefix', default=default.output_file_prefix, help='Output file prefix [default: %default]') output_group.add_option('-r', '--output-raw', dest='output_raw', default=default.output_raw, action='store_true', help='Retrieve raw data [default: %default]') parser.add_option_group(output_group) (options, args) = parser.parse_args() # Disable normal output for 'ansible' and 'support' output options. if options.output_type in ['ansible']: Output.set_std_output(False) # Ignore dummy platform package self.__ignore_dummy_platform = options.ignore_dummy # Get basic system info. self.__sysinfo = Sysinfo() self.__alienvault_config = self.__sysinfo.get_alienvault_config() self.__successful_config = self.__sysinfo.get_successful_config() Output.emphasized('\nAlienVault Doctor version %s (%s)\n' % (default.version, default.nickname), ['AlienVault Doctor'], [GREEN]) # Parse Doctor configuration file options. if path.isfile(default.doctor_cfg_file): self.__parse_doctor_cfg__() else: Output.warning('Doctor configuration file does not exist, trying to continue...') # Parse plugin configuration files. if not path.isdir(options.plugin_dir): Output.error('"%s" is not a valid directory' % options.plugin_dir) sys.exit(default.error_codes['invalid_dir']) else: self.__plugin_dir = options.plugin_dir output_fd = None # Parse output options. if options.output_type in ['file', 'support']: mode = 'w+' # Support ticket ID has to be a 8 char long, all digit string. if options.output_type == 'support': if options.output_file_prefix == default.output_file_prefix or \ len(options.output_file_prefix) != 8 or not options.output_file_prefix.isdigit(): Output.error('For "support" output, a valid ticket number has to be specified as the file prefix (-f option)') sys.exit(default.error_codes['undef_support_prefix']) Output.set_std_output(False) if not path.exists(options.output_path): os.mkdir(options.output_path) Output.info('Output file directory "%s" created\n' % options.output_path) if path.isdir(options.output_path): try: self.__output_file = path.join(options.output_path, options.output_file_prefix + '-' + str(int(time.time())) + '.doctor') output_fd = open(self.__output_file, mode) except IOError as e: Output.warning('Cannot open file "%s" for writing: %s' % (self.__output_file, e)) else: Output.warning('"%s" is not a valid directory, messages will be shown in stdout only' % options.output_path) elif options.output_type == 'ansible': output_fd = sys.stdout elif options.output_type == 'none': pass else: Output.warning('"%s" is not a valid output type, messages will be shown in stdout only' % options.output_type) # Show some system info. self.__system_summary = self.__sysinfo.show_platform_info(extended=bool(options.verbose)) if self.__system_summary['Hardware profile'] != 'ossim-free': # Run a list of plugins or categories of plugins self.__plugin_list = options.plugin_list.split(',') if self.__plugin_list == [] or 'all' in self.__plugin_list: self.__plugin_list = os.listdir(options.plugin_dir) # Filter by category. self.__category_list = options.category_list.split(',') # Filter checks by severity. self.__severity_list = options.severity_list.split(',') # Filter checks by appliance_type. self.__appliance_type_list = options.appliance_type_list.split(',') # Run! Run! Run! Output.emphasized('\nHmmm, let the Doctor have a look at you%s' % ('...\n' if options.verbose > 0 else '\n'), ['Doctor'], [GREEN], False) for filename in self.__plugin_list: if filename.endswith('.plg'): if options.verbose < 1: Progress.dots() self.__run_plugin__(options.plugin_dir + '/' + filename, options.verbose, options.output_raw) # Separator print '' else: Output.emphasized('\nThe Doctor is not aimed to diagnose an ossim free version...', ['Doctor'], [GREEN]) # Show summary only for screen output. if options.output_type == default.output_type: if self.__system_summary['Hardware profile'] != 'ossim-free': if self.__summary != {}: Output.emphasized('\nHooray! The Doctor has diagnosed you, check out the results...', ['Doctor'], [GREEN]) else: Output.emphasized('\nThe Doctor has finished, nothing to see here though', ['Doctor'], [GREEN]) # Show if the system is in the 'Strike zone' if not self.__in_strike_zone: Output.emphasized('\n Be careful! Seems that you are not in the Strike Zone! Please check the output below.', ['Strike', 'Zone'], [RED]) # Show per plugin results. plugin_det = {} for x, y in self.__summary.iteritems(): if self.__plugin_dir in x: Output.emphasized('\n Plugin %s didn\'t run: %s' % (x, y['summary']), [x]) continue ident = int(y['id']) if 'id' in y.keys() else int(x.split(" ", 1)[0]) plugin_det[ident] = x plugin_ids = plugin_det.keys() plugin_ids.sort() failing_checks = [] for plugin_id in plugin_ids: plugin_name = plugin_det[plugin_id] result = self.__summary[plugin_name] plugin_description = result.get('description', None) plugin_strike_zone = result.get('strike_zone', None) if (not 'checks' in result.keys() or not result['checks']) and ('summary' in result.keys()): Output.emphasized('\n Plugin %s didn\'t run: %s' % (plugin_name, result['summary']), [plugin_name]) else: checks = result['checks'] header = '\n Plugin: %s' % plugin_name if plugin_description is not None: header += '\n %s' % plugin_description if plugin_strike_zone is not None: header += '\n In the Strike Zone?: %s' % str(plugin_strike_zone) Output.emphasized(header, [plugin_name, 'In the Strike Zone?']) for (check_name, check_result) in checks.items(): if check_result['result'] == 'failed': failing_checks.append({'check': check_name, 'severity': check_result['severity'], 'strike_zone': check_result['strike_zone'], 'detail': check_result['detail']}) if check_result['severity'] == 'Emerg': severity_color = RED elif check_result['severity'] == 'Alert': severity_color = RED elif check_result['severity'] == 'Critical': severity_color = RED elif check_result['severity'] == 'Error': severity_color = RED elif check_result['severity'] == 'Warning': severity_color = YELLOW elif check_result['severity'] == 'Notice': severity_color = GREEN elif check_result['severity'] == 'Info': severity_color = GREEN elif check_result['severity'] == 'Debug': severity_color = BLUE else: severity_color = YELLOW Output.emphasized('%s[*] %s: %s' % ((' '*9), check_name, check_result['summary']), ['*', check_name], [severity_color, EMPH]) if check_result['remediation'] != '': Output.emphasized('%sWord of advice: %s' % ((' '*13), check_result['remediation']), ['Word of advice']) else: Output.emphasized('%s[*] %s: All good' % ((' '*9), check_name), ['*', check_name], [GREEN, EMPH]) if options.ko_only: Output.emphasized('\n\n%s%s' % (' '*5, '*'*22), ['%s%s' % (' '*5, '*'*22)]) Output.emphasized(' Failing checks ', ['Failing checks']) Output.emphasized('%s%s' % (' '*5, '*'*22), ['%s%s' % (' '*5, '*'*22)]) if len(failing_checks) == 0: Output.emphasized('\n%sNone' % (' '*13)) else: for check_item in failing_checks: Output.emphasized('\n%sCheck: %s' % ((' '*13), check_item['check']), ['Check']) Output.emphasized('%sSeverity: %s' % ((' '*13), check_item['severity']), ['Severity']) Output.emphasized('%sStrike Zone: %s' % ((' '*13), check_item['strike_zone']), ['Strike Zone']) Output.emphasized('%sDetail: %s' % ((' '*13), check_item['detail']), ['Detail']) elif options.output_type in ['file', 'support']: if self.__system_summary['Hardware profile'] != 'ossim-free': full_summary = dict(self.__system_summary, **self.__summary) else: full_summary = dict(self.__system_summary) full_summary['strike_zone'] = self.__in_strike_zone output_data = plain_data = json.dumps(full_summary, sort_keys=True, indent=4, separators=(',', ': ')) + '\n' # 'file' output mode will store the results in a plain file. # 'support' output mode will try to upload the encrypted and compressed file to a FTP server. if options.output_type == 'file': output_fd.write(output_data) output_fd.close() Output.emphasized('\n\nResults are stored in %s' % self.__output_file, [self.__output_file]) elif options.output_type == 'support': output_data = plain_data if output_data is not None: output_data = self.__compress__(output_data) if output_data is not None: output_fd.write(self.__cipher__(output_data)) output_fd.close() # If the FTP upload fails, let the file stay in the directory for the web to take care of it. if output_data is not None: if self.__upload__(self.__output_file): unlink(self.__output_file) else: # Notify that there was a non fatal error. # Printing this on screen will notify the user. # The permissions are changed for the web UI to read it. uid = pwd.getpwnam("root").pw_uid gid = grp.getgrnam("alienvault").gr_gid os.chown(self.__output_file, uid, gid) os.chmod(self.__output_file, 0640) print '%s' % self.__output_file self.__rc = default.exit_codes['ftp_upload_failed'] elif options.output_type == 'ansible': if self.__system_summary['Hardware profile'] != 'ossim-free': full_summary = dict(self.__system_summary, **self.__summary) else: full_summary = dict(self.__system_summary) full_summary['strike_zone'] = self.__in_strike_zone output_fd.write(json.dumps(full_summary, sort_keys=True, indent=4, separators=(',', ': ')) + '\n') print '' sys.exit(self.__rc) # Parse doctor.cfg for some configuration values. def __parse_doctor_cfg__(self): parser = RawConfigParser() parser.read(default.doctor_cfg_file) self.__config = parser._sections['main'] # Load plugin file def __load_plugin_file(self, filename): config_file = None try: config_file = PluginConfigParser() config_file.read(filename) except PluginConfigParserError as e: raise PluginError(e.msg, filename) except Exception as e: raise PluginError("Cannot parse plugin file: %s" % str(e), filename) return config_file # Run a plugin. def __run_plugin__(self, filename, verbose, raw): # Parse the plugin configuration file. # Check if file exists if not path.isfile(filename): msg = 'Plugin file does not exist: %s' % filename self.__generate_blocked_output(config_file=None, plugin=filename, plugin_data={}, sections=[], error_msg=msg) return # Check for file extension. if not filename.endswith('.plg'): msg = 'File extension is not .plg' self.__generate_blocked_output(config_file=None, plugin=filename, plugin_data={}, sections=[], error_msg=msg) return # Check for db connections and some other basic param config cfg_msg = '' for key in self.__successful_config.keys(): if not self.__successful_config[key]['result']: cfg_msg = ';'.join([cfg_msg, self.__successful_config[key]['error']]) if cfg_msg != '': self.__generate_blocked_output(config_file=None, plugin=filename, plugin_data={}, sections=[], error_msg=cfg_msg) config_file = None try: config_file = self.__load_plugin_file(filename) except PluginError as e: self.__generate_blocked_output(config_file=None, plugin=e.plugin, plugin_data={}, sections=[], error_msg=e.msg) return # Fill the Plugin Object if config_file: try: plugin = Plugin(filename, config_file, self.__alienvault_config, self.__severity_list, self.__appliance_type_list, self.__ignore_dummy_platform, verbose, raw) if (plugin.get_checks_len() > 0) and (plugin.check_category(self.__category_list)): result = plugin.run() self.__in_strike_zone &= result.get('strike_zone', True) self.__summary[plugin.get_name()] = result else: del plugin except (PluginError, PluginConfigParserError, CheckError) as e: if verbose > 0: Output.warning(e.msg) sections = [] try: sections = config_file.sections() except Exception: pass self.__generate_blocked_output(config_file=config_file, plugin=e.plugin, plugin_data=e.kwargs, sections=sections, error_msg=e.msg) except KeyError, msg: Output.error('Unknown error running plugin "%s": %s' % (filename, str(msg))) else:
class Doctor: ''' Class Doctor. Main class. ''' def __init__(self): self.__options = {} self.__config = {} self.__plugin_list = [] self.__plugin_dir = '' self.__category_list = [] self.__alienvault_config = {} self.__successful_config = {} self.__system_summary = [] self.__summary = {} self.__in_strike_zone = True self.__ignore_dummy_platform = False self.__output_file = '' self.__rc = 0 # Start the actual process. def run(self): # Parse command line options. parser = OptionParser( description='Save the world, one Alien at a time', version=default.version_string) parser.add_option( "-v", "--verbose", dest="verbose", default=default.verbose, action="count", help= "More meaningful warnings [default: %default]. Maximum verbosity depth is 2 (-vv)" ) parser.add_option( "-l", "--plugin-list", dest="plugin_list", default=default.plugin_list, help= "A list of plugins you want to run, separated by commas [default: run all plugins]" ) parser.add_option( "-c", "--category_list", dest="category_list", default=default.category_list, help= "A list of plugin categories you want to run [default: run all plugins]" ) parser.add_option( "-s", "--severity_list", dest="severity_list", default=default.severity_list, help= "A list of check severities you want to run [default: run all checks]" ) parser.add_option( "-a", "--appliance_type", dest="appliance_type_list", default=default.appliance_type_list, help= "Appliance whose checks you want to run [default: run checks for current appliance] " ) parser.add_option( "-P", "--plugin-dir", dest="plugin_dir", default=default.plugin_dir, help="Directory where plugins are stored [default: %default]") parser.add_option("-k", "--ko", dest="ko_only", default=default.ko, action="store_true", help=SUPPRESS_HELP) parser.add_option("-i", "--ignore-dummy", dest="ignore_dummy", default=default.ignore_dummy, action="store_true", help=SUPPRESS_HELP) output_group = OptionGroup(parser, 'Output options') output_group.add_option('-o', '--output-type', dest='output_type', type='choice', choices=default.valid_output_types, default=default.output_type, help='Output type [default: %default]') output_group.add_option('-p', '--output-path', dest='output_path', default=default.output_path, help='Output file path [default: %default]') output_group.add_option('-f', '--output-file-prefix', dest='output_file_prefix', default=default.output_file_prefix, help='Output file prefix [default: %default]') output_group.add_option('-r', '--output-raw', dest='output_raw', default=default.output_raw, action='store_true', help='Retrieve raw data [default: %default]') parser.add_option_group(output_group) (options, args) = parser.parse_args() # Disable normal output for 'ansible' and 'support' output options. if options.output_type in ['ansible']: Output.set_std_output(False) # Ignore dummy platform package self.__ignore_dummy_platform = options.ignore_dummy # Get basic system info. self.__sysinfo = Sysinfo() self.__alienvault_config = self.__sysinfo.get_alienvault_config() self.__successful_config = self.__sysinfo.get_successful_config() Output.emphasized( '\nAlienVault Doctor version %s (%s)\n' % (default.version, default.nickname), ['AlienVault Doctor'], [GREEN]) # Parse Doctor configuration file options. if path.isfile(default.doctor_cfg_file): self.__parse_doctor_cfg__() else: Output.warning( 'Doctor configuration file does not exist, trying to continue...' ) # Parse plugin configuration files. if not path.isdir(options.plugin_dir): Output.error('"%s" is not a valid directory' % options.plugin_dir) sys.exit(default.error_codes['invalid_dir']) else: self.__plugin_dir = options.plugin_dir output_fd = None # Parse output options. if options.output_type in ['file', 'support']: mode = 'w+' # Support ticket ID has to be a 8 char long, all digit string. if options.output_type == 'support': if options.output_file_prefix == default.output_file_prefix or \ len(options.output_file_prefix) != 8 or not options.output_file_prefix.isdigit(): Output.error( 'For "support" output, a valid ticket number has to be specified as the file prefix (-f option)' ) sys.exit(default.error_codes['undef_support_prefix']) Output.set_std_output(False) if not path.exists(options.output_path): os.mkdir(options.output_path) Output.info('Output file directory "%s" created\n' % options.output_path) if path.isdir(options.output_path): try: self.__output_file = path.join( options.output_path, options.output_file_prefix + '-' + str(int(time.time())) + '.doctor') output_fd = open(self.__output_file, mode) except IOError as e: Output.warning('Cannot open file "%s" for writing: %s' % (self.__output_file, e)) else: Output.warning( '"%s" is not a valid directory, messages will be shown in stdout only' % options.output_path) elif options.output_type == 'ansible': output_fd = sys.stdout elif options.output_type == 'none': pass else: Output.warning( '"%s" is not a valid output type, messages will be shown in stdout only' % options.output_type) # Show some system info. self.__system_summary = self.__sysinfo.show_platform_info( extended=bool(options.verbose)) if self.__system_summary['Hardware profile'] != 'ossim-free': # Run a list of plugins or categories of plugins self.__plugin_list = options.plugin_list.split(',') if self.__plugin_list == [] or 'all' in self.__plugin_list: self.__plugin_list = os.listdir(options.plugin_dir) # Filter by category. self.__category_list = options.category_list.split(',') # Filter checks by severity. self.__severity_list = options.severity_list.split(',') # Filter checks by appliance_type. self.__appliance_type_list = options.appliance_type_list.split(',') # Run! Run! Run! Output.emphasized( '\nHmmm, let the Doctor have a look at you%s' % ('...\n' if options.verbose > 0 else '\n'), ['Doctor'], [GREEN], False) for filename in self.__plugin_list: if filename.endswith('.plg'): if options.verbose < 1: Progress.dots() self.__run_plugin__(options.plugin_dir + '/' + filename, options.verbose, options.output_raw) # Separator print '' else: Output.emphasized( '\nThe Doctor is not aimed to diagnose an ossim free version...', ['Doctor'], [GREEN]) # Show summary only for screen output. if options.output_type == default.output_type: if self.__system_summary['Hardware profile'] != 'ossim-free': if self.__summary != {}: Output.emphasized( '\nHooray! The Doctor has diagnosed you, check out the results...', ['Doctor'], [GREEN]) else: Output.emphasized( '\nThe Doctor has finished, nothing to see here though', ['Doctor'], [GREEN]) # Show if the system is in the 'Strike zone' if not self.__in_strike_zone: Output.emphasized( '\n Be careful! Seems that you are not in the Strike Zone! Please check the output below.', ['Strike', 'Zone'], [RED]) # Show per plugin results. plugin_det = {} for x, y in self.__summary.iteritems(): if self.__plugin_dir in x: Output.emphasized( '\n Plugin %s didn\'t run: %s' % (x, y['summary']), [x]) continue ident = int(y['id']) if 'id' in y.keys() else int( x.split(" ", 1)[0]) plugin_det[ident] = x plugin_ids = plugin_det.keys() plugin_ids.sort() failing_checks = [] for plugin_id in plugin_ids: plugin_name = plugin_det[plugin_id] result = self.__summary[plugin_name] plugin_description = result.get('description', None) plugin_strike_zone = result.get('strike_zone', None) if (not 'checks' in result.keys() or not result['checks']) and ('summary' in result.keys()): Output.emphasized( '\n Plugin %s didn\'t run: %s' % (plugin_name, result['summary']), [plugin_name]) else: checks = result['checks'] header = '\n Plugin: %s' % plugin_name if plugin_description is not None: header += '\n %s' % plugin_description if plugin_strike_zone is not None: header += '\n In the Strike Zone?: %s' % str( plugin_strike_zone) Output.emphasized(header, [plugin_name, 'In the Strike Zone?']) for (check_name, check_result) in checks.items(): if check_result['result'] == 'failed': failing_checks.append({ 'check': check_name, 'severity': check_result['severity'], 'strike_zone': check_result['strike_zone'], 'detail': check_result['detail'] }) if check_result['severity'] == 'Emerg': severity_color = RED elif check_result['severity'] == 'Alert': severity_color = RED elif check_result['severity'] == 'Critical': severity_color = RED elif check_result['severity'] == 'Error': severity_color = RED elif check_result['severity'] == 'Warning': severity_color = YELLOW elif check_result['severity'] == 'Notice': severity_color = GREEN elif check_result['severity'] == 'Info': severity_color = GREEN elif check_result['severity'] == 'Debug': severity_color = BLUE else: severity_color = YELLOW Output.emphasized( '%s[*] %s: %s' % ((' ' * 9), check_name, check_result['summary']), ['*', check_name], [severity_color, EMPH]) if check_result['remediation'] != '': Output.emphasized( '%sWord of advice: %s' % ((' ' * 13), check_result['remediation']), ['Word of advice']) else: Output.emphasized( '%s[*] %s: All good' % ((' ' * 9), check_name), ['*', check_name], [GREEN, EMPH]) if options.ko_only: Output.emphasized('\n\n%s%s' % (' ' * 5, '*' * 22), ['%s%s' % (' ' * 5, '*' * 22)]) Output.emphasized(' Failing checks ', ['Failing checks']) Output.emphasized('%s%s' % (' ' * 5, '*' * 22), ['%s%s' % (' ' * 5, '*' * 22)]) if len(failing_checks) == 0: Output.emphasized('\n%sNone' % (' ' * 13)) else: for check_item in failing_checks: Output.emphasized( '\n%sCheck: %s' % ((' ' * 13), check_item['check']), ['Check']) Output.emphasized( '%sSeverity: %s' % ((' ' * 13), check_item['severity']), ['Severity']) Output.emphasized( '%sStrike Zone: %s' % ((' ' * 13), check_item['strike_zone']), ['Strike Zone']) Output.emphasized( '%sDetail: %s' % ((' ' * 13), check_item['detail']), ['Detail']) elif options.output_type in ['file', 'support']: if self.__system_summary['Hardware profile'] != 'ossim-free': full_summary = dict(self.__system_summary, **self.__summary) else: full_summary = dict(self.__system_summary) full_summary['strike_zone'] = self.__in_strike_zone output_data = plain_data = json.dumps( full_summary, sort_keys=True, indent=4, separators=(',', ': ')) + '\n' # 'file' output mode will store the results in a plain file. # 'support' output mode will try to upload the encrypted and compressed file to a FTP server. if options.output_type == 'file': output_fd.write(output_data) output_fd.close() Output.emphasized( '\n\nResults are stored in %s' % self.__output_file, [self.__output_file]) elif options.output_type == 'support': output_data = plain_data if output_data is not None: output_data = self.__compress__(output_data) if output_data is not None: output_fd.write(self.__cipher__(output_data)) output_fd.close() # If the FTP upload fails, let the file stay in the directory for the web to take care of it. if output_data is not None: if self.__upload__(self.__output_file): unlink(self.__output_file) else: # Notify that there was a non fatal error. # Printing this on screen will notify the user. # The permissions are changed for the web UI to read it. uid = pwd.getpwnam("root").pw_uid gid = grp.getgrnam("alienvault").gr_gid os.chown(self.__output_file, uid, gid) os.chmod(self.__output_file, 0640) print '%s' % self.__output_file self.__rc = default.exit_codes['ftp_upload_failed'] elif options.output_type == 'ansible': if self.__system_summary['Hardware profile'] != 'ossim-free': full_summary = dict(self.__system_summary, **self.__summary) else: full_summary = dict(self.__system_summary) full_summary['strike_zone'] = self.__in_strike_zone output_fd.write( json.dumps(full_summary, sort_keys=True, indent=4, separators=(',', ': ')) + '\n') print '' sys.exit(self.__rc) # Parse doctor.cfg for some configuration values. def __parse_doctor_cfg__(self): parser = RawConfigParser() parser.read(default.doctor_cfg_file) self.__config = parser._sections['main'] # Load plugin file def __load_plugin_file(self, filename): config_file = None try: config_file = PluginConfigParser() config_file.read(filename) except PluginConfigParserError as e: raise PluginError(e.msg, filename) except Exception as e: raise PluginError("Cannot parse plugin file: %s" % str(e), filename) return config_file # Run a plugin. def __run_plugin__(self, filename, verbose, raw): # Parse the plugin configuration file. # Check if file exists if not path.isfile(filename): msg = 'Plugin file does not exist: %s' % filename self.__generate_blocked_output(config_file=None, plugin=filename, plugin_data={}, sections=[], error_msg=msg) return # Check for file extension. if not filename.endswith('.plg'): msg = 'File extension is not .plg' self.__generate_blocked_output(config_file=None, plugin=filename, plugin_data={}, sections=[], error_msg=msg) return # Check for db connections and some other basic param config cfg_msg = '' for key in self.__successful_config.keys(): if not self.__successful_config[key]['result']: cfg_msg = ';'.join( [cfg_msg, self.__successful_config[key]['error']]) if cfg_msg != '': self.__generate_blocked_output(config_file=None, plugin=filename, plugin_data={}, sections=[], error_msg=cfg_msg) config_file = None try: config_file = self.__load_plugin_file(filename) except PluginError as e: self.__generate_blocked_output(config_file=None, plugin=e.plugin, plugin_data={}, sections=[], error_msg=e.msg) return # Fill the Plugin Object if config_file: try: plugin = Plugin(filename, config_file, self.__alienvault_config, self.__severity_list, self.__appliance_type_list, self.__ignore_dummy_platform, verbose, raw) if (plugin.get_checks_len() > 0) and (plugin.check_category( self.__category_list)): result = plugin.run() self.__in_strike_zone &= result.get('strike_zone', True) self.__summary[plugin.get_name()] = result else: del plugin except (PluginError, PluginConfigParserError, CheckError) as e: if verbose > 0: Output.warning(e.msg) sections = [] try: sections = config_file.sections() except Exception: pass self.__generate_blocked_output(config_file=config_file, plugin=e.plugin, plugin_data=e.kwargs, sections=sections, error_msg=e.msg) except KeyError, msg: Output.error('Unknown error running plugin "%s": %s' % (filename, str(msg))) else: