-/* @(#) $Id: rules_op.c,v 1.6 2009/06/24 18:53:08 dcid Exp $ */
+/* @(#) $Id: ./src/shared/rules_op.c, 2011/09/08 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
+ * License details at the LICENSE file included with OSSEC or
* online at: http://www.ossec.net/en/licensing.html
*/
#include "rules_op.h"
+/* Chaging path for test rule. */
+#ifdef TESTRULE
+ #undef RULEPATH
+ #define RULEPATH "rules/"
+#endif
+
/** Prototypes **/
-int _OS_GetRulesAttributes(char **attributes,
+int _OS_GetRulesAttributes(char **attributes,
char **values,
RuleInfo *ruleinfo_pt);
RuleInfo *_OS_AllocateRule();
/* Rules_OP_ReadRules, v0.3, 2005/03/21
* Read the log rules.
* v0.3: Fixed many memory problems.
- */
-int OS_ReadXMLRules(char *rulefile,
+ */
+int OS_ReadXMLRules(char *rulefile,
void *(*ruleact_function)(RuleInfo *rule, void *data),
void *data)
{
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_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_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_dodiff = "check_diff";
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";
-
+
char *rulepath;
-
+
int i;
- /* Building the rule file name + path */
- i = strlen(RULEPATH) + strlen(rulefile) + 2;
- rulepath = (char *)calloc(i,sizeof(char));
- if(!rulepath)
+ /* If no directory in the rulefile add the default */
+ if((strchr(rulefile, '/')) == NULL)
{
- ErrorExit(MEM_ERROR,__local_name);
+ /* Building the rule file name + path */
+ i = strlen(RULEPATH) + strlen(rulefile) + 2;
+ rulepath = (char *)calloc(i,sizeof(char));
+ if(!rulepath)
+ {
+ ErrorExit(MEM_ERROR,ARGV0);
+ }
+ 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);
-
-
- /* Reading the XML */
+
+
+ /* Reading the XML */
if(OS_ReadXML(rulepath,&xml) < 0)
{
merror(XML_ERROR, __local_name, rulepath, xml.err, xml.err_line);
/* Debug wrapper */
debug1("%s: DEBUG: read xml for rule '%s'.", __local_name, rulepath);
-
+
/* Applying any variable found */
if(OS_ApplyVariables(&xml) != 0)
/* Debug wrapper */
debug1("%s: DEBUG: XML Variables applied.", __local_name);
-
+
/* Getting the root elements */
node = OS_GetElementsbyNode(&xml, NULL);
{
merror(CONFIG_ERROR, __local_name, rulepath);
OS_ClearXML(&xml);
- return(-1);
+ return(-1);
}
/* Zeroing the rule memory -- not used anymore */
free(rulepath);
-
+
/* Checking if there is any invalid global option */
i = 0;
}
- /* Getting the rules now */
+ /* Getting the rules now */
i = 0;
while(node[i])
{
XML_NODE rule = NULL;
- /* Getting all rules for a global group */
+ /* Getting all rules for a global group */
rule = OS_GetElementsbyNode(&xml,node[i]);
if(rule == NULL)
{
{
/* Rules options */
int k = 0;
- char *regex = NULL, *match = NULL, *url = NULL,
+ char *regex = NULL, *match = NULL, *url = NULL,
*if_matched_regex = NULL, *if_matched_group = NULL,
*user = NULL, *id = NULL, *srcport = NULL,
*dstport = NULL, *status = NULL, *hostname = NULL,
*extra_data = NULL, *program_name = NULL;
-
+
RuleInfo *config_ruleinfo = NULL;
XML_NODE rule_opt = NULL;
-
+
/* Checking if the rule element is correct */
if((!rule[j]->element)||
/* Checking for the attributes of the rule */
if((!rule[j]->attributes) || (!rule[j]->values))
{
- merror(RL_INV_RULE, __local_name, rulefile);
+ merror(RL_INV_RULE, __local_name, rulefile);
OS_ClearXML(&xml);
return(-1);
}
-
+
/* Attribute block */
config_ruleinfo = _OS_AllocateRule();
* be fine
*/
os_strdup(node[i]->values[0], config_ruleinfo->group);
-
- /* Getting rules options */
+
+ /* Getting rules options */
rule_opt = OS_GetElementsbyNode(&xml, rule[j]);
if(rule_opt == NULL)
{
merror(RL_NO_OPT, __local_name, config_ruleinfo->sigid);
OS_ClearXML(&xml);
- return(-1);
+ return(-1);
}
-
- /* Reading the whole rule block */
+
+ /* Reading the whole rule block */
while(rule_opt[k])
{
if((!rule_opt[k]->element)||(!rule_opt[k]->content))
}
else if(strcasecmp(rule_opt[k]->element,xml_day_time) == 0)
{
- config_ruleinfo->day_time =
+ config_ruleinfo->day_time =
OS_IsValidTime(rule_opt[k]->content);
if(!config_ruleinfo->day_time)
{
}
else if(strcasecmp(rule_opt[k]->element,xml_week_day) == 0)
{
- config_ruleinfo->week_day =
+ config_ruleinfo->week_day =
OS_IsValidDay(rule_opt[k]->content);
if(!config_ruleinfo->week_day)
int ip_s = 0;
/* Getting size of source ip list */
- while(config_ruleinfo->srcip &&
+ while(config_ruleinfo->srcip &&
config_ruleinfo->srcip[ip_s])
{
ip_s++;
}
- config_ruleinfo->srcip =
+ config_ruleinfo->srcip =
realloc(config_ruleinfo->srcip,
(ip_s + 2) * sizeof(os_ip *));
/* Allocating memory for the individual entries */
- os_calloc(1, sizeof(os_ip),
+ 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,
+ if(!OS_IsValidIP(rule_opt[k]->content,
config_ruleinfo->srcip[ip_s]))
{
merror(INVALID_IP, __local_name, rule_opt[k]->content);
else if(strcasecmp(rule_opt[k]->element,xml_srcport) == 0)
{
srcport = os_LoadString(srcport, 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_action) == 0)
{
- config_ruleinfo->action =
+ config_ruleinfo->action =
os_LoadString(config_ruleinfo->action,
rule_opt[k]->content);
}
{
if(!OS_StrIsNum(rule_opt[k]->content))
{
- merror(INVALID_CONFIG, __local_name,
+ merror(INVALID_CONFIG, __local_name,
xml_if_level,
- rule_opt[k]->content);
+ rule_opt[k]->content);
return(-1);
}
rule_opt[k]->content);
return(-1);
}
- config_ruleinfo->if_matched_sid =
+ config_ruleinfo->if_matched_sid =
atoi(rule_opt[k]->content);
}
config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
}
else if(strcasecmp(rule_opt[k]->element,
+ xml_dodiff)==0)
+ {
+ config_ruleinfo->context++;
+ 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;
else if(strcasecmp(rule_opt[k]->element,
xml_options) == 0)
{
- if(strcmp("alert_by_email",
+ if(strcmp("alert_by_email",
rule_opt[k]->content) == 0)
{
if(!(config_ruleinfo->alert_opts & DO_MAILALERT))
config_ruleinfo->alert_opts&=0xfff-DO_MAILALERT;
}
}
- else if(strcmp("log_alert",
+ else if(strcmp("log_alert",
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, __local_name, xml_options,
rule_opt[k]->content);
rule_opt[k]->content);
OS_ClearXML(&xml);
return(-1);
- }
+ }
}
else if(strcasecmp(rule_opt[k]->element,
xml_ignore) == 0)
return(-1);
}
}
+ /* XXX As new features are added into ../analysisd/rules.c
+ * This code needs to be updated to match, but is out of date
+ * it's become a nightmare to correct with out just make the
+ * problem for someone later.
+ *
+ * This hack will allow any crap xml to pass without an
+ * error. The correct fix is to refactor the code so that
+ * ../analysisd/rules* and this code are not duplicates
+ *
else
{
merror(XML_INVELEM, __local_name, rule_opt[k]->element);
OS_ClearXML(&xml);
return(-1);
}
+ */
k++;
}
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 &&
/* Calling the function provided. */
ruleact_function(config_ruleinfo, data);
-
+
j++; /* next rule */
} /* while(rule[j]) */
OS_ClearNode(rule);
i++;
-
+
} /* while (node[i]) */
/* Cleaning global node */
RuleInfo *_OS_AllocateRule()
{
RuleInfo *ruleinfo_pt = NULL;
-
-
+
+
/* Allocation memory for structure */
ruleinfo_pt = (RuleInfo *)calloc(1,sizeof(RuleInfo));
if(ruleinfo_pt == NULL)
{
ErrorExit(MEM_ERROR,__local_name);
}
-
+
/* Default values */
ruleinfo_pt->level = -1;
/* Default category is syslog */
ruleinfo_pt->category = SYSLOG;
- ruleinfo_pt->ar = NULL;
-
+ ruleinfo_pt->ar = NULL;
+
ruleinfo_pt->context = 0;
-
+
/* Default sigid of -1 */
ruleinfo_pt->sigid = -1;
ruleinfo_pt->firedtimes = 0;
ruleinfo_pt->ignore_time = 0;
ruleinfo_pt->timeframe = 0;
ruleinfo_pt->time_ignored = 0;
-
- ruleinfo_pt->context_opts = 0;
- ruleinfo_pt->alert_opts = 0;
- ruleinfo_pt->ignore = 0;
- ruleinfo_pt->ckignore = 0;
+
+ ruleinfo_pt->context_opts = 0;
+ ruleinfo_pt->alert_opts = 0;
+ ruleinfo_pt->ignore = 0;
+ ruleinfo_pt->ckignore = 0;
ruleinfo_pt->day_time = NULL;
ruleinfo_pt->week_day = NULL;
ruleinfo_pt->comment = NULL;
ruleinfo_pt->info = NULL;
ruleinfo_pt->cve = 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;
ruleinfo_pt->hostname = NULL;
ruleinfo_pt->program_name = NULL;
ruleinfo_pt->action = NULL;
-
+
/* Zeroing last matched events */
ruleinfo_pt->__frequency = 0;
ruleinfo_pt->last_events = NULL;
/* 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;
return(ruleinfo_pt);
RuleInfo *ruleinfo_pt)
{
int k = 0;
-
+
char *xml_id = "id";
char *xml_level = "level";
char *xml_maxsize = "maxsize";
char *xml_noalert = "noalert";
char *xml_ignore_time = "ignore";
char *xml_overwrite = "overwrite";
-
-
+
+
/* Getting attributes */
while(attributes[k])
{
{
if(OS_StrIsNum(values[k]) && (strlen(values[k]) <= 6 ))
{
- ruleinfo_pt->sigid = atoi(values[k]);
+ ruleinfo_pt->sigid = atoi(values[k]);
}
else
{
ruleinfo_pt->maxsize = atoi(values[k]);
/* adding EXTRAINFO options */
- if(ruleinfo_pt->maxsize > 0 &&
+ if(ruleinfo_pt->maxsize > 0 &&
!(ruleinfo_pt->alert_opts & DO_EXTRAINFO))
{
ruleinfo_pt->alert_opts |= DO_EXTRAINFO;
/* Rule accuracy */
else if(strcasecmp(attributes[k],xml_accuracy) == 0)
{
- merror("%s: XXX: Use of 'accuracy' isn't supported. Ignoring.",
+ merror("%s: XXX: Use of 'accuracy' isn't supported. Ignoring.",
__local_name);
}
/* Rule ignore_time */
else
{
merror(XML_VALUEERR,__local_name, attributes[k], values[k]);
- return(-1);
+ return(-1);
}
}
/* Rule noalert */
/* print rule */
void OS_PrintRuleinfo(RuleInfo *rule)
{
- debug1("%s: __local_name: Print Rule:%d, level %d, ignore: %d, frequency:%d",
+ debug1("%s: __local_name: Print Rule:%d, level %d, ignore: %d, frequency:%d",
__local_name,
- rule->sigid,
+ rule->sigid,
rule->level,
rule->ignore_time,
rule->frequency);