1 /* @(#) $Id: ./src/analysisd/rules.c, 2011/09/08 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
7 * This program is a free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General Public
9 * License (version 2) as published by the FSF - Free Software
12 * License details at the LICENSE file included with OSSEC or
13 * online at: http://www.ossec.net/en/licensing.html
20 #include "eventinfo.h"
21 #include "compiled_rules/compiled_rules.h"
24 /* Chaging path for test rule. */
27 #define RULEPATH "rules/"
32 /* Internal functions */
33 int getattributes(char **attributes,
36 int *maxsize, int *timeframe,
37 int *frequency, int *accuracy,
38 int *noalert, int *ignore_time, int *overwrite);
39 int doesRuleExist(int sid, RuleNode *r_node);
42 void Rule_AddAR(RuleInfo *config_rule);
43 char *loadmemory(char *at, char *str);
44 int getDecoderfromlist(char *name);
50 /* Rules_OP_ReadRules, v0.1, 2005/07/04
51 * Will initialize the rules list
53 void Rules_OP_CreateRules()
56 /* Initializing the rule list */
62 /* Rules_OP_ReadRules, v0.3, 2005/03/21
64 * v0.3: Fixed many memory problems.
66 int Rules_OP_ReadRules(char * rulefile)
72 /* These are the available options for the rule configuration */
74 char *xml_group = "group";
75 char *xml_rule = "rule";
77 char *xml_regex = "regex";
78 char *xml_match = "match";
79 char *xml_decoded = "decoded_as";
80 char *xml_category = "category";
81 char *xml_cve = "cve";
82 char *xml_info = "info";
83 char *xml_day_time = "time";
84 char *xml_week_day = "weekday";
85 char *xml_comment = "description";
86 char *xml_ignore = "ignore";
87 char *xml_check_if_ignored = "check_if_ignored";
89 char *xml_srcip = "srcip";
90 char *xml_srcport = "srcport";
91 char *xml_dstip = "dstip";
92 char *xml_dstport = "dstport";
93 char *xml_user = "user";
94 char *xml_url = "url";
96 char *xml_data = "extra_data";
97 char *xml_hostname = "hostname";
98 char *xml_program_name = "program_name";
99 char *xml_status = "status";
100 char *xml_action = "action";
101 char *xml_compiled = "compiled_rule";
103 char *xml_list = "list";
104 char *xml_list_lookup = "lookup";
105 char *xml_list_field = "field";
106 char *xml_list_cvalue = "check_value";
107 char *xml_match_key = "match_key";
108 char *xml_not_match_key = "not_match_key";
109 char *xml_match_key_value = "match_key_value";
110 char *xml_address_key = "address_match_key";
111 char *xml_not_address_key = "not_address_match_key";
112 char *xml_address_key_value = "address_match_key_value";
114 char *xml_if_sid = "if_sid";
115 char *xml_if_group = "if_group";
116 char *xml_if_level = "if_level";
117 char *xml_fts = "if_fts";
119 char *xml_if_matched_regex = "if_matched_regex";
120 char *xml_if_matched_group = "if_matched_group";
121 char *xml_if_matched_sid = "if_matched_sid";
123 char *xml_same_source_ip = "same_source_ip";
124 char *xml_same_src_port = "same_src_port";
125 char *xml_same_dst_port = "same_dst_port";
126 char *xml_same_user = "same_user";
127 char *xml_same_location = "same_location";
128 char *xml_same_id = "same_id";
129 char *xml_dodiff = "check_diff";
131 char *xml_different_url = "different_url";
133 char *xml_notsame_source_ip = "not_same_source_ip";
134 char *xml_notsame_user = "not_same_user";
135 char *xml_notsame_agent = "not_same_agent";
136 char *xml_notsame_id = "not_same_id";
138 char *xml_options = "options";
143 int default_timeframe = 360;
146 /* If no directory in the rulefile add the default */
147 if((strchr(rulefile, '/')) == NULL)
149 /* Building the rule file name + path */
150 i = strlen(RULEPATH) + strlen(rulefile) + 2;
151 rulepath = (char *)calloc(i,sizeof(char));
154 ErrorExit(MEM_ERROR,ARGV0);
156 snprintf(rulepath,i,"%s/%s",RULEPATH,rulefile);
160 os_strdup(rulefile, rulepath);
161 debug1("%s is the rulefile", rulefile);
162 debug1("Not modifing the rule path");
168 /* Reading the XML */
169 if(OS_ReadXML(rulepath,&xml) < 0)
171 merror(XML_ERROR, ARGV0, rulepath, xml.err, xml.err_line);
178 debug2("%s: DEBUG: read xml for rule.", ARGV0);
182 /* Applying any variable found */
183 if(OS_ApplyVariables(&xml) != 0)
185 merror(XML_ERROR_VAR, ARGV0, rulepath, xml.err);
191 debug2("%s: DEBUG: XML Variables applied.", ARGV0);
194 /* Getting the root elements */
195 node = OS_GetElementsbyNode(&xml,NULL);
198 merror(CONFIG_ERROR, ARGV0, rulepath);
204 /* Zeroing the rule memory -- not used anymore */
208 /* Getting default time frame */
209 default_timeframe = getDefine_Int("analysisd",
214 /* Checking if there is any invalid global option */
219 if(strcasecmp(node[i]->element,xml_group) != 0)
221 merror("rules_op: Invalid root element \"%s\"."
222 "Only \"group\" is allowed",node[i]->element);
226 if((!node[i]->attributes) || (!node[i]->values)||
227 (!node[i]->values[0]) || (!node[i]->attributes[0]) ||
228 (strcasecmp(node[i]->attributes[0],"name") != 0) ||
229 (node[i]->attributes[1]))
231 merror("rules_op: Invalid root element '%s'."
232 "Only the group name is allowed",node[i]->element);
239 merror(XML_READ_ERROR, ARGV0);
247 /* Getting the rules now */
251 XML_NODE rule = NULL;
255 /* Getting all rules for a global group */
256 rule = OS_GetElementsbyNode(&xml,node[i]);
259 merror("%s: Group '%s' without any rule.",
260 ARGV0, node[i]->element);
267 RuleInfo *config_ruleinfo = NULL;
270 /* Checking if the rule element is correct */
271 if((!rule[j]->element)||
272 (strcasecmp(rule[j]->element,xml_rule) != 0))
274 merror("%s: Invalid configuration. '%s' is not "
275 "a valid element.", ARGV0, rule[j]->element);
281 /* Checking for the attributes of the rule */
282 if((!rule[j]->attributes) || (!rule[j]->values))
284 merror("%s: Invalid rule '%d'. You must specify"
285 " an ID and a level at least.", ARGV0, j);
291 /* Attribute block */
293 int id = -1,level = -1,maxsize = 0,timeframe = 0;
294 int frequency = 0, accuracy = 1, noalert = 0, ignore_time = 0;
297 /* Getting default time frame */
298 timeframe = default_timeframe;
301 if(getattributes(rule[j]->attributes,rule[j]->values,
302 &id,&level,&maxsize,&timeframe,
303 &frequency,&accuracy,&noalert,
304 &ignore_time, &overwrite) < 0)
306 merror("%s: Invalid attribute for rule.", ARGV0);
311 if((id == -1) || (level == -1))
313 merror("%s: No rule id or level specified for "
314 "rule '%d'.",ARGV0, j);
319 if(overwrite != 1 && doesRuleExist(id, NULL))
321 merror("%s: Duplicate rule ID:%d",ARGV0, id);
326 /* Allocating memory and initializing structure */
327 config_ruleinfo = zerorulemember(id, level, maxsize,
329 noalert, ignore_time, overwrite);
332 /* If rule is 0, set it to level 99 to have high priority.
333 * set it to 0 again later
335 if(config_ruleinfo->level == 0)
336 config_ruleinfo->level = 99;
339 /* Each level now is going to be multiplied by 100.
340 * If the accuracy is set to 0 we don't multiply,
341 * so it will be at the end of the list. We will
342 * divide by 100 later.
346 config_ruleinfo->level *= 100;
349 if(config_ruleinfo->maxsize > 0)
351 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
353 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
357 } /* end attributes/memory allocation block */
360 /* Here we can assign the group name to the rule.
361 * The level is correct so the rule is probably going to
364 os_strdup(node[i]->values[0], config_ruleinfo->group);
367 /* Rule elements block */
371 int count_info_detail = 0;
372 RuleInfoDetail *last_info_detail = NULL;
376 char *if_matched_regex = NULL;
377 char *if_matched_group = NULL;
380 char *srcport = NULL;
381 char *dstport = NULL;
383 char *hostname = NULL;
384 char *extra_data = NULL;
385 char *program_name = NULL;
387 XML_NODE rule_opt = NULL;
388 rule_opt = OS_GetElementsbyNode(&xml,rule[j]);
391 merror("%s: Rule '%d' without any option. "
392 "It may lead to false positives and some "
393 "other problems for the system. Exiting.",
394 ARGV0, config_ruleinfo->sigid);
401 if((!rule_opt[k]->element)||(!rule_opt[k]->content))
403 else if(strcasecmp(rule_opt[k]->element,xml_regex)==0)
407 rule_opt[k]->content);
409 else if(strcasecmp(rule_opt[k]->element,xml_match)==0)
413 rule_opt[k]->content);
415 else if(strcasecmp(rule_opt[k]->element, xml_decoded)==0)
417 config_ruleinfo->decoded_as =
418 getDecoderfromlist(rule_opt[k]->content);
420 if(config_ruleinfo->decoded_as == 0)
422 merror("%s: Invalid decoder name: '%s'.",
423 ARGV0, rule_opt[k]->content);
428 else if(strcasecmp(rule_opt[k]->element,xml_cve)==0)
430 if(config_ruleinfo->info_details == NULL)
432 config_ruleinfo->info_details = zeroinfodetails(RULEINFODETAIL_CVE,
433 rule_opt[k]->content);
437 for (last_info_detail = config_ruleinfo->info_details;
438 last_info_detail->next != NULL;
439 last_info_detail = last_info_detail->next)
443 /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */
444 if (count_info_detail <= MAX_RULEINFODETAIL)
446 last_info_detail->next = zeroinfodetails(RULEINFODETAIL_CVE,
447 rule_opt[k]->content);
451 /* keep old methods for now */
452 config_ruleinfo->cve=
453 loadmemory(config_ruleinfo->cve,
454 rule_opt[k]->content);
456 else if(strcasecmp(rule_opt[k]->element,xml_info)==0)
459 info_type = get_info_attributes(rule_opt[k]->attributes,
460 rule_opt[k]->values);
461 debug1("info_type = %d", info_type);
463 if(config_ruleinfo->info_details == NULL)
465 config_ruleinfo->info_details = zeroinfodetails(info_type,
466 rule_opt[k]->content);
470 for (last_info_detail = config_ruleinfo->info_details;
471 last_info_detail->next != NULL;
472 last_info_detail = last_info_detail->next) {
475 /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */
476 if (count_info_detail <= MAX_RULEINFODETAIL) {
477 last_info_detail->next = zeroinfodetails(info_type, rule_opt[k]->content);
482 /* keep old methods for now */
483 config_ruleinfo->info=
484 loadmemory(config_ruleinfo->info,
485 rule_opt[k]->content);
487 else if(strcasecmp(rule_opt[k]->element,xml_day_time)==0)
489 config_ruleinfo->day_time =
490 OS_IsValidTime(rule_opt[k]->content);
491 if(!config_ruleinfo->day_time)
493 merror(INVALID_CONFIG, ARGV0,
494 rule_opt[k]->element,
495 rule_opt[k]->content);
499 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
500 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
502 else if(strcasecmp(rule_opt[k]->element,xml_week_day)==0)
504 config_ruleinfo->week_day =
505 OS_IsValidDay(rule_opt[k]->content);
507 if(!config_ruleinfo->week_day)
509 merror(INVALID_CONFIG, ARGV0,
510 rule_opt[k]->element,
511 rule_opt[k]->content);
514 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
515 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
517 else if(strcasecmp(rule_opt[k]->element,xml_group)==0)
519 config_ruleinfo->group =
520 loadmemory(config_ruleinfo->group,
521 rule_opt[k]->content);
523 else if(strcasecmp(rule_opt[k]->element,xml_comment)==0)
527 newline = strchr(rule_opt[k]->content, '\n');
533 config_ruleinfo->comment=
534 loadmemory(config_ruleinfo->comment,
535 rule_opt[k]->content);
537 else if(strcasecmp(rule_opt[k]->element,xml_srcip)==0)
541 /* Getting size of source ip list */
542 while(config_ruleinfo->srcip &&
543 config_ruleinfo->srcip[ip_s])
548 config_ruleinfo->srcip =
549 realloc(config_ruleinfo->srcip,
550 (ip_s + 2) * sizeof(os_ip *));
553 /* Allocating memory for the individual entries */
554 os_calloc(1, sizeof(os_ip),
555 config_ruleinfo->srcip[ip_s]);
556 config_ruleinfo->srcip[ip_s +1] = NULL;
559 /* Checking if the ip is valid */
560 if(!OS_IsValidIP(rule_opt[k]->content,
561 config_ruleinfo->srcip[ip_s]))
563 merror(INVALID_IP, ARGV0, rule_opt[k]->content);
567 if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
568 config_ruleinfo->alert_opts |= DO_PACKETINFO;
570 else if(strcasecmp(rule_opt[k]->element,xml_dstip)==0)
574 /* Getting size of source ip list */
575 while(config_ruleinfo->dstip &&
576 config_ruleinfo->dstip[ip_s])
581 config_ruleinfo->dstip =
582 realloc(config_ruleinfo->dstip,
583 (ip_s + 2) * sizeof(os_ip *));
586 /* Allocating memory for the individual entries */
587 os_calloc(1, sizeof(os_ip),
588 config_ruleinfo->dstip[ip_s]);
589 config_ruleinfo->dstip[ip_s +1] = NULL;
592 /* Checking if the ip is valid */
593 if(!OS_IsValidIP(rule_opt[k]->content,
594 config_ruleinfo->dstip[ip_s]))
596 merror(INVALID_IP, ARGV0, rule_opt[k]->content);
600 if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
601 config_ruleinfo->alert_opts |= DO_PACKETINFO;
603 else if(strcasecmp(rule_opt[k]->element,xml_user)==0)
607 rule_opt[k]->content);
609 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
610 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
612 else if(strcasecmp(rule_opt[k]->element,xml_id)==0)
616 rule_opt[k]->content);
618 else if(strcasecmp(rule_opt[k]->element,xml_srcport)==0)
622 rule_opt[k]->content);
623 if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
624 config_ruleinfo->alert_opts |= DO_PACKETINFO;
626 else if(strcasecmp(rule_opt[k]->element,xml_dstport)==0)
630 rule_opt[k]->content);
632 if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
633 config_ruleinfo->alert_opts |= DO_PACKETINFO;
635 else if(strcasecmp(rule_opt[k]->element,xml_status)==0)
639 rule_opt[k]->content);
641 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
642 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
644 else if(strcasecmp(rule_opt[k]->element,xml_hostname)==0)
648 rule_opt[k]->content);
650 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
651 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
653 else if(strcasecmp(rule_opt[k]->element,xml_data)==0)
656 loadmemory(extra_data,
657 rule_opt[k]->content);
659 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
660 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
662 else if(strcasecmp(rule_opt[k]->element,
663 xml_program_name)==0)
666 loadmemory(program_name,
667 rule_opt[k]->content);
669 else if(strcasecmp(rule_opt[k]->element,xml_action)==0)
671 config_ruleinfo->action =
672 loadmemory(config_ruleinfo->action,
673 rule_opt[k]->content);
675 else if(strcasecmp(rule_opt[k]->element,xml_list)==0)
677 debug1("-> %s == %s",rule_opt[k]->element, xml_list);
678 if (rule_opt[k]->attributes && rule_opt[k]->values && rule_opt[k]->content)
682 OSMatch *matcher=NULL;
683 int lookup_type = LR_STRING_MATCH;
684 while(rule_opt[k]->attributes[list_att_num])
686 if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_lookup) == 0)
688 if(strcasecmp(rule_opt[k]->values[list_att_num],xml_match_key) == 0)
689 lookup_type = LR_STRING_MATCH;
690 else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_not_match_key)==0)
691 lookup_type = LR_STRING_NOT_MATCH;
692 else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_match_key_value)==0)
693 lookup_type = LR_STRING_MATCH_VALUE;
694 else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_address_key)==0)
695 lookup_type = LR_ADDRESS_MATCH;
696 else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_not_address_key)==0)
697 lookup_type = LR_ADDRESS_NOT_MATCH;
698 else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_address_key_value)==0)
699 lookup_type = LR_ADDRESS_MATCH_VALUE;
702 merror(INVALID_CONFIG, ARGV0,
703 rule_opt[k]->element,
704 rule_opt[k]->content);
705 merror("%s: List match lookup=\"%s\" is not valid.",
706 ARGV0,rule_opt[k]->values[list_att_num]);
710 else if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_field)==0)
712 if(strcasecmp(rule_opt[k]->values[list_att_num],xml_srcip)==0)
713 rule_type = RULE_SRCIP;
714 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_srcport)==0)
715 rule_type = RULE_SRCPORT;
716 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_dstip)==0)
717 rule_type = RULE_DSTIP;
718 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_dstport)==0)
719 rule_type = RULE_DSTPORT;
720 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_user)==0)
721 rule_type = RULE_USER;
722 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_url)==0)
723 rule_type = RULE_URL;
724 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_id)==0)
726 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_hostname)==0)
727 rule_type = RULE_HOSTNAME;
728 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_program_name)==0)
729 rule_type = RULE_PROGRAM_NAME;
730 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_status)==0)
731 rule_type = RULE_STATUS;
732 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_action)==0)
733 rule_type = RULE_ACTION;
736 merror(INVALID_CONFIG, ARGV0,
737 rule_opt[k]->element,
738 rule_opt[k]->content);
739 merror("%s: List match field=\"%s\" is not valid.",
740 ARGV0,rule_opt[k]->values[list_att_num]);
744 else if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_cvalue)==0)
746 os_calloc(1, sizeof(OSMatch), matcher);
747 if(!OSMatch_Compile(rule_opt[k]->values[list_att_num], matcher, 0))
749 merror(INVALID_CONFIG, ARGV0,
750 rule_opt[k]->element,
751 rule_opt[k]->content);
752 merror(REGEX_COMPILE,
754 rule_opt[k]->values[list_att_num],
761 merror("%s:List feild=\"%s\" is not valid",ARGV0,
762 rule_opt[k]->values[list_att_num]);
763 merror(INVALID_CONFIG, ARGV0,
764 rule_opt[k]->element, rule_opt[k]->content);
771 merror("%s:List requires the field=\"\" Attrubute",ARGV0);
772 merror(INVALID_CONFIG, ARGV0,
773 rule_opt[k]->element, rule_opt[k]->content);
777 /* Wow it's all ready - this seams too complex to get to this point */
778 config_ruleinfo->lists = OS_AddListRule(config_ruleinfo->lists,
781 rule_opt[k]->content,
783 if (config_ruleinfo->lists == NULL)
785 merror("%s: List error: Could not load %s", ARGV0, rule_opt[k]->content);
791 merror("%s:List must have a correctly formatted feild attribute",
793 merror(INVALID_CONFIG,
795 rule_opt[k]->element,
796 rule_opt[k]->content);
799 /* xml_list eval is done */
801 else if(strcasecmp(rule_opt[k]->element,xml_url)==0)
805 rule_opt[k]->content);
807 else if(strcasecmp(rule_opt[k]->element, xml_compiled)==0)
811 while(compiled_rules_name[it_id])
813 if(strcmp(compiled_rules_name[it_id],
814 rule_opt[k]->content) == 0)
819 /* checking if the name is valid. */
820 if(!compiled_rules_name[it_id])
822 merror("%s: ERROR: Compiled rule not found: '%s'",
823 ARGV0, rule_opt[k]->content);
824 merror(INVALID_CONFIG, ARGV0,
825 rule_opt[k]->element, rule_opt[k]->content);
830 config_ruleinfo->compiled_rule = compiled_rules_list[it_id];
831 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
832 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
835 /* We allow these four categories so far */
836 else if(strcasecmp(rule_opt[k]->element, xml_category)==0)
838 if(strcmp(rule_opt[k]->content, "firewall") == 0)
840 config_ruleinfo->category = FIREWALL;
842 else if(strcmp(rule_opt[k]->content, "ids") == 0)
844 config_ruleinfo->category = IDS;
846 else if(strcmp(rule_opt[k]->content, "syslog") == 0)
848 config_ruleinfo->category = SYSLOG;
850 else if(strcmp(rule_opt[k]->content, "web-log") == 0)
852 config_ruleinfo->category = WEBLOG;
854 else if(strcmp(rule_opt[k]->content, "squid") == 0)
856 config_ruleinfo->category = SQUID;
858 else if(strcmp(rule_opt[k]->content,"windows") == 0)
860 config_ruleinfo->category = DECODER_WINDOWS;
862 else if(strcmp(rule_opt[k]->content,"ossec") == 0)
864 config_ruleinfo->category = OSSEC_RL;
868 merror(INVALID_CAT, ARGV0, rule_opt[k]->content);
872 else if(strcasecmp(rule_opt[k]->element,xml_if_sid)==0)
874 config_ruleinfo->if_sid=
875 loadmemory(config_ruleinfo->if_sid,
876 rule_opt[k]->content);
878 else if(strcasecmp(rule_opt[k]->element,xml_if_level)==0)
880 if(!OS_StrIsNum(rule_opt[k]->content))
882 merror(INVALID_CONFIG, ARGV0,
884 rule_opt[k]->content);
888 config_ruleinfo->if_level=
889 loadmemory(config_ruleinfo->if_level,
890 rule_opt[k]->content);
892 else if(strcasecmp(rule_opt[k]->element,xml_if_group)==0)
894 config_ruleinfo->if_group=
895 loadmemory(config_ruleinfo->if_group,
896 rule_opt[k]->content);
898 else if(strcasecmp(rule_opt[k]->element,
899 xml_if_matched_regex) == 0)
901 config_ruleinfo->context = 1;
903 loadmemory(if_matched_regex,
904 rule_opt[k]->content);
906 else if(strcasecmp(rule_opt[k]->element,
907 xml_if_matched_group) == 0)
909 config_ruleinfo->context = 1;
911 loadmemory(if_matched_group,
912 rule_opt[k]->content);
914 else if(strcasecmp(rule_opt[k]->element,
915 xml_if_matched_sid) == 0)
917 config_ruleinfo->context = 1;
918 if(!OS_StrIsNum(rule_opt[k]->content))
920 merror(INVALID_CONFIG, ARGV0,
922 rule_opt[k]->content);
925 config_ruleinfo->if_matched_sid =
926 atoi(rule_opt[k]->content);
929 else if(strcasecmp(rule_opt[k]->element,
930 xml_same_source_ip)==0)
932 config_ruleinfo->context_opts|= SAME_SRCIP;
934 else if(strcasecmp(rule_opt[k]->element,
935 xml_same_src_port)==0)
937 config_ruleinfo->context_opts|= SAME_SRCPORT;
939 if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
940 config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
942 else if(strcasecmp(rule_opt[k]->element,
945 config_ruleinfo->context = 1;
946 config_ruleinfo->context_opts|= SAME_DODIFF;
947 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
948 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
950 else if(strcasecmp(rule_opt[k]->element,
951 xml_same_dst_port) == 0)
953 config_ruleinfo->context_opts|= SAME_DSTPORT;
955 if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
956 config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
958 else if(strcasecmp(rule_opt[k]->element,
959 xml_notsame_source_ip)==0)
961 config_ruleinfo->context_opts&= NOT_SAME_SRCIP;
963 else if(strcmp(rule_opt[k]->element, xml_same_id) == 0)
965 config_ruleinfo->context_opts|= SAME_ID;
967 else if(strcmp(rule_opt[k]->element,
968 xml_different_url) == 0)
970 config_ruleinfo->context_opts|= DIFFERENT_URL;
972 if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
973 config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
975 else if(strcmp(rule_opt[k]->element,xml_notsame_id) == 0)
977 config_ruleinfo->context_opts&= NOT_SAME_ID;
979 else if(strcasecmp(rule_opt[k]->element,
982 config_ruleinfo->alert_opts |= DO_FTS;
984 else if(strcasecmp(rule_opt[k]->element,
987 config_ruleinfo->context_opts|= SAME_USER;
989 if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
990 config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
992 else if(strcasecmp(rule_opt[k]->element,
993 xml_notsame_user)==0)
995 config_ruleinfo->context_opts&= NOT_SAME_USER;
997 else if(strcasecmp(rule_opt[k]->element,
998 xml_same_location)==0)
1000 config_ruleinfo->context_opts|= SAME_LOCATION;
1001 if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
1002 config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
1004 else if(strcasecmp(rule_opt[k]->element,
1005 xml_notsame_agent)==0)
1007 config_ruleinfo->context_opts&= NOT_SAME_AGENT;
1009 else if(strcasecmp(rule_opt[k]->element,
1012 if(strcmp("alert_by_email",
1013 rule_opt[k]->content) == 0)
1015 if(!(config_ruleinfo->alert_opts & DO_MAILALERT))
1017 config_ruleinfo->alert_opts|= DO_MAILALERT;
1020 else if(strcmp("no_email_alert",
1021 rule_opt[k]->content) == 0)
1023 if(config_ruleinfo->alert_opts & DO_MAILALERT)
1025 config_ruleinfo->alert_opts&=0xfff-DO_MAILALERT;
1028 else if(strcmp("log_alert",
1029 rule_opt[k]->content) == 0)
1031 if(!(config_ruleinfo->alert_opts & DO_LOGALERT))
1033 config_ruleinfo->alert_opts|= DO_LOGALERT;
1036 else if(strcmp("no_log", rule_opt[k]->content) == 0)
1038 if(config_ruleinfo->alert_opts & DO_LOGALERT)
1040 config_ruleinfo->alert_opts &=0xfff-DO_LOGALERT;
1043 else if(strcmp("no_ar", rule_opt[k]->content) == 0)
1045 if(!(config_ruleinfo->alert_opts & NO_AR))
1047 config_ruleinfo->alert_opts|= NO_AR;
1052 merror(XML_VALUEERR, ARGV0, xml_options,
1053 rule_opt[k]->content);
1055 merror("%s: Invalid option '%s' for "
1056 "rule '%d'.",ARGV0, rule_opt[k]->element,
1057 config_ruleinfo->sigid);
1062 else if(strcasecmp(rule_opt[k]->element,
1065 if(strstr(rule_opt[k]->content, "user") != NULL)
1067 config_ruleinfo->ignore|=FTS_DSTUSER;
1069 if(strstr(rule_opt[k]->content, "srcip") != NULL)
1071 config_ruleinfo->ignore|=FTS_SRCIP;
1073 if(strstr(rule_opt[k]->content, "dstip") != NULL)
1075 config_ruleinfo->ignore|=FTS_DSTIP;
1077 if(strstr(rule_opt[k]->content, "id") != NULL)
1079 config_ruleinfo->ignore|=FTS_ID;
1081 if(strstr(rule_opt[k]->content,"location")!= NULL)
1083 config_ruleinfo->ignore|=FTS_LOCATION;
1085 if(strstr(rule_opt[k]->content,"data")!= NULL)
1087 config_ruleinfo->ignore|=FTS_DATA;
1089 if(strstr(rule_opt[k]->content, "name") != NULL)
1091 config_ruleinfo->ignore|=FTS_NAME;
1094 if(!config_ruleinfo->ignore)
1096 merror("%s: Wrong ignore option: '%s'",
1098 rule_opt[k]->content);
1102 else if(strcasecmp(rule_opt[k]->element,
1103 xml_check_if_ignored) == 0)
1105 if(strstr(rule_opt[k]->content, "user") != NULL)
1107 config_ruleinfo->ckignore|=FTS_DSTUSER;
1109 if(strstr(rule_opt[k]->content, "srcip") != NULL)
1111 config_ruleinfo->ckignore|=FTS_SRCIP;
1113 if(strstr(rule_opt[k]->content, "dstip") != NULL)
1115 config_ruleinfo->ckignore|=FTS_DSTIP;
1117 if(strstr(rule_opt[k]->content, "id") != NULL)
1119 config_ruleinfo->ckignore|=FTS_ID;
1121 if(strstr(rule_opt[k]->content,"location")!= NULL)
1123 config_ruleinfo->ckignore|=FTS_LOCATION;
1125 if(strstr(rule_opt[k]->content,"data")!= NULL)
1127 config_ruleinfo->ignore|=FTS_DATA;
1129 if(strstr(rule_opt[k]->content, "name") != NULL)
1131 config_ruleinfo->ckignore|=FTS_NAME;
1134 if(!config_ruleinfo->ckignore)
1136 merror("%s: Wrong check_if_ignored option: '%s'",
1138 rule_opt[k]->content);
1144 merror("%s: Invalid option '%s' for "
1145 "rule '%d'.",ARGV0, rule_opt[k]->element,
1146 config_ruleinfo->sigid);
1154 /* Checking for a valid use of frequency */
1155 if((config_ruleinfo->context_opts ||
1156 config_ruleinfo->frequency) &&
1157 !config_ruleinfo->context)
1159 merror("%s: Invalid use of frequency/context options. "
1160 "Missing if_matched on rule '%d'.",
1161 ARGV0, config_ruleinfo->sigid);
1167 /* If if_matched_group we must have a if_sid or if_group */
1168 if(if_matched_group)
1170 if(!config_ruleinfo->if_sid && !config_ruleinfo->if_group)
1172 os_strdup(if_matched_group,
1173 config_ruleinfo->if_group);
1177 /* If_matched_sid, we need to get the if_sid */
1178 if(config_ruleinfo->if_matched_sid &&
1179 !config_ruleinfo->if_sid &&
1180 !config_ruleinfo->if_group)
1182 os_calloc(16, sizeof(char), config_ruleinfo->if_sid);
1183 snprintf(config_ruleinfo->if_sid, 15, "%d",
1184 config_ruleinfo->if_matched_sid);
1187 /* Checking the regexes */
1190 os_calloc(1, sizeof(OSRegex), config_ruleinfo->regex);
1191 if(!OSRegex_Compile(regex, config_ruleinfo->regex, 0))
1193 merror(REGEX_COMPILE, ARGV0, regex,
1194 config_ruleinfo->regex->error);
1201 /* Adding in match */
1204 os_calloc(1, sizeof(OSMatch), config_ruleinfo->match);
1205 if(!OSMatch_Compile(match, config_ruleinfo->match, 0))
1207 merror(REGEX_COMPILE, ARGV0, match,
1208 config_ruleinfo->match->error);
1218 os_calloc(1, sizeof(OSMatch), config_ruleinfo->id);
1219 if(!OSMatch_Compile(id, config_ruleinfo->id, 0))
1221 merror(REGEX_COMPILE, ARGV0, id,
1222 config_ruleinfo->id->error);
1229 /* Adding srcport */
1232 os_calloc(1, sizeof(OSMatch), config_ruleinfo->srcport);
1233 if(!OSMatch_Compile(srcport, config_ruleinfo->srcport, 0))
1235 merror(REGEX_COMPILE, ARGV0, srcport,
1236 config_ruleinfo->id->error);
1243 /* Adding dstport */
1246 os_calloc(1, sizeof(OSMatch), config_ruleinfo->dstport);
1247 if(!OSMatch_Compile(dstport, config_ruleinfo->dstport, 0))
1249 merror(REGEX_COMPILE, ARGV0, dstport,
1250 config_ruleinfo->id->error);
1257 /* Adding in status */
1260 os_calloc(1, sizeof(OSMatch), config_ruleinfo->status);
1261 if(!OSMatch_Compile(status, config_ruleinfo->status, 0))
1263 merror(REGEX_COMPILE, ARGV0, status,
1264 config_ruleinfo->status->error);
1271 /* Adding in hostname */
1274 os_calloc(1, sizeof(OSMatch), config_ruleinfo->hostname);
1275 if(!OSMatch_Compile(hostname, config_ruleinfo->hostname,0))
1277 merror(REGEX_COMPILE, ARGV0, hostname,
1278 config_ruleinfo->hostname->error);
1285 /* Adding extra data */
1288 os_calloc(1, sizeof(OSMatch), config_ruleinfo->extra_data);
1289 if(!OSMatch_Compile(extra_data,
1290 config_ruleinfo->extra_data, 0))
1292 merror(REGEX_COMPILE, ARGV0, extra_data,
1293 config_ruleinfo->extra_data->error);
1300 /* Adding in program name */
1303 os_calloc(1,sizeof(OSMatch),config_ruleinfo->program_name);
1304 if(!OSMatch_Compile(program_name,
1305 config_ruleinfo->program_name,0))
1307 merror(REGEX_COMPILE, ARGV0, program_name,
1308 config_ruleinfo->program_name->error);
1312 program_name = NULL;
1315 /* Adding in user */
1318 os_calloc(1, sizeof(OSMatch), config_ruleinfo->user);
1319 if(!OSMatch_Compile(user, config_ruleinfo->user, 0))
1321 merror(REGEX_COMPILE, ARGV0, user,
1322 config_ruleinfo->user->error);
1332 os_calloc(1, sizeof(OSMatch), config_ruleinfo->url);
1333 if(!OSMatch_Compile(url, config_ruleinfo->url, 0))
1335 merror(REGEX_COMPILE, ARGV0, url,
1336 config_ruleinfo->url->error);
1343 /* Adding matched_group */
1344 if(if_matched_group)
1346 os_calloc(1, sizeof(OSMatch),
1347 config_ruleinfo->if_matched_group);
1349 if(!OSMatch_Compile(if_matched_group,
1350 config_ruleinfo->if_matched_group,
1353 merror(REGEX_COMPILE, ARGV0, if_matched_group,
1354 config_ruleinfo->if_matched_group->error);
1357 free(if_matched_group);
1358 if_matched_group = NULL;
1361 /* Adding matched_regex */
1362 if(if_matched_regex)
1364 os_calloc(1, sizeof(OSRegex),
1365 config_ruleinfo->if_matched_regex);
1366 if(!OSRegex_Compile(if_matched_regex,
1367 config_ruleinfo->if_matched_regex, 0))
1369 merror(REGEX_COMPILE, ARGV0, if_matched_regex,
1370 config_ruleinfo->if_matched_regex->error);
1373 free(if_matched_regex);
1374 if_matched_regex = NULL;
1376 } /* enf of elements block */
1379 /* Assigning an active response to the rule */
1380 Rule_AddAR(config_ruleinfo);
1382 j++; /* next rule */
1385 /* Creating the last_events if necessary */
1386 if(config_ruleinfo->context)
1389 os_calloc(MAX_LAST_EVENTS + 1, sizeof(char *),
1390 config_ruleinfo->last_events);
1392 /* Zeroing each entry */
1393 for(;ii<=MAX_LAST_EVENTS;ii++)
1395 config_ruleinfo->last_events[ii] = NULL;
1400 /* Adding the rule to the rules list.
1401 * Only the template rules are supposed
1402 * to be at the top level. All others
1403 * will be a "child" of someone.
1405 if(config_ruleinfo->sigid < 10)
1407 OS_AddRule(config_ruleinfo);
1409 else if(config_ruleinfo->alert_opts & DO_OVERWRITE)
1411 if(!OS_AddRuleInfo(NULL, config_ruleinfo,
1412 config_ruleinfo->sigid))
1414 merror("%s: Overwrite rule '%d' not found.",
1415 ARGV0, config_ruleinfo->sigid);
1422 OS_AddChild(config_ruleinfo);
1425 /* Cleaning what we do not need */
1426 if(config_ruleinfo->if_group)
1428 free(config_ruleinfo->if_group);
1429 config_ruleinfo->if_group = NULL;
1432 /* Setting the event_search pointer */
1433 if(config_ruleinfo->if_matched_sid)
1435 config_ruleinfo->event_search =
1436 (void *)Search_LastSids;
1438 /* Marking rules that match this id */
1439 OS_MarkID(NULL, config_ruleinfo);
1442 /* Marking the rules that match if_matched_group */
1443 else if(config_ruleinfo->if_matched_group)
1446 config_ruleinfo->group_search = OSList_Create();
1447 if(!config_ruleinfo->group_search)
1449 ErrorExit(MEM_ERROR, ARGV0);
1452 /* Marking rules that match this group */
1453 OS_MarkGroup(NULL, config_ruleinfo);
1455 /* Setting function pointer */
1456 config_ruleinfo->event_search =
1457 (void *)Search_LastGroups;
1459 else if(config_ruleinfo->context)
1461 if((config_ruleinfo->context == 1) &&
1462 (config_ruleinfo->context_opts & SAME_DODIFF))
1464 config_ruleinfo->context = 0;
1468 config_ruleinfo->event_search =
1469 (void *)Search_LastEvents;
1473 } /* while(rule[j]) */
1477 } /* while (node[i]) */
1479 /* Cleaning global node */
1485 RuleNode *dbg_node = OS_GetFirstRule();
1490 RuleNode *child_node = dbg_node->child;
1492 printf("** Child Node for %d **\n",dbg_node->ruleinfo->sigid);
1495 child_node = child_node->next;
1498 dbg_node = dbg_node->next;
1503 /* Done over here */
1509 * Allocate memory at "*at" and copy *str to it.
1510 * If *at already exist, realloc the memory and cat str
1512 * It will return the new string
1514 char *loadmemory(char *at, char *str)
1519 if((strsize = strlen(str)) < OS_SIZE_2048)
1521 at = calloc(strsize+1,sizeof(char));
1524 merror(MEM_ERROR,ARGV0);
1527 strncpy(at,str,strsize);
1532 merror(SIZE_ERROR,ARGV0,str);
1536 else /*at is not null. Need to reallocat its memory and copy str to it*/
1538 int strsize = strlen(str);
1539 int atsize = strlen(at);
1540 int finalsize = atsize+strsize+1;
1542 if((atsize > OS_SIZE_2048) || (strsize > OS_SIZE_2048))
1544 merror(SIZE_ERROR,ARGV0,str);
1548 at = realloc(at, (finalsize)*sizeof(char));
1552 merror(MEM_ERROR,ARGV0);
1556 strncat(at,str,strsize);
1558 at[finalsize-1]='\0';
1566 RuleInfoDetail *zeroinfodetails(int type, char *data)
1568 RuleInfoDetail *info_details_pt = NULL;
1570 info_details_pt = (RuleInfoDetail *)calloc(1,sizeof(RuleInfoDetail));
1572 if (info_details_pt == NULL)
1574 ErrorExit(MEM_ERROR,ARGV0);
1577 info_details_pt->type = type;
1580 os_strdup(data, info_details_pt->data);
1582 info_details_pt->next = NULL;
1585 return(info_details_pt);
1589 RuleInfo *zerorulemember(int id, int level,
1590 int maxsize, int frequency,
1591 int timeframe, int noalert,
1592 int ignore_time, int overwrite)
1594 RuleInfo *ruleinfo_pt = NULL;
1596 /* Allocation memory for structure */
1597 ruleinfo_pt = (RuleInfo *)calloc(1,sizeof(RuleInfo));
1599 if(ruleinfo_pt == NULL)
1601 ErrorExit(MEM_ERROR,ARGV0);
1604 /* Default values */
1605 ruleinfo_pt->level = level;
1607 /* Default category is syslog */
1608 ruleinfo_pt->category = SYSLOG;
1610 ruleinfo_pt->ar = NULL;
1612 ruleinfo_pt->context = 0;
1614 ruleinfo_pt->sigid = id;
1615 ruleinfo_pt->firedtimes = 0;
1616 ruleinfo_pt->maxsize = maxsize;
1617 ruleinfo_pt->frequency = frequency;
1618 if(ruleinfo_pt->frequency > _max_freq)
1620 _max_freq = ruleinfo_pt->frequency;
1622 ruleinfo_pt->ignore_time = ignore_time;
1623 ruleinfo_pt->timeframe = timeframe;
1624 ruleinfo_pt->time_ignored = 0;
1626 ruleinfo_pt->context_opts = 0;
1627 ruleinfo_pt->alert_opts = 0;
1628 ruleinfo_pt->ignore = 0;
1629 ruleinfo_pt->ckignore = 0;
1633 ruleinfo_pt->alert_opts |= NO_ALERT;
1635 if(Config.mailbylevel <= level)
1636 ruleinfo_pt->alert_opts |= DO_MAILALERT;
1637 if(Config.logbylevel <= level)
1638 ruleinfo_pt->alert_opts |= DO_LOGALERT;
1640 /* Overwriting a rule */
1643 ruleinfo_pt->alert_opts |= DO_OVERWRITE;
1646 ruleinfo_pt->day_time = NULL;
1647 ruleinfo_pt->week_day = NULL;
1649 ruleinfo_pt->group = NULL;
1650 ruleinfo_pt->regex = NULL;
1651 ruleinfo_pt->match = NULL;
1652 ruleinfo_pt->decoded_as = 0;
1654 ruleinfo_pt->comment = NULL;
1655 ruleinfo_pt->info = NULL;
1656 ruleinfo_pt->cve = NULL;
1657 ruleinfo_pt->info_details = NULL;
1659 ruleinfo_pt->if_sid = NULL;
1660 ruleinfo_pt->if_group = NULL;
1661 ruleinfo_pt->if_level = NULL;
1663 ruleinfo_pt->if_matched_regex = NULL;
1664 ruleinfo_pt->if_matched_group = NULL;
1665 ruleinfo_pt->if_matched_sid = 0;
1667 ruleinfo_pt->user = NULL;
1668 ruleinfo_pt->srcip = NULL;
1669 ruleinfo_pt->srcport = NULL;
1670 ruleinfo_pt->dstip = NULL;
1671 ruleinfo_pt->dstport = NULL;
1672 ruleinfo_pt->url = NULL;
1673 ruleinfo_pt->id = NULL;
1674 ruleinfo_pt->status = NULL;
1675 ruleinfo_pt->hostname = NULL;
1676 ruleinfo_pt->program_name = NULL;
1677 ruleinfo_pt->action = NULL;
1679 /* Zeroing last matched events */
1680 ruleinfo_pt->__frequency = 0;
1681 ruleinfo_pt->last_events = NULL;
1683 /* zeroing the list of previous matches */
1684 ruleinfo_pt->sid_prev_matched = NULL;
1685 ruleinfo_pt->group_prev_matched = NULL;
1687 ruleinfo_pt->sid_search = NULL;
1688 ruleinfo_pt->group_search = NULL;
1690 ruleinfo_pt->event_search = NULL;
1691 ruleinfo_pt->compiled_rule = NULL;
1692 ruleinfo_pt->lists = NULL;
1694 return(ruleinfo_pt);
1697 int get_info_attributes(char **attributes, char **values)
1699 char *xml_type = "type";
1702 return(RULEINFODETAIL_TEXT);
1704 while(attributes[k])
1708 merror("rules_op: Entry info type \"%s\" does not have a value",
1712 else if(strcasecmp(attributes[k],xml_type) == 0)
1714 if(strcmp(values[k], "text") == 0)
1716 return(RULEINFODETAIL_TEXT);
1718 else if(strcmp(values[k], "link") == 0)
1720 return(RULEINFODETAIL_LINK);
1722 else if(strcmp(values[k], "cve") == 0)
1724 return(RULEINFODETAIL_CVE);
1726 else if(strcmp(values[k], "osvdb") == 0)
1728 return(RULEINFODETAIL_OSVDB);
1732 return(RULEINFODETAIL_TEXT);
1735 /* Get the attributes */
1736 int getattributes(char **attributes, char **values,
1737 int *id, int *level,
1738 int *maxsize, int *timeframe,
1739 int *frequency, int *accuracy,
1740 int *noalert, int *ignore_time, int *overwrite)
1744 char *xml_id = "id";
1745 char *xml_level = "level";
1746 char *xml_maxsize = "maxsize";
1747 char *xml_timeframe = "timeframe";
1748 char *xml_frequency = "frequency";
1749 char *xml_accuracy = "accuracy";
1750 char *xml_noalert = "noalert";
1751 char *xml_ignore_time = "ignore";
1752 char *xml_overwrite = "overwrite";
1755 /* Getting attributes */
1756 while(attributes[k])
1760 merror("rules_op: Attribute \"%s\" without value."
1764 /* Getting rule Id */
1765 else if(strcasecmp(attributes[k],xml_id) == 0)
1767 if(OS_StrIsNum(values[k]))
1769 sscanf(values[k],"%6d",id);
1773 merror("rules_op: Invalid rule id: %s. "
1780 else if(strcasecmp(attributes[k],xml_level) == 0)
1782 if(OS_StrIsNum(values[k]))
1784 sscanf(values[k],"%4d",level);
1788 merror("rules_op: Invalid level: %s. "
1794 /* Getting maxsize */
1795 else if(strcasecmp(attributes[k],xml_maxsize) == 0)
1797 if(OS_StrIsNum(values[k]))
1799 sscanf(values[k],"%4d",maxsize);
1803 merror("rules_op: Invalid maxsize: %s. "
1809 /* Getting timeframe */
1810 else if(strcasecmp(attributes[k],xml_timeframe) == 0)
1812 if(OS_StrIsNum(values[k]))
1814 sscanf(values[k],"%5d",timeframe);
1818 merror("rules_op: Invalid timeframe: %s. "
1824 /* Getting frequency */
1825 else if(strcasecmp(attributes[k],xml_frequency) == 0)
1827 if(OS_StrIsNum(values[k]))
1829 sscanf(values[k],"%4d",frequency);
1833 merror("rules_op: Invalid frequency: %s. "
1840 else if(strcasecmp(attributes[k],xml_accuracy) == 0)
1842 if(OS_StrIsNum(values[k]))
1844 sscanf(values[k],"%4d",accuracy);
1848 merror("rules_op: Invalid accuracy: %s. "
1854 /* Rule ignore_time */
1855 else if(strcasecmp(attributes[k],xml_ignore_time) == 0)
1857 if(OS_StrIsNum(values[k]))
1859 sscanf(values[k],"%6d",ignore_time);
1863 merror("rules_op: Invalid ignore_time: %s. "
1870 else if(strcasecmp(attributes[k],xml_noalert) == 0)
1874 else if(strcasecmp(attributes[k], xml_overwrite) == 0)
1876 if(strcmp(values[k], "yes") == 0)
1880 else if(strcmp(values[k], "no") == 0)
1886 merror("rules_op: Invalid overwrite: %s. "
1887 "Can only by 'yes' or 'no'.", values[k]);
1893 merror("rules_op: Invalid attribute \"%s\". "
1894 "Only id, level, maxsize, accuracy, noalert and timeframe "
1895 "are allowed.", attributes[k]);
1904 /* Bind active responses to the rule.
1907 void Rule_AddAR(RuleInfo *rule_config)
1909 int rule_ar_size = 0;
1911 int rule_real_level = 0;
1913 OSListNode *my_ars_node;
1916 /* Setting the correctly levels
1917 * We play internally with the rules, to set
1918 * the priorities... Rules with 0 of accuracy,
1919 * receive a low level and go down in the list
1921 if(rule_config->level == 9900)
1922 rule_real_level = 0;
1924 else if(rule_config->level >= 100)
1925 rule_real_level = rule_config->level/100;
1928 /* No AR for ignored rules */
1929 if(rule_real_level == 0)
1934 /* No AR when options no_ar is set */
1935 if(rule_config->alert_opts & NO_AR)
1940 if(!active_responses)
1945 /* Looping on all AR */
1946 my_ars_node = OSList_GetFirstNode(active_responses);
1949 active_response *my_ar;
1952 my_ar = (active_response *)my_ars_node->data;
1955 /* Checking if the level for the ar is higher */
1958 if(rule_real_level >= my_ar->level)
1964 /* Checking if group matches */
1965 if(my_ar->rules_group)
1967 if(OS_Regex(my_ar->rules_group, rule_config->group))
1973 /* Checking if rule id matches */
1977 char *str_pt = my_ar->rules_id;
1979 while(*str_pt != '\0')
1981 /* We allow spaces in between */
1988 /* If is digit, we get the value
1989 * and search for the next digit
1992 else if(isdigit((int)*str_pt))
1994 r_id = atoi(str_pt);
1996 /* mark to ar if id matches */
1997 if(r_id == rule_config->sigid)
2002 str_pt = strchr(str_pt, ',');
2013 /* Checking for duplicate commas */
2014 else if(*str_pt == ',')
2025 } /* eof of rules_id */
2028 /* Bind AR to the rule */
2033 rule_config->ar = realloc(rule_config->ar,
2035 *sizeof(active_response *));
2037 /* Always set the last node to NULL */
2038 rule_config->ar[rule_ar_size - 1] = my_ar;
2039 rule_config->ar[rule_ar_size] = NULL;
2042 my_ars_node = OSList_GetNextNode(active_responses);
2050 void printRuleinfo(RuleInfo *rule, int node)
2052 debug1("%d : rule:%d, level %d, timeout: %d",
2061 /* Add Rule to hash. */
2062 int AddHash_Rule(RuleNode *node)
2069 snprintf(_id_key, 14, "%d", node->ruleinfo->sigid);
2070 os_strdup(_id_key, id_key);
2073 /* Adding key to hash. */
2074 OSHash_Add(Config.g_rules_hash, id_key, node->ruleinfo);
2077 AddHash_Rule(node->child);
2089 int _setlevels(RuleNode *node, int nnode)
2094 if(node->ruleinfo->level == 9900)
2095 node->ruleinfo->level = 0;
2097 if(node->ruleinfo->level >= 100)
2098 node->ruleinfo->level/=100;
2102 /* Rule information */
2103 printRuleinfo(node->ruleinfo, nnode);
2108 chl_size = _setlevels(node->child, nnode+1);
2119 /* test if a rule id exists
2120 * return 1 when exists
2123 int doesRuleExist(int sid, RuleNode *r_node)
2125 /* start from the beginning of the list by default */
2127 r_node = OS_GetFirstRule();
2131 /* Checking if the sigid matches */
2132 if(r_node->ruleinfo->sigid == sid)
2135 /* Checking if the rule has a child */
2138 /* check recursive */
2139 if(doesRuleExist(sid, r_node->child))
2143 /* go to the next rule */
2144 r_node = r_node->next;