def get_config(self, conf, local=False): """ Retrieves local or merged dictionary of dicts local app context. This function creates parity for use with writeConfFile in splunk.clilib. Should use cli.getMergedConf(), but does not support custom conf files. :param conf: Splunk conf file file name :param local: local config only :return: dictionary of dicts """ cli.getMergedConf() conf = "%s.conf" % conf defaultconfpath = os.path.join(self.dir, "default", conf) stanzaDict = cli.readConfFile(defaultconfpath) if os.path.exists(defaultconfpath) else {} localconfpath = os.path.join(self.dir, "local", conf) if not local: if os.path.exists(localconfpath): localconf = cli.readConfFile(localconfpath) for setting, stanza in localconf.items(): if setting in stanzaDict: stanzaDict[setting].update(stanza) else: stanzaDict[setting] = stanza else: stanzaDict = cli.readConfFile(localconfpath) if os.path.exists(localconfpath) else {} return stanzaDict
def get_config(self, conf, local=False): """ Retrieves local or merged dictionary of dicts local app context. This function creates parity for use with writeConfFile in splunk.clilib. Should use cli.getMergedConf(), but does not support custom conf files. :param conf: Splunk conf file file name :param local: local config only :return: dictionary of dicts """ cli.getMergedConf() conf = "%s.conf" % conf defaultconfpath = os.path.join(self.dir, "default", conf) stanzaDict = cli.readConfFile(defaultconfpath) if os.path.exists( defaultconfpath) else {} localconfpath = os.path.join(self.dir, "local", conf) if not local: if os.path.exists(localconfpath): localconf = cli.readConfFile(localconfpath) for setting, stanza in localconf.items(): if setting in stanzaDict: stanzaDict[setting].update(stanza) else: stanzaDict[setting] = stanza else: stanzaDict = cli.readConfFile(localconfpath) if os.path.exists( localconfpath) else {} return stanzaDict
def _merger(self, src, dst, dryRun): try: if dryRun: # Be less verbose for dry runs. More detailed information is # likely to be misleading because of dry run limitations. logger.notice(lit("INFO_MIGRATE_MOVE_DRYRUN__S") % src) return root, ext = os.path.splitext(src) if ext == ".conf": if os.path.lexists(dst): # Combine src and dst confs; don't override anything in dst. combinedConf = comm.readConfFile(src) dstConf = comm.readConfFile(dst) for k in dstConf.keys(): if combinedConf.has_key(k): combinedConf[k].update(dstConf[k]) else: combinedConf[k] = dstConf[k] # In case we don't have permission to truncate the # file, just remove it preemptively. safe_remove(dst) logger.notice( lit("INFO_MIGRATE_MERGE_CONF__S_S") % (src, dst)) comm.writeConfFile(dst, combinedConf) else: comm.copyItem(src, dst) else: if os.path.lexists(dst): logger.notice( lit("INFO_MIGRATE_IGNORE_DUP__S_S") % (src, dst)) else: comm.copyItem(src, dst) except Exception, e: logger.warn(lit("WARN_MIGRATE_NO_CREATE__S") % dst) logger.exception(e)
def _merger(self, src, dst, dryRun): try: if dryRun: # Be less verbose for dry runs. More detailed information is # likely to be misleading because of dry run limitations. logger.notice(lit("INFO_MIGRATE_MOVE_DRYRUN__S") % src) return root, ext = os.path.splitext(src) if ext == ".conf": if os.path.lexists(dst): # Combine src and dst confs; don't override anything in dst. combinedConf = comm.readConfFile(src) dstConf = comm.readConfFile(dst) for k in dstConf.keys(): if combinedConf.has_key(k): combinedConf[k].update(dstConf[k]) else: combinedConf[k] = dstConf[k] # In case we don't have permission to truncate the # file, just remove it preemptively. safe_remove(dst) logger.notice(lit("INFO_MIGRATE_MERGE_CONF__S_S") % (src, dst)) comm.writeConfFile(dst, combinedConf) else: comm.copyItem(src, dst) else: if os.path.lexists(dst): logger.notice(lit("INFO_MIGRATE_IGNORE_DUP__S_S") % (src, dst)) else: comm.copyItem(src, dst) except Exception, e: logger.warn(lit("WARN_MIGRATE_NO_CREATE__S") % dst) logger.exception(e)
def __get_self_conf_stanza(self, conf_name, stanza): appdir = os.path.join(sys.prefix, 'etc', 'system') apikeyconfpath = os.path.join(appdir, 'default', conf_name) apikeyconf = cli.readConfFile(apikeyconfpath) localconfpath = os.path.join(appdir, 'local', conf_name) if os.path.exists(localconfpath): localconf = cli.readConfFile(localconfpath) for name, content in localconf.items(): if name in apikeyconf: apikeyconf[name].update(content) else: apikeyconf[name] = content return apikeyconf.get(stanza, {})
def __init__(self): StreamingCommand.__init__(self) appdir = path.dirname(path.dirname(__file__)) defconfpath = path.join(appdir, "default", "app.conf") defconf = cli.readConfFile(defconfpath).get('macformat') or {} localconfpath = path.join(appdir, "local", "app.conf") localconf = (cli.readConfFile(localconfpath).get('macformat') or {}) if path.exists(localconfpath) else {} self.def_format = localconf.get('format') or defconf.get( 'format') or 'none' inputs = localconf.get('inputs') or defconf.get('inputs') self.def_inputs = re.split('[\s,]', inputs) if inputs else ['macaddress']
def getIntegrationDetails(stanza): whereAmI = os.path.dirname(os.path.dirname(__file__)) defaultPath = os.path.join(whereAmI, "default", "app.conf") defaultConf = cli.readConfFile(defaultPath) localPath = os.path.join(whereAmI, "local", "app.conf") if os.path.exists(localPath): localConf = cli.readConfFile(localPath) for name, content in localConf.items(): if name in defaultConf: defaultConf[name].update(content) else: defaultConf[name] = content return defaultConf[stanza]
def getSelfConfStanza(stanza, appdir): apikeyconfpath = os.path.join(appdir, "default", "app.conf") apikeyconf = cli.readConfFile(apikeyconfpath) localconfpath = os.path.join(appdir, "local", "app.conf") if os.path.exists(localconfpath): used_conf = cli.readConfFile(localconfpath) else: used_conf = apikeyconf for name, content in used_conf.items(): if name in apikeyconf: apikeyconf[name].update(content) else: apikeyconf[name] = content return apikeyconf[stanza]
def getSelfConfStanza(stanza): appdir = os.path.dirname(os.path.dirname(__file__)) apikeyconfpath = os.path.join(appdir, "default", "octopus.conf") apikeyconf = cli.readConfFile(apikeyconfpath) localconfpath = os.path.join(appdir, "local", "octopus.conf") if os.path.exists(localconfpath): localconf = cli.readConfFile(localconfpath) for name, content in localconf.items(): if name in apikeyconf: apikeyconf[name].update(content) else: apikeyconf[name] = content return apikeyconf[stanza]
def logging_level(helper, app_name): """ This function sets logger to the defined level in misp42splunk app and writes logs to a dedicated file """ # retrieve log level _SPLUNK_PATH = os.environ['SPLUNK_HOME'] settings_file = os.path.join( _SPLUNK_PATH, 'etc', 'apps', app_name, 'local', app_name.lower() + '_settings.conf' ) run_level = 'ERROR' if os.path.exists(settings_file): app_settings = cli.readConfFile(settings_file) for name, content in list(app_settings.items()): if 'logging' in name: if 'loglevel' in content: set_level = content['loglevel'] if set_level in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']: run_level = set_level else: helper.log_error("[HC501] file {} does not exist".format(settings_file)) return run_level
def migrateFieldActions(infile, outfile): ''' The general function that takes an input file path and an output file path generates the migration and writes it out. infile => the file to read in from outfile => the file to write out to. ''' parsed_infile = comm.readConfFile(infile) output = {} for stanza in parsed_infile: if "default" == stanza: continue new_stanza = migrateFieldActionStanza(parsed_infile[stanza]) if new_stanza != None: output[stanza] = new_stanza outdir = os.path.abspath(os.path.dirname(outfile)) try: os.makedirs(outdir, 0755) except OSError, e: if e.errno == errno.EEXIST: pass else: logger.warn("Could not create the directory specified in '%s'." % outfile) raise
def setLocalMgmtPort(args, fromCLI): paramReq = ("port", ) paramOpt = () comm.validateArgs(paramReq, paramOpt, args) if fromCLI: validate.checkPortNum("port", args["port"]) retDict = {} host = "localhost" key = "mgmtHostPort" currSetts = comm.readConfFile(fullWebConfig) if not webSettingsStanza in currSetts: currSetts[webSettingsStanza] = {} if key in currSetts[webSettingsStanza]: try: # this expects the uri as "blah:8000" - or just "a:b", really. host, oldPortWhichIsGarbage = currSetts[webSettingsStanza][ key].split(":", 1) except ValueError: pass # leaves localhost value from above currSetts[webSettingsStanza][key] = "%s:%s" % (host, args["port"]) comm.writeConfFile(fullWebConfig, currSetts) return retDict
def get_self_conf_stanza(stanza, config_file_name): ''' Returns a dictionary of application config params after provided stanza and config file ''' appdir = os.path.dirname(os.path.dirname(__file__)) apikeyconfpath = os.path.join(appdir, 'default', config_file_name) apikeyconf = cli.readConfFile(apikeyconfpath) localconfpath = os.path.join(appdir, 'local', config_file_name) if os.path.exists(localconfpath): localconf = cli.readConfFile(localconfpath) for name, content in localconf.items(): if name in apikeyconf: apikeyconf[name].update(content) else: apikeyconf[name] = content return apikeyconf[stanza]
def _read_conf_stanza(file_name, stanza): default_path = os.path.join(APP_DIR, "default", file_name) stanza_config = {} if isfile(default_path): default_conf = cli.readConfFile(default_path) stanza_config = default_conf[stanza] return stanza_config
def GetBaseDirectory(): appdir = os.path.dirname(os.path.dirname(__file__)) localconfpath = os.path.join(appdir, "local", "vol.conf") conf = {} if os.path.exists(localconfpath): localconf = cli.readConfFile(localconfpath) for name, content in localconf.items(): if name == "configs": return content['base_directory']
def getStanza(conf, stanza): """ :param conf: splunk conf file :param stanza: stanza (entry) from conf file :return: returns dictionary of setting """ appdir = os.path.dirname(os.path.dirname(__file__)) conf = "%s.conf" % conf apikeyconfpath = os.path.join(appdir, "default", conf) apikeyconf = cli.readConfFile(apikeyconfpath) localconfpath = os.path.join(appdir, "local", conf) if os.path.exists(localconfpath): localconf = cli.readConfFile(localconfpath) for name, content in localconf.items(): if name in apikeyconf: apikeyconf[name].update(content) else: apikeyconf[name] = content return apikeyconf[stanza]
def getstanza(conf, stanza): """ #Returns dict object of config file settings #:param conf: Splunk conf file name #:param stanza: stanza (entry) from conf file #:return: returns dictionary of setting """ appdir = os.path.dirname(os.path.dirname(__file__)) conf = "%s.conf" % conf apikeyconfpath = os.path.join(appdir, "default", conf) apikeyconf = cli.readConfFile(apikeyconfpath) localconfpath = os.path.join(appdir, "local", conf) if os.path.exists(localconfpath): localconf = cli.readConfFile(localconfpath) for name, content in localconf.items(): if name in apikeyconf: apikeyconf[name].update(content) else: apikeyconf[name] = content return apikeyconf[stanza]
def setLocalName(args, fromCLI): paramReq = ("name", ) paramOpt = () comm.validateArgs(paramReq, paramOpt, args) name = args["name"] if name.count(" ") + name.count(":") > 0: raise ArgError, "Name '%s' is invalid. Names cannot contain spaces or colons." % name currSetts = comm.readConfFile(fullServerConfig) if not serverGeneralStanza in currSetts: currSetts[serverGeneralStanza] = {} currSetts[serverGeneralStanza]["serverName"] = name comm.writeConfFile(fullServerConfig, currSetts) return {}
def setLocalName(args, fromCLI): paramReq = ("name",) paramOpt = () comm.validateArgs(paramReq, paramOpt, args) name = args["name"] if name.count(" ") + name.count(":") > 0: raise ArgError, "Name '%s' is invalid. Names cannot contain spaces or colons." % name currSetts = comm.readConfFile(fullServerConfig) if not serverGeneralStanza in currSetts: currSetts[serverGeneralStanza] = {} currSetts[serverGeneralStanza]["serverName"] = name comm.writeConfFile(fullServerConfig, currSetts) return {}
def getInstanceName(argsDict, fromCLI): reqkeys = () optkeys = () returnDict = {} comm.validateArgs(reqkeys, optkeys, argsDict ) currSetts = comm.readConfFile(fullServerConfig) returnDict["instancename"] = "(unset)"; if serverGeneralStanza in currSetts: if "serverName" in currSetts[serverGeneralStanza]: returnDict["instancename"] = currSetts[serverGeneralStanza]["serverName"] if fromCLI: logger.info("Server name: %s." % returnDict["instancename"]) return returnDict
def getInstanceName(argsDict, fromCLI): reqkeys = () optkeys = () returnDict = {} comm.validateArgs(reqkeys, optkeys, argsDict) currSetts = comm.readConfFile(fullServerConfig) returnDict["instancename"] = "(unset)" if serverGeneralStanza in currSetts: if "serverName" in currSetts[serverGeneralStanza]: returnDict["instancename"] = currSetts[serverGeneralStanza][ "serverName"] if fromCLI: logger.info("Server name: %s." % returnDict["instancename"]) return returnDict
def stanzaDisable(args, fromCLI): """ Disables a given stanza in a given conf file. """ paramsReq = (ARG_CONFIG, ARG_MODNAME, ARG_STANZA) paramsOpt = (ARG_AUTHSTR, ARG_USEFS) comm.validateArgs(paramsReq, paramsOpt, args) returnDict = {} stanza = args[ARG_STANZA] confFile = bundle_paths.make_path(args[ARG_CONFIG] + ".conf") authStr = (ARG_AUTHSTR in args) and args[ARG_AUTHSTR] or "" # see if it's currently enabled. currStatus = stanzaStatusInternal( { ARG_CONFIG: args[ARG_CONFIG], ARG_MODNAME: args[ARG_MODNAME], ARG_STANZA: stanza, ARG_AUTHSTR: authStr }, fromCLI) currEnabled = currStatus["enabled"] # get the local .conf file. don't use the stanzas given to us from "status", # because they're merged - we don't want to write out all the merged settings. # btw, readConfFile checks to see if the path exists and does the right thing. confStanzas = comm.readConfFile(confFile) if currEnabled: # then disable it returnDict["restartRequired"] = True # create the stanza if it's not in the .conf already (could be on via default bundle) if not stanza in confStanzas: confStanzas[stanza] = {} # and make sure we set the disabled key in local to be true. confStanzas[stanza][KEY_DISABLED] = "true" stanzaXml = comm.flatDictToXML(confStanzas[stanza]) # the following is now always true: # in order to support "splunk set deploy-poll", we allow this stuff to also write to the local filesystem. logger.debug("Attempting to disable module via local filesystem.") comm.writeConfFile(confFile, confStanzas) if not currEnabled: logger.info("%s is already disabled." % args[ARG_MODNAME]) else: logger.info("%s disabled." % args[ARG_MODNAME]) return returnDict
def setLocalHttp(args, fromCLI): paramReq = ("port",) paramOpt = () comm.validateArgs(paramReq, paramOpt, args) if fromCLI: validate.checkPortNum("port", args["port"]) retDict = {} key = "httpport" currSetts = comm.readConfFile(fullWebConfig) if not webSettingsStanza in currSetts: currSetts[webSettingsStanza] = {} currSetts[webSettingsStanza][key] = args["port"] comm.writeConfFile(fullWebConfig, currSetts) return retDict
def __init__(self, bundle): self._dict = { } self._dict[self._STANZA_INSTALL] = { } try: base = bundle.location() self._manifest_writable = join(base, Bundle._LOCAL, self._MANIFEST) self._manifest_install = join(base, Bundle._DEFAULT, self._MANIFEST) all_candidates = [ self._manifest_writable, self._manifest_install, join(base, self._MANIFEST) ] # find actual MANIFEST to read for candidate in all_candidates: if os.path.isfile(candidate): self._dict = comm.readConfFile(candidate) break except: pass
def setLocalHttp(args, fromCLI): paramReq = ("port", ) paramOpt = () comm.validateArgs(paramReq, paramOpt, args) if fromCLI: validate.checkPortNum("port", args["port"]) retDict = {} key = "httpport" currSetts = comm.readConfFile(fullWebConfig) if not webSettingsStanza in currSetts: currSetts[webSettingsStanza] = {} currSetts[webSettingsStanza][key] = args["port"] comm.writeConfFile(fullWebConfig, currSetts) return retDict
def stanzaEnable(args, fromCLI): """ Enables a given stanza in a given conf file. """ paramsReq = (ARG_CONFIG, ARG_MODNAME, ARG_STANZA) paramsOpt = (ARG_AUTHSTR, ARG_USEFS) comm.validateArgs(paramsReq, paramsOpt, args) returnDict = {} authStr = (ARG_AUTHSTR in args) and args[ARG_AUTHSTR] or "" stanza = args[ARG_STANZA] confFile = bundle_paths.make_path(args[ARG_CONFIG] + ".conf") currStatus = stanzaStatusInternal( { ARG_CONFIG: args[ARG_CONFIG], ARG_MODNAME: args[ARG_MODNAME], ARG_STANZA: stanza, ARG_AUTHSTR: authStr }, fromCLI) currEnabled = currStatus["enabled"] # get the local .conf file. don't use the stanzas given to us from "status", # because they're merged - we don't want to write out all the merged settings. # btw, readConfFile checks to see if the path exists and does the right thing. confStanzas = comm.readConfFile(confFile) if not currEnabled: # then enable it returnDict["restartRequired"] = True # create the stanza if it's not in the .conf already (if it was never enabled) if not stanza in confStanzas: confStanzas[stanza] = {} # at this point the only way for it to be disabled is for the disabled key to be true. # set it false regardless of whether or not it exists. confStanzas[stanza][KEY_DISABLED] = "false" stanzaXml = comm.flatDictToXML(confStanzas[stanza]) # the following is now always true: # if applicable, just write to the local FS (used by splunk set deploy-poll). logger.debug("Attempting to enable module via local filesystem.") comm.writeConfFile(confFile, confStanzas) if currEnabled: logger.info("%s is already enabled." % args[ARG_MODNAME]) else: logger.info("%s enabled." % args[ARG_MODNAME]) return returnDict
def logging_level(): _SPLUNK_PATH = os.environ['SPLUNK_HOME'] app_name = 'misp42splunk' settings_file = _SPLUNK_PATH + os.sep + 'etc' + os.sep + 'apps' \ + os.sep + app_name + os.sep \ + 'local' + os.sep + 'misp42splunk_settings.conf' run_level = 'ERROR' if os.path.exists(settings_file): misp42splunk_settings = cli.readConfFile(settings_file) for name, content in list(misp42splunk_settings.items()): if 'logging' in name: if 'loglevel' in content: set_level = content['loglevel'] if set_level in [ 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL' ]: run_level = set_level return run_level
def __init__(self, bundle): self._dict = {} self._dict[self._STANZA_INSTALL] = {} try: base = bundle.location() self._manifest_writable = join(base, Bundle._LOCAL, self._MANIFEST) self._manifest_install = join(base, Bundle._DEFAULT, self._MANIFEST) all_candidates = [ self._manifest_writable, self._manifest_install, join(base, self._MANIFEST) ] # find actual MANIFEST to read for candidate in all_candidates: if os.path.isfile(candidate): self._dict = comm.readConfFile(candidate) break except: pass
def stanzaDisable(args, fromCLI): """ Disables a given stanza in a given conf file. """ paramsReq = (ARG_CONFIG, ARG_MODNAME, ARG_STANZA) paramsOpt = (ARG_AUTHSTR, ARG_USEFS) comm.validateArgs(paramsReq, paramsOpt, args) returnDict = {} stanza = args[ARG_STANZA] confFile = bundle_paths.make_path(args[ARG_CONFIG] + ".conf") authStr = (ARG_AUTHSTR in args) and args[ARG_AUTHSTR] or "" # see if it's currently enabled. currStatus = stanzaStatusInternal({ARG_CONFIG : args[ARG_CONFIG], ARG_MODNAME : args[ARG_MODNAME], ARG_STANZA : stanza, ARG_AUTHSTR: authStr}, fromCLI) currEnabled = currStatus["enabled"] # get the local .conf file. don't use the stanzas given to us from "status", # because they're merged - we don't want to write out all the merged settings. # btw, readConfFile checks to see if the path exists and does the right thing. confStanzas = comm.readConfFile(confFile) if currEnabled: # then disable it returnDict["restartRequired"] = True # create the stanza if it's not in the .conf already (could be on via default bundle) if not stanza in confStanzas: confStanzas[stanza] = {} # and make sure we set the disabled key in local to be true. confStanzas[stanza][KEY_DISABLED] = "true" stanzaXml = comm.flatDictToXML(confStanzas[stanza]) # the following is now always true: # in order to support "splunk set deploy-poll", we allow this stuff to also write to the local filesystem. logger.debug("Attempting to disable module via local filesystem.") comm.writeConfFile(confFile, confStanzas) if not currEnabled: logger.info("%s is already disabled." % args[ARG_MODNAME]) else: logger.info("%s disabled." % args[ARG_MODNAME]) return returnDict
def stanzaEnable(args, fromCLI): """ Enables a given stanza in a given conf file. """ paramsReq = (ARG_CONFIG, ARG_MODNAME, ARG_STANZA) paramsOpt = (ARG_AUTHSTR, ARG_USEFS) comm.validateArgs(paramsReq, paramsOpt, args) returnDict = {} authStr = (ARG_AUTHSTR in args) and args[ARG_AUTHSTR] or "" stanza = args[ARG_STANZA] confFile = bundle_paths.make_path(args[ARG_CONFIG] + ".conf") currStatus = stanzaStatusInternal({ARG_CONFIG : args[ARG_CONFIG], ARG_MODNAME : args[ARG_MODNAME], ARG_STANZA : stanza, ARG_AUTHSTR: authStr}, fromCLI) currEnabled = currStatus["enabled"] # get the local .conf file. don't use the stanzas given to us from "status", # because they're merged - we don't want to write out all the merged settings. # btw, readConfFile checks to see if the path exists and does the right thing. confStanzas = comm.readConfFile(confFile) if not currEnabled: # then enable it returnDict["restartRequired"] = True # create the stanza if it's not in the .conf already (if it was never enabled) if not stanza in confStanzas: confStanzas[stanza] = {} # at this point the only way for it to be disabled is for the disabled key to be true. # set it false regardless of whether or not it exists. confStanzas[stanza][KEY_DISABLED] = "false" stanzaXml = comm.flatDictToXML(confStanzas[stanza]) # the following is now always true: # if applicable, just write to the local FS (used by splunk set deploy-poll). logger.debug("Attempting to enable module via local filesystem.") comm.writeConfFile(confFile, confStanzas) if currEnabled: logger.info("%s is already enabled." % args[ARG_MODNAME]) else: logger.info("%s enabled." % args[ARG_MODNAME]) return returnDict
def setLocalMgmtPort(args, fromCLI): paramReq = ("port",) paramOpt = () comm.validateArgs(paramReq, paramOpt, args) if fromCLI: validate.checkPortNum("port", args["port"]) retDict = {} host = "localhost" key = "mgmtHostPort" currSetts = comm.readConfFile(fullWebConfig) if not webSettingsStanza in currSetts: currSetts[webSettingsStanza] = {} if key in currSetts[webSettingsStanza]: try: # this expects the uri as "blah:8000" - or just "a:b", really. host, oldPortWhichIsGarbage = currSetts[webSettingsStanza][key].split(":", 1) except ValueError: pass # leaves localhost value from above currSetts[webSettingsStanza][key] = "%s:%s" % (host, args["port"]) comm.writeConfFile(fullWebConfig, currSetts) return retDict
def prepare_config(helper, app_name, misp_instance, storage_passwords): config_args = dict() # get MISP instance to be used _SPLUNK_PATH = os.environ['SPLUNK_HOME'] misp_instances_file = os.path.join(_SPLUNK_PATH, 'etc', 'apps', app_name, 'local', app_name + '_instances.conf') if os.path.exists(misp_instances_file): inputsConf = cli.readConfFile(misp_instances_file) foundStanza = False for name, content in list(inputsConf.items()): if misp_instance == str(name): app_config = content foundStanza = True if not foundStanza: raise Exception( "local/misp42splunk_instances.conf does not contain " "any stanza %s ", str(misp_instance)) return None else: raise Exception( "local/misp42splunk_instances.conf does not exist. Please " "configure an inputs entry for %s", misp_instance) return None # save MISP settings stored in misp42splunk_instances_file into config_arg misp_url = str(app_config['misp_url']).rstrip('/') if misp_url.startswith('https://'): config_args['misp_url'] = misp_url else: raise Exception("[MC203] misp_url must start with https://. " "Please set a valid misp_url") return None if int(app_config['misp_verifycert']) == 1: misp_ca_full_path = app_config.get('misp_ca_full_path', '') if misp_ca_full_path != '': config_args['misp_verifycert'] = misp_ca_full_path else: config_args['misp_verifycert'] = True else: config_args['misp_verifycert'] = False # get client cert parameters if int(app_config['client_use_cert']) == 1: config_args['client_cert_full_path'] = \ app_config['client_cert_full_path'] else: config_args['client_cert_full_path'] = None # test if client certificate file is readable if config_args['client_cert_full_path'] is not None: try: # open client_cert_full_path if exists and log. with open(config_args['client_cert_full_path'], 'rb'): logging.info( "client_cert_full_path file at %s was successfully opened", str(config_args['client_cert_full_path'])) except IOError: # file misp_instances.csv not readable logging.error( "[MC204] client_cert_full_path file at %s not readable", str(config_args['client_cert_full_path'])) raise Exception("client_cert_full_path file at %s not readable", str(config_args['client_cert_full_path'])) return None # get proxy parameters if any config_args['proxies'] = dict() if int(app_config['misp_use_proxy']) == 1: proxy = helper.get_proxy() if proxy: proxy_url = '://' if 'proxy_username' in proxy: if proxy['proxy_username'] not in ['', None]: proxy_url = proxy_url + \ proxy['proxy_username'] + ':' \ + proxy['proxy_password'] + '@' proxy_url = proxy_url + proxy['proxy_url'] + \ ':' + proxy['proxy_port'] + '/' config_args['proxies'] = { "http": "http" + proxy_url, "https": "https" + proxy_url } # get clear version of misp_key config_args['misp_key'] = None for credential in storage_passwords: # usercreds = {'username':credential.content.get('username'), # 'password':credential.content.get('clear_password')} username = credential.content.get('username') if misp_instance in username \ and 'misp_key' in credential.content.get('clear_password'): misp_instance_key = json.loads( credential.content.get('clear_password')) config_args['misp_key'] = str(misp_instance_key['misp_key']) if config_args['misp_key'] is None: raise Exception("misp_key NOT found for instance %s", misp_instance) return None # settings return config_args
def prepare_alert_config(helper): config_args = dict() # get MISP instance to be used misp_instance = helper.get_param("misp_instance") stanza_name = 'misp://' + misp_instance helper.log_info("stanza_name={}".format(stanza_name)) # get MISP instance parameters # open local/inputs.conf _SPLUNK_PATH = os.environ['SPLUNK_HOME'] app_name = 'misp42splunk' inputs_conf_file = _SPLUNK_PATH + os.sep + 'etc' + os.sep + 'apps' + os.sep + app_name + os.sep + 'local' + os.sep + 'inputs.conf' if os.path.exists(inputs_conf_file): inputsConf = cli.readConfFile(inputs_conf_file) for name, content in inputsConf.items(): if stanza_name in name: mispconf = content helper.log_info(json.dumps(mispconf)) if not mispconf: helper.log_error("local/inputs.conf does not contain settings for stanza: {}".format(stanza_name)) else: helper.log_error("local/inputs.conf does not exist. Please configure misp instances first.") # get clear version of misp_key # get session key sessionKey = helper.settings['session_key'] splunkService = client.connect(token=sessionKey) storage_passwords = splunkService.storage_passwords config_args['misp_key'] = None for credential in storage_passwords: usercreds = {'username':credential.content.get('username'),'password':credential.content.get('clear_password')} if misp_instance in credential.content.get('username') and 'misp_key' in credential.content.get('clear_password'): misp_instance_key = json.loads(credential.content.get('clear_password')) config_args['misp_key'] = str(misp_instance_key['misp_key']) helper.log_info('misp_key found for instance {}'.format(misp_instance)) if config_args['misp_key'] is None: helper.log_error('misp_key NOT found for instance {}'.format(misp_instance)) # get MISP settings stored in inputs.conf config_args['misp_url'] = mispconf['misp_url'] helper.log_info("config_args['misp_url'] {}".format(config_args['misp_url'])) if int(mispconf['misp_verifycert']) == 1: config_args['misp_verifycert'] = True else: config_args['misp_verifycert'] = False helper.log_info("config_args['misp_verifycert'] {}".format(config_args['misp_verifycert'])) # get client cert parameters if int(mispconf['client_use_cert']) == 1: config_args['client_cert_full_path'] = mispconf['client_cert_full_path'] else: config_args['client_cert_full_path'] = None helper.log_info("config_args['client_cert_full_path'] {}".format(config_args['client_cert_full_path'])) # get proxy parameters if any config_args['proxies'] = dict() if int(mispconf['misp_use_proxy']) == 1: proxy = helper.get_proxy() if proxy: proxy_url = '://' if proxy['proxy_username'] is not '': proxy_url = proxy_url + proxy['proxy_username'] + ':' + proxy['proxy_password'] + '@' proxy_url = proxy_url + proxy['proxy_url'] + ':' + proxy['proxy_port'] + '/' config_args['proxies'] = { "http": "http" + proxy_url, "https": "https" + proxy_url } # Get string values from alert form config_args['mode']= str(helper.get_param("mode")) config_args['type']= int(helper.get_param("type")) if not helper.get_param("unique"): config_args['unique'] = "no_timestamp_field" else: config_args['unique'] = str(helper.get_param("unique")) # add filename of the file containing the result of the search config_args['filename'] = str(helper.settings['results_file']) return config_args
def prepare_config(helper, app_name, misp_instance, storage_passwords, session_key=None): config_args = dict() # get settings for MISP instance if session_key is None: response = helper.service.get('misp42splunk_account') else: service = splunklib.client.connect(token=session_key) response = service.get('misp42splunk_account') helper.log_debug("[MC-PC-D01] response.status={}".format(response.status)) if response.status == 200: data_body = splunklib.data.load(response.body.read()) else: helper.log_error("[MC-PC-E01] Unexpected status received {}".format( response.status)) raise Exception("[MC-PC-E01] Unexpected status received %s", str(response.status)) return None foundStanza = False instance_count = int(data_body['feed']['totalResults']) helper.log_debug("[MC-PC-D02] instance_count={}".format(instance_count)) if instance_count == 0: # No misp instance configured helper.log_error("[MC-PC-E02] no misp instance configured") raise Exception( "[MC-PC-E02] no misp instance configured. Please configure an entry for %s", str(misp_instance)) return None elif instance_count == 1: # Single misp instance configured instance = data_body['feed']['entry'] helper.log_debug("[MC-PC-D03] single instance={}".format(instance)) if misp_instance == str(instance['title']): app_config = instance['content'] foundStanza = True else: # Multiple misp instances configured misp_instances = data_body['feed']['entry'] for instance in list(misp_instances): helper.log_debug("[MC-PC-D04] instance item={}".format(instance)) if misp_instance == str(instance['title']): app_config = instance['content'] foundStanza = True if not foundStanza: raise Exception( "[MC-PC-E03] no misp_instance with specified name found: %s ", str(misp_instance)) return None # save MISP settings stored in app_config into config_arg misp_url = str(app_config.get('misp_url', '')).rstrip('/') if misp_url.startswith('https://'): config_args['misp_url'] = misp_url else: raise Exception( "[MC-PC-E04] misp_url must start with https://. Please set a valid misp_url" ) return None if int(app_config.get('misp_verifycert', '0')) == 1: misp_ca_full_path = app_config.get('misp_ca_full_path', '') if misp_ca_full_path != '': config_args['misp_verifycert'] = misp_ca_full_path else: config_args['misp_verifycert'] = True else: config_args['misp_verifycert'] = False # get client cert parameters if int(app_config.get('client_use_cert', '0')) == 1: config_args['client_cert_full_path'] = app_config.get( 'client_cert_full_path', 'no_path') else: config_args['client_cert_full_path'] = None # test if client certificate file is readable if config_args['client_cert_full_path'] is not None: try: # open client_cert_full_path if exists and log. with open(config_args['client_cert_full_path'], 'rb'): helper.log_info( "client_cert_full_path file at {} was successfully opened". format(config_args['client_cert_full_path'])) except IOError: # file misp_instances.csv not readable helper.log_error( "[MC-PC-E05] client_cert_full_path file at {} not readable". format(config_args['client_cert_full_path'])) raise Exception( "[MC-PC-E05] client_cert_full_path file at {} not readable". format(config_args['client_cert_full_path'])) return None # get clear version of misp_key and proxy password config_args['misp_key'] = None proxy_clear_password = None # avoid picking wrong key if stanza is a substring of another stanza misp_instance_index = misp_instance + "``splunk_cred_sep``" for credential in storage_passwords: cred_app_name = credential.access.get('app') if (app_name in cred_app_name) and (cred_app_name is not None): username = credential.content.get('username') if misp_instance_index in username: clear_credentials = credential.content.get('clear_password') if 'misp_key' in clear_credentials: misp_instance_key = json.loads(clear_credentials) config_args['misp_key'] = str( misp_instance_key['misp_key']) elif 'proxy' in username: clear_credentials = credential.content.get('clear_password') if 'proxy_password' in clear_credentials: proxy_creds = json.loads(clear_credentials) proxy_clear_password = str(proxy_creds['proxy_password']) if config_args['misp_key'] is None: raise Exception( "[MC205] misp_key NOT found for instance {}".format(misp_instance)) return None # get proxy parameters if any config_args['proxies'] = dict() if int(app_config.get('misp_use_proxy', '0')) == 1: proxy = None settings_file = os.path.join(os.environ['SPLUNK_HOME'], 'etc', 'apps', app_name, 'local', app_name + '_settings.conf') if os.path.exists(settings_file): app_settings = cli.readConfFile(settings_file) for name, content in list(app_settings.items()): if 'proxy' in name: proxy = content if proxy: proxy_url = '://' if 'proxy_username' in proxy \ and proxy_clear_password is not None: if proxy['proxy_username'] not in ['', None]: proxy_url = proxy_url + \ proxy['proxy_username'] + ':' \ + proxy_clear_password + '@' proxy_url = proxy_url + proxy['proxy_hostname'] + \ ':' + proxy['proxy_port'] + '/' config_args['proxies'] = { "http": "http" + proxy_url, "https": "https" + proxy_url } return config_args
'timestamp="' + when.strftime('%Y-%m-%dT%H:%M:%SZ') + '" type="inventory" serial="1_LFEIPB4UJ" item="40mm Secondary Display System" class="III" state="OK" status="Offline" power="' + str(power) + '" efficiency="' + str(efficiency) + '" error_rate="' + str(error_rate) + '" cleanup="' + str(cleanup) + '" log="{[\'date\':\'' + log1.strftime('%Y-%m-%d') + '\',\'work\':\'created rollback point and patched firmware to newest version\',\'modification\':\'mod1\',\'by\':\'BURTONA\'],[\'date\':\'' + log2.strftime('%Y-%m-%d') + '\',\'work\':\'rolled firmware to restore point due to screen tearing issue\',\'modification\':\'mod2\',\'by\':\'PEACHES\']}"' ) when = when + td(hours=1) ############################################################################# ### BACKLOG LOADED; DON'T LOAD IT AGAIN UNLESS SPECIFICALLY TOLD TO ### AND RELOAD mcrn.conf SO IT SHOWS PROPERLY IN setup.xml: confD = cli.readConfFile(splunk_dir + '/etc/apps/mcrn_syslog/default/mcrn.conf') confL = cli.readConfFile(splunk_dir + '/etc/apps/mcrn_syslog/local/mcrn.conf') for name, content in confL.items(): if name in confD: confD[name].update(content) else: confD[name] = content conf = confD['backlog'] with open(local_conf, 'w') as CONF: CONF.write('[backlog]\ndisabled = 0\nreload_backlog = 0\nmgmt_port = ' + conf['mgmt_port'] + ' \n') endpoint = 'https://localhost:' + conf[ 'mgmt_port'] + '/servicesNS/nobody/mcrn_syslog/configs/conf-mcrn/_reload?output_mode=json' head = {'Authorization': 'Splunk ' + sys.stdin.read()}
def scan_file(dirpath, name): if name.endswith(MANIFEST_EXTENSION) and os.path.exists( os.path.join( dirpath, name[:-len(MANIFEST_EXTENSION)] + MASTER_EXTENSION)): cfg_pathname = os.path.join(dirpath, name) if cfg_pathname in _seen_filenames: return _seen_filenames.add(cfg_pathname) config = comm.readConfFile(cfg_pathname) def lower_keys(x): if isinstance(x, dict): return dict((k.lower(), lower_keys(v)) for k, v in x.iteritems()) return x ''' ConfigParser supports case-insensitive keys, since we've moved off it (because it's not BOM-aware) we must also, but the section names (e.g. 'param:myParam') must preserve case ''' for k in config.keys(): config[k] = lower_keys(config[k]) # assert that conf file has base classes defined try: className = config['module']['classname'] superClass = config['module']['superclass'] if config[ 'module'].has_key('superclass') else None except KeyError: logger.warn( "Manifest file %s does not contain a valid module section" % cfg_pathname) return if className == superClass: raise ModuleMapperException( '%s defines className == superClass !!' % cfg_pathname) # assemble the parameter configuration info params = {} stickyParams = [] persistableParams = [] for section_name in config.keys(): section = config[section_name] if section_name.startswith('param:'): pname = section_name[6:].strip() if 'default' in section.keys( ) and 'required' in section.keys( ) and splunk.util.normalizeBoolean( section['required']): raise ModuleMapperException( 'Cannot use required=True with a default value in Manifest file %s, parameter %s' % (cfg_pathname, pname)) params[pname] = { 'required': splunk.util.normalizeBoolean(section['required']) if section.has_key('required') else False, 'default': section['default'] if section.has_key('default') else None, 'values': [ val.strip() for val in section['values'].split(',') ] if section.has_key('values') else None, 'label': section['label'] if section.has_key('label') else None, 'translate': section['translate'] if section.has_key('translate') else None } # add params to persistence lists if section.has_key( 'sticky') and splunk.util.normalizeBoolean( section['sticky']): stickyParams.append(pname) if section.has_key('persistable' ) and splunk.util.normalizeBoolean( section['persistable']): persistableParams.append(pname) # check dupes if (className in _duplicateDefender): logger.error( "ASSERT - duplicate definition of %s in %s/%s" % (className, dirpath, name)) return _duplicateDefender.add(className) # enable support for including other module configuration if config['module'].has_key('include'): include = [ mod_name.strip() for mod_name in config['module']['include'].split(',') ] else: include = [] if config['module'].has_key('description'): description = config['module']['description'] else: description = None # assemble final module definition dict mod = { 'class': className, 'appName': '', 'superClass': superClass, 'path': dirpath, 'filePrefix': name[:-len(MANIFEST_EXTENSION)], 'params': params, 'stickyParams': stickyParams, 'persistableParams': persistableParams, 'include': include, 'description': description } moduleList.append(mod) moduleHash[className] = mod
def prepare_config(self): config_args = dict() # get MISP instance to be used misp_instance = self.misp_instance stanza_name = 'misp://' + misp_instance logging.info("stanza_name={}".format(stanza_name)) # get MISP instance parameters # open local/inputs.conf _SPLUNK_PATH = os.environ['SPLUNK_HOME'] app_name = 'misp42splunk' inputs_conf_file = _SPLUNK_PATH + os.sep + 'etc' + os.sep + 'apps' + os.sep + app_name + os.sep + 'local' + os.sep + 'inputs.conf' if os.path.exists(inputs_conf_file): inputsConf = cli.readConfFile(inputs_conf_file) foundStanza = False for name, content in inputsConf.items(): if stanza_name in name: mispconf = content foundStanza = True logging.info(json.dumps(mispconf)) if not foundStanza: logging.error( "local/inputs.conf does not contain settings for stanza: {}". format(stanza_name)) raise Exception( 'local/inputs.conf does not contain any stanza %s ', str(stanza_name)) else: logging.error( "local/inputs.conf does not exist. Please configure misp instances first." ) raise Exception( 'local/inputs.conf does not exist. Please configure an inputs entry for %s', misp_instance) # get clear version of misp_key storage_passwords = self.service.storage_passwords config_args['misp_key'] = None for credential in storage_passwords: usercreds = { 'username': credential.content.get('username'), 'password': credential.content.get('clear_password') } if misp_instance in credential.content.get( 'username') and 'misp_key' in credential.content.get( 'clear_password'): misp_instance_key = json.loads( credential.content.get('clear_password')) config_args['misp_key'] = str(misp_instance_key['misp_key']) logging.info( 'misp_key found for instance {}'.format(misp_instance)) if 'proxy' in credential.content.get( 'username') and 'proxy_password' in credential.content.get( 'clear_password'): proxy_password = str( json.loads(credential.content.get('clear_password'))) logging.info('proxy_password found for misp42splunk') if config_args['misp_key'] is None: logging.error( 'misp_key NOT found for instance {}'.format(misp_instance)) raise Exception('misp_key NOT found for instance %s ', misp_instance) #settings # get MISP settings stored in inputs.conf config_args['misp_url'] = mispconf['misp_url'] logging.info("config_args['misp_url'] {}".format(config_args['misp_url'])) if int(mispconf['misp_verifycert']) == 1: config_args['misp_verifycert'] = True else: config_args['misp_verifycert'] = False logging.info("config_args['misp_verifycert'] {}".format( config_args['misp_verifycert'])) config_args['proxies'] = dict() if int(mispconf['misp_use_proxy']) == 1: settings_file = _SPLUNK_PATH + os.sep + 'etc' + os.sep + 'apps' + os.sep + app_name + os.sep + 'local' + os.sep + 'misp42splunk_settings.conf' if os.path.exists(settings_file): misp42splunk_settings = cli.readConfFile(settings_file) foundProxy = False for name, content in misp42splunk_settings.items(): if 'proxy' in name: proxy = content foundProxy = True logging.info("Successfully found proxy settings") if not foundProxy: logging.error( "misp_use_proxy is True and local/misp42splunk_settings.conf does not contain settings for proxy" ) raise Exception( 'misp_use_proxy is True and local/misp42splunk_settings.conf does not contain settings for proxy' ) else: logging.error( "misp_use_proxy is True and local/misp42splunk_settings.conf does not exist. Please configure misp42splunk first." ) raise Exception( "misp_use_proxy is True and local/misp42splunk_settings.conf does not exist. Please configure misp42splunk first." ) if proxy: proxy_url = '://' if proxy['proxy_username'] is not '': proxy_url = proxy_url + proxy[ 'proxy_username'] + ':' + proxy_password + '@' proxy_url = proxy_url + proxy['proxy_url'] + ':' + proxy[ 'proxy_port'] + '/' config_args['proxies'] = { "http": "http" + proxy_url, "https": "https" + proxy_url } # get client cert parameters if int(mispconf['client_use_cert']) == 1: config_args['client_cert_full_path'] = mispconf[ 'client_cert_full_path'] else: config_args['client_cert_full_path'] = None logging.info("config_args['client_cert_full_path'] {}".format( config_args['client_cert_full_path'])) # test if client certificate file is readable if config_args['client_cert_full_path'] is not None: try: with open( config_args['client_cert_full_path'], 'rb' ) as file_object: # open client_cert_full_path if exists and log. logging.info( 'client_cert_full_path file at %s was successfully opened', str(config_args['client_cert_full_path'])) except IOError: # file misp_instances.csv not readable logging.error('client_cert_full_path file at %s not readable', str(config_args['client_cert_full_path'])) raise Exception('client_cert_full_path file at %s not readable', str(config_args['client_cert_full_path'])) return config_args
def prepare_alert_config(helper): config_args = dict() # get MISP instance to be used th_instance = helper.get_param("th_instance") stanza_name = 'connector_to_thehive_instance://' + th_instance helper.log_info("stanza_name={}".format(stanza_name)) # get MISP instance parameters # open local/inputs.conf _SPLUNK_PATH = os.environ['SPLUNK_HOME'] app_name = "TA-thehive" inputs_conf_file = _SPLUNK_PATH + os.sep + 'etc' + os.sep + 'apps' \ + os.sep + app_name + os.sep + 'local' + os.sep + 'inputs.conf' if os.path.exists(inputs_conf_file): helper.log_info("File {} exists".format(stanza_name)) inputsConf = cli.readConfFile(inputs_conf_file) foundStanza = False for name, content in inputsConf.items(): if stanza_name in name: thehiveconf = content foundStanza = True helper.log_info(json.dumps(thehiveconf)) if foundStanza is False: helper.log_error( "local/inputs.conf does not contain settings for stanza: {}". format(stanza_name)) return None else: helper.log_error( "local/inputs.conf does not exist. Please configure misp instances first." ) return None # get clear version of thehive_key # get session key sessionKey = helper.settings['session_key'] splunkService = client.connect(token=sessionKey) storage_passwords = splunkService.storage_passwords config_args['thehive_key'] = None for credential in storage_passwords: # usercreds = {'username':credential.content.get('username'),'password':credential.content.get('clear_password')} if th_instance in credential.content.get('username') \ and 'thehive_key' in credential.content.get('clear_password'): th_instance_key = json.loads( credential.content.get('clear_password')) config_args['thehive_key'] = str(th_instance_key['thehive_key']) helper.log_info( 'thehive_key found for instance {}'.format(th_instance)) if config_args['thehive_key'] is None: helper.log_error( 'thehive_key NOT found for instance {}'.format(th_instance)) # get MISP settings stored in inputs.conf config_args['thehive_url'] = thehiveconf['thehive_url'] + '/api/alert' helper.log_info("config_args['thehive_url'] {}".format( config_args['thehive_url'])) if int(thehiveconf['thehive_verifycert']) == 1: config_args['thehive_verifycert'] = True else: config_args['thehive_verifycert'] = False helper.log_info("config_args['thehive_verifycert'] {}".format( config_args['thehive_verifycert'])) # get client cert parameters if int(thehiveconf['client_use_cert']) == 1: config_args['client_cert_full_path'] = thehiveconf[ 'client_cert_full_path'] else: config_args['client_cert_full_path'] = None helper.log_info("config_args['client_cert_full_path'] {}".format( config_args['client_cert_full_path'])) # get proxy parameters if any config_args['proxies'] = dict() if int(thehiveconf['thehive_use_proxy']) == 1: proxy = helper.get_proxy() if proxy: proxy_url = '://' if proxy['proxy_username'] is not '': proxy_url = proxy_url + proxy['proxy_username'] + ':' + proxy[ 'proxy_password'] + '@' proxy_url = proxy_url + proxy['proxy_url'] + ':' + proxy[ 'proxy_port'] + '/' config_args['proxies'] = { "http": "http" + proxy_url, "https": "https" + proxy_url } # Get string values from alert form myTemplate = helper.get_param("th_case_template") if myTemplate in [None, '']: config_args['caseTemplate'] = "default" else: config_args['caseTemplate'] = myTemplate myType = helper.get_param("th_type") if myType in [None, '']: config_args['type'] = "alert" else: config_args['type'] = myType mySource = helper.get_param("th_source") if mySource in [None, '']: config_args['source'] = "splunk" else: config_args['source'] = mySource if not helper.get_param("th_unique_id"): config_args['unique'] = "oneEvent" else: config_args['unique'] = helper.get_param("th_unique_id") if not helper.get_param("th_title"): config_args['title'] = "notable event" else: config_args['title'] = helper.get_param("th_title") myDescription = helper.get_param("th_description") if myDescription in [None, '']: config_args['description'] = "No description provided." else: config_args['description'] = myDescription myTags = helper.get_param("th_tags") if myTags in [None, '']: config_args['tags'] = [] else: tags = [] tag_list = myTags.split(',') for tag in tag_list: if tag not in tags: tags.append(tag) config_args['tags'] = tags # Get numeric values from alert form config_args['severity'] = int(helper.get_param("th_severity")) config_args['tlp'] = int(helper.get_param("th_tlp")) config_args['pap'] = int(helper.get_param("th_pap")) # add filename of the file containing the result of the search config_args['filename'] = str(helper.settings['results_file']) return config_args
def configmodel(self, **kwargs): method = cherrypy.request.method if method == 'GET': applist = next(os.walk(deploymentapps))[1] applist.remove('users') return json.dumps(applist) if method == 'POST': data = cherrypy.request.params logger.info('%s %s' % (vmodule, json.dumps(data))) logger.info('%s %s' % (vmodule, type(data['apps[]']))) if not data: logger.info('%s no data received' % vmodule) logger.info(json.dumps(data)) return '' else: data = json.loads(data['apps[]']) applist = [] confsettings = [] conffiles = [] mergedconfs = {} logger.info('%s app config requests: %s' % (vmodule, json.dumps(data))) if not isinstance(data, list): applist.append(data) else: applist = data # Iterates through each app for app in applist: logger.info('%s retrieving configs for %s' % (vmodule, app)) apppath = os.path.join(deploymentapps, app) mergedfiles = {} mergedconfs ={} default = 'default' local = 'local' appdefaultpath = os.path.join(apppath, default) applocalpath = os.path.join(apppath, local) defaultconffiles = conflist(appdefaultpath) if os.path.exists(appdefaultpath) else [] localconffiles = conflist(applocalpath) if os.path.exists(applocalpath) else [] conffiles = conffiles + defaultconffiles + localconffiles try: conffiles = list(set(conffiles)) except Exception as e: logger.info("%s" % e ) # Merges default and local for app for conffile in conffiles: logger.info("%s merging %s" % (vmodule, conffile)) defaultfile = os.path.join(appdefaultpath, conffile) localfile = os.path.join(applocalpath, conffile) defaultconf = cli.readConfFile(defaultfile) if os.path.exists(defaultfile) else {} localconf = cli.readConfFile(localfile) if os.path.exists(localfile) else {} if not (default and local): continue if defaultconf: for stanza, settings in defaultconf.items(): for key, value in settings.items(): defaultconf[stanza][key] = ["%s/%s" % (app, default), value] if localconf: for stanza, settings in localconf.items(): for key, value in settings.items(): settings[key] = ["%s/%s" % (app, local), value] if stanza in defaultconf: defaultconf[stanza].update(settings) else: defaultconf[stanza] = settings mergedfiles[conffile] = defaultconf confsettings.append({app: mergedfiles}) # Iterates through each configuration file found in all select apps. for conffile in conffiles: mergedconfs[conffile] = {} for app in confsettings: for appname, conf in app.items(): if conffile in conf: for stanza, settings in conf[conffile].items(): if stanza in mergedconfs[conffile]: mergedconfs[conffile][stanza].update(settings) else: mergedconfs[conffile][stanza] = settings return json.dumps(mergedconfs)
def __init__(self, client, search_settings=None, logger=None): # Initialize all settings to None self.logger = logger # Check the python version self.logger.debug("[S1] Python version detected: " + str(sys.version_info)) namespace = "TA-thehive-cortex" # Prepare the query query = {"output_mode": "json"} # Get instances if search_settings is not None and "namespace" in search_settings: namespace = search_settings["namespace"] # Get logging logging_settings = json.loads( client.get("TA_thehive_cortex_settings/logging", owner="nobody", app=namespace, **query).body.read())["entry"][0]["content"] if "loglevel" in logging_settings: logger.setLevel(logging_settings["loglevel"]) self.logger.debug("[S2] Logging mode set to " + str(logging_settings["loglevel"])) # get proxy creds if any proxy_clear_password = None for credential in client.storage_passwords: username = credential.content.get('username') if 'proxy' in username: clear_credentials = credential.content.get('clear_password') if 'proxy_password' in clear_credentials: proxy_creds = json.loads(clear_credentials) proxy_clear_password = str(proxy_creds['proxy_password']) self.__instances = {} instances_by_account_name = {} try: content = client.kvstore["kv_thehive_cortex_instances"].data.query( ) for row in content: self.logger.debug("[S5] KVStore, getting " + str(row)) # Process the new instance row_id = row["id"] del row["id"] # Keep information for storage password if (row["account_name"] not in instances_by_account_name): instances_by_account_name[row["account_name"]] = [row_id] else: instances_by_account_name[row["account_name"]].append( row_id) # Check some fields use_proxy = True if ("True" in row["proxies"] or "true" in row["proxies"]) else False # get proxy parameters if any row["proxies"] = dict() if use_proxy is True: proxy = None settings_file = os.path.join( os.environ['SPLUNK_HOME'], 'etc', 'apps', 'TA-thehive-cortex', 'local', 'ta_thehive_cortex_settings.conf') if os.path.exists(settings_file): app_settings = cli.readConfFile(settings_file) for name, content in list(app_settings.items()): if 'proxy' in name: proxy = content if proxy: proxy_url = '://' if 'proxy_username' in proxy \ and proxy_clear_password is not None: if proxy['proxy_username'] not in ['', None]: proxy_url = proxy_url + \ proxy['proxy_username'] + ':' \ + proxy_clear_password + '@' proxy_url = proxy_url + proxy['proxy_hostname'] + \ ':' + proxy['proxy_port'] + '/' row["proxies"] = { "http": "http" + proxy_url, "https": "https" + proxy_url } row["organisation"] = row[ "organisation"] if row["organisation"] != "-" else None self.logger.debug("[S10] KVStore, adding key \"" + str(row_id) + "\" " + str(row)) # Store the new instance row_dict = json.loads(json.dumps(row)) self.__instances[row_id] = row_dict except IOError as e: self.logger.error( "[S11-ERROR] Could not open/access/process KVStore: ") sys.exit(11) # Get additional parameters self.__additional_parameters = json.loads( client.get("TA_thehive_cortex_settings/additional_parameters", owner="nobody", app=namespace, **query).body.read())["entry"][0]["content"] self.logger.debug("[S15] Getting these additional parameters: " + str(self.__additional_parameters)) # Get username of account name for account_details in json.loads( client.get("TA_thehive_cortex_account", owner="nobody", app=namespace, **query).body.read())["entry"]: account_details_name = account_details["name"] if account_details_name in instances_by_account_name.keys(): instances_of_account_name = instances_by_account_name[ account_details_name] for i in instances_of_account_name: if "username" in account_details["content"]: self.__instances[i]["username"] = account_details[ "content"]["username"] self.logger.debug("[S20] Getting these usernames from account: " + str(self.__instances)) # Get storage passwords for account passwords for s in client.storage_passwords: for account in instances_by_account_name.keys(): # Get account details by instance if account in s['username'] and "password" in s[ 'clear_password']: instances_of_account_name = instances_by_account_name[ account] for i in instances_of_account_name: self.__instances[i]["password"] = str( json.loads(s["clear_password"])["password"]) self.logger.debug( "[S25] Getting these passwords from storage passwords: " + str(self.__instances))
def scan_file(dirpath, name): if name.endswith(MANIFEST_EXTENSION) and os.path.exists(os.path.join(dirpath, name[:-len(MANIFEST_EXTENSION)] + MASTER_EXTENSION)): cfg_pathname = os.path.join(dirpath, name) if cfg_pathname in _seen_filenames: return _seen_filenames.add(cfg_pathname) config = comm.readConfFile(cfg_pathname) def lower_keys(x): if isinstance(x, dict): return dict((k.lower(), lower_keys(v)) for k, v in x.iteritems()) return x ''' ConfigParser supports case-insensitive keys, since we've moved off it (because it's not BOM-aware) we must also, but the section names (e.g. 'param:myParam') must preserve case ''' for k in config.keys(): config[k] = lower_keys(config[k]) # assert that conf file has base classes defined try: className = config['module']['classname'] superClass = config['module']['superclass'] if config['module'].has_key('superclass') else None except KeyError: logger.warn("Manifest file %s does not contain a valid module section" % cfg_pathname) return if className == superClass: raise ModuleMapperException('%s defines className == superClass !!' % cfg_pathname) # assemble the parameter configuration info params = {} stickyParams = [] persistableParams = [] for section_name in config.keys(): section = config[section_name] if section_name.startswith('param:'): pname = section_name[6:].strip() if 'default' in section.keys() and 'required' in section.keys() and splunk.util.normalizeBoolean(section['required']): raise ModuleMapperException( 'Cannot use required=True with a default value in Manifest file %s, parameter %s' % (cfg_pathname, pname)) params[pname] = { 'required': splunk.util.normalizeBoolean(section['required']) if section.has_key('required') else False, 'default': section['default'] if section.has_key('default') else None, 'values' : [val.strip() for val in section['values'].split(',')] if section.has_key('values') else None, 'label': section['label'] if section.has_key('label') else None, 'translate': section['translate'] if section.has_key('translate') else None } # add params to persistence lists if section.has_key('sticky') and splunk.util.normalizeBoolean(section['sticky']): stickyParams.append(pname) if section.has_key('persistable') and splunk.util.normalizeBoolean(section['persistable']): persistableParams.append(pname) # check dupes if (className in _duplicateDefender): logger.error("ASSERT - duplicate definition of %s in %s/%s" % (className, dirpath, name)) return _duplicateDefender.add(className) # enable support for including other module configuration if config['module'].has_key('include'): include = [ mod_name.strip() for mod_name in config['module']['include'].split(',') ] else: include = [] if config['module'].has_key('description'): description = config['module']['description'] else: description = None # assemble final module definition dict mod = { 'class': className, 'appName': '', 'superClass': superClass, 'path': dirpath, 'filePrefix': name[:-len(MANIFEST_EXTENSION)], 'params': params, 'stickyParams': stickyParams, 'persistableParams': persistableParams, 'include': include, 'description': description } moduleList.append(mod) moduleHash[className] = mod
def prepare_alert_config(helper): config_args = dict() # get MISP instance to be used misp_instance = helper.get_param("misp_instance") stanza_name = 'misp://' + misp_instance helper.log_info("stanza_name={}".format(stanza_name)) # get MISP instance parameters # open local/inputs.conf _SPLUNK_PATH = os.environ['SPLUNK_HOME'] app_name = 'misp42splunk' inputs_conf_file = _SPLUNK_PATH + os.sep + 'etc' + os.sep + 'apps' + \ os.sep + app_name + os.sep + 'local' + os.sep + 'inputs.conf' if os.path.exists(inputs_conf_file): input_conf = cli.readConfFile(inputs_conf_file) for name, content in list(input_conf.items()): if stanza_name in name: mispconf = content helper.log_info(json.dumps(mispconf)) if not mispconf: helper.log_error("local/inputs.conf does not contain settings \ for stanza: {}".format(stanza_name)) else: helper.log_error("local/inputs.conf does not exist. \ Please configure misp instances first.") # get clear version of misp_key # get session key sessionKey = helper.settings['session_key'] splunkService = client.connect(token=sessionKey) storage_passwords = splunkService.storage_passwords config_args['misp_key'] = None for credential in storage_passwords: # usercreds = {'username':credential.content.get('username'), # 'password':credential.content.get('clear_password')} if misp_instance in credential.content.get('username') and \ 'misp_key' in credential.content.get('clear_password'): misp_instance_key = json.loads( credential.content.get('clear_password')) config_args['misp_key'] = str(misp_instance_key['misp_key']) helper.log_info('misp_key found for instance \ {}'.format(misp_instance)) if config_args['misp_key'] is None: helper.log_error('misp_key NOT found for instance \ {}'.format(misp_instance)) # get MISP settings stored in inputs.conf misp_url = mispconf['misp_url'] if misp_url.startswith('https://'): config_args['misp_url'] = misp_url helper.log_info("config_args['misp_url'] {}".format( config_args['misp_url'])) else: helper.log_error( "misp_url must starts with HTTPS. Please set a valid misp_url") exit(1) helper.log_info("config_args['misp_url'] \ {}".format(config_args['misp_url'])) if int(mispconf['misp_verifycert']) == 1: config_args['misp_verifycert'] = True else: config_args['misp_verifycert'] = False helper.log_info("config_args['misp_verifycert'] \ {}".format(config_args['misp_verifycert'])) # get client cert parameters if int(mispconf['client_use_cert']) == 1: config_args['client_cert_full_path'] = \ mispconf['client_cert_full_path'] else: config_args['client_cert_full_path'] = None helper.log_info("config_args['client_cert_full_path'] \ {}".format(config_args['client_cert_full_path'])) # get proxy parameters if any config_args['proxies'] = dict() if int(mispconf['misp_use_proxy']) == 1: proxy = helper.get_proxy() if proxy: proxy_url = '://' if proxy['proxy_username'] is not '': proxy_url = proxy_url + proxy['proxy_username'] + \ ':' + proxy['proxy_password'] + '@' proxy_url = proxy_url + proxy['proxy_url'] + \ ':' + proxy['proxy_port'] + '/' config_args['proxies'] = { "http": "http" + proxy_url, "https": "https" + proxy_url } # Get string values from alert form config_args['tlp'] = str(helper.get_param("tlp").replace('_', ':')) config_args['pap'] = str(helper.get_param("pap").replace('_', ':')) helper.log_debug("config_args['pap'] {}".format(config_args['pap'])) if not helper.get_param("eventid"): config_args['eventid'] = "0" else: config_args['eventid'] = str(helper.get_param("eventid")) if not helper.get_param("unique"): config_args['eventkey'] = "oneEvent" else: config_args['eventkey'] = str(helper.get_param("unique")) if not helper.get_param("info"): config_args['info'] = "notable event" else: config_args['info'] = str(helper.get_param("info")) tags = helper.get_param("tags") if tags: config_args['tags'] = str(helper.get_param("tags")) else: config_args['tags'] = None # Get numeric values from alert form config_args['analysis'] = int(helper.get_param("analysis")) config_args['threatlevel'] = int(helper.get_param("threatlevel")) config_args['distribution'] = int(helper.get_param("distribution")) # add filename of the file containing the result of the search config_args['filename'] = str(helper.settings['results_file']) return config_args