From 195dee5f7411de7fe55087bb819b02f8f864c7fc Mon Sep 17 00:00:00 2001 From: robiscool Date: Wed, 21 Sep 2011 11:28:59 -0700 Subject: snort-dev, remove orion package add snort-dev package --- .../patches/spoink_patch/2.8.6/plugbase.c | 1544 ++++++++++++++++++++ 1 file changed, 1544 insertions(+) create mode 100644 config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c (limited to 'config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c') diff --git a/config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c b/config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c new file mode 100644 index 00000000..31f381a8 --- /dev/null +++ b/config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c @@ -0,0 +1,1544 @@ +/* $Id$ */ +/* +** Copyright (C) 2002-2010 Sourcefire, Inc. +** Copyright (C) 1998-2002 Martin Roesch +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License Version 2 as +** published by the Free Software Foundation. You may not use, modify or +** distribute this program under any other version of the GNU General +** Public License. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifndef WIN32 +#include +#include +#include +#endif /* !WIN32 */ +#include +#include + +#include "sf_types.h" +#include "plugbase.h" +#include "spo_plugbase.h" +#include "snort.h" +#include "debug.h" +#include "util.h" +#include "log.h" +#include "detect.h" + +/* built-in preprocessors */ +#include "preprocessors/spp_rpc_decode.h" +#include "preprocessors/spp_bo.h" +#include "preprocessors/spp_stream5.h" +#include "preprocessors/spp_arpspoof.h" +#include "preprocessors/spp_perfmonitor.h" +#include "preprocessors/spp_httpinspect.h" +#include "preprocessors/spp_sfportscan.h" +#include "preprocessors/spp_frag3.h" + +/* built-in detection plugins */ +#include "detection-plugins/sp_pattern_match.h" +#include "detection-plugins/sp_tcp_flag_check.h" +#include "detection-plugins/sp_icmp_type_check.h" +#include "detection-plugins/sp_icmp_code_check.h" +#include "detection-plugins/sp_ttl_check.h" +#include "detection-plugins/sp_ip_id_check.h" +#include "detection-plugins/sp_tcp_ack_check.h" +#include "detection-plugins/sp_tcp_seq_check.h" +#include "detection-plugins/sp_dsize_check.h" +#include "detection-plugins/sp_ipoption_check.h" +#include "detection-plugins/sp_rpc_check.h" +#include "detection-plugins/sp_icmp_id_check.h" +#include "detection-plugins/sp_icmp_seq_check.h" +#include "detection-plugins/sp_session.h" +#include "detection-plugins/sp_ip_tos_check.h" +#include "detection-plugins/sp_ip_fragbits.h" +#include "detection-plugins/sp_tcp_win_check.h" +#include "detection-plugins/sp_ip_same_check.h" +#include "detection-plugins/sp_ip_proto.h" +#include "detection-plugins/sp_ip_same_check.h" +#include "detection-plugins/sp_clientserver.h" +#include "detection-plugins/sp_byte_check.h" +#include "detection-plugins/sp_byte_jump.h" +#include "detection-plugins/sp_isdataat.h" +#include "detection-plugins/sp_pcre.h" +#include "detection-plugins/sp_flowbits.h" +#include "detection-plugins/sp_file_data.h" +#include "detection-plugins/sp_asn1.h" +#ifdef ENABLE_REACT +#include "detection-plugins/sp_react.h" +#endif +#ifdef ENABLE_RESPOND +#include "detection-plugins/sp_respond.h" +#endif +#include "detection-plugins/sp_ftpbounce.h" +#include "detection-plugins/sp_urilen_check.h" +#include "detection-plugins/sp_cvs.h" + +/* built-in output plugins */ +#include "output-plugins/spo_alert_syslog.h" +#include "output-plugins/spo_log_tcpdump.h" +#include "output-plugins/spo_database.h" +#include "output-plugins/spo_alert_fast.h" +#include "output-plugins/spo_alert_full.h" +#include "output-plugins/spo_alert_unixsock.h" +#include "output-plugins/spo_csv.h" +#include "output-plugins/spo_unified.h" +#include "output-plugins/spo_log_null.h" +#include "output-plugins/spo_log_ascii.h" +#include "output-plugins/spo_unified2.h" +#include "output-plugins/spo_pf.h" + +#ifdef ARUBA +#include "output-plugins/spo_alert_arubaaction.h" +#endif + +#ifdef HAVE_LIBPRELUDE +#include "output-plugins/spo_alert_prelude.h" +#endif + +#ifdef LINUX +#include "output-plugins/spo_alert_sf_socket.h" +#endif + +#include "output-plugins/spo_alert_test.h" + +extern ListHead *head_tmp; +extern PreprocConfigFuncNode *preproc_config_funcs; +extern OutputConfigFuncNode *output_config_funcs; +extern RuleOptConfigFuncNode *rule_opt_config_funcs; +extern RuleOptOverrideInitFuncNode *rule_opt_override_init_funcs; +extern RuleOptParseCleanupNode *rule_opt_parse_cleanup_list; +extern PreprocSignalFuncNode *preproc_restart_funcs; +extern PreprocSignalFuncNode *preproc_clean_exit_funcs; +extern PreprocSignalFuncNode *preproc_shutdown_funcs; +extern PreprocSignalFuncNode *preproc_reset_funcs; +extern PreprocSignalFuncNode *preproc_reset_stats_funcs; +extern PreprocStatsFuncNode *preproc_stats_funcs; +extern PluginSignalFuncNode *plugin_shutdown_funcs; +extern PluginSignalFuncNode *plugin_clean_exit_funcs; +extern PluginSignalFuncNode *plugin_restart_funcs; +extern OutputFuncNode *AlertList; +extern OutputFuncNode *LogList; + + +/**************************** Detection Plugin API ****************************/ +/* For translation from enum to char* */ +#ifdef DEBUG +static const char *optTypeMap[OPT_TYPE_MAX] = +{ + "action", + "logging", + "detection" +}; + +#define ENUM2STR(num, map) \ + ((num < sizeof(map)/sizeof(map[0])) ? map[num] : "undefined") +#endif + + +void RegisterRuleOptions(void) +{ + LogMessage("Initializing Plug-ins!\n"); + + SetupPatternMatch(); + SetupTCPFlagCheck(); + SetupIcmpTypeCheck(); + SetupIcmpCodeCheck(); + SetupTtlCheck(); + SetupIpIdCheck(); + SetupTcpAckCheck(); + SetupTcpSeqCheck(); + SetupDsizeCheck(); + SetupIpOptionCheck(); + SetupRpcCheck(); + SetupIcmpIdCheck(); + SetupIcmpSeqCheck(); + SetupSession(); + SetupIpTosCheck(); + SetupFragBits(); + SetupFragOffset(); + SetupTcpWinCheck(); + SetupIpProto(); + SetupIpSameCheck(); + SetupClientServer(); + SetupByteTest(); + SetupByteJump(); + SetupIsDataAt(); + SetupFileData(); + SetupPcre(); + SetupFlowBits(); + SetupAsn1(); +#ifdef ENABLE_REACT + SetupReact(); +#endif +#ifdef ENABLE_RESPOND + SetupRespond(); +#endif + SetupFTPBounce(); + SetupUriLenCheck(); + SetupCvs(); +} + +/**************************************************************************** + * + * Function: RegisterRuleOption(char *, void (*func)(), enum OptionType) + * + * Purpose: Associates a rule option keyword with an option setup/linking + * function. + * + * Arguments: keyword => The option keyword to associate with the option + * handler + * *func => function pointer to the handler + * type => used to determine where keyword is allowed + * + * Returns: void function + * + ***************************************************************************/ +void RegisterRuleOption(char *opt_name, RuleOptConfigFunc config_func, + RuleOptOverrideInitFunc override_init_func, + RuleOptType opt_type, + RuleOptOtnHandler otn_handler) +{ + RuleOptConfigFuncNode *node; + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Registering keyword:func => %s/%s:%p\n", + ENUM2STR(opt_type, optTypeMap), opt_name, config_func);); + + node = (RuleOptConfigFuncNode *)SnortAlloc(sizeof(RuleOptConfigFuncNode)); + + if (rule_opt_config_funcs == NULL) + { + rule_opt_config_funcs = node; + } + else + { + RuleOptConfigFuncNode *tmp = rule_opt_config_funcs; + RuleOptConfigFuncNode *last; + + do + { + if (strcasecmp(tmp->keyword, opt_name) == 0) + { + free(node); + FatalError("Duplicate detection plugin keyword: %s.\n", + file_line, opt_name); + } + + last = tmp; + tmp = tmp->next; + + } while (tmp != NULL); + + last->next = node; + } + + node->keyword = SnortStrdup(opt_name); + node->type = opt_type; + node->func = config_func; + node->otn_handler = otn_handler; + + if (override_init_func != NULL) + { + RuleOptOverrideInitFuncNode *node_override = + (RuleOptOverrideInitFuncNode *)SnortAlloc(sizeof(RuleOptOverrideInitFuncNode)); + + if (rule_opt_override_init_funcs == NULL) + { + rule_opt_override_init_funcs = node_override; + } + else + { + RuleOptOverrideInitFuncNode *tmp = rule_opt_override_init_funcs; + RuleOptOverrideInitFuncNode *last; + + do + { + if (strcasecmp(tmp->keyword, opt_name) == 0) + { + free(node_override); + FatalError("RegisterRuleOption: Duplicate detection plugin keyword:" + " (%s) (%s)!\n", tmp->keyword, opt_name); + } + + last = tmp; + tmp = tmp->next; + + } while (tmp != NULL); + + last->next = node_override; + } + + node_override->keyword = SnortStrdup(opt_name); + node_override->type = opt_type; + node_override->func = override_init_func; + node_override->otn_handler = otn_handler; + } +} + +void RegisterOverrideKeyword(char *keyword, char *option, RuleOptOverrideFunc func) +{ + RuleOptOverrideInitFuncNode *node = rule_opt_override_init_funcs; + + while (node != NULL) + { + if (strcasecmp(node->keyword, keyword) == 0) + { + node->func(keyword, option, func); + break; + } + + node = node->next; + } +} + +/**************************************************************************** + * + * Function: DumpPlugIns() + * + * Purpose: Prints the keyword->function list + * + * Arguments: None. + * + * Returns: void function + * + ***************************************************************************/ +void DumpRuleOptions(void) +{ + RuleOptConfigFuncNode *node; + + node = rule_opt_config_funcs; + + LogMessage("-------------------------------------------------\n"); + LogMessage(" Keyword | Plugin Registered @\n"); + LogMessage("-------------------------------------------------\n"); + + while (node != NULL) + { + LogMessage("%-13s: %p\n", node->keyword, node->func); + node = node->next; + } + + LogMessage("-------------------------------------------------\n"); + LogMessage("\n"); +} + + +/**************************************************************************** + * + * Function: AddOptFuncToList(int (*func)(), OptTreeNode *) + * + * Purpose: Links the option detection module to the OTN + * + * Arguments: (*func)() => function pointer to the detection module + * otn => pointer to the current OptTreeNode + * + * Returns: void function + * + ***************************************************************************/ +OptFpList * AddOptFuncToList(RuleOptEvalFunc func, OptTreeNode *otn) +{ + OptFpList *ofp = (OptFpList *)SnortAlloc(sizeof(OptFpList)); + + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding new rule to list\n");); + + /* if there are no nodes on the function list... */ + if (otn->opt_func == NULL) + { + otn->opt_func = ofp; + } + else + { + OptFpList *tmp = otn->opt_func; + + /* walk to the end of the list */ + while (tmp->next != NULL) + tmp = tmp->next; + + tmp->next = ofp; + } + + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Set OptTestFunc to %p\n", func);); + + ofp->OptTestFunc = func; + + return ofp; +} + +/**************************************************************************** + * + * Function: AddRspFuncToList(int (*func)(), OptTreeNode *) + * + * Purpose: Adds Response function to OTN + * + * Arguments: (*func)() => function pointer to the response module + * otn => pointer to the current OptTreeNode + * + * Returns: void function + * + ***************************************************************************/ +void AddRspFuncToList(ResponseFunc func, OptTreeNode *otn, void *params) +{ + RspFpList *rsp = (RspFpList *)SnortAlloc(sizeof(RspFpList)); + + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding response to list\n");); + + /* if there are no nodes on the function list... */ + if (otn->rsp_func == NULL) + { + otn->rsp_func = rsp; + } + else + { + RspFpList *tmp = otn->rsp_func; + + /* walk to the end of the list */ + while (tmp->next != NULL) + tmp = tmp->next; + + tmp->next = rsp; + } + + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Set ResponseFunc to %p\n", func);); + + rsp->func = func; + rsp->params = params; +} + +void PostConfigInitPlugins(PluginSignalFuncNode *post_config_funcs) +{ + while (post_config_funcs != NULL) + { + post_config_funcs->func(0, post_config_funcs->arg); + post_config_funcs = post_config_funcs->next; + } +} + +void FreeRuleOptConfigFuncs(RuleOptConfigFuncNode *head) +{ + + while (head != NULL) + { + RuleOptConfigFuncNode *tmp = head; + + head = head->next; + + if (tmp->keyword != NULL) + free(tmp->keyword); + + free(tmp); + } +} + +void FreeRuleOptOverrideInitFuncs(RuleOptOverrideInitFuncNode *head) +{ + + while (head != NULL) + { + RuleOptOverrideInitFuncNode *tmp = head; + + head = head->next; + + if (tmp->keyword != NULL) + free(tmp->keyword); + + free(tmp); + } +} + +void FreePluginSigFuncs(PluginSignalFuncNode *head) +{ + while (head != NULL) + { + PluginSignalFuncNode *tmp = head; + + head = head->next; + + /* don't free sig->arg, that's free'd by the CleanExit/Restart func */ + free(tmp); + } +} + + +/************************** Preprocessor Plugin API ***************************/ +static void AddFuncToPreprocSignalList(PreprocSignalFunc, void *, + PreprocSignalFuncNode **, uint16_t, uint32_t); + + +void RegisterPreprocessors(void) +{ + LogMessage("Initializing Preprocessors!\n"); + + SetupARPspoof(); + SetupFrag3(); + SetupStream5(); + SetupRpcDecode(); + SetupBo(); + SetupHttpInspect(); + SetupPerfMonitor(); + SetupSfPortscan(); +} + +/**************************************************************************** + * + * Function: RegisterPreprocessor(char *, void (*)(char *)) + * + * Purpose: Associates a preprocessor statement with its function. + * + * Arguments: keyword => The option keyword to associate with the + * preprocessor + * *func => function pointer to the handler + * + * Returns: void function + * + ***************************************************************************/ +#ifndef SNORT_RELOAD +void RegisterPreprocessor(char *keyword, PreprocConfigFunc func) +#else +void RegisterPreprocessor(char *keyword, PreprocConfigFunc func, + PreprocReloadFunc rfunc, PreprocReloadSwapFunc sfunc, + PreprocReloadSwapFreeFunc ffunc) +#endif +{ + PreprocConfigFuncNode *node = + (PreprocConfigFuncNode *)SnortAlloc(sizeof(PreprocConfigFuncNode)); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:preproc => %s:%p\n", keyword, func);); + + if (preproc_config_funcs == NULL) + { + preproc_config_funcs = node; + } + else + { + PreprocConfigFuncNode *tmp = preproc_config_funcs; + PreprocConfigFuncNode *last; + + do + { + if (strcasecmp(tmp->keyword, keyword) == 0) + { + free(node); + FatalError("Duplicate preprocessor keyword: %s.\n", keyword); + } + + last = tmp; + tmp = tmp->next; + + } while (tmp != NULL); + + last->next = node; + } + + node->keyword = SnortStrdup(keyword); + node->config_func = func; + +#ifdef SNORT_RELOAD + node->reload_func = rfunc; + node->reload_swap_func = sfunc; + node->reload_swap_free_func = ffunc; +#endif +} + +PreprocConfigFuncNode * GetPreprocConfig(char *keyword) +{ + PreprocConfigFuncNode *head = preproc_config_funcs; + + if (keyword == NULL) + return NULL; + + while (head != NULL) + { + if (strcasecmp(head->keyword, keyword) == 0) + return head; + + head = head->next; + } + + return NULL; +} + +PreprocConfigFunc GetPreprocConfigFunc(char *keyword) +{ + PreprocConfigFuncNode *head = preproc_config_funcs; + + if (keyword == NULL) + return NULL; + + while (head != NULL) + { + if (strcasecmp(head->keyword, keyword) == 0) + return head->config_func; + + head = head->next; + } + + return NULL; +} + +/**************************************************************************** + * + * Function: RegisterPreprocStats(char *keyword, void (*func)(int)) + * + * Purpose: Registers a function for printing preprocessor final stats + * (or other if it has a use for printing final stats) + * + * Arguments: keyword => keyword (preprocessor) whose stats will print + * func => function pointer to the handler + * + * Returns: void function + * + ***************************************************************************/ +void RegisterPreprocStats(char *keyword, PreprocStatsFunc func) +{ + PreprocStatsFuncNode *node; + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering final stats function: " + "preproc => %s:%p\n", keyword, func);); + + node = (PreprocStatsFuncNode *)SnortAlloc(sizeof(PreprocStatsFuncNode)); + + if (preproc_stats_funcs == NULL) + { + preproc_stats_funcs = node; + } + else + { + PreprocStatsFuncNode *tmp = preproc_stats_funcs; + PreprocStatsFuncNode *last; + + do + { + if (strcasecmp(tmp->keyword, keyword) == 0) + { + free(node); + FatalError("Duplicate preprocessor keyword: %s.\n", keyword); + } + + last = tmp; + tmp = tmp->next; + + } while (tmp != NULL); + + last->next = node; + } + + node->keyword = SnortStrdup(keyword); + node->func = func; +} + +/**************************************************************************** + * + * Function: DumpPreprocessors() + * + * Purpose: Prints the keyword->preprocess list + * + * Arguments: None. + * + * Returns: void function + * + ***************************************************************************/ +void DumpPreprocessors(void) +{ + PreprocConfigFuncNode *node = preproc_config_funcs; + + LogMessage("-------------------------------------------------\n"); + LogMessage(" Keyword | Preprocessor @ \n"); + LogMessage("-------------------------------------------------\n"); + + while (node != NULL) + { + LogMessage("%-13s: %p\n", node->keyword, node->config_func); + node = node->next; + } + + LogMessage("-------------------------------------------------\n\n"); +} + +int IsPreprocEnabled(uint32_t preproc_id) +{ + PreprocEvalFuncNode *node; + SnortConfig *sc = snort_conf_for_parsing; + tSfPolicyId policy_id = getParserPolicy(); + SnortPolicy *p; + + if (sc == NULL) + { + FatalError("%s(%d) Snort config for parsing is NULL.\n", + __FILE__, __LINE__); + } + + p = sc->targeted_policies[policy_id]; + if (p == NULL) + return 0; + + for (node = p->preproc_eval_funcs; node != NULL; node = node->next) + { + if (node->preproc_id == preproc_id) + return 1; + } + + return 0; +} + +PreprocEvalFuncNode * AddFuncToPreprocList(PreprocEvalFunc func, uint16_t priority, + uint32_t preproc_id, uint32_t proto_mask) +{ + PreprocEvalFuncNode *node; + SnortConfig *sc = snort_conf_for_parsing; + tSfPolicyId policy_id = getParserPolicy(); + SnortPolicy *p; + + if (sc == NULL) + { + FatalError("%s(%d) Snort config for parsing is NULL.\n", + __FILE__, __LINE__); + } + + p = sc->targeted_policies[policy_id]; + if (p == NULL) + return NULL; + + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, + "Adding preprocessor function ID %d/bit %d/pri %d to list\n", + preproc_id, p->num_preprocs, priority);); + + node = (PreprocEvalFuncNode *)SnortAlloc(sizeof(PreprocEvalFuncNode)); + + if (p->preproc_eval_funcs == NULL) + { + p->preproc_eval_funcs = node; + } + else + { + PreprocEvalFuncNode *tmp = p->preproc_eval_funcs; + PreprocEvalFuncNode *last = NULL; + + do + { + if (tmp->preproc_id == preproc_id) + { + free(node); + FatalError("Preprocessor already registered with ID %d\n", + preproc_id); + } + + /* Insert higher priority preprocessors first. Lower priority + * number means higher priority */ + if (priority < tmp->priority) + break; + + last = tmp; + tmp = tmp->next; + + } while (tmp != NULL); + + /* Priority higher than first item in list */ + if (last == NULL) + { + node->next = tmp; + p->preproc_eval_funcs = node; + } + else + { + node->next = tmp; + last->next = node; + } + } + + node->func = func; + node->priority = priority; + node->preproc_id = preproc_id; + node->preproc_bit = (1 << preproc_id); + node->proto_mask = proto_mask; + + p->num_preprocs++; + p->preproc_proto_mask |= proto_mask; + p->preproc_bit_mask |= node->preproc_bit; + + return node; +} + +void AddFuncToPreprocPostConfigList(PreprocPostConfigFunc func, void *data) +{ + PreprocPostConfigFuncNode *node; + SnortConfig *sc = snort_conf_for_parsing; + + if (sc == NULL) + { + FatalError("%s(%d) Snort config for parsing is NULL.\n", + __FILE__, __LINE__); + } + + node = (PreprocPostConfigFuncNode *)SnortAlloc(sizeof(PreprocPostConfigFuncNode)); + + if (sc->preproc_post_config_funcs == NULL) + { + sc->preproc_post_config_funcs = node; + } + else + { + PreprocPostConfigFuncNode *tmp = sc->preproc_post_config_funcs; + + while (tmp->next != NULL) + tmp = tmp->next; + + tmp->next = node; + } + + node->data = data; + node->func = func; +} + +void PostConfigPreprocessors(SnortConfig *sc) +{ + PreprocPostConfigFuncNode *list; + + if (sc == NULL) + { + FatalError("%s(%d) Snort config is NULL.\n", + __FILE__, __LINE__); + } + + snort_conf_for_parsing = sc; + + list = sc->preproc_post_config_funcs; + + for (; list != NULL; list = list->next) + { + if (list->func != NULL) + list->func(list->data); + } + + snort_conf_for_parsing = NULL; +} + +#ifdef SNORT_RELOAD +void SwapPreprocConfigurations(void) +{ + PreprocConfigFuncNode *node = preproc_config_funcs; + + for (; node != NULL; node = node->next) + { + if (node->reload_swap_func != NULL) + node->swap_free_data = node->reload_swap_func(); + } +} + +void FreeSwappedPreprocConfigurations(void) +{ + PreprocConfigFuncNode *node = preproc_config_funcs; + + for (; node != NULL; node = node->next) + { + if ((node->reload_swap_free_func != NULL) && + (node->swap_free_data != NULL)) + { + node->reload_swap_free_func(node->swap_free_data); + node->swap_free_data = NULL; + } + } +} + +void AddFuncToPreprocReloadVerifyList(PreprocReloadVerifyFunc func) +{ + PreprocReloadVerifyFuncNode *node; + SnortConfig *sc = snort_conf_for_parsing; + + if (sc == NULL) + { + FatalError("%s(%d) Snort config for parsing is NULL.\n", + __FILE__, __LINE__); + } + + node = (PreprocReloadVerifyFuncNode *)SnortAlloc(sizeof(PreprocReloadVerifyFuncNode)); + + if (sc->preproc_reload_verify_funcs == NULL) + { + sc->preproc_reload_verify_funcs = node; + } + else + { + PreprocReloadVerifyFuncNode *tmp = sc->preproc_reload_verify_funcs; + + while (tmp->next != NULL) + tmp = tmp->next; + + tmp->next = node; + } + + node->func = func; +} + +void FreePreprocReloadVerifyFuncList(PreprocReloadVerifyFuncNode *head) +{ + while (head != NULL) + { + PreprocReloadVerifyFuncNode *tmp = head; + + head = head->next; + free(tmp); + } +} +#endif + +void AddFuncToConfigCheckList(PreprocCheckConfigFunc func) +{ + PreprocCheckConfigFuncNode *node; + SnortConfig *sc = snort_conf_for_parsing; + + if (sc == NULL) + { + FatalError("%s(%d) Snort config for parsing is NULL.\n", + __FILE__, __LINE__); + } + + node = (PreprocCheckConfigFuncNode *)SnortAlloc(sizeof(PreprocCheckConfigFuncNode)); + + if (sc->preproc_config_check_funcs == NULL) + { + sc->preproc_config_check_funcs = node; + } + else + { + PreprocCheckConfigFuncNode *tmp = sc->preproc_config_check_funcs; + + while (tmp->next != NULL) + tmp = tmp->next; + + tmp->next = node; + } + + node->func = func; +} + +/* functions to aid in cleaning up after plugins */ +void AddFuncToPreprocRestartList(PreprocSignalFunc func, void *arg, + uint16_t priority, uint32_t preproc_id) +{ + AddFuncToPreprocSignalList(func, arg, &preproc_restart_funcs, priority, preproc_id); +} + +void AddFuncToPreprocCleanExitList(PreprocSignalFunc func, void *arg, + uint16_t priority, uint32_t preproc_id) +{ + AddFuncToPreprocSignalList(func, arg, &preproc_clean_exit_funcs, priority, preproc_id); +} + +void AddFuncToPreprocShutdownList(PreprocSignalFunc func, void *arg, + uint16_t priority, uint32_t preproc_id) +{ + AddFuncToPreprocSignalList(func, arg, &preproc_shutdown_funcs, priority, preproc_id); +} + +void AddFuncToPreprocResetList(PreprocSignalFunc func, void *arg, + uint16_t priority, uint32_t preproc_id) +{ + AddFuncToPreprocSignalList(func, arg, &preproc_reset_funcs, priority, preproc_id); +} + +void AddFuncToPreprocResetStatsList(PreprocSignalFunc func, void *arg, + uint16_t priority, uint32_t preproc_id) +{ + AddFuncToPreprocSignalList(func, arg, &preproc_reset_stats_funcs, priority, preproc_id); +} + +static void AddFuncToPreprocSignalList(PreprocSignalFunc func, void *arg, + PreprocSignalFuncNode **list, + uint16_t priority, uint32_t preproc_id) +{ + PreprocSignalFuncNode *node; + + if (list == NULL) + return; + + node = (PreprocSignalFuncNode *)SnortAlloc(sizeof(PreprocSignalFuncNode)); + + if (*list == NULL) + { + *list = node; + } + else + { + PreprocSignalFuncNode *tmp = *list; + PreprocSignalFuncNode *last = NULL; + + do + { + /* Insert higher priority stuff first. Lower priority + * number means higher priority */ + if (priority < tmp->priority) + break; + + last = tmp; + tmp = tmp->next; + + } while (tmp != NULL); + + /* Priority higher than first item in list */ + if (last == NULL) + { + node->next = tmp; + *list = node; + } + else + { + node->next = tmp; + last->next = node; + } + } + + node->func = func; + node->arg = arg; + node->preproc_id = preproc_id; + node->priority = priority; +} + +void AddFuncToPreprocReassemblyPktList(PreprocReassemblyPktFunc func, uint32_t preproc_id) +{ + PreprocReassemblyPktFuncNode *node; + SnortConfig *sc = snort_conf_for_parsing; + tSfPolicyId policy_id = getParserPolicy(); + SnortPolicy *p; + + if (sc == NULL) + { + FatalError("%s(%d) Snort config for parsing is NULL.\n", + __FILE__, __LINE__); + } + + p = sc->targeted_policies[policy_id]; + if (p == NULL) + return; + + node = (PreprocReassemblyPktFuncNode *)SnortAlloc(sizeof(PreprocReassemblyPktFuncNode)); + + if (p->preproc_reassembly_pkt_funcs == NULL) + { + p->preproc_reassembly_pkt_funcs = node; + } + else + { + PreprocReassemblyPktFuncNode *tmp = p->preproc_reassembly_pkt_funcs; + + /* just insert at front of list */ + p->preproc_reassembly_pkt_funcs = node; + node->next = tmp; + } + + node->func = func; + node->preproc_id = preproc_id; +} + +void FreePreprocConfigFuncs(void) +{ + PreprocConfigFuncNode *head = preproc_config_funcs; + PreprocConfigFuncNode *tmp; + + while (head != NULL) + { + tmp = head->next; + if (head->keyword != NULL) + free(head->keyword); + free(head); + head = tmp; + } +} + +void FreePreprocCheckConfigFuncs(PreprocCheckConfigFuncNode *head) +{ + PreprocCheckConfigFuncNode *tmp; + + while (head != NULL) + { + tmp = head->next; + free(head); + head = tmp; + } +} + +void FreePreprocPostConfigFuncs(PreprocPostConfigFuncNode *head) +{ + PreprocPostConfigFuncNode *tmp; + + while (head != NULL) + { + tmp = head->next; + free(head); + head = tmp; + } +} + +void FreePreprocStatsFuncs(PreprocStatsFuncNode *head) +{ + PreprocStatsFuncNode *tmp; + + while (head != NULL) + { + tmp = head->next; + if (head->keyword != NULL) + free(head->keyword); + free(head); + head = tmp; + } +} + +void FreePreprocEvalFuncs(PreprocEvalFuncNode *head) +{ + PreprocEvalFuncNode *tmp; + + while (head != NULL) + { + tmp = head->next; + //if (head->context) + // free(head->context); + free(head); + head = tmp; + } +} + +void FreePreprocReassemblyPktFuncs(PreprocReassemblyPktFuncNode *head) +{ + PreprocReassemblyPktFuncNode *tmp; + + while (head != NULL) + { + tmp = head->next; + free(head); + head = tmp; + } +} + +void FreePreprocSigFuncs(PreprocSignalFuncNode *head) +{ + PreprocSignalFuncNode *tmp; + + while (head != NULL) + { + tmp = head->next; + /* don't free sig->arg, that's free'd by the CleanExit/Restart func */ + free(head); + head = tmp; + } +} + +void CheckPreprocessorsConfig(SnortConfig *sc) +{ + PreprocCheckConfigFuncNode *idx; + + if (sc == NULL) + { + FatalError("%s(%d) Snort config is NULL.\n", + __FILE__, __LINE__); + } + + snort_conf_for_parsing = sc; + + idx = sc->preproc_config_check_funcs; + + LogMessage("Verifying Preprocessor Configurations!\n"); + + while(idx != NULL) + { + idx->func(); + idx = idx->next; + } + + snort_conf_for_parsing = NULL; +} + +#ifdef SNORT_RELOAD +int VerifyReloadedPreprocessors(SnortConfig *sc) +{ + PreprocReloadVerifyFuncNode *node; + + if (sc == NULL) + { + FatalError("%s(%d) Snort config is NULL.\n", + __FILE__, __LINE__); + } + + snort_conf_for_parsing = sc; + + node = sc->preproc_reload_verify_funcs; + while (node != NULL) + { + if (node->func != NULL) + { + if (node->func() == -1) + return -1; + } + + node = node->next; + } + + snort_conf_for_parsing = NULL; + + return 0; +} +#endif + + +/***************************** Output Plugin API *****************************/ +extern OutputConfigFuncNode *output_config_funcs; + +static void AppendOutputFuncList(OutputFunc, void *, OutputFuncNode **); + +void RegisterOutputPlugins(void) +{ + LogMessage("Initializing Output Plugins!\n"); + + AlertSyslogSetup(); + LogTcpdumpSetup(); + DatabaseSetup(); + AlertFastSetup(); + AlertFullSetup(); + AlertPfSetup(); +#ifndef WIN32 + /* Win32 doesn't support AF_UNIX sockets */ + AlertUnixSockSetup(); +#endif /* !WIN32 */ + AlertCSVSetup(); + LogNullSetup(); + UnifiedSetup(); + Unified2Setup(); + LogAsciiSetup(); + +#ifdef ARUBA + AlertArubaActionSetup(); +#endif + +#ifdef LINUX + /* This uses linux only capabilities */ + AlertSFSocket_Setup(); +#endif + +#ifdef HAVE_LIBPRELUDE + AlertPreludeSetup(); +#endif + + AlertTestSetup(); +} + +/**************************************************************************** + * + * Function: RegisterOutputPlugin(char *, void (*func)(Packet *, u_char *)) + * + * Purpose: Associates an output statement with its function. + * + * Arguments: keyword => The output keyword to associate with the + * output processor + * type => alert or log types + * *func => function pointer to the handler + * + * Returns: void function + * + ***************************************************************************/ +void RegisterOutputPlugin(char *keyword, int type_flags, OutputConfigFunc func) +{ + OutputConfigFuncNode *node = (OutputConfigFuncNode *)SnortAlloc(sizeof(OutputConfigFuncNode)); + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:output => %s:%p\n", + keyword, func);); + + if (output_config_funcs == NULL) + { + output_config_funcs = node; + } + else + { + OutputConfigFuncNode *tmp = output_config_funcs; + OutputConfigFuncNode *last; + + do + { + if (strcasecmp(tmp->keyword, keyword) == 0) + { + free(node); + FatalError("Duplicate output keyword: %s\n", keyword); + } + + last = tmp; + tmp = tmp->next; + + } while (tmp != NULL); + + last->next = node; + } + + node->keyword = SnortStrdup(keyword); + node->func = func; + node->output_type_flags = type_flags; +} + +OutputConfigFunc GetOutputConfigFunc(char *keyword) +{ + OutputConfigFuncNode *head = output_config_funcs; + + if (keyword == NULL) + return NULL; + + while (head != NULL) + { + if (strcasecmp(head->keyword, keyword) == 0) + return head->func; + + head = head->next; + } + + return NULL; +} + +int GetOutputTypeFlags(char *keyword) +{ + OutputConfigFuncNode *head = output_config_funcs; + + if (keyword == NULL) + return 0; + + while (head != NULL) + { + if (strcasecmp(head->keyword, keyword) == 0) + return head->output_type_flags; + + head = head->next; + } + + return 0; +} + +void FreeOutputConfigFuncs(void) +{ + OutputConfigFuncNode *head = output_config_funcs; + OutputConfigFuncNode *tmp; + + while (head != NULL) + { + tmp = head->next; + if (head->keyword != NULL) + free(head->keyword); + free(head); + head = tmp; + } +} + +void FreeOutputList(OutputFuncNode *list) +{ + while (list != NULL) + { + OutputFuncNode *tmp = list; + + list = list->next; + free(tmp); + } +} + +/**************************************************************************** + * + * Function: DumpOutputPlugins() + * + * Purpose: Prints the keyword->preprocess list + * + * Arguments: None. + * + * Returns: void function + * + ***************************************************************************/ +void DumpOutputPlugins(void) +{ + OutputConfigFuncNode *idx = output_config_funcs; + + LogMessage("-------------------------------------------------\n"); + LogMessage(" Keyword | Output @ \n"); + LogMessage("-------------------------------------------------\n"); + while(idx != NULL) + { + LogMessage("%-13s: %p\n", idx->keyword, idx->func); + idx = idx->next; + } + LogMessage("-------------------------------------------------\n\n"); +} + +void AddFuncToOutputList(OutputFunc func, OutputType type, void *arg) +{ + switch (type) + { + case OUTPUT_TYPE__ALERT: + if (head_tmp != NULL) + AppendOutputFuncList(func, arg, &head_tmp->AlertList); + else + AppendOutputFuncList(func, arg, &AlertList); + + break; + + case OUTPUT_TYPE__LOG: + if (head_tmp != NULL) + AppendOutputFuncList(func, arg, &head_tmp->LogList); + else + AppendOutputFuncList(func, arg, &LogList); + + break; + + default: + /* just to be error-prone */ + FatalError("Unknown output type: %i. Possible bug, please " + "report.\n", type); + } +} + +void AppendOutputFuncList(OutputFunc func, void *arg, OutputFuncNode **list) +{ + OutputFuncNode *node; + + if (list == NULL) + return; + + node = (OutputFuncNode *)SnortAlloc(sizeof(OutputFuncNode)); + + if (*list == NULL) + { + *list = node; + } + else + { + OutputFuncNode *tmp = *list; + + while (tmp->next != NULL) + tmp = tmp->next; + + tmp->next = node; + } + + node->func = func; + node->arg = arg; +} + + +/************************** Miscellaneous Functions **************************/ + +/* functions to aid in cleaning up after plugins + * Used for both rule options and output. Preprocessors have their own */ +void AddFuncToRestartList(PluginSignalFunc func, void *arg) +{ + AddFuncToSignalList(func, arg, &plugin_restart_funcs); +} + +void AddFuncToCleanExitList(PluginSignalFunc func, void *arg) +{ + AddFuncToSignalList(func, arg, &plugin_clean_exit_funcs); +} + +void AddFuncToShutdownList(PluginSignalFunc func, void *arg) +{ + AddFuncToSignalList(func, arg, &plugin_shutdown_funcs); +} + +void AddFuncToPostConfigList(PluginSignalFunc func, void *arg) +{ + SnortConfig *sc = snort_conf_for_parsing; + + if (sc == NULL) + { + FatalError("%s(%d) Snort config for parsing is NULL.\n", + __FILE__, __LINE__); + } + + AddFuncToSignalList(func, arg, &sc->plugin_post_config_funcs); +} + +void AddFuncToSignalList(PluginSignalFunc func, void *arg, PluginSignalFuncNode **list) +{ + PluginSignalFuncNode *node; + + if (list == NULL) + return; + + node = (PluginSignalFuncNode *)SnortAlloc(sizeof(PluginSignalFuncNode)); + + if (*list == NULL) + { + *list = node; + } + else + { + PluginSignalFuncNode *tmp = *list; + + while (tmp->next != NULL) + tmp = tmp->next; + + tmp->next = node; + } + + node->func = func; + node->arg = arg; +} + +void AddFuncToRuleOptParseCleanupList(RuleOptParseCleanupFunc func) +{ + RuleOptParseCleanupNode *node = + (RuleOptParseCleanupNode *)SnortAlloc(sizeof(RuleOptParseCleanupNode)); + + if (rule_opt_parse_cleanup_list == NULL) + { + rule_opt_parse_cleanup_list = node; + } + else + { + RuleOptParseCleanupNode *tmp = rule_opt_parse_cleanup_list; + + while (tmp->next != NULL) + tmp = tmp->next; + + tmp->next = node; + } + + node->func = func; +} + +void RuleOptParseCleanup(void) +{ + RuleOptParseCleanupNode *list = rule_opt_parse_cleanup_list; + + for (; list != NULL; list = list->next) + { + if (list->func != NULL) + list->func(); + } +} + +void FreeRuleOptParseCleanupList(RuleOptParseCleanupNode *head) +{ + while (head != NULL) + { + RuleOptParseCleanupNode *tmp = head; + + head = head->next; + free(tmp); + } +} + + -- cgit v1.2.3