X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?a=blobdiff_plain;f=src%2Fanalysisd%2Frules.c;h=ee110709026f532e834247b1d5a55a7ee07fb3ec;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hp=8c97197cdfc419ba216493b7b8968a15ed899f4f;hpb=914feba5d54f979cd5d7e69c349c3d01f630042a;p=ossec-hids.git diff --git a/src/analysisd/rules.c b/src/analysisd/rules.c old mode 100755 new mode 100644 index 8c97197..ee11070 --- a/src/analysisd/rules.c +++ b/src/analysisd/rules.c @@ -1,1394 +1,1676 @@ -/* @(#) $Id: rules.c,v 1.79 2009/11/04 18:45:37 dcid Exp $ */ - /* Copyright (C) 2009 Trend Micro Inc. * All rights reserved. * * This program is a free software; you can redistribute it * and/or modify it under the terms of the GNU General Public - * License (version 3) as published by the FSF - Free Software + * License (version 2) as published by the FSF - Free Software * Foundation. - * - * License details at the LICENSE file included with OSSEC or - * online at: http://www.ossec.net/en/licensing.html */ - - #include "rules.h" #include "config.h" #include "eventinfo.h" #include "compiled_rules/compiled_rules.h" +/* Global definition */ +RuleInfo *currently_rule; -/* Chaging path for test rule. */ +/* Change path for test rule */ #ifdef TESTRULE - #undef RULEPATH - #define RULEPATH "rules/" +#undef RULEPATH +#define RULEPATH "rules/" #endif - - -/* Internal functions */ -int getattributes(char **attributes, +/* Prototypes */ +static int getattributes(char **attributes, char **values, - int *id, int *level, + int *id, int *level, int *maxsize, int *timeframe, - int *frequency, int *accuracy, + int *frequency, int *accuracy, int *noalert, int *ignore_time, int *overwrite); +static int doesRuleExist(int sid, RuleNode *r_node); +static void Rule_AddAR(RuleInfo *config_rule); +static char *loadmemory(char *at, const char *str); +static void printRuleinfo(const RuleInfo *rule, int node); - -void Rule_AddAR(RuleInfo *config_rule); -char *loadmemory(char *at, char *str); -int getDecoderfromlist(char *name); - -extern int _max_freq; - - - -/* Rules_OP_ReadRules, v0.1, 2005/07/04 - * Will initialize the rules list - */ +/* Will initialize the rules list */ void Rules_OP_CreateRules() { - - /* Initializing the rule list */ + /* Initialize the rule list */ OS_CreateRuleList(); return; } - - -/* Rules_OP_ReadRules, v0.3, 2005/03/21 - * Read the log rules. - * v0.3: Fixed many memory problems. - */ -int Rules_OP_ReadRules(char * rulefile) +/* Read the log rules */ +int Rules_OP_ReadRules(const char *rulefile) { OS_XML xml; XML_NODE node = NULL; - /* XML variables */ + /* XML variables */ /* These are the available options for the rule configuration */ - - char *xml_group = "group"; - char *xml_rule = "rule"; - - char *xml_regex = "regex"; - char *xml_match = "match"; - char *xml_decoded = "decoded_as"; - char *xml_category = "category"; - char *xml_cve = "cve"; - char *xml_info = "info"; - char *xml_day_time = "time"; - char *xml_week_day = "weekday"; - char *xml_comment = "description"; - char *xml_ignore = "ignore"; - char *xml_check_if_ignored = "check_if_ignored"; - - char *xml_srcip = "srcip"; - char *xml_srcport = "srcport"; - char *xml_dstip = "dstip"; - char *xml_dstport = "dstport"; - char *xml_user = "user"; - char *xml_url = "url"; - char *xml_id = "id"; - char *xml_data = "extra_data"; - char *xml_hostname = "hostname"; - char *xml_program_name = "program_name"; - char *xml_status = "status"; - char *xml_action = "action"; - char *xml_compiled = "compiled_rule"; - - char *xml_if_sid = "if_sid"; - char *xml_if_group = "if_group"; - char *xml_if_level = "if_level"; - char *xml_fts = "if_fts"; - - char *xml_if_matched_regex = "if_matched_regex"; - char *xml_if_matched_group = "if_matched_group"; - char *xml_if_matched_sid = "if_matched_sid"; - - char *xml_same_source_ip = "same_source_ip"; - char *xml_same_src_port = "same_src_port"; - char *xml_same_dst_port = "same_dst_port"; - char *xml_same_user = "same_user"; - char *xml_same_location = "same_location"; - char *xml_same_id = "same_id"; - - char *xml_different_url = "different_url"; - - char *xml_notsame_source_ip = "not_same_source_ip"; - char *xml_notsame_user = "not_same_user"; - char *xml_notsame_agent = "not_same_agent"; - char *xml_notsame_id = "not_same_id"; - - char *xml_options = "options"; - + + const char *xml_group = "group"; + const char *xml_rule = "rule"; + + const char *xml_regex = "regex"; + const char *xml_pcre2 = "pcre2"; + const char *xml_match = "match"; + const char *xml_match_pcre2 = "match_pcre2"; + const char *xml_decoded = "decoded_as"; + const char *xml_category = "category"; + const char *xml_cve = "cve"; + const char *xml_info = "info"; + const char *xml_day_time = "time"; + const char *xml_week_day = "weekday"; + const char *xml_comment = "description"; + const char *xml_ignore = "ignore"; + const char *xml_check_if_ignored = "check_if_ignored"; + + const char *xml_srcip = "srcip"; + const char *xml_srcgeoip = "srcgeoip"; + const char *xml_srcport = "srcport"; + const char *xml_srcgeoip_pcre2 = "srcgeoip_pcre2"; + const char *xml_srcport_pcre2 = "srcport_pcre2"; + const char *xml_dstip = "dstip"; + const char *xml_dstgeoip = "dstgeoip"; + const char *xml_dstport = "dstport"; + const char *xml_user = "user"; + const char *xml_url = "url"; + const char *xml_id = "id"; + const char *xml_data = "extra_data"; + const char *xml_hostname = "hostname"; + const char *xml_program_name = "program_name"; + const char *xml_status = "status"; + const char *xml_dstgeoip_pcre2 = "dstgeoip_pcre2"; + const char *xml_dstport_pcre2 = "dstport_pcre2"; + const char *xml_user_pcre2 = "user_pcre2"; + const char *xml_url_pcre2 = "url_pcre2"; + const char *xml_id_pcre2 = "id_pcre2"; + const char *xml_data_pcre2 = "extra_data_pcre2"; + const char *xml_hostname_pcre2 = "hostname_pcre2"; + const char *xml_program_name_pcre2 = "program_name_pcre2"; + const char *xml_status_pcre2 = "status_pcre2"; + const char *xml_action = "action"; + const char *xml_compiled = "compiled_rule"; + const char *xml_field = "field"; + const char *xml_name = "name"; + + + const char *xml_list = "list"; + const char *xml_list_lookup = "lookup"; + const char *xml_list_field = "field"; + const char *xml_list_cvalue = "check_value"; + const char *xml_match_key = "match_key"; + const char *xml_not_match_key = "not_match_key"; + const char *xml_match_key_value = "match_key_value"; + const char *xml_address_key = "address_match_key"; + const char *xml_not_address_key = "not_address_match_key"; + const char *xml_address_key_value = "address_match_key_value"; + + const char *xml_if_sid = "if_sid"; + const char *xml_if_group = "if_group"; + const char *xml_if_level = "if_level"; + const char *xml_fts = "if_fts"; + + const char *xml_if_matched_regex = "if_matched_regex"; + const char *xml_if_matched_group = "if_matched_group"; + const char *xml_if_matched_sid = "if_matched_sid"; + + const char *xml_same_source_ip = "same_source_ip"; + const char *xml_same_src_port = "same_src_port"; + const char *xml_same_dst_port = "same_dst_port"; + const char *xml_same_user = "same_user"; + const char *xml_same_location = "same_location"; + const char *xml_same_id = "same_id"; + const char *xml_dodiff = "check_diff"; + + const char *xml_different_url = "different_url"; + const char *xml_different_srcip = "different_srcip"; + const char *xml_different_srcgeoip = "different_srcgeoip"; + + const char *xml_notsame_source_ip = "not_same_source_ip"; + const char *xml_notsame_user = "not_same_user"; + const char *xml_notsame_agent = "not_same_agent"; + const char *xml_notsame_id = "not_same_id"; + + const char *xml_options = "options"; + char *rulepath; - - int i; - int default_timeframe = 360; + size_t i; + int default_timeframe = 360; - /* Building the rule file name + path */ - i = strlen(RULEPATH) + strlen(rulefile) + 2; - rulepath = (char *)calloc(i,sizeof(char)); - if(!rulepath) - { - ErrorExit(MEM_ERROR,ARGV0); + /* If no directory in the rulefile, add the default */ + if ((strchr(rulefile, '/')) == NULL) { + /* Build the rule file name + path */ + i = strlen(RULEPATH) + strlen(rulefile) + 2; + rulepath = (char *)calloc(i, sizeof(char)); + if (!rulepath) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + snprintf(rulepath, i, "%s/%s", RULEPATH, rulefile); + } else { + os_strdup(rulefile, rulepath); + debug1("%s is the rulefile", rulefile); + debug1("Not modifing the rule path"); } - - snprintf(rulepath,i,"%s/%s",RULEPATH,rulefile); - - i = 0; - - /* Reading the XML */ - if(OS_ReadXML(rulepath,&xml) < 0) - { + + i = 0; + + /* Read the XML */ + if (OS_ReadXML(rulepath, &xml) < 0) { merror(XML_ERROR, ARGV0, rulepath, xml.err, xml.err_line); free(rulepath); - return(-1); + return (-1); } - - - /* Debug wrapper */ debug2("%s: DEBUG: read xml for rule.", ARGV0); - - - /* Applying any variable found */ - if(OS_ApplyVariables(&xml) != 0) - { + /* Apply any variable found */ + if (OS_ApplyVariables(&xml) != 0) { merror(XML_ERROR_VAR, ARGV0, rulepath, xml.err); - return(-1); + free(rulepath); + return (-1); } - - - /* Debug wrapper */ debug2("%s: DEBUG: XML Variables applied.", ARGV0); - - /* Getting the root elements */ - node = OS_GetElementsbyNode(&xml,NULL); - if(!node) - { + /* Get the root elements */ + node = OS_GetElementsbyNode(&xml, NULL); + if (!node) { merror(CONFIG_ERROR, ARGV0, rulepath); OS_ClearXML(&xml); - return(-1); + free(rulepath); + return (-1); } - - /* Zeroing the rule memory -- not used anymore */ + /* Zero the rule memory -- not used anymore */ free(rulepath); - - /* Getting default time frame */ + /* Get default time frame */ default_timeframe = getDefine_Int("analysisd", "default_timeframe", - 60, 3600); - + 60, MAX_TIMEFRAME); - /* Checking if there is any invalid global option */ - while(node[i]) - { - if(node[i]->element) - { - if(strcasecmp(node[i]->element,xml_group) != 0) - { + /* Check if there is any invalid global option */ + while (node[i]) { + if (node[i]->element) { + if (strcasecmp(node[i]->element, xml_group) != 0) { merror("rules_op: Invalid root element \"%s\"." - "Only \"group\" is allowed",node[i]->element); + "Only \"group\" is allowed", node[i]->element); OS_ClearXML(&xml); - return(-1); + return (-1); } - if((!node[i]->attributes) || (!node[i]->values)|| + if ((!node[i]->attributes) || (!node[i]->values) || (!node[i]->values[0]) || (!node[i]->attributes[0]) || - (strcasecmp(node[i]->attributes[0],"name") != 0) || - (node[i]->attributes[1])) - { + (strcasecmp(node[i]->attributes[0], "name") != 0) || + (node[i]->attributes[1])) { merror("rules_op: Invalid root element '%s'." - "Only the group name is allowed",node[i]->element); + "Only the group name is allowed", node[i]->element); OS_ClearXML(&xml); - return(-1); + return (-1); } - } - else - { + } else { merror(XML_READ_ERROR, ARGV0); OS_ClearXML(&xml); - return(-1); + return (-1); } i++; } - - /* Getting the rules now */ - i=0; - while(node[i]) - { + /* Get the rules */ + i = 0; + while (node[i]) { XML_NODE rule = NULL; int j = 0; - /* Getting all rules for a global group */ - rule = OS_GetElementsbyNode(&xml,node[i]); - if(rule == NULL) - { + /* Get all rules for a global group */ + rule = OS_GetElementsbyNode(&xml, node[i]); + if (rule == NULL) { merror("%s: Group '%s' without any rule.", - ARGV0, node[i]->element); + ARGV0, node[i]->element); OS_ClearXML(&xml); - return(-1); + return (-1); } - while(rule[j]) - { + while (rule[j]) { RuleInfo *config_ruleinfo = NULL; - - /* Checking if the rule element is correct */ - if((!rule[j]->element)|| - (strcasecmp(rule[j]->element,xml_rule) != 0)) - { + /* Check if the rule element is correct */ + if ((!rule[j]->element) || + (strcasecmp(rule[j]->element, xml_rule) != 0)) { merror("%s: Invalid configuration. '%s' is not " "a valid element.", ARGV0, rule[j]->element); OS_ClearXML(&xml); - return(-1); + return (-1); } - - /* Checking for the attributes of the rule */ - if((!rule[j]->attributes) || (!rule[j]->values)) - { + /* Check for the attributes of the rule */ + if ((!rule[j]->attributes) || (!rule[j]->values)) { merror("%s: Invalid rule '%d'. You must specify" - " an ID and a level at least.", ARGV0, j); + " an ID and a level at least.", ARGV0, j); OS_ClearXML(&xml); - return(-1); + return (-1); } - /* Attribute block */ { - int id = -1,level = -1,maxsize = 0,timeframe = 0; + int id = -1, level = -1, maxsize = 0, timeframe = 0; int frequency = 0, accuracy = 1, noalert = 0, ignore_time = 0; int overwrite = 0; - - /* Getting default time frame */ + + /* Get default timeframe */ timeframe = default_timeframe; - - if(getattributes(rule[j]->attributes,rule[j]->values, - &id,&level,&maxsize,&timeframe, - &frequency,&accuracy,&noalert, - &ignore_time, &overwrite) < 0) - { + if (getattributes(rule[j]->attributes, rule[j]->values, + &id, &level, &maxsize, &timeframe, + &frequency, &accuracy, &noalert, + &ignore_time, &overwrite) < 0) { merror("%s: Invalid attribute for rule.", ARGV0); OS_ClearXML(&xml); - return(-1); + return (-1); } - - if((id == -1) || (level == -1)) - { + + if ((id == -1) || (level == -1)) { merror("%s: No rule id or level specified for " - "rule '%d'.",ARGV0, j); + "rule '%d'.", ARGV0, j); OS_ClearXML(&xml); - return(-1); + return (-1); } - /* Allocating memory and initializing structure */ + if (overwrite != 1 && doesRuleExist(id, NULL)) { + merror("%s: Duplicate rule ID:%d", ARGV0, id); + OS_ClearXML(&xml); + return (-1); + } + + /* Allocate memory and initialize structure */ config_ruleinfo = zerorulemember(id, level, maxsize, - frequency,timeframe, - noalert, ignore_time, overwrite); - + frequency, timeframe, + noalert, ignore_time, overwrite); /* If rule is 0, set it to level 99 to have high priority. - * set it to 0 again later + * Set it to 0 again later. */ - if(config_ruleinfo->level == 0) - config_ruleinfo->level = 99; - - - /* Each level now is going to be multiplied by 100. - * If the accuracy is set to 0 we don't multiply, - * so it will be at the end of the list. We will - * divide by 100 later. - */ - if(accuracy) - { - config_ruleinfo->level *= 100; - } - - if(config_ruleinfo->maxsize > 0) - { - if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) - { - config_ruleinfo->alert_opts |= DO_EXTRAINFO; - } - } - - } /* end attributes/memory allocation block */ + if (config_ruleinfo->level == 0) { + config_ruleinfo->level = 99; + } + /* Each level now is going to be multiplied by 100. + * If the accuracy is set to 0 we don't multiply, + * so it will be at the end of the list. We will + * divide by 100 later. + */ + if (accuracy) { + config_ruleinfo->level *= 100; + } + + if (config_ruleinfo->maxsize > 0) { + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } + + } /* end attributes/memory allocation block */ /* Here we can assign the group name to the rule. * The level is correct so the rule is probably going to * be fine */ os_strdup(node[i]->values[0], config_ruleinfo->group); - /* Rule elements block */ { int k = 0; + int ifield = 0; + int info_type = 0; + int count_info_detail = 0; + RuleInfoDetail *last_info_detail = NULL; char *regex = NULL; char *match = NULL; + char *pcre2 = NULL; + char *match_pcre2 = NULL; char *url = NULL; + char *url_pcre2 = NULL; char *if_matched_regex = NULL; char *if_matched_group = NULL; char *user = NULL; char *id = NULL; char *srcport = NULL; char *dstport = NULL; + char *srcgeoip = NULL; + char *dstgeoip = NULL; + char *status = NULL; char *hostname = NULL; char *extra_data = NULL; char *program_name = NULL; - + + char *user_pcre2 = NULL; + char *id_pcre2 = NULL; + char *srcport_pcre2 = NULL; + char *dstport_pcre2 = NULL; + char *srcgeoip_pcre2 = NULL; + char *dstgeoip_pcre2 = NULL; + + char *status_pcre2 = NULL; + char *hostname_pcre2 = NULL; + char *extra_data_pcre2 = NULL; + char *program_name_pcre2 = NULL; + XML_NODE rule_opt = NULL; - rule_opt = OS_GetElementsbyNode(&xml,rule[j]); - if(rule_opt == NULL) - { + rule_opt = OS_GetElementsbyNode(&xml, rule[j]); + if (rule_opt == NULL) { merror("%s: Rule '%d' without any option. " - "It may lead to false positives and some " - "other problems for the system. Exiting.", - ARGV0, config_ruleinfo->sigid); + "It may lead to false positives and some " + "other problems for the system. Exiting.", + ARGV0, config_ruleinfo->sigid); OS_ClearXML(&xml); - return(-1); + return (-1); } - - while(rule_opt[k]) - { - if((!rule_opt[k]->element)||(!rule_opt[k]->content)) + + while (rule_opt[k]) { + if ((!rule_opt[k]->element) || (!rule_opt[k]->content)) { break; - else if(strcasecmp(rule_opt[k]->element,xml_regex)==0) - { + } else if (strcasecmp(rule_opt[k]->element, xml_regex) == 0) { regex = loadmemory(regex, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element,xml_match)==0) - { + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_pcre2) == 0) { + pcre2 = + loadmemory(pcre2, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_match) == 0) { match = loadmemory(match, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element, xml_decoded)==0) - { - config_ruleinfo->decoded_as = + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_match_pcre2) == 0) { + match_pcre2 = + loadmemory(match_pcre2, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_decoded) == 0) { + config_ruleinfo->decoded_as = getDecoderfromlist(rule_opt[k]->content); - - if(config_ruleinfo->decoded_as == 0) - { + + if (config_ruleinfo->decoded_as == 0) { merror("%s: Invalid decoder name: '%s'.", ARGV0, rule_opt[k]->content); OS_ClearXML(&xml); - return(-1); + return (-1); } - } - else if(strcasecmp(rule_opt[k]->element,xml_info)==0) - { - config_ruleinfo->info= + } else if (strcasecmp(rule_opt[k]->element, xml_cve) == 0) { + if (config_ruleinfo->info_details == NULL) { + config_ruleinfo->info_details = zeroinfodetails(RULEINFODETAIL_CVE, + rule_opt[k]->content); + } else { + for (last_info_detail = config_ruleinfo->info_details; + last_info_detail->next != NULL; + last_info_detail = last_info_detail->next) { + count_info_detail++; + } + /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */ + if (count_info_detail <= MAX_RULEINFODETAIL) { + last_info_detail->next = zeroinfodetails(RULEINFODETAIL_CVE, + rule_opt[k]->content); + } + } + + /* keep old methods for now */ + config_ruleinfo->cve = + loadmemory(config_ruleinfo->cve, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_info) == 0) { + + info_type = get_info_attributes(rule_opt[k]->attributes, + rule_opt[k]->values); + debug1("info_type = %d", info_type); + + if (config_ruleinfo->info_details == NULL) { + config_ruleinfo->info_details = zeroinfodetails(info_type, + rule_opt[k]->content); + } else { + for (last_info_detail = config_ruleinfo->info_details; + last_info_detail->next != NULL; + last_info_detail = last_info_detail->next) { + count_info_detail++; + } + /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */ + if (count_info_detail <= MAX_RULEINFODETAIL) { + last_info_detail->next = zeroinfodetails(info_type, rule_opt[k]->content); + } + } + + + /* keep old methods for now */ + config_ruleinfo->info = loadmemory(config_ruleinfo->info, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element,xml_day_time)==0) - { - config_ruleinfo->day_time = + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_day_time) == 0) { + config_ruleinfo->day_time = OS_IsValidTime(rule_opt[k]->content); - if(!config_ruleinfo->day_time) - { + if (!config_ruleinfo->day_time) { merror(INVALID_CONFIG, ARGV0, - rule_opt[k]->element, - rule_opt[k]->content); - return(-1); + rule_opt[k]->element, + rule_opt[k]->content); + return (-1); } - if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { config_ruleinfo->alert_opts |= DO_EXTRAINFO; - } - else if(strcasecmp(rule_opt[k]->element,xml_week_day)==0) - { - config_ruleinfo->week_day = + } + } else if (strcasecmp(rule_opt[k]->element, xml_week_day) == 0) { + config_ruleinfo->week_day = OS_IsValidDay(rule_opt[k]->content); - - if(!config_ruleinfo->week_day) - { + + if (!config_ruleinfo->week_day) { merror(INVALID_CONFIG, ARGV0, - rule_opt[k]->element, - rule_opt[k]->content); - return(-1); + rule_opt[k]->element, + rule_opt[k]->content); + return (-1); } - if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { config_ruleinfo->alert_opts |= DO_EXTRAINFO; - } - else if(strcasecmp(rule_opt[k]->element,xml_group)==0) - { + } + } else if (strcasecmp(rule_opt[k]->element, xml_group) == 0) { config_ruleinfo->group = loadmemory(config_ruleinfo->group, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element,xml_cve)==0) - { - config_ruleinfo->cve= - loadmemory(config_ruleinfo->cve, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element,xml_comment)==0) - { + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_comment) == 0) { char *newline; newline = strchr(rule_opt[k]->content, '\n'); - if(newline) - { + if (newline) { *newline = ' '; } - - config_ruleinfo->comment= + + config_ruleinfo->comment = loadmemory(config_ruleinfo->comment, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element,xml_srcip)==0) - { - int ip_s = 0; - + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_srcip) == 0) { + unsigned int ip_s = 0; + /* Getting size of source ip list */ - while(config_ruleinfo->srcip && - config_ruleinfo->srcip[ip_s]) - { + while (config_ruleinfo->srcip && + config_ruleinfo->srcip[ip_s]) { ip_s++; } - - config_ruleinfo->srcip = - realloc(config_ruleinfo->srcip, + + config_ruleinfo->srcip = + (os_ip **) realloc(config_ruleinfo->srcip, (ip_s + 2) * sizeof(os_ip *)); - - + + /* Allocating memory for the individual entries */ - os_calloc(1, sizeof(os_ip), - config_ruleinfo->srcip[ip_s]); - config_ruleinfo->srcip[ip_s +1] = NULL; - - + os_calloc(1, sizeof(os_ip), + config_ruleinfo->srcip[ip_s]); + config_ruleinfo->srcip[ip_s + 1] = NULL; + + /* Checking if the ip is valid */ - if(!OS_IsValidIP(rule_opt[k]->content, - config_ruleinfo->srcip[ip_s])) - { + if (!OS_IsValidIP(rule_opt[k]->content, + config_ruleinfo->srcip[ip_s])) { merror(INVALID_IP, ARGV0, rule_opt[k]->content); - return(-1); + return (-1); } - if(!(config_ruleinfo->alert_opts & DO_PACKETINFO)) + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { config_ruleinfo->alert_opts |= DO_PACKETINFO; - } - else if(strcasecmp(rule_opt[k]->element,xml_dstip)==0) - { - int ip_s = 0; + } + } else if (strcasecmp(rule_opt[k]->element, xml_dstip) == 0) { + unsigned int ip_s = 0; /* Getting size of source ip list */ - while(config_ruleinfo->dstip && - config_ruleinfo->dstip[ip_s]) - { + while (config_ruleinfo->dstip && + config_ruleinfo->dstip[ip_s]) { ip_s++; } config_ruleinfo->dstip = - realloc(config_ruleinfo->dstip, + (os_ip **) realloc(config_ruleinfo->dstip, (ip_s + 2) * sizeof(os_ip *)); /* Allocating memory for the individual entries */ os_calloc(1, sizeof(os_ip), - config_ruleinfo->dstip[ip_s]); - config_ruleinfo->dstip[ip_s +1] = NULL; + config_ruleinfo->dstip[ip_s]); + config_ruleinfo->dstip[ip_s + 1] = NULL; /* Checking if the ip is valid */ - if(!OS_IsValidIP(rule_opt[k]->content, - config_ruleinfo->dstip[ip_s])) - { + if (!OS_IsValidIP(rule_opt[k]->content, + config_ruleinfo->dstip[ip_s])) { merror(INVALID_IP, ARGV0, rule_opt[k]->content); - return(-1); + return (-1); } - if(!(config_ruleinfo->alert_opts & DO_PACKETINFO)) + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { config_ruleinfo->alert_opts |= DO_PACKETINFO; - } - else if(strcasecmp(rule_opt[k]->element,xml_user)==0) - { + } + } else if (strcasecmp(rule_opt[k]->element, xml_user) == 0) { user = loadmemory(user, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if(strcasecmp(rule_opt[k]->element,xml_srcgeoip)==0) { + srcgeoip = + loadmemory(srcgeoip, rule_opt[k]->content); if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) config_ruleinfo->alert_opts |= DO_EXTRAINFO; - } - else if(strcasecmp(rule_opt[k]->element,xml_id)==0) - { + } else if(strcasecmp(rule_opt[k]->element,xml_dstgeoip)==0) { + dstgeoip = + loadmemory(dstgeoip, + rule_opt[k]->content); + + if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } else if (strcasecmp(rule_opt[k]->element, xml_id) == 0) { id = loadmemory(id, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element,xml_srcport)==0) - { + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_srcport) == 0) { srcport = loadmemory(srcport, - rule_opt[k]->content); - if(!(config_ruleinfo->alert_opts & DO_PACKETINFO)) + rule_opt[k]->content); + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { config_ruleinfo->alert_opts |= DO_PACKETINFO; - } - else if(strcasecmp(rule_opt[k]->element,xml_dstport)==0) - { + } + } else if (strcasecmp(rule_opt[k]->element, xml_dstport) == 0) { dstport = loadmemory(dstport, - rule_opt[k]->content); + rule_opt[k]->content); - if(!(config_ruleinfo->alert_opts & DO_PACKETINFO)) + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { config_ruleinfo->alert_opts |= DO_PACKETINFO; - } - else if(strcasecmp(rule_opt[k]->element,xml_status)==0) - { + } + } else if (strcasecmp(rule_opt[k]->element, xml_status) == 0) { status = loadmemory(status, - rule_opt[k]->content); - - if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { config_ruleinfo->alert_opts |= DO_EXTRAINFO; - } - else if(strcasecmp(rule_opt[k]->element,xml_hostname)==0) - { + } + } else if (strcasecmp(rule_opt[k]->element, xml_hostname) == 0) { hostname = loadmemory(hostname, - rule_opt[k]->content); - - if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { config_ruleinfo->alert_opts |= DO_EXTRAINFO; - } - else if(strcasecmp(rule_opt[k]->element,xml_data)==0) - { + } + } else if (strcasecmp(rule_opt[k]->element, xml_data) == 0) { extra_data = loadmemory(extra_data, - rule_opt[k]->content); + rule_opt[k]->content); - if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { config_ruleinfo->alert_opts |= DO_EXTRAINFO; - } - else if(strcasecmp(rule_opt[k]->element, - xml_program_name)==0) - { + } + } else if (strcasecmp(rule_opt[k]->element, + xml_program_name) == 0) { program_name = loadmemory(program_name, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_user_pcre2) == 0) { + user_pcre2 = + loadmemory(user_pcre2, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if(strcasecmp(rule_opt[k]->element,xml_srcgeoip_pcre2)==0) { + srcgeoip_pcre2 = + loadmemory(srcgeoip_pcre2, rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element,xml_action)==0) - { - config_ruleinfo->action = - loadmemory(config_ruleinfo->action, + + if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } else if(strcasecmp(rule_opt[k]->element,xml_dstgeoip_pcre2)==0) { + dstgeoip_pcre2 = + loadmemory(dstgeoip_pcre2, rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element,xml_url)==0) - { - url= + + if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } else if (strcasecmp(rule_opt[k]->element, xml_id_pcre2) == 0) { + id_pcre2 = + loadmemory(id_pcre2, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_srcport_pcre2) == 0) { + srcport_pcre2 = + loadmemory(srcport_pcre2, + rule_opt[k]->content); + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_dstport_pcre2) == 0) { + dstport_pcre2 = + loadmemory(dstport_pcre2, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_status_pcre2) == 0) { + status_pcre2 = + loadmemory(status_pcre2, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_hostname_pcre2) == 0) { + hostname_pcre2 = + loadmemory(hostname_pcre2, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_data_pcre2) == 0) { + extra_data_pcre2 = + loadmemory(extra_data_pcre2, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_program_name_pcre2) == 0) { + program_name_pcre2 = + loadmemory(program_name_pcre2, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_action) == 0) { + config_ruleinfo->action = + loadmemory(config_ruleinfo->action, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_field) == 0) { + if (rule_opt[k]->attributes[0]) { + os_calloc(1, sizeof(FieldInfo), config_ruleinfo->fields[ifield]); + + if (strcasecmp(rule_opt[k]->attributes[0], xml_name) == 0) { + config_ruleinfo->fields[ifield]->name = loadmemory(config_ruleinfo->fields[ifield]->name, rule_opt[k]->values[0]); + } else { + merror("%s: Bad attribute '%s' for field.", ARGV0, rule_opt[k]->attributes[0]); + return -1; + } + } else { + merror("%s: No such attribute '%s' for field.", ARGV0, xml_name); + return (-1); + } + + os_calloc(1, sizeof(OSRegex), config_ruleinfo->fields[ifield]->regex); + + if (!OSRegex_Compile(rule_opt[k]->content, config_ruleinfo->fields[ifield]->regex, 0)) { + merror(REGEX_COMPILE, ARGV0, rule_opt[k]->content, config_ruleinfo->fields[ifield]->regex->error); + return -1; + } + + ifield++; + + } else if (strcasecmp(rule_opt[k]->element, xml_list) == 0) { + debug1("-> %s == %s", rule_opt[k]->element, xml_list); + if (rule_opt[k]->attributes && rule_opt[k]->values && rule_opt[k]->content) { + int list_att_num = 0; + int rule_type = 0; + OSMatch *matcher = NULL; + int lookup_type = LR_STRING_MATCH; + while (rule_opt[k]->attributes[list_att_num]) { + if (strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_lookup) == 0) { + if (strcasecmp(rule_opt[k]->values[list_att_num], xml_match_key) == 0) { + lookup_type = LR_STRING_MATCH; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_not_match_key) == 0) { + lookup_type = LR_STRING_NOT_MATCH; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_match_key_value) == 0) { + lookup_type = LR_STRING_MATCH_VALUE; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_address_key) == 0) { + lookup_type = LR_ADDRESS_MATCH; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_not_address_key) == 0) { + lookup_type = LR_ADDRESS_NOT_MATCH; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_address_key_value) == 0) { + lookup_type = LR_ADDRESS_MATCH_VALUE; + } else { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + merror("%s: List match lookup=\"%s\" is not valid.", + ARGV0, rule_opt[k]->values[list_att_num]); + return (-1); + } + } else if (strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_field) == 0) { + if (strcasecmp(rule_opt[k]->values[list_att_num], xml_srcip) == 0) { + rule_type = RULE_SRCIP; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_srcport) == 0) { + rule_type = RULE_SRCPORT; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_dstip) == 0) { + rule_type = RULE_DSTIP; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_dstport) == 0) { + rule_type = RULE_DSTPORT; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_user) == 0) { + rule_type = RULE_USER; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_url) == 0) { + rule_type = RULE_URL; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_id) == 0) { + rule_type = RULE_ID; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_hostname) == 0) { + rule_type = RULE_HOSTNAME; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_program_name) == 0) { + rule_type = RULE_PROGRAM_NAME; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_status) == 0) { + rule_type = RULE_STATUS; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_action) == 0) { + rule_type = RULE_ACTION; + } else { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + merror("%s: List match field=\"%s\" is not valid.", + ARGV0, rule_opt[k]->values[list_att_num]); + return (-1); + } + } else if (strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_cvalue) == 0) { + os_calloc(1, sizeof(OSMatch), matcher); + if (!OSMatch_Compile(rule_opt[k]->values[list_att_num], matcher, 0)) { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + merror(REGEX_COMPILE, + ARGV0, + rule_opt[k]->values[list_att_num], + matcher->error); + return (-1); + } + } else { + merror("%s:List field=\"%s\" is not valid", ARGV0, + rule_opt[k]->values[list_att_num]); + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, rule_opt[k]->content); + return (-1); + } + list_att_num++; + } + if (rule_type == 0) { + merror("%s:List requires the field=\"\" Attrubute", ARGV0); + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, rule_opt[k]->content); + return (-1); + } + + /* Wow it's all ready - this seems too complex to get to this point */ + config_ruleinfo->lists = OS_AddListRule(config_ruleinfo->lists, + lookup_type, + rule_type, + rule_opt[k]->content, + matcher); + if (config_ruleinfo->lists == NULL) { + merror("%s: List error: Could not load %s", ARGV0, rule_opt[k]->content); + return (-1); + } + } else { + merror("%s:List must have a correctly formatted field attribute", + ARGV0); + merror(INVALID_CONFIG, + ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + return (-1); + } + /* xml_list eval is done */ + } else if (strcasecmp(rule_opt[k]->element, xml_url) == 0) { + url = loadmemory(url, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element, xml_compiled)==0) - { + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_url_pcre2) == 0) { + url_pcre2 = + loadmemory(url_pcre2, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_compiled) == 0) { int it_id = 0; - while(compiled_rules_name[it_id]) - { - if(strcmp(compiled_rules_name[it_id], - rule_opt[k]->content) == 0) + while (compiled_rules_name[it_id]) { + if (strcmp(compiled_rules_name[it_id], + rule_opt[k]->content) == 0) { break; + } it_id++; } - /* checking if the name is valid. */ - if(!compiled_rules_name[it_id]) - { - merror("%s: ERROR: Compiled rule not found: '%s'", - ARGV0, rule_opt[k]->content); - merror(INVALID_CONFIG, ARGV0, + /* Checking if the name is valid */ + if (!compiled_rules_name[it_id]) { + merror("%s: ERROR: Compiled rule not found: '%s'", + ARGV0, rule_opt[k]->content); + merror(INVALID_CONFIG, ARGV0, rule_opt[k]->element, rule_opt[k]->content); - return(-1); + return (-1); } - config_ruleinfo->compiled_rule = compiled_rules_list[it_id]; - if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + config_ruleinfo->compiled_rule = (void *(*)(void *)) compiled_rules_list[it_id]; + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } } - /* We allow these four categories so far */ - else if(strcasecmp(rule_opt[k]->element, xml_category)==0) - { - if(strcmp(rule_opt[k]->content, "firewall") == 0) - { + else if (strcasecmp(rule_opt[k]->element, xml_category) == 0) { + if (strcmp(rule_opt[k]->content, "firewall") == 0) { config_ruleinfo->category = FIREWALL; - } - else if(strcmp(rule_opt[k]->content, "ids") == 0) - { + } else if (strcmp(rule_opt[k]->content, "ids") == 0) { config_ruleinfo->category = IDS; - } - else if(strcmp(rule_opt[k]->content, "syslog") == 0) - { + } else if (strcmp(rule_opt[k]->content, "syslog") == 0) { config_ruleinfo->category = SYSLOG; - } - else if(strcmp(rule_opt[k]->content, "web-log") == 0) - { + } else if (strcmp(rule_opt[k]->content, "web-log") == 0) { config_ruleinfo->category = WEBLOG; - } - else if(strcmp(rule_opt[k]->content, "squid") == 0) - { + } else if (strcmp(rule_opt[k]->content, "squid") == 0) { config_ruleinfo->category = SQUID; - } - else if(strcmp(rule_opt[k]->content,"windows") == 0) - { - config_ruleinfo->category = WINDOWS; - } - else if(strcmp(rule_opt[k]->content,"ossec") == 0) - { + } else if (strcmp(rule_opt[k]->content, "windows") == 0) { + config_ruleinfo->category = DECODER_WINDOWS; + } else if (strcmp(rule_opt[k]->content, "ossec") == 0) { config_ruleinfo->category = OSSEC_RL; - } - else - { + } else { merror(INVALID_CAT, ARGV0, rule_opt[k]->content); - return(-1); + return (-1); } - } - else if(strcasecmp(rule_opt[k]->element,xml_if_sid)==0) - { - config_ruleinfo->if_sid= + } else if (strcasecmp(rule_opt[k]->element, xml_if_sid) == 0) { + config_ruleinfo->if_sid = loadmemory(config_ruleinfo->if_sid, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element,xml_if_level)==0) - { - if(!OS_StrIsNum(rule_opt[k]->content)) - { - merror(INVALID_CONFIG, ARGV0, - "if_level", - rule_opt[k]->content); - return(-1); + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_if_level) == 0) { + if (!OS_StrIsNum(rule_opt[k]->content)) { + merror(INVALID_CONFIG, ARGV0, + "if_level", + rule_opt[k]->content); + return (-1); } - config_ruleinfo->if_level= + config_ruleinfo->if_level = loadmemory(config_ruleinfo->if_level, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element,xml_if_group)==0) - { - config_ruleinfo->if_group= + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_if_group) == 0) { + config_ruleinfo->if_group = loadmemory(config_ruleinfo->if_group, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element, - xml_if_matched_regex) == 0) - { + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, + xml_if_matched_regex) == 0) { config_ruleinfo->context = 1; - if_matched_regex= + if_matched_regex = loadmemory(if_matched_regex, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element, - xml_if_matched_group) == 0) - { + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, + xml_if_matched_group) == 0) { config_ruleinfo->context = 1; - if_matched_group= + if_matched_group = loadmemory(if_matched_group, - rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element, - xml_if_matched_sid) == 0) - { + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, + xml_if_matched_sid) == 0) { config_ruleinfo->context = 1; - if(!OS_StrIsNum(rule_opt[k]->content)) - { + if (!OS_StrIsNum(rule_opt[k]->content)) { merror(INVALID_CONFIG, ARGV0, - "if_matched_sid", - rule_opt[k]->content); - return(-1); + "if_matched_sid", + rule_opt[k]->content); + return (-1); } - config_ruleinfo->if_matched_sid = + config_ruleinfo->if_matched_sid = atoi(rule_opt[k]->content); - } - else if(strcasecmp(rule_opt[k]->element, - xml_same_source_ip)==0) - { - config_ruleinfo->context_opts|= SAME_SRCIP; - } - else if(strcasecmp(rule_opt[k]->element, - xml_same_src_port)==0) - { - config_ruleinfo->context_opts|= SAME_SRCPORT; - - if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) + } else if (strcasecmp(rule_opt[k]->element, + xml_same_source_ip) == 0) { + config_ruleinfo->context_opts |= SAME_SRCIP; + } else if (strcasecmp(rule_opt[k]->element, + xml_same_src_port) == 0) { + config_ruleinfo->context_opts |= SAME_SRCPORT; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { config_ruleinfo->alert_opts |= SAME_EXTRAINFO; - } - else if(strcasecmp(rule_opt[k]->element, - xml_same_dst_port) == 0) - { - config_ruleinfo->context_opts|= SAME_DSTPORT; - + } + } else if (strcasecmp(rule_opt[k]->element, + xml_dodiff) == 0) { + config_ruleinfo->context = 1; + config_ruleinfo->context_opts |= SAME_DODIFF; + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_same_dst_port) == 0) { + config_ruleinfo->context_opts |= SAME_DSTPORT; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_notsame_source_ip) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_SRCIP; + } else if (strcmp(rule_opt[k]->element, xml_same_id) == 0) { + config_ruleinfo->context_opts |= SAME_ID; + } else if (strcmp(rule_opt[k]->element, + xml_different_url) == 0) { + config_ruleinfo->context_opts |= DIFFERENT_URL; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if(strcmp(rule_opt[k]->element, + xml_different_srcip) == 0) { + config_ruleinfo->context_opts|= DIFFERENT_SRCIP; + if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) config_ruleinfo->alert_opts |= SAME_EXTRAINFO; - } - else if(strcasecmp(rule_opt[k]->element, - xml_notsame_source_ip)==0) - { - config_ruleinfo->context_opts&= NOT_SAME_SRCIP; - } - else if(strcmp(rule_opt[k]->element, xml_same_id) == 0) - { - config_ruleinfo->context_opts|= SAME_ID; - } - else if(strcmp(rule_opt[k]->element, - xml_different_url) == 0) - { - config_ruleinfo->context_opts|= DIFFERENT_URL; - + } else if(strcmp(rule_opt[k]->element, + xml_different_srcgeoip) == 0) { + config_ruleinfo->context_opts|= DIFFERENT_SRCGEOIP; + if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) config_ruleinfo->alert_opts |= SAME_EXTRAINFO; - } - else if(strcmp(rule_opt[k]->element,xml_notsame_id) == 0) - { - config_ruleinfo->context_opts&= NOT_SAME_ID; - } - else if(strcasecmp(rule_opt[k]->element, - xml_fts) == 0) - { + } else if (strcmp(rule_opt[k]->element, xml_notsame_id) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_ID; + } else if (strcasecmp(rule_opt[k]->element, + xml_fts) == 0) { config_ruleinfo->alert_opts |= DO_FTS; - } - else if(strcasecmp(rule_opt[k]->element, - xml_same_user)==0) - { - config_ruleinfo->context_opts|= SAME_USER; - - if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) + } else if (strcasecmp(rule_opt[k]->element, + xml_same_user) == 0) { + config_ruleinfo->context_opts |= SAME_USER; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { config_ruleinfo->alert_opts |= SAME_EXTRAINFO; - } - else if(strcasecmp(rule_opt[k]->element, - xml_notsame_user)==0) - { - config_ruleinfo->context_opts&= NOT_SAME_USER; - } - else if(strcasecmp(rule_opt[k]->element, - xml_same_location)==0) - { - config_ruleinfo->context_opts|= SAME_LOCATION; - if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) + } + } else if (strcasecmp(rule_opt[k]->element, + xml_notsame_user) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_USER; + } else if (strcasecmp(rule_opt[k]->element, + xml_same_location) == 0) { + config_ruleinfo->context_opts |= SAME_LOCATION; + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { config_ruleinfo->alert_opts |= SAME_EXTRAINFO; - } - else if(strcasecmp(rule_opt[k]->element, - xml_notsame_agent)==0) - { - config_ruleinfo->context_opts&= NOT_SAME_AGENT; - } - else if(strcasecmp(rule_opt[k]->element, - xml_options) == 0) - { - if(strcmp("alert_by_email", - rule_opt[k]->content) == 0) - { - if(!(config_ruleinfo->alert_opts & DO_MAILALERT)) - { - config_ruleinfo->alert_opts|= DO_MAILALERT; - } } - else if(strcmp("no_email_alert", - rule_opt[k]->content) == 0) - { - if(config_ruleinfo->alert_opts & DO_MAILALERT) - { - config_ruleinfo->alert_opts&=0xfff-DO_MAILALERT; + } else if (strcasecmp(rule_opt[k]->element, + xml_notsame_agent) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_AGENT; + } else if (strcasecmp(rule_opt[k]->element, + xml_options) == 0) { + if (strcmp("alert_by_email", + rule_opt[k]->content) == 0) { + if (!(config_ruleinfo->alert_opts & DO_MAILALERT)) { + config_ruleinfo->alert_opts |= DO_MAILALERT; } - } - else if(strcmp("log_alert", - rule_opt[k]->content) == 0) - { - if(!(config_ruleinfo->alert_opts & DO_LOGALERT)) - { - config_ruleinfo->alert_opts|= DO_LOGALERT; + } else if (strcmp("no_email_alert", + rule_opt[k]->content) == 0) { + if (config_ruleinfo->alert_opts & DO_MAILALERT) { + config_ruleinfo->alert_opts &= 0xfff - DO_MAILALERT; } - } - else if(strcmp("no_log", rule_opt[k]->content) == 0) - { - if(config_ruleinfo->alert_opts & DO_LOGALERT) - { - config_ruleinfo->alert_opts &=0xfff-DO_LOGALERT; + } else if (strcmp("log_alert", + rule_opt[k]->content) == 0) { + if (!(config_ruleinfo->alert_opts & DO_LOGALERT)) { + config_ruleinfo->alert_opts |= DO_LOGALERT; } - } - else - { + } else if (strcmp("no_log", rule_opt[k]->content) == 0) { + if (config_ruleinfo->alert_opts & DO_LOGALERT) { + config_ruleinfo->alert_opts &= 0xfff - DO_LOGALERT; + } + } else if (strcmp("no_ar", rule_opt[k]->content) == 0) { + if (!(config_ruleinfo->alert_opts & NO_AR)) { + config_ruleinfo->alert_opts |= NO_AR; + } + } else { merror(XML_VALUEERR, ARGV0, xml_options, - rule_opt[k]->content); + rule_opt[k]->content); merror("%s: Invalid option '%s' for " - "rule '%d'.",ARGV0, rule_opt[k]->element, + "rule '%d'.", ARGV0, rule_opt[k]->element, config_ruleinfo->sigid); OS_ClearXML(&xml); - return(-1); - } - } - else if(strcasecmp(rule_opt[k]->element, - xml_ignore) == 0) - { - if(strstr(rule_opt[k]->content, "user") != NULL) - { - config_ruleinfo->ignore|=FTS_DSTUSER; + return (-1); } - if(strstr(rule_opt[k]->content, "srcip") != NULL) - { - config_ruleinfo->ignore|=FTS_SRCIP; + } else if (strcasecmp(rule_opt[k]->element, + xml_ignore) == 0) { + if (strstr(rule_opt[k]->content, "user") != NULL) { + config_ruleinfo->ignore |= FTS_DSTUSER; } - if(strstr(rule_opt[k]->content, "dstip") != NULL) - { - config_ruleinfo->ignore|=FTS_DSTIP; + if (strstr(rule_opt[k]->content, "srcip") != NULL) { + config_ruleinfo->ignore |= FTS_SRCIP; } - if(strstr(rule_opt[k]->content, "id") != NULL) - { - config_ruleinfo->ignore|=FTS_ID; + if (strstr(rule_opt[k]->content, "dstip") != NULL) { + config_ruleinfo->ignore |= FTS_DSTIP; } - if(strstr(rule_opt[k]->content,"location")!= NULL) - { - config_ruleinfo->ignore|=FTS_LOCATION; + if (strstr(rule_opt[k]->content, "id") != NULL) { + config_ruleinfo->ignore |= FTS_ID; } - if(strstr(rule_opt[k]->content,"data")!= NULL) - { - config_ruleinfo->ignore|=FTS_DATA; + if (strstr(rule_opt[k]->content, "location") != NULL) { + config_ruleinfo->ignore |= FTS_LOCATION; } - if(strstr(rule_opt[k]->content, "name") != NULL) - { - config_ruleinfo->ignore|=FTS_NAME; + if (strstr(rule_opt[k]->content, "data") != NULL) { + config_ruleinfo->ignore |= FTS_DATA; + } + if (strstr(rule_opt[k]->content, "name") != NULL) { + config_ruleinfo->ignore |= FTS_NAME; } - if(!config_ruleinfo->ignore) - { - merror("%s: Wrong ignore option: '%s'", - ARGV0, - rule_opt[k]->content); - return(-1); + if (!config_ruleinfo->ignore) { + merror("%s: Wrong ignore option: '%s'", + ARGV0, + rule_opt[k]->content); + return (-1); } - } - else if(strcasecmp(rule_opt[k]->element, - xml_check_if_ignored) == 0) - { - if(strstr(rule_opt[k]->content, "user") != NULL) - { - config_ruleinfo->ckignore|=FTS_DSTUSER; + } else if (strcasecmp(rule_opt[k]->element, + xml_check_if_ignored) == 0) { + if (strstr(rule_opt[k]->content, "user") != NULL) { + config_ruleinfo->ckignore |= FTS_DSTUSER; } - if(strstr(rule_opt[k]->content, "srcip") != NULL) - { - config_ruleinfo->ckignore|=FTS_SRCIP; + if (strstr(rule_opt[k]->content, "srcip") != NULL) { + config_ruleinfo->ckignore |= FTS_SRCIP; } - if(strstr(rule_opt[k]->content, "dstip") != NULL) - { - config_ruleinfo->ckignore|=FTS_DSTIP; + if (strstr(rule_opt[k]->content, "dstip") != NULL) { + config_ruleinfo->ckignore |= FTS_DSTIP; } - if(strstr(rule_opt[k]->content, "id") != NULL) - { - config_ruleinfo->ckignore|=FTS_ID; + if (strstr(rule_opt[k]->content, "id") != NULL) { + config_ruleinfo->ckignore |= FTS_ID; } - if(strstr(rule_opt[k]->content,"location")!= NULL) - { - config_ruleinfo->ckignore|=FTS_LOCATION; + if (strstr(rule_opt[k]->content, "location") != NULL) { + config_ruleinfo->ckignore |= FTS_LOCATION; } - if(strstr(rule_opt[k]->content,"data")!= NULL) - { - config_ruleinfo->ignore|=FTS_DATA; + if (strstr(rule_opt[k]->content, "data") != NULL) { + config_ruleinfo->ckignore |= FTS_DATA; } - if(strstr(rule_opt[k]->content, "name") != NULL) - { - config_ruleinfo->ckignore|=FTS_NAME; + if (strstr(rule_opt[k]->content, "name") != NULL) { + config_ruleinfo->ckignore |= FTS_NAME; } - if(!config_ruleinfo->ckignore) - { - merror("%s: Wrong check_if_ignored option: '%s'", - ARGV0, - rule_opt[k]->content); - return(-1); + if (!config_ruleinfo->ckignore) { + merror("%s: Wrong check_if_ignored option: '%s'", + ARGV0, + rule_opt[k]->content); + return (-1); } - } - else - { + } else { merror("%s: Invalid option '%s' for " - "rule '%d'.",ARGV0, rule_opt[k]->element, - config_ruleinfo->sigid); + "rule '%d'.", ARGV0, rule_opt[k]->element, + config_ruleinfo->sigid); OS_ClearXML(&xml); - return(-1); + return (-1); } k++; } - - /* Checking for a valid use of frequency */ - if((config_ruleinfo->context_opts || - config_ruleinfo->frequency) && - !config_ruleinfo->context) - { + /* Check for valid use of frequency */ + if ((config_ruleinfo->context_opts || + config_ruleinfo->frequency) && + !config_ruleinfo->context) { merror("%s: Invalid use of frequency/context options. " "Missing if_matched on rule '%d'.", ARGV0, config_ruleinfo->sigid); OS_ClearXML(&xml); - return(-1); + return (-1); } - /* If if_matched_group we must have a if_sid or if_group */ - if(if_matched_group) - { - if(!config_ruleinfo->if_sid && !config_ruleinfo->if_group) - { - os_strdup(if_matched_group, - config_ruleinfo->if_group); + if (if_matched_group) { + if (!config_ruleinfo->if_sid && !config_ruleinfo->if_group) { + os_strdup(if_matched_group, + config_ruleinfo->if_group); } } /* If_matched_sid, we need to get the if_sid */ - if(config_ruleinfo->if_matched_sid && - !config_ruleinfo->if_sid && - !config_ruleinfo->if_group) - { + if (config_ruleinfo->if_matched_sid && + !config_ruleinfo->if_sid && + !config_ruleinfo->if_group) { os_calloc(16, sizeof(char), config_ruleinfo->if_sid); - snprintf(config_ruleinfo->if_sid, 15, "%d", + snprintf(config_ruleinfo->if_sid, 15, "%d", config_ruleinfo->if_matched_sid); } - - /* Checking the regexes */ - if(regex) - { + + /* Check the regexes */ + if (regex) { os_calloc(1, sizeof(OSRegex), config_ruleinfo->regex); - if(!OSRegex_Compile(regex, config_ruleinfo->regex, 0)) - { - merror(REGEX_COMPILE, ARGV0, regex, - config_ruleinfo->regex->error); - return(-1); + if (!OSRegex_Compile(regex, config_ruleinfo->regex, 0)) { + merror(REGEX_COMPILE, ARGV0, regex, + config_ruleinfo->regex->error); + return (-1); } free(regex); regex = NULL; } - - /* Adding in match */ - if(match) - { + + if (pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->pcre2); + if (!OSPcre2_Compile(pcre2, config_ruleinfo->pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, pcre2, + config_ruleinfo->pcre2->error); + return (-1); + } + free(pcre2); + pcre2 = NULL; + } + + /* Add in match */ + if (match) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->match); - if(!OSMatch_Compile(match, config_ruleinfo->match, 0)) - { + if (!OSMatch_Compile(match, config_ruleinfo->match, 0)) { merror(REGEX_COMPILE, ARGV0, match, - config_ruleinfo->match->error); - return(-1); + config_ruleinfo->match->error); + return (-1); } free(match); match = NULL; } - - /* Adding in id */ - if(id) - { + else if (match_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->match_pcre2); + if (!OSPcre2_Compile(match_pcre2, config_ruleinfo->match_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, match_pcre2, + config_ruleinfo->match_pcre2->error); + return (-1); + } + free(match_pcre2); + match_pcre2 = NULL; + } + + /* Add in id */ + if (id) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->id); - if(!OSMatch_Compile(id, config_ruleinfo->id, 0)) - { - merror(REGEX_COMPILE, ARGV0, id, - config_ruleinfo->id->error); - return(-1); + if (!OSMatch_Compile(id, config_ruleinfo->id, 0)) { + merror(REGEX_COMPILE, ARGV0, id, + config_ruleinfo->id->error); + return (-1); } free(id); id = NULL; } + if (id_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->id_pcre2); + if (!OSPcre2_Compile(id_pcre2, config_ruleinfo->id_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, id, + config_ruleinfo->id_pcre2->error); + return (-1); + } + free(id_pcre2); + id_pcre2 = NULL; + } - /* Adding srcport */ - if(srcport) - { + /* Add srcport */ + if (srcport) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->srcport); - if(!OSMatch_Compile(srcport, config_ruleinfo->srcport, 0)) - { - merror(REGEX_COMPILE, ARGV0, srcport, - config_ruleinfo->id->error); - return(-1); + if (!OSMatch_Compile(srcport, config_ruleinfo->srcport, 0)) { + merror(REGEX_COMPILE, ARGV0, srcport, + config_ruleinfo->id->error); + return (-1); } free(srcport); srcport = NULL; } + if (srcport_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->srcport_pcre2); + if (!OSPcre2_Compile(srcport_pcre2, config_ruleinfo->srcport_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, srcport_pcre2, + config_ruleinfo->id->error); + return (-1); + } + free(srcport_pcre2); + srcport_pcre2 = NULL; + } - /* Adding dstport */ - if(dstport) - { + /* Add dstport */ + if (dstport) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->dstport); - if(!OSMatch_Compile(dstport, config_ruleinfo->dstport, 0)) - { - merror(REGEX_COMPILE, ARGV0, dstport, - config_ruleinfo->id->error); - return(-1); + if (!OSMatch_Compile(dstport, config_ruleinfo->dstport, 0)) { + merror(REGEX_COMPILE, ARGV0, dstport, + config_ruleinfo->id->error); + return (-1); } free(dstport); dstport = NULL; } + else if (dstport_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->dstport_pcre2); + if (!OSPcre2_Compile(dstport_pcre2, config_ruleinfo->dstport_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, dstport_pcre2, + config_ruleinfo->id->error); + return (-1); + } + free(dstport_pcre2); + dstport_pcre2 = NULL; + } - /* Adding in status */ - if(status) - { + /* Add in status */ + if (status) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->status); - if(!OSMatch_Compile(status, config_ruleinfo->status, 0)) - { + if (!OSMatch_Compile(status, config_ruleinfo->status, 0)) { merror(REGEX_COMPILE, ARGV0, status, - config_ruleinfo->status->error); - return(-1); + config_ruleinfo->status->error); + return (-1); } free(status); status = NULL; } + else if (status_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->status_pcre2); + if (!OSPcre2_Compile(status_pcre2, config_ruleinfo->status_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, status_pcre2, + config_ruleinfo->status_pcre2->error); + return (-1); + } + free(status_pcre2); + status_pcre2 = NULL; + } - /* Adding in hostname */ - if(hostname) - { + /* Add in hostname */ + if (hostname) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->hostname); - if(!OSMatch_Compile(hostname, config_ruleinfo->hostname,0)) - { + if (!OSMatch_Compile(hostname, config_ruleinfo->hostname, 0)) { merror(REGEX_COMPILE, ARGV0, hostname, - config_ruleinfo->hostname->error); - return(-1); + config_ruleinfo->hostname->error); + return (-1); } free(hostname); hostname = NULL; } + else if (hostname_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->hostname_pcre2); + if (!OSPcre2_Compile(hostname_pcre2, config_ruleinfo->hostname_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, hostname_pcre2, + config_ruleinfo->hostname_pcre2->error); + return (-1); + } + free(hostname_pcre2); + hostname_pcre2 = NULL; + } - /* Adding extra data */ - if(extra_data) - { + /* Add extra data */ + if (extra_data) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->extra_data); - if(!OSMatch_Compile(extra_data, - config_ruleinfo->extra_data, 0)) - { + if (!OSMatch_Compile(extra_data, + config_ruleinfo->extra_data, 0)) { merror(REGEX_COMPILE, ARGV0, extra_data, - config_ruleinfo->extra_data->error); - return(-1); + config_ruleinfo->extra_data->error); + return (-1); } free(extra_data); extra_data = NULL; } + else if (extra_data_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->extra_data_pcre2); + if (!OSPcre2_Compile(extra_data_pcre2, + config_ruleinfo->extra_data_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, extra_data_pcre2, + config_ruleinfo->extra_data_pcre2->error); + return (-1); + } + free(extra_data_pcre2); + extra_data_pcre2 = NULL; + } - /* Adding in program name */ - if(program_name) - { - os_calloc(1,sizeof(OSMatch),config_ruleinfo->program_name); - if(!OSMatch_Compile(program_name, - config_ruleinfo->program_name,0)) - { + /* Add in program name */ + if (program_name) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->program_name); + if (!OSMatch_Compile(program_name, + config_ruleinfo->program_name, 0)) { merror(REGEX_COMPILE, ARGV0, program_name, - config_ruleinfo->program_name->error); - return(-1); + config_ruleinfo->program_name->error); + return (-1); } free(program_name); program_name = NULL; } - - /* Adding in user */ - if(user) - { + else if (program_name_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->program_name_pcre2); + if (!OSPcre2_Compile(program_name_pcre2, + config_ruleinfo->program_name_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, program_name_pcre2, + config_ruleinfo->program_name_pcre2->error); + return (-1); + } + free(program_name_pcre2); + program_name_pcre2 = NULL; + } + + /* Add in user */ + if (user) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->user); - if(!OSMatch_Compile(user, config_ruleinfo->user, 0)) - { + if (!OSMatch_Compile(user, config_ruleinfo->user, 0)) { merror(REGEX_COMPILE, ARGV0, user, - config_ruleinfo->user->error); - return(-1); + config_ruleinfo->user->error); + return (-1); } free(user); user = NULL; } - - /* Adding in url */ - if(url) - { - os_calloc(1, sizeof(OSMatch), config_ruleinfo->url); - if(!OSMatch_Compile(url, config_ruleinfo->url, 0)) - { - merror(REGEX_COMPILE, ARGV0, url, - config_ruleinfo->url->error); + else if (user_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->user_pcre2); + if (!OSPcre2_Compile(user_pcre2, config_ruleinfo->user_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, user_pcre2, + config_ruleinfo->user_pcre2->error); + return (-1); + } + free(user_pcre2); + user_pcre2 = NULL; + } + + /* Adding in srcgeoip */ + if(srcgeoip) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->srcgeoip); + if(!OSMatch_Compile(srcgeoip, config_ruleinfo->srcgeoip, 0)) { + merror(REGEX_COMPILE, ARGV0, srcgeoip, + config_ruleinfo->srcgeoip->error); return(-1); } + free(srcgeoip); + srcgeoip = NULL; + } + else if(srcgeoip_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->srcgeoip_pcre2); + if(!OSPcre2_Compile(srcgeoip_pcre2, config_ruleinfo->srcgeoip_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, srcgeoip_pcre2, + config_ruleinfo->srcgeoip_pcre2->error); + return(-1); + } + free(srcgeoip_pcre2); + srcgeoip_pcre2 = NULL; + } + + + /* Adding in dstgeoip */ + if(dstgeoip) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->dstgeoip); + if(!OSMatch_Compile(dstgeoip, config_ruleinfo->dstgeoip, 0)) { + merror(REGEX_COMPILE, ARGV0, dstgeoip, + config_ruleinfo->dstgeoip->error); + return(-1); + } + free(dstgeoip); + dstgeoip = NULL; + } + else if(dstgeoip_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->dstgeoip_pcre2); + if(!OSPcre2_Compile(dstgeoip_pcre2, config_ruleinfo->dstgeoip_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, dstgeoip_pcre2, + config_ruleinfo->dstgeoip_pcre2->error); + return(-1); + } + free(dstgeoip_pcre2); + dstgeoip_pcre2 = NULL; + } + + + /* Add in URL */ + if (url) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->url); + if (!OSMatch_Compile(url, config_ruleinfo->url, 0)) { + merror(REGEX_COMPILE, ARGV0, url, + config_ruleinfo->url->error); + return (-1); + } free(url); url = NULL; } - - /* Adding matched_group */ - if(if_matched_group) - { - os_calloc(1, sizeof(OSMatch), - config_ruleinfo->if_matched_group); - - if(!OSMatch_Compile(if_matched_group, - config_ruleinfo->if_matched_group, - 0)) - { + else if (url_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->url_pcre2); + if (!OSPcre2_Compile(url_pcre2, config_ruleinfo->url_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, url_pcre2, + config_ruleinfo->url_pcre2->error); + return (-1); + } + free(url_pcre2); + url_pcre2 = NULL; + } + + /* Add matched_group */ + if (if_matched_group) { + os_calloc(1, sizeof(OSMatch), + config_ruleinfo->if_matched_group); + + if (!OSMatch_Compile(if_matched_group, + config_ruleinfo->if_matched_group, + 0)) { merror(REGEX_COMPILE, ARGV0, if_matched_group, - config_ruleinfo->if_matched_group->error); - return(-1); + config_ruleinfo->if_matched_group->error); + return (-1); } free(if_matched_group); if_matched_group = NULL; } - - /* Adding matched_regex */ - if(if_matched_regex) - { - os_calloc(1, sizeof(OSRegex), - config_ruleinfo->if_matched_regex); - if(!OSRegex_Compile(if_matched_regex, - config_ruleinfo->if_matched_regex, 0)) - { - merror(REGEX_COMPILE, ARGV0, if_matched_regex, - config_ruleinfo->if_matched_regex->error); - return(-1); + + /* Add matched_regex */ + if (if_matched_regex) { + os_calloc(1, sizeof(OSRegex), + config_ruleinfo->if_matched_regex); + if (!OSRegex_Compile(if_matched_regex, + config_ruleinfo->if_matched_regex, 0)) { + merror(REGEX_COMPILE, ARGV0, if_matched_regex, + config_ruleinfo->if_matched_regex->error); + return (-1); } free(if_matched_regex); if_matched_regex = NULL; } - } /* enf of elements block */ + OS_ClearNode(rule_opt); + } /* end of elements block */ - - /* Assigning an active response to the rule */ + /* Assign an active response to the rule */ Rule_AddAR(config_ruleinfo); j++; /* next rule */ - - /* Creating the last_events if necessary */ - if(config_ruleinfo->context) - { + /* Create the last_events if necessary */ + if (config_ruleinfo->context) { int ii = 0; - os_calloc(MAX_LAST_EVENTS + 1, sizeof(char *), + os_calloc(MAX_LAST_EVENTS + 1, sizeof(char *), config_ruleinfo->last_events); - - /* Zeroing each entry */ - for(;ii<=MAX_LAST_EVENTS;ii++) - { + + /* Zero each entry */ + for (; ii <= MAX_LAST_EVENTS; ii++) { config_ruleinfo->last_events[ii] = NULL; } } - - /* Adding the rule to the rules list. + /* Add the rule to the rules list. * Only the template rules are supposed * to be at the top level. All others * will be a "child" of someone. */ - if(config_ruleinfo->sigid < 10) - { + if (config_ruleinfo->sigid < 10) { OS_AddRule(config_ruleinfo); - } - else if(config_ruleinfo->alert_opts & DO_OVERWRITE) - { - if(!OS_AddRuleInfo(NULL, config_ruleinfo, - config_ruleinfo->sigid)) - { + } else if (config_ruleinfo->alert_opts & DO_OVERWRITE) { + if (!OS_AddRuleInfo(NULL, config_ruleinfo, + config_ruleinfo->sigid)) { merror("%s: Overwrite rule '%d' not found.", - ARGV0, config_ruleinfo->sigid); + ARGV0, config_ruleinfo->sigid); OS_ClearXML(&xml); - return(-1); + return (-1); } - } - else - { + } else { OS_AddChild(config_ruleinfo); } - /* Cleaning what we do not need */ - if(config_ruleinfo->if_group) - { + /* Clean what we do not need */ + if (config_ruleinfo->if_group) { free(config_ruleinfo->if_group); config_ruleinfo->if_group = NULL; } - /* Setting the event_search pointer */ - if(config_ruleinfo->if_matched_sid) - { - config_ruleinfo->event_search = - (void *)Search_LastSids; - - /* Marking rules that match this id */ - OS_MarkID(NULL, config_ruleinfo); + /* Set the event_search pointer */ + if (config_ruleinfo->if_matched_sid) { + config_ruleinfo->event_search = (void *(*)(void *, void *)) + Search_LastSids; + + /* Mark rules that match this id */ + OS_MarkID(NULL, config_ruleinfo); } - - /* Marking the rules that match if_matched_group */ - else if(config_ruleinfo->if_matched_group) - { - /* Creating list */ + + /* Mark the rules that match if_matched_group */ + else if (config_ruleinfo->if_matched_group) { + /* Create list */ config_ruleinfo->group_search = OSList_Create(); - if(!config_ruleinfo->group_search) - { - ErrorExit(MEM_ERROR, ARGV0); + if (!config_ruleinfo->group_search) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); } - /* Marking rules that match this group */ + /* Mark rules that match this group */ OS_MarkGroup(NULL, config_ruleinfo); - /* Setting function pointer */ - config_ruleinfo->event_search = - (void *)Search_LastGroups; - } - else if(config_ruleinfo->context) - { - config_ruleinfo->event_search = - (void *)Search_LastEvents; + /* Set function pointer */ + config_ruleinfo->event_search = (void *(*)(void *, void *)) + Search_LastGroups; + } else if (config_ruleinfo->context) { + if ((config_ruleinfo->context == 1) && + (config_ruleinfo->context_opts & SAME_DODIFF)) { + config_ruleinfo->context = 0; + } else { + config_ruleinfo->event_search = (void *(*)(void *, void *)) + Search_LastEvents; + } } } /* while(rule[j]) */ OS_ClearNode(rule); i++; - + } /* while (node[i]) */ - /* Cleaning global node */ + /* Clean global node */ OS_ClearNode(node); OS_ClearXML(&xml); - #ifdef DEBUG +#ifdef DEBUG { RuleNode *dbg_node = OS_GetFirstRule(); - while(dbg_node) - { - if(dbg_node->child) - { + while (dbg_node) { + if (dbg_node->child) { RuleNode *child_node = dbg_node->child; - printf("** Child Node for %d **\n",dbg_node->ruleinfo->sigid); - while(child_node) - { + printf("** Child Node for %d **\n", dbg_node->ruleinfo->sigid); + while (child_node) { child_node = child_node->next; } } dbg_node = dbg_node->next; } } - #endif +#endif /* Done over here */ - return(0); + return (0); } - -/* loadmemory: v0.1 - * Allocate memory at "*at" and copy *str to it. - * If *at already exist, realloc the memory and cat str - * on it. - * It will return the new string +/* Allocate memory at "*at" and copy *str to it. + * If *at already exist, realloc the memory and cat str on it. + * Returns the new string */ -char *loadmemory(char *at, char *str) +static char *loadmemory(char *at, const char *str) { - if(at == NULL) - { - int strsize = 0; - if((strsize = strlen(str)) < OS_SIZE_2048) - { - at = calloc(strsize+1,sizeof(char)); - if(at == NULL) - { - merror(MEM_ERROR,ARGV0); - return(NULL); + if (at == NULL) { + size_t strsize = 0; + if ((strsize = strlen(str)) < OS_SIZE_2048) { + at = (char *) calloc(strsize + 1, sizeof(char)); + if (at == NULL) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (NULL); } - strncpy(at,str,strsize); - return(at); - } - else - { - merror(SIZE_ERROR,ARGV0,str); - return(NULL); + strncpy(at, str, strsize); + return (at); + } else { + merror(SIZE_ERROR, ARGV0, str); + return (NULL); } - } - else /*at is not null. Need to reallocat its memory and copy str to it*/ - { - int strsize = strlen(str); - int atsize = strlen(at); - int finalsize = atsize+strsize+1; - - if((atsize > OS_SIZE_2048) || (strsize > OS_SIZE_2048)) - { - merror(SIZE_ERROR,ARGV0,str); - return(NULL); + } else { + /* at is not null. Need to reallocate its memory and copy str to it */ + size_t strsize = strlen(str); + size_t atsize = strlen(at); + size_t finalsize = atsize + strsize + 1; + + if ((atsize > OS_SIZE_2048) || (strsize > OS_SIZE_2048)) { + merror(SIZE_ERROR, ARGV0, str); + return (NULL); } - - at = realloc(at, (finalsize)*sizeof(char)); - - if(at == NULL) - { - merror(MEM_ERROR,ARGV0); - return(NULL); + + at = (char *) realloc(at, (finalsize) * sizeof(char)); + + if (at == NULL) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (NULL); } - - strncat(at,str,strsize); - - at[finalsize-1]='\0'; - - return(at); + + strncat(at, str, strsize); + at[finalsize - 1] = '\0'; + + return (at); } - return(NULL); + return (NULL); } +RuleInfoDetail *zeroinfodetails(int type, const char *data) +{ + RuleInfoDetail *info_details_pt = NULL; + + info_details_pt = (RuleInfoDetail *)calloc(1, sizeof(RuleInfoDetail)); + + if (info_details_pt == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + info_details_pt->type = type; + os_strdup(data, info_details_pt->data); + info_details_pt->next = NULL; -RuleInfo *zerorulemember(int id, int level, + return (info_details_pt); +} + +RuleInfo *zerorulemember(int id, int level, int maxsize, int frequency, - int timeframe, int noalert, + int timeframe, int noalert, int ignore_time, int overwrite) { RuleInfo *ruleinfo_pt = NULL; - - /* Allocation memory for structure */ - ruleinfo_pt = (RuleInfo *)calloc(1,sizeof(RuleInfo)); - if(ruleinfo_pt == NULL) - { - ErrorExit(MEM_ERROR,ARGV0); + /* Allocate memory for structure */ + ruleinfo_pt = (RuleInfo *)calloc(1, sizeof(RuleInfo)); + + if (ruleinfo_pt == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); } - + /* Default values */ ruleinfo_pt->level = level; /* Default category is syslog */ ruleinfo_pt->category = SYSLOG; - ruleinfo_pt->ar = NULL; - + ruleinfo_pt->ar = NULL; + ruleinfo_pt->context = 0; - + ruleinfo_pt->sigid = id; ruleinfo_pt->firedtimes = 0; ruleinfo_pt->maxsize = maxsize; ruleinfo_pt->frequency = frequency; - if(ruleinfo_pt->frequency > _max_freq) - { + if (ruleinfo_pt->frequency > _max_freq) { _max_freq = ruleinfo_pt->frequency; } ruleinfo_pt->ignore_time = ignore_time; ruleinfo_pt->timeframe = timeframe; ruleinfo_pt->time_ignored = 0; - - ruleinfo_pt->context_opts = 0; - ruleinfo_pt->alert_opts = 0; - ruleinfo_pt->ignore = 0; - ruleinfo_pt->ckignore = 0; - if(noalert) - { + ruleinfo_pt->context_opts = 0; + ruleinfo_pt->alert_opts = 0; + ruleinfo_pt->ignore = 0; + ruleinfo_pt->ckignore = 0; + + if (noalert) { ruleinfo_pt->alert_opts |= NO_ALERT; } - if(Config.mailbylevel <= level) + if (Config.mailbylevel <= level) { ruleinfo_pt->alert_opts |= DO_MAILALERT; - if(Config.logbylevel <= level) + } + if (Config.logbylevel <= level) { ruleinfo_pt->alert_opts |= DO_LOGALERT; + } - /* Overwriting a rule */ - if(overwrite) - { + /* Overwrite a rule */ + if (overwrite) { ruleinfo_pt->alert_opts |= DO_OVERWRITE; } @@ -1403,16 +1685,17 @@ RuleInfo *zerorulemember(int id, int level, ruleinfo_pt->comment = NULL; ruleinfo_pt->info = NULL; ruleinfo_pt->cve = NULL; - + ruleinfo_pt->info_details = NULL; + ruleinfo_pt->if_sid = NULL; ruleinfo_pt->if_group = NULL; ruleinfo_pt->if_level = NULL; - + ruleinfo_pt->if_matched_regex = NULL; ruleinfo_pt->if_matched_group = NULL; ruleinfo_pt->if_matched_sid = 0; - - ruleinfo_pt->user = NULL; + + ruleinfo_pt->user = NULL; ruleinfo_pt->srcip = NULL; ruleinfo_pt->srcport = NULL; ruleinfo_pt->dstip = NULL; @@ -1423,268 +1706,250 @@ RuleInfo *zerorulemember(int id, int level, ruleinfo_pt->hostname = NULL; ruleinfo_pt->program_name = NULL; ruleinfo_pt->action = NULL; - - /* Zeroing last matched events */ + os_calloc(Config.decoder_order_size, sizeof(FieldInfo*), ruleinfo_pt->fields); + + + /* Zero last matched events */ ruleinfo_pt->__frequency = 0; ruleinfo_pt->last_events = NULL; - /* zeroing the list of previous matches */ + /* Zeroing the list of previous matches */ ruleinfo_pt->sid_prev_matched = NULL; ruleinfo_pt->group_prev_matched = NULL; - + ruleinfo_pt->sid_search = NULL; ruleinfo_pt->group_search = NULL; - + ruleinfo_pt->event_search = NULL; ruleinfo_pt->compiled_rule = NULL; + ruleinfo_pt->lists = NULL; - return(ruleinfo_pt); + return (ruleinfo_pt); } +int get_info_attributes(char **attributes, char **values) +{ + const char *xml_type = "type"; + int k = 0; + + if (!attributes) { + return (RULEINFODETAIL_TEXT); + } + + while (attributes[k]) { + if (!values[k]) { + merror("rules_op: Entry info type \"%s\" does not have a value", + attributes[k]); + return (-1); + } else if (strcasecmp(attributes[k], xml_type) == 0) { + if (strcmp(values[k], "text") == 0) { + return (RULEINFODETAIL_TEXT); + } else if (strcmp(values[k], "link") == 0) { + return (RULEINFODETAIL_LINK); + } else if (strcmp(values[k], "cve") == 0) { + return (RULEINFODETAIL_CVE); + } else if (strcmp(values[k], "osvdb") == 0) { + return (RULEINFODETAIL_OSVDB); + } + } + } + return (RULEINFODETAIL_TEXT); +} /* Get the attributes */ -int getattributes(char **attributes, char **values, - int *id, int *level, +static int getattributes(char **attributes, char **values, + int *id, int *level, int *maxsize, int *timeframe, - int *frequency, int *accuracy, + int *frequency, int *accuracy, int *noalert, int *ignore_time, int *overwrite) { - int k=0; - - char *xml_id = "id"; - char *xml_level = "level"; - char *xml_maxsize = "maxsize"; - char *xml_timeframe = "timeframe"; - char *xml_frequency = "frequency"; - char *xml_accuracy = "accuracy"; - char *xml_noalert = "noalert"; - char *xml_ignore_time = "ignore"; - char *xml_overwrite = "overwrite"; - - - /* Getting attributes */ - while(attributes[k]) - { - if(!values[k]) - { + int k = 0; + + const char *xml_id = "id"; + const char *xml_level = "level"; + const char *xml_maxsize = "maxsize"; + const char *xml_timeframe = "timeframe"; + const char *xml_frequency = "frequency"; + const char *xml_accuracy = "accuracy"; + const char *xml_noalert = "noalert"; + const char *xml_ignore_time = "ignore"; + const char *xml_overwrite = "overwrite"; + + /* Get attributes */ + while (attributes[k]) { + if (!values[k]) { merror("rules_op: Attribute \"%s\" without value." - ,attributes[k]); - return(-1); + , attributes[k]); + return (-1); } - /* Getting rule Id */ - else if(strcasecmp(attributes[k],xml_id) == 0) - { - if(OS_StrIsNum(values[k])) - { - sscanf(values[k],"%6d",id); - } - else - { + /* Get rule id */ + else if (strcasecmp(attributes[k], xml_id) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%6d", id); + } else { merror("rules_op: Invalid rule id: %s. " - "Must be integer" , - values[k]); - return(-1); + "Must be integer" , + values[k]); + return (-1); } } - /* Getting level */ - else if(strcasecmp(attributes[k],xml_level) == 0) - { - if(OS_StrIsNum(values[k])) - { - sscanf(values[k],"%4d",level); - } - else - { + /* Get level */ + else if (strcasecmp(attributes[k], xml_level) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%4d", level); + } else { merror("rules_op: Invalid level: %s. " - "Must be integer" , - values[k]); - return(-1); + "Must be integer" , + values[k]); + return (-1); } } - /* Getting maxsize */ - else if(strcasecmp(attributes[k],xml_maxsize) == 0) - { - if(OS_StrIsNum(values[k])) - { - sscanf(values[k],"%4d",maxsize); - } - else - { + /* Get maxsize */ + else if (strcasecmp(attributes[k], xml_maxsize) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%4d", maxsize); + } else { merror("rules_op: Invalid maxsize: %s. " - "Must be integer" , - values[k]); - return(-1); + "Must be integer" , + values[k]); + return (-1); } } - /* Getting timeframe */ - else if(strcasecmp(attributes[k],xml_timeframe) == 0) - { - if(OS_StrIsNum(values[k])) - { - sscanf(values[k],"%5d",timeframe); - } - else - { + /* Get timeframe */ + else if (strcasecmp(attributes[k], xml_timeframe) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%5d", timeframe); + } else { merror("rules_op: Invalid timeframe: %s. " - "Must be integer" , - values[k]); - return(-1); + "Must be integer" , + values[k]); + return (-1); } } - /* Getting frequency */ - else if(strcasecmp(attributes[k],xml_frequency) == 0) - { - if(OS_StrIsNum(values[k])) - { - sscanf(values[k],"%4d",frequency); - } - else - { + /* Get frequency */ + else if (strcasecmp(attributes[k], xml_frequency) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%4d", frequency); + } else { merror("rules_op: Invalid frequency: %s. " - "Must be integer" , - values[k]); - return(-1); + "Must be integer" , + values[k]); + return (-1); } } /* Rule accuracy */ - else if(strcasecmp(attributes[k],xml_accuracy) == 0) - { - if(OS_StrIsNum(values[k])) - { - sscanf(values[k],"%4d",accuracy); - } - else - { + else if (strcasecmp(attributes[k], xml_accuracy) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%4d", accuracy); + } else { merror("rules_op: Invalid accuracy: %s. " "Must be integer" , values[k]); - return(-1); + return (-1); } } - /* Rule ignore_time */ - else if(strcasecmp(attributes[k],xml_ignore_time) == 0) - { - if(OS_StrIsNum(values[k])) - { - sscanf(values[k],"%6d",ignore_time); - } - else - { + /* Rule ignore_time */ + else if (strcasecmp(attributes[k], xml_ignore_time) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%6d", ignore_time); + } else { merror("rules_op: Invalid ignore_time: %s. " "Must be integer" , values[k]); - return(-1); + return (-1); } } /* Rule noalert */ - else if(strcasecmp(attributes[k],xml_noalert) == 0) - { + else if (strcasecmp(attributes[k], xml_noalert) == 0) { *noalert = 1; - } - else if(strcasecmp(attributes[k], xml_overwrite) == 0) - { - if(strcmp(values[k], "yes") == 0) - { + } else if (strcasecmp(attributes[k], xml_overwrite) == 0) { + if (strcmp(values[k], "yes") == 0) { *overwrite = 1; - } - else if(strcmp(values[k], "no") == 0) - { + } else if (strcmp(values[k], "no") == 0) { *overwrite = 0; - } - else - { + } else { merror("rules_op: Invalid overwrite: %s. " "Can only by 'yes' or 'no'.", values[k]); - return(-1); + return (-1); } - } - else - { + } else { merror("rules_op: Invalid attribute \"%s\". " - "Only id, level, maxsize, accuracy, noalert and timeframe " - "are allowed.", attributes[k]); - return(-1); + "Only id, level, maxsize, accuracy, noalert and timeframe " + "are allowed.", attributes[k]); + return (-1); } k++; } - return(0); + return (0); } - -/* Bind active responses to the rule. - * No return. - */ -void Rule_AddAR(RuleInfo *rule_config) +/* Bind active responses to a rule */ +static void Rule_AddAR(RuleInfo *rule_config) { - int rule_ar_size = 0; + unsigned int rule_ar_size = 0; int mark_to_ar = 0; int rule_real_level = 0; - + OSListNode *my_ars_node; - - - /* Setting the correctly levels + + /* Set the correct levels * We play internally with the rules, to set * the priorities... Rules with 0 of accuracy, * receive a low level and go down in the list */ - if(rule_config->level == 9900) + if (rule_config->level == 9900) { rule_real_level = 0; - - else if(rule_config->level >= 100) - rule_real_level = rule_config->level/100; - - + } + + else if (rule_config->level >= 100) { + rule_real_level = rule_config->level / 100; + } + /* No AR for ignored rules */ - if(rule_real_level == 0) - { + if (rule_real_level == 0) { return; } - if(!active_responses) - { + /* No AR when options no_ar is set */ + if (rule_config->alert_opts & NO_AR) { + return; + } + + if (!active_responses) { return; } - - /* Looping on all AR */ + + /* Loop on all AR */ my_ars_node = OSList_GetFirstNode(active_responses); - while(my_ars_node) - { + while (my_ars_node) { active_response *my_ar; my_ar = (active_response *)my_ars_node->data; mark_to_ar = 0; - /* Checking if the level for the ar is higher */ - if(my_ar->level) - { - if(rule_real_level >= my_ar->level) - { + /* Check if the level for the ar is higher */ + if (my_ar->level) { + if (rule_real_level >= my_ar->level) { mark_to_ar = 1; } } - - /* Checking if group matches */ - if(my_ar->rules_group) - { - if(OS_Regex(my_ar->rules_group, rule_config->group)) - { - mark_to_ar = 1; - } + + /* Check if group matches */ + if (my_ar->rules_group) { + if (OS_Regex(my_ar->rules_group, rule_config->group)) { + mark_to_ar = 1; + } } - - /* Checking if rule id matches */ - if(my_ar->rules_id) - { + + /* Check if rule id matches */ + if (my_ar->rules_id) { int r_id = 0; char *str_pt = my_ar->rules_id; - while(*str_pt != '\0') - { + while (*str_pt != '\0') { /* We allow spaces in between */ - if(*str_pt == ' ') - { + if (*str_pt == ' ') { str_pt++; continue; } @@ -1693,123 +1958,102 @@ void Rule_AddAR(RuleInfo *rule_config) * and search for the next digit * available */ - else if(isdigit((int)*str_pt)) - { + else if (isdigit((int)*str_pt)) { r_id = atoi(str_pt); - + /* mark to ar if id matches */ - if(r_id == rule_config->sigid) - { + if (r_id == rule_config->sigid) { mark_to_ar = 1; } - + str_pt = strchr(str_pt, ','); - if(str_pt) - { + if (str_pt) { str_pt++; - } - else - { + } else { break; } } - /* Checking for duplicate commas */ - else if(*str_pt == ',') - { + /* Check for duplicate commas */ + else if (*str_pt == ',') { str_pt++; continue; } - else - { + else { break; } } } /* eof of rules_id */ - - - /* Bind AR to the rule */ - if(mark_to_ar == 1) - { + + /* Bind AR to the rule */ + if (mark_to_ar == 1) { rule_ar_size++; - rule_config->ar = realloc(rule_config->ar, + rule_config->ar = (active_response **) realloc(rule_config->ar, (rule_ar_size + 1) - *sizeof(active_response *)); - + * sizeof(active_response *)); + /* Always set the last node to NULL */ rule_config->ar[rule_ar_size - 1] = my_ar; - rule_config->ar[rule_ar_size] = NULL; + rule_config->ar[rule_ar_size] = NULL; } - + my_ars_node = OSList_GetNextNode(active_responses); } return; } - -/* print rule */ -void printRuleinfo(RuleInfo *rule, int node) +static void printRuleinfo(const RuleInfo *rule, int node) { - debug1("%d : rule:%d, level %d, timeout: %d", - node, - rule->sigid, - rule->level, - rule->ignore_time); + debug1("%d : rule:%d, level %d, timeout: %d", + node, + rule->sigid, + rule->level, + rule->ignore_time); } - - -/* Add Rule to hash. */ +/* Add rule to hash */ int AddHash_Rule(RuleNode *node) { - while(node) - { - char _id_key[15]; - char *id_key; - - snprintf(_id_key, 14, "%d", node->ruleinfo->sigid); - os_strdup(_id_key, id_key); - - - /* Adding key to hash. */ + while (node) { + char id_key[15]; + + snprintf(id_key, 14, "%d", node->ruleinfo->sigid); + + /* Add key to hash */ OSHash_Add(Config.g_rules_hash, id_key, node->ruleinfo); - if(node->child) - { + if (node->child) { AddHash_Rule(node->child); } node = node->next; } - return(0); + return (0); } - - -/* _set levels */ int _setlevels(RuleNode *node, int nnode) { int l_size = 0; - while(node) - { - if(node->ruleinfo->level == 9900) + while (node) { + if (node->ruleinfo->level == 9900) { node->ruleinfo->level = 0; + } - if(node->ruleinfo->level >= 100) - node->ruleinfo->level/=100; + if (node->ruleinfo->level >= 100) { + node->ruleinfo->level /= 100; + } l_size++; - + /* Rule information */ printRuleinfo(node->ruleinfo, nnode); - - if(node->child) - { + + if (node->child) { int chl_size = 0; - chl_size = _setlevels(node->child, nnode+1); + chl_size = _setlevels(node->child, nnode + 1); l_size += chl_size; } @@ -1817,8 +2061,36 @@ int _setlevels(RuleNode *node, int nnode) node = node->next; } - return(l_size); + return (l_size); } +/* Test if a rule id exists + * return 1 if exists, otherwise 0 + */ +static int doesRuleExist(int sid, RuleNode *r_node) +{ + /* Start from the beginning of the list by default */ + if (!r_node) { + r_node = OS_GetFirstRule(); + } + + while (r_node) { + /* Check if the sigid matches */ + if (r_node->ruleinfo->sigid == sid) { + return (1); + } + + /* Check if the rule has a child */ + if (r_node->child) { + /* Check recursively */ + if (doesRuleExist(sid, r_node->child)) { + return (1); + } + } -/* EOF */ + /* Go to the next rule */ + r_node = r_node->next; + } + + return (0); +}