-/* @(#) $Id: rules.c,v 1.79 2009/11/04 18:45:37 dcid Exp $ */
+/* @(#) $Id$ */
/* 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
return;
}
-
-
/* Rules_OP_ReadRules, v0.3, 2005/03/21
* Read the log rules.
* v0.3: Fixed many memory problems.
char *xml_status = "status";
char *xml_action = "action";
char *xml_compiled = "compiled_rule";
-
+
+ char *xml_list = "list";
+ char *xml_list_lookup = "lookup";
+ char *xml_list_field = "field";
+ char *xml_list_cvalue = "check_value";
+ char *xml_match_key = "match_key";
+ char *xml_not_match_key = "not_match_key";
+ char *xml_match_key_value = "match_key_value";
+ char *xml_address_key = "address_match_key";
+ char *xml_not_address_key = "not_address_match_key";
+ char *xml_address_key_value = "address_match_key_value";
+
char *xml_if_sid = "if_sid";
char *xml_if_group = "if_group";
char *xml_if_level = "if_level";
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";
int default_timeframe = 360;
- /* 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,ARGV0);
+ /* 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);
i = 0;
/* Rule elements block */
{
int k = 0;
+ int info_type = 0;
+ int count_info_detail = 0;
+ RuleInfoDetail *last_info_detail = NULL;
char *regex = NULL;
char *match = NULL;
char *url = NULL;
return(-1);
}
}
+ 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);
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)
{
char *newline;
loadmemory(config_ruleinfo->action,
rule_opt[k]->content);
}
+ 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 feild=\"%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 seams 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 feild 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=
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;
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,
}
else if(config_ruleinfo->context)
{
- config_ruleinfo->event_search =
+ if((config_ruleinfo->context == 1) &&
+ (config_ruleinfo->context_opts & SAME_DODIFF))
+ {
+ config_ruleinfo->context = 0;
+ }
+ else
+ {
+ config_ruleinfo->event_search =
(void *)Search_LastEvents;
+ }
}
} /* while(rule[j]) */
}
+RuleInfoDetail *zeroinfodetails(int type, char *data)
+{
+ RuleInfoDetail *info_details_pt = NULL;
+
+ info_details_pt = (RuleInfoDetail *)calloc(1,sizeof(RuleInfoDetail));
+
+ if (info_details_pt == NULL)
+ {
+ ErrorExit(MEM_ERROR,ARGV0);
+ }
+ /* type */
+ info_details_pt->type = type;
+
+ /* data */
+ os_strdup(data, info_details_pt->data);
+
+ info_details_pt->next = NULL;
+
+
+ return(info_details_pt);
+}
+
+
RuleInfo *zerorulemember(int id, int level,
int maxsize, int frequency,
int timeframe, int noalert,
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->event_search = NULL;
ruleinfo_pt->compiled_rule = NULL;
+ ruleinfo_pt->lists = NULL;
return(ruleinfo_pt);
}
+int get_info_attributes(char **attributes, char **values)
+{
+ 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,
return;
}
+ /* No AR when options no_ar is set */
+ if(rule_config->alert_opts & NO_AR)
+ {
+ return;
+ }
+
if(!active_responses)
{
return;