3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 2) as published by the FSF - Free Software
11 * License details at the LICENSE file included with OSSEC or
12 * online at: http://www.ossec.net/en/licensing.html
19 #include "eventinfo.h"
20 #include "compiled_rules/compiled_rules.h"
23 /* Chaging path for test rule. */
26 #define RULEPATH "rules/"
31 /* Internal functions */
32 int getattributes(char **attributes,
35 int *maxsize, int *timeframe,
36 int *frequency, int *accuracy,
37 int *noalert, int *ignore_time, int *overwrite);
40 void Rule_AddAR(RuleInfo *config_rule);
41 char *loadmemory(char *at, char *str);
42 int getDecoderfromlist(char *name);
48 /* Rules_OP_ReadRules, v0.1, 2005/07/04
49 * Will initialize the rules list
51 void Rules_OP_CreateRules()
54 /* Initializing the rule list */
60 /* Rules_OP_ReadRules, v0.3, 2005/03/21
62 * v0.3: Fixed many memory problems.
64 int Rules_OP_ReadRules(char * rulefile)
70 /* These are the available options for the rule configuration */
72 char *xml_group = "group";
73 char *xml_rule = "rule";
75 char *xml_regex = "regex";
76 char *xml_match = "match";
77 char *xml_decoded = "decoded_as";
78 char *xml_category = "category";
79 char *xml_cve = "cve";
80 char *xml_info = "info";
81 char *xml_day_time = "time";
82 char *xml_week_day = "weekday";
83 char *xml_comment = "description";
84 char *xml_ignore = "ignore";
85 char *xml_check_if_ignored = "check_if_ignored";
87 char *xml_srcip = "srcip";
88 char *xml_srcport = "srcport";
89 char *xml_dstip = "dstip";
90 char *xml_dstport = "dstport";
91 char *xml_user = "user";
92 char *xml_url = "url";
94 char *xml_data = "extra_data";
95 char *xml_hostname = "hostname";
96 char *xml_program_name = "program_name";
97 char *xml_status = "status";
98 char *xml_action = "action";
99 char *xml_compiled = "compiled_rule";
101 char *xml_list = "list";
102 char *xml_list_lookup = "lookup";
103 char *xml_list_field = "field";
104 char *xml_list_cvalue = "check_value";
105 char *xml_match_key = "match_key";
106 char *xml_not_match_key = "not_match_key";
107 char *xml_match_key_value = "match_key_value";
108 char *xml_address_key = "address_match_key";
109 char *xml_not_address_key = "not_address_match_key";
110 char *xml_address_key_value = "address_match_key_value";
112 char *xml_if_sid = "if_sid";
113 char *xml_if_group = "if_group";
114 char *xml_if_level = "if_level";
115 char *xml_fts = "if_fts";
117 char *xml_if_matched_regex = "if_matched_regex";
118 char *xml_if_matched_group = "if_matched_group";
119 char *xml_if_matched_sid = "if_matched_sid";
121 char *xml_same_source_ip = "same_source_ip";
122 char *xml_same_src_port = "same_src_port";
123 char *xml_same_dst_port = "same_dst_port";
124 char *xml_same_user = "same_user";
125 char *xml_same_location = "same_location";
126 char *xml_same_id = "same_id";
127 char *xml_dodiff = "check_diff";
129 char *xml_different_url = "different_url";
131 char *xml_notsame_source_ip = "not_same_source_ip";
132 char *xml_notsame_user = "not_same_user";
133 char *xml_notsame_agent = "not_same_agent";
134 char *xml_notsame_id = "not_same_id";
136 char *xml_options = "options";
141 int default_timeframe = 360;
144 /* If no directory in the rulefile add the default */
145 if((strchr(rulefile, '/')) == NULL)
147 /* Building the rule file name + path */
148 i = strlen(RULEPATH) + strlen(rulefile) + 2;
149 rulepath = (char *)calloc(i,sizeof(char));
152 ErrorExit(MEM_ERROR,ARGV0);
154 snprintf(rulepath,i,"%s/%s",RULEPATH,rulefile);
158 os_strdup(rulefile, rulepath);
159 debug1("%s is the rulefile", rulefile);
160 debug1("Not modifing the rule path");
166 /* Reading the XML */
167 if(OS_ReadXML(rulepath,&xml) < 0)
169 merror(XML_ERROR, ARGV0, rulepath, xml.err, xml.err_line);
176 debug2("%s: DEBUG: read xml for rule.", ARGV0);
180 /* Applying any variable found */
181 if(OS_ApplyVariables(&xml) != 0)
183 merror(XML_ERROR_VAR, ARGV0, rulepath, xml.err);
189 debug2("%s: DEBUG: XML Variables applied.", ARGV0);
192 /* Getting the root elements */
193 node = OS_GetElementsbyNode(&xml,NULL);
196 merror(CONFIG_ERROR, ARGV0, rulepath);
202 /* Zeroing the rule memory -- not used anymore */
206 /* Getting default time frame */
207 default_timeframe = getDefine_Int("analysisd",
212 /* Checking if there is any invalid global option */
217 if(strcasecmp(node[i]->element,xml_group) != 0)
219 merror("rules_op: Invalid root element \"%s\"."
220 "Only \"group\" is allowed",node[i]->element);
224 if((!node[i]->attributes) || (!node[i]->values)||
225 (!node[i]->values[0]) || (!node[i]->attributes[0]) ||
226 (strcasecmp(node[i]->attributes[0],"name") != 0) ||
227 (node[i]->attributes[1]))
229 merror("rules_op: Invalid root element '%s'."
230 "Only the group name is allowed",node[i]->element);
237 merror(XML_READ_ERROR, ARGV0);
245 /* Getting the rules now */
249 XML_NODE rule = NULL;
253 /* Getting all rules for a global group */
254 rule = OS_GetElementsbyNode(&xml,node[i]);
257 merror("%s: Group '%s' without any rule.",
258 ARGV0, node[i]->element);
265 RuleInfo *config_ruleinfo = NULL;
268 /* Checking if the rule element is correct */
269 if((!rule[j]->element)||
270 (strcasecmp(rule[j]->element,xml_rule) != 0))
272 merror("%s: Invalid configuration. '%s' is not "
273 "a valid element.", ARGV0, rule[j]->element);
279 /* Checking for the attributes of the rule */
280 if((!rule[j]->attributes) || (!rule[j]->values))
282 merror("%s: Invalid rule '%d'. You must specify"
283 " an ID and a level at least.", ARGV0, j);
289 /* Attribute block */
291 int id = -1,level = -1,maxsize = 0,timeframe = 0;
292 int frequency = 0, accuracy = 1, noalert = 0, ignore_time = 0;
295 /* Getting default time frame */
296 timeframe = default_timeframe;
299 if(getattributes(rule[j]->attributes,rule[j]->values,
300 &id,&level,&maxsize,&timeframe,
301 &frequency,&accuracy,&noalert,
302 &ignore_time, &overwrite) < 0)
304 merror("%s: Invalid attribute for rule.", ARGV0);
309 if((id == -1) || (level == -1))
311 merror("%s: No rule id or level specified for "
312 "rule '%d'.",ARGV0, j);
317 /* Allocating memory and initializing structure */
318 config_ruleinfo = zerorulemember(id, level, maxsize,
320 noalert, ignore_time, overwrite);
323 /* If rule is 0, set it to level 99 to have high priority.
324 * set it to 0 again later
326 if(config_ruleinfo->level == 0)
327 config_ruleinfo->level = 99;
330 /* Each level now is going to be multiplied by 100.
331 * If the accuracy is set to 0 we don't multiply,
332 * so it will be at the end of the list. We will
333 * divide by 100 later.
337 config_ruleinfo->level *= 100;
340 if(config_ruleinfo->maxsize > 0)
342 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
344 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
348 } /* end attributes/memory allocation block */
351 /* Here we can assign the group name to the rule.
352 * The level is correct so the rule is probably going to
355 os_strdup(node[i]->values[0], config_ruleinfo->group);
358 /* Rule elements block */
362 int count_info_detail = 0;
363 RuleInfoDetail *last_info_detail = NULL;
367 char *if_matched_regex = NULL;
368 char *if_matched_group = NULL;
371 char *srcport = NULL;
372 char *dstport = NULL;
374 char *hostname = NULL;
375 char *extra_data = NULL;
376 char *program_name = NULL;
378 XML_NODE rule_opt = NULL;
379 rule_opt = OS_GetElementsbyNode(&xml,rule[j]);
382 merror("%s: Rule '%d' without any option. "
383 "It may lead to false positives and some "
384 "other problems for the system. Exiting.",
385 ARGV0, config_ruleinfo->sigid);
392 if((!rule_opt[k]->element)||(!rule_opt[k]->content))
394 else if(strcasecmp(rule_opt[k]->element,xml_regex)==0)
398 rule_opt[k]->content);
400 else if(strcasecmp(rule_opt[k]->element,xml_match)==0)
404 rule_opt[k]->content);
406 else if(strcasecmp(rule_opt[k]->element, xml_decoded)==0)
408 config_ruleinfo->decoded_as =
409 getDecoderfromlist(rule_opt[k]->content);
411 if(config_ruleinfo->decoded_as == 0)
413 merror("%s: Invalid decoder name: '%s'.",
414 ARGV0, rule_opt[k]->content);
419 else if(strcasecmp(rule_opt[k]->element,xml_cve)==0)
421 if(config_ruleinfo->info_details == NULL)
423 config_ruleinfo->info_details = zeroinfodetails(RULEINFODETAIL_CVE,
424 rule_opt[k]->content);
428 for (last_info_detail = config_ruleinfo->info_details;
429 last_info_detail->next != NULL;
430 last_info_detail = last_info_detail->next)
434 /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */
435 if (count_info_detail <= MAX_RULEINFODETAIL)
437 last_info_detail->next = zeroinfodetails(RULEINFODETAIL_CVE,
438 rule_opt[k]->content);
442 /* keep old methods for now */
443 config_ruleinfo->cve=
444 loadmemory(config_ruleinfo->cve,
445 rule_opt[k]->content);
447 else if(strcasecmp(rule_opt[k]->element,xml_info)==0)
450 info_type = get_info_attributes(rule_opt[k]->attributes,
451 rule_opt[k]->values);
452 debug1("info_type = %d", info_type);
454 if(config_ruleinfo->info_details == NULL)
456 config_ruleinfo->info_details = zeroinfodetails(info_type,
457 rule_opt[k]->content);
461 for (last_info_detail = config_ruleinfo->info_details;
462 last_info_detail->next != NULL;
463 last_info_detail = last_info_detail->next) {
466 /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */
467 if (count_info_detail <= MAX_RULEINFODETAIL) {
468 last_info_detail->next = zeroinfodetails(info_type, rule_opt[k]->content);
473 /* keep old methods for now */
474 config_ruleinfo->info=
475 loadmemory(config_ruleinfo->info,
476 rule_opt[k]->content);
478 else if(strcasecmp(rule_opt[k]->element,xml_day_time)==0)
480 config_ruleinfo->day_time =
481 OS_IsValidTime(rule_opt[k]->content);
482 if(!config_ruleinfo->day_time)
484 merror(INVALID_CONFIG, ARGV0,
485 rule_opt[k]->element,
486 rule_opt[k]->content);
490 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
491 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
493 else if(strcasecmp(rule_opt[k]->element,xml_week_day)==0)
495 config_ruleinfo->week_day =
496 OS_IsValidDay(rule_opt[k]->content);
498 if(!config_ruleinfo->week_day)
500 merror(INVALID_CONFIG, ARGV0,
501 rule_opt[k]->element,
502 rule_opt[k]->content);
505 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
506 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
508 else if(strcasecmp(rule_opt[k]->element,xml_group)==0)
510 config_ruleinfo->group =
511 loadmemory(config_ruleinfo->group,
512 rule_opt[k]->content);
514 else if(strcasecmp(rule_opt[k]->element,xml_comment)==0)
518 newline = strchr(rule_opt[k]->content, '\n');
524 config_ruleinfo->comment=
525 loadmemory(config_ruleinfo->comment,
526 rule_opt[k]->content);
528 else if(strcasecmp(rule_opt[k]->element,xml_srcip)==0)
532 /* Getting size of source ip list */
533 while(config_ruleinfo->srcip &&
534 config_ruleinfo->srcip[ip_s])
539 config_ruleinfo->srcip =
540 realloc(config_ruleinfo->srcip,
541 (ip_s + 2) * sizeof(os_ip *));
544 /* Allocating memory for the individual entries */
545 os_calloc(1, sizeof(os_ip),
546 config_ruleinfo->srcip[ip_s]);
547 config_ruleinfo->srcip[ip_s +1] = NULL;
550 /* Checking if the ip is valid */
551 if(!OS_IsValidIP(rule_opt[k]->content,
552 config_ruleinfo->srcip[ip_s]))
554 merror(INVALID_IP, ARGV0, rule_opt[k]->content);
558 if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
559 config_ruleinfo->alert_opts |= DO_PACKETINFO;
561 else if(strcasecmp(rule_opt[k]->element,xml_dstip)==0)
565 /* Getting size of source ip list */
566 while(config_ruleinfo->dstip &&
567 config_ruleinfo->dstip[ip_s])
572 config_ruleinfo->dstip =
573 realloc(config_ruleinfo->dstip,
574 (ip_s + 2) * sizeof(os_ip *));
577 /* Allocating memory for the individual entries */
578 os_calloc(1, sizeof(os_ip),
579 config_ruleinfo->dstip[ip_s]);
580 config_ruleinfo->dstip[ip_s +1] = NULL;
583 /* Checking if the ip is valid */
584 if(!OS_IsValidIP(rule_opt[k]->content,
585 config_ruleinfo->dstip[ip_s]))
587 merror(INVALID_IP, ARGV0, rule_opt[k]->content);
591 if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
592 config_ruleinfo->alert_opts |= DO_PACKETINFO;
594 else if(strcasecmp(rule_opt[k]->element,xml_user)==0)
598 rule_opt[k]->content);
600 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
601 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
603 else if(strcasecmp(rule_opt[k]->element,xml_id)==0)
607 rule_opt[k]->content);
609 else if(strcasecmp(rule_opt[k]->element,xml_srcport)==0)
613 rule_opt[k]->content);
614 if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
615 config_ruleinfo->alert_opts |= DO_PACKETINFO;
617 else if(strcasecmp(rule_opt[k]->element,xml_dstport)==0)
621 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_status)==0)
630 rule_opt[k]->content);
632 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
633 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
635 else if(strcasecmp(rule_opt[k]->element,xml_hostname)==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_data)==0)
647 loadmemory(extra_data,
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,
654 xml_program_name)==0)
657 loadmemory(program_name,
658 rule_opt[k]->content);
660 else if(strcasecmp(rule_opt[k]->element,xml_action)==0)
662 config_ruleinfo->action =
663 loadmemory(config_ruleinfo->action,
664 rule_opt[k]->content);
666 else if(strcasecmp(rule_opt[k]->element,xml_list)==0)
668 debug1("-> %s == %s",rule_opt[k]->element, xml_list);
669 if (rule_opt[k]->attributes && rule_opt[k]->values && rule_opt[k]->content)
673 OSMatch *matcher=NULL;
674 int lookup_type = LR_STRING_MATCH;
675 while(rule_opt[k]->attributes[list_att_num])
677 if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_lookup) == 0)
679 if(strcasecmp(rule_opt[k]->values[list_att_num],xml_match_key) == 0)
680 lookup_type = LR_STRING_MATCH;
681 else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_not_match_key)==0)
682 lookup_type = LR_STRING_NOT_MATCH;
683 else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_match_key_value)==0)
684 lookup_type = LR_STRING_MATCH_VALUE;
685 else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_address_key)==0)
686 lookup_type = LR_ADDRESS_MATCH;
687 else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_not_address_key)==0)
688 lookup_type = LR_ADDRESS_NOT_MATCH;
689 else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_address_key_value)==0)
690 lookup_type = LR_ADDRESS_MATCH_VALUE;
693 merror(INVALID_CONFIG, ARGV0,
694 rule_opt[k]->element,
695 rule_opt[k]->content);
696 merror("%s: List match lookup=\"%s\" is not valid.",
697 ARGV0,rule_opt[k]->values[list_att_num]);
701 else if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_field)==0)
703 if(strcasecmp(rule_opt[k]->values[list_att_num],xml_srcip)==0)
704 rule_type = RULE_SRCIP;
705 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_srcport)==0)
706 rule_type = RULE_SRCPORT;
707 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_dstip)==0)
708 rule_type = RULE_DSTIP;
709 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_dstport)==0)
710 rule_type = RULE_DSTPORT;
711 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_user)==0)
712 rule_type = RULE_USER;
713 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_url)==0)
714 rule_type = RULE_URL;
715 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_id)==0)
717 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_hostname)==0)
718 rule_type = RULE_HOSTNAME;
719 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_program_name)==0)
720 rule_type = RULE_PROGRAM_NAME;
721 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_status)==0)
722 rule_type = RULE_STATUS;
723 else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_action)==0)
724 rule_type = RULE_ACTION;
727 merror(INVALID_CONFIG, ARGV0,
728 rule_opt[k]->element,
729 rule_opt[k]->content);
730 merror("%s: List match field=\"%s\" is not valid.",
731 ARGV0,rule_opt[k]->values[list_att_num]);
735 else if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_cvalue)==0)
737 os_calloc(1, sizeof(OSMatch), matcher);
738 if(!OSMatch_Compile(rule_opt[k]->values[list_att_num], matcher, 0))
740 merror(INVALID_CONFIG, ARGV0,
741 rule_opt[k]->element,
742 rule_opt[k]->content);
743 merror(REGEX_COMPILE,
745 rule_opt[k]->values[list_att_num],
752 merror("%s:List feild=\"%s\" is not valid",ARGV0,
753 rule_opt[k]->values[list_att_num]);
754 merror(INVALID_CONFIG, ARGV0,
755 rule_opt[k]->element, rule_opt[k]->content);
762 merror("%s:List requires the field=\"\" Attrubute",ARGV0);
763 merror(INVALID_CONFIG, ARGV0,
764 rule_opt[k]->element, rule_opt[k]->content);
768 /* Wow it's all ready - this seams too complex to get to this point */
769 config_ruleinfo->lists = OS_AddListRule(config_ruleinfo->lists,
772 rule_opt[k]->content,
774 if (config_ruleinfo->lists == NULL)
776 merror("%s: List error: Could not load %s", ARGV0, rule_opt[k]->content);
782 merror("%s:List must have a correctly formatted feild attribute",
784 merror(INVALID_CONFIG,
786 rule_opt[k]->element,
787 rule_opt[k]->content);
790 /* xml_list eval is done */
792 else if(strcasecmp(rule_opt[k]->element,xml_url)==0)
796 rule_opt[k]->content);
798 else if(strcasecmp(rule_opt[k]->element, xml_compiled)==0)
802 while(compiled_rules_name[it_id])
804 if(strcmp(compiled_rules_name[it_id],
805 rule_opt[k]->content) == 0)
810 /* checking if the name is valid. */
811 if(!compiled_rules_name[it_id])
813 merror("%s: ERROR: Compiled rule not found: '%s'",
814 ARGV0, rule_opt[k]->content);
815 merror(INVALID_CONFIG, ARGV0,
816 rule_opt[k]->element, rule_opt[k]->content);
821 config_ruleinfo->compiled_rule = compiled_rules_list[it_id];
822 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
823 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
826 /* We allow these four categories so far */
827 else if(strcasecmp(rule_opt[k]->element, xml_category)==0)
829 if(strcmp(rule_opt[k]->content, "firewall") == 0)
831 config_ruleinfo->category = FIREWALL;
833 else if(strcmp(rule_opt[k]->content, "ids") == 0)
835 config_ruleinfo->category = IDS;
837 else if(strcmp(rule_opt[k]->content, "syslog") == 0)
839 config_ruleinfo->category = SYSLOG;
841 else if(strcmp(rule_opt[k]->content, "web-log") == 0)
843 config_ruleinfo->category = WEBLOG;
845 else if(strcmp(rule_opt[k]->content, "squid") == 0)
847 config_ruleinfo->category = SQUID;
849 else if(strcmp(rule_opt[k]->content,"windows") == 0)
851 config_ruleinfo->category = WINDOWS;
853 else if(strcmp(rule_opt[k]->content,"ossec") == 0)
855 config_ruleinfo->category = OSSEC_RL;
859 merror(INVALID_CAT, ARGV0, rule_opt[k]->content);
863 else if(strcasecmp(rule_opt[k]->element,xml_if_sid)==0)
865 config_ruleinfo->if_sid=
866 loadmemory(config_ruleinfo->if_sid,
867 rule_opt[k]->content);
869 else if(strcasecmp(rule_opt[k]->element,xml_if_level)==0)
871 if(!OS_StrIsNum(rule_opt[k]->content))
873 merror(INVALID_CONFIG, ARGV0,
875 rule_opt[k]->content);
879 config_ruleinfo->if_level=
880 loadmemory(config_ruleinfo->if_level,
881 rule_opt[k]->content);
883 else if(strcasecmp(rule_opt[k]->element,xml_if_group)==0)
885 config_ruleinfo->if_group=
886 loadmemory(config_ruleinfo->if_group,
887 rule_opt[k]->content);
889 else if(strcasecmp(rule_opt[k]->element,
890 xml_if_matched_regex) == 0)
892 config_ruleinfo->context = 1;
894 loadmemory(if_matched_regex,
895 rule_opt[k]->content);
897 else if(strcasecmp(rule_opt[k]->element,
898 xml_if_matched_group) == 0)
900 config_ruleinfo->context = 1;
902 loadmemory(if_matched_group,
903 rule_opt[k]->content);
905 else if(strcasecmp(rule_opt[k]->element,
906 xml_if_matched_sid) == 0)
908 config_ruleinfo->context = 1;
909 if(!OS_StrIsNum(rule_opt[k]->content))
911 merror(INVALID_CONFIG, ARGV0,
913 rule_opt[k]->content);
916 config_ruleinfo->if_matched_sid =
917 atoi(rule_opt[k]->content);
920 else if(strcasecmp(rule_opt[k]->element,
921 xml_same_source_ip)==0)
923 config_ruleinfo->context_opts|= SAME_SRCIP;
925 else if(strcasecmp(rule_opt[k]->element,
926 xml_same_src_port)==0)
928 config_ruleinfo->context_opts|= SAME_SRCPORT;
930 if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
931 config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
933 else if(strcasecmp(rule_opt[k]->element,
936 config_ruleinfo->context++;
937 config_ruleinfo->context_opts|= SAME_DODIFF;
938 if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
939 config_ruleinfo->alert_opts |= DO_EXTRAINFO;
941 else if(strcasecmp(rule_opt[k]->element,
942 xml_same_dst_port) == 0)
944 config_ruleinfo->context_opts|= SAME_DSTPORT;
946 if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
947 config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
949 else if(strcasecmp(rule_opt[k]->element,
950 xml_notsame_source_ip)==0)
952 config_ruleinfo->context_opts&= NOT_SAME_SRCIP;
954 else if(strcmp(rule_opt[k]->element, xml_same_id) == 0)
956 config_ruleinfo->context_opts|= SAME_ID;
958 else if(strcmp(rule_opt[k]->element,
959 xml_different_url) == 0)
961 config_ruleinfo->context_opts|= DIFFERENT_URL;
963 if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
964 config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
966 else if(strcmp(rule_opt[k]->element,xml_notsame_id) == 0)
968 config_ruleinfo->context_opts&= NOT_SAME_ID;
970 else if(strcasecmp(rule_opt[k]->element,
973 config_ruleinfo->alert_opts |= DO_FTS;
975 else if(strcasecmp(rule_opt[k]->element,
978 config_ruleinfo->context_opts|= SAME_USER;
980 if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
981 config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
983 else if(strcasecmp(rule_opt[k]->element,
984 xml_notsame_user)==0)
986 config_ruleinfo->context_opts&= NOT_SAME_USER;
988 else if(strcasecmp(rule_opt[k]->element,
989 xml_same_location)==0)
991 config_ruleinfo->context_opts|= SAME_LOCATION;
992 if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
993 config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
995 else if(strcasecmp(rule_opt[k]->element,
996 xml_notsame_agent)==0)
998 config_ruleinfo->context_opts&= NOT_SAME_AGENT;
1000 else if(strcasecmp(rule_opt[k]->element,
1003 if(strcmp("alert_by_email",
1004 rule_opt[k]->content) == 0)
1006 if(!(config_ruleinfo->alert_opts & DO_MAILALERT))
1008 config_ruleinfo->alert_opts|= DO_MAILALERT;
1011 else if(strcmp("no_email_alert",
1012 rule_opt[k]->content) == 0)
1014 if(config_ruleinfo->alert_opts & DO_MAILALERT)
1016 config_ruleinfo->alert_opts&=0xfff-DO_MAILALERT;
1019 else if(strcmp("log_alert",
1020 rule_opt[k]->content) == 0)
1022 if(!(config_ruleinfo->alert_opts & DO_LOGALERT))
1024 config_ruleinfo->alert_opts|= DO_LOGALERT;
1027 else if(strcmp("no_log", rule_opt[k]->content) == 0)
1029 if(config_ruleinfo->alert_opts & DO_LOGALERT)
1031 config_ruleinfo->alert_opts &=0xfff-DO_LOGALERT;
1034 else if(strcmp("no_ar", rule_opt[k]->content) == 0)
1036 if(!(config_ruleinfo->alert_opts & NO_AR))
1038 config_ruleinfo->alert_opts|= NO_AR;
1043 merror(XML_VALUEERR, ARGV0, xml_options,
1044 rule_opt[k]->content);
1046 merror("%s: Invalid option '%s' for "
1047 "rule '%d'.",ARGV0, rule_opt[k]->element,
1048 config_ruleinfo->sigid);
1053 else if(strcasecmp(rule_opt[k]->element,
1056 if(strstr(rule_opt[k]->content, "user") != NULL)
1058 config_ruleinfo->ignore|=FTS_DSTUSER;
1060 if(strstr(rule_opt[k]->content, "srcip") != NULL)
1062 config_ruleinfo->ignore|=FTS_SRCIP;
1064 if(strstr(rule_opt[k]->content, "dstip") != NULL)
1066 config_ruleinfo->ignore|=FTS_DSTIP;
1068 if(strstr(rule_opt[k]->content, "id") != NULL)
1070 config_ruleinfo->ignore|=FTS_ID;
1072 if(strstr(rule_opt[k]->content,"location")!= NULL)
1074 config_ruleinfo->ignore|=FTS_LOCATION;
1076 if(strstr(rule_opt[k]->content,"data")!= NULL)
1078 config_ruleinfo->ignore|=FTS_DATA;
1080 if(strstr(rule_opt[k]->content, "name") != NULL)
1082 config_ruleinfo->ignore|=FTS_NAME;
1085 if(!config_ruleinfo->ignore)
1087 merror("%s: Wrong ignore option: '%s'",
1089 rule_opt[k]->content);
1093 else if(strcasecmp(rule_opt[k]->element,
1094 xml_check_if_ignored) == 0)
1096 if(strstr(rule_opt[k]->content, "user") != NULL)
1098 config_ruleinfo->ckignore|=FTS_DSTUSER;
1100 if(strstr(rule_opt[k]->content, "srcip") != NULL)
1102 config_ruleinfo->ckignore|=FTS_SRCIP;
1104 if(strstr(rule_opt[k]->content, "dstip") != NULL)
1106 config_ruleinfo->ckignore|=FTS_DSTIP;
1108 if(strstr(rule_opt[k]->content, "id") != NULL)
1110 config_ruleinfo->ckignore|=FTS_ID;
1112 if(strstr(rule_opt[k]->content,"location")!= NULL)
1114 config_ruleinfo->ckignore|=FTS_LOCATION;
1116 if(strstr(rule_opt[k]->content,"data")!= NULL)
1118 config_ruleinfo->ignore|=FTS_DATA;
1120 if(strstr(rule_opt[k]->content, "name") != NULL)
1122 config_ruleinfo->ckignore|=FTS_NAME;
1125 if(!config_ruleinfo->ckignore)
1127 merror("%s: Wrong check_if_ignored option: '%s'",
1129 rule_opt[k]->content);
1135 merror("%s: Invalid option '%s' for "
1136 "rule '%d'.",ARGV0, rule_opt[k]->element,
1137 config_ruleinfo->sigid);
1145 /* Checking for a valid use of frequency */
1146 if((config_ruleinfo->context_opts ||
1147 config_ruleinfo->frequency) &&
1148 !config_ruleinfo->context)
1150 merror("%s: Invalid use of frequency/context options. "
1151 "Missing if_matched on rule '%d'.",
1152 ARGV0, config_ruleinfo->sigid);
1158 /* If if_matched_group we must have a if_sid or if_group */
1159 if(if_matched_group)
1161 if(!config_ruleinfo->if_sid && !config_ruleinfo->if_group)
1163 os_strdup(if_matched_group,
1164 config_ruleinfo->if_group);
1168 /* If_matched_sid, we need to get the if_sid */
1169 if(config_ruleinfo->if_matched_sid &&
1170 !config_ruleinfo->if_sid &&
1171 !config_ruleinfo->if_group)
1173 os_calloc(16, sizeof(char), config_ruleinfo->if_sid);
1174 snprintf(config_ruleinfo->if_sid, 15, "%d",
1175 config_ruleinfo->if_matched_sid);
1178 /* Checking the regexes */
1181 os_calloc(1, sizeof(OSRegex), config_ruleinfo->regex);
1182 if(!OSRegex_Compile(regex, config_ruleinfo->regex, 0))
1184 merror(REGEX_COMPILE, ARGV0, regex,
1185 config_ruleinfo->regex->error);
1192 /* Adding in match */
1195 os_calloc(1, sizeof(OSMatch), config_ruleinfo->match);
1196 if(!OSMatch_Compile(match, config_ruleinfo->match, 0))
1198 merror(REGEX_COMPILE, ARGV0, match,
1199 config_ruleinfo->match->error);
1209 os_calloc(1, sizeof(OSMatch), config_ruleinfo->id);
1210 if(!OSMatch_Compile(id, config_ruleinfo->id, 0))
1212 merror(REGEX_COMPILE, ARGV0, id,
1213 config_ruleinfo->id->error);
1220 /* Adding srcport */
1223 os_calloc(1, sizeof(OSMatch), config_ruleinfo->srcport);
1224 if(!OSMatch_Compile(srcport, config_ruleinfo->srcport, 0))
1226 merror(REGEX_COMPILE, ARGV0, srcport,
1227 config_ruleinfo->id->error);
1234 /* Adding dstport */
1237 os_calloc(1, sizeof(OSMatch), config_ruleinfo->dstport);
1238 if(!OSMatch_Compile(dstport, config_ruleinfo->dstport, 0))
1240 merror(REGEX_COMPILE, ARGV0, dstport,
1241 config_ruleinfo->id->error);
1248 /* Adding in status */
1251 os_calloc(1, sizeof(OSMatch), config_ruleinfo->status);
1252 if(!OSMatch_Compile(status, config_ruleinfo->status, 0))
1254 merror(REGEX_COMPILE, ARGV0, status,
1255 config_ruleinfo->status->error);
1262 /* Adding in hostname */
1265 os_calloc(1, sizeof(OSMatch), config_ruleinfo->hostname);
1266 if(!OSMatch_Compile(hostname, config_ruleinfo->hostname,0))
1268 merror(REGEX_COMPILE, ARGV0, hostname,
1269 config_ruleinfo->hostname->error);
1276 /* Adding extra data */
1279 os_calloc(1, sizeof(OSMatch), config_ruleinfo->extra_data);
1280 if(!OSMatch_Compile(extra_data,
1281 config_ruleinfo->extra_data, 0))
1283 merror(REGEX_COMPILE, ARGV0, extra_data,
1284 config_ruleinfo->extra_data->error);
1291 /* Adding in program name */
1294 os_calloc(1,sizeof(OSMatch),config_ruleinfo->program_name);
1295 if(!OSMatch_Compile(program_name,
1296 config_ruleinfo->program_name,0))
1298 merror(REGEX_COMPILE, ARGV0, program_name,
1299 config_ruleinfo->program_name->error);
1303 program_name = NULL;
1306 /* Adding in user */
1309 os_calloc(1, sizeof(OSMatch), config_ruleinfo->user);
1310 if(!OSMatch_Compile(user, config_ruleinfo->user, 0))
1312 merror(REGEX_COMPILE, ARGV0, user,
1313 config_ruleinfo->user->error);
1323 os_calloc(1, sizeof(OSMatch), config_ruleinfo->url);
1324 if(!OSMatch_Compile(url, config_ruleinfo->url, 0))
1326 merror(REGEX_COMPILE, ARGV0, url,
1327 config_ruleinfo->url->error);
1334 /* Adding matched_group */
1335 if(if_matched_group)
1337 os_calloc(1, sizeof(OSMatch),
1338 config_ruleinfo->if_matched_group);
1340 if(!OSMatch_Compile(if_matched_group,
1341 config_ruleinfo->if_matched_group,
1344 merror(REGEX_COMPILE, ARGV0, if_matched_group,
1345 config_ruleinfo->if_matched_group->error);
1348 free(if_matched_group);
1349 if_matched_group = NULL;
1352 /* Adding matched_regex */
1353 if(if_matched_regex)
1355 os_calloc(1, sizeof(OSRegex),
1356 config_ruleinfo->if_matched_regex);
1357 if(!OSRegex_Compile(if_matched_regex,
1358 config_ruleinfo->if_matched_regex, 0))
1360 merror(REGEX_COMPILE, ARGV0, if_matched_regex,
1361 config_ruleinfo->if_matched_regex->error);
1364 free(if_matched_regex);
1365 if_matched_regex = NULL;
1367 } /* enf of elements block */
1370 /* Assigning an active response to the rule */
1371 Rule_AddAR(config_ruleinfo);
1373 j++; /* next rule */
1376 /* Creating the last_events if necessary */
1377 if(config_ruleinfo->context)
1380 os_calloc(MAX_LAST_EVENTS + 1, sizeof(char *),
1381 config_ruleinfo->last_events);
1383 /* Zeroing each entry */
1384 for(;ii<=MAX_LAST_EVENTS;ii++)
1386 config_ruleinfo->last_events[ii] = NULL;
1391 /* Adding the rule to the rules list.
1392 * Only the template rules are supposed
1393 * to be at the top level. All others
1394 * will be a "child" of someone.
1396 if(config_ruleinfo->sigid < 10)
1398 OS_AddRule(config_ruleinfo);
1400 else if(config_ruleinfo->alert_opts & DO_OVERWRITE)
1402 if(!OS_AddRuleInfo(NULL, config_ruleinfo,
1403 config_ruleinfo->sigid))
1405 merror("%s: Overwrite rule '%d' not found.",
1406 ARGV0, config_ruleinfo->sigid);
1413 OS_AddChild(config_ruleinfo);
1416 /* Cleaning what we do not need */
1417 if(config_ruleinfo->if_group)
1419 free(config_ruleinfo->if_group);
1420 config_ruleinfo->if_group = NULL;
1423 /* Setting the event_search pointer */
1424 if(config_ruleinfo->if_matched_sid)
1426 config_ruleinfo->event_search =
1427 (void *)Search_LastSids;
1429 /* Marking rules that match this id */
1430 OS_MarkID(NULL, config_ruleinfo);
1433 /* Marking the rules that match if_matched_group */
1434 else if(config_ruleinfo->if_matched_group)
1437 config_ruleinfo->group_search = OSList_Create();
1438 if(!config_ruleinfo->group_search)
1440 ErrorExit(MEM_ERROR, ARGV0);
1443 /* Marking rules that match this group */
1444 OS_MarkGroup(NULL, config_ruleinfo);
1446 /* Setting function pointer */
1447 config_ruleinfo->event_search =
1448 (void *)Search_LastGroups;
1450 else if(config_ruleinfo->context)
1452 if((config_ruleinfo->context == 1) &&
1453 (config_ruleinfo->context_opts & SAME_DODIFF))
1455 config_ruleinfo->context = 0;
1459 config_ruleinfo->event_search =
1460 (void *)Search_LastEvents;
1464 } /* while(rule[j]) */
1468 } /* while (node[i]) */
1470 /* Cleaning global node */
1476 RuleNode *dbg_node = OS_GetFirstRule();
1481 RuleNode *child_node = dbg_node->child;
1483 printf("** Child Node for %d **\n",dbg_node->ruleinfo->sigid);
1486 child_node = child_node->next;
1489 dbg_node = dbg_node->next;
1494 /* Done over here */
1500 * Allocate memory at "*at" and copy *str to it.
1501 * If *at already exist, realloc the memory and cat str
1503 * It will return the new string
1505 char *loadmemory(char *at, char *str)
1510 if((strsize = strlen(str)) < OS_SIZE_2048)
1512 at = calloc(strsize+1,sizeof(char));
1515 merror(MEM_ERROR,ARGV0);
1518 strncpy(at,str,strsize);
1523 merror(SIZE_ERROR,ARGV0,str);
1527 else /*at is not null. Need to reallocat its memory and copy str to it*/
1529 int strsize = strlen(str);
1530 int atsize = strlen(at);
1531 int finalsize = atsize+strsize+1;
1533 if((atsize > OS_SIZE_2048) || (strsize > OS_SIZE_2048))
1535 merror(SIZE_ERROR,ARGV0,str);
1539 at = realloc(at, (finalsize)*sizeof(char));
1543 merror(MEM_ERROR,ARGV0);
1547 strncat(at,str,strsize);
1549 at[finalsize-1]='\0';
1557 RuleInfoDetail *zeroinfodetails(int type, char *data)
1559 RuleInfoDetail *info_details_pt = NULL;
1561 info_details_pt = (RuleInfoDetail *)calloc(1,sizeof(RuleInfoDetail));
1563 if (info_details_pt == NULL)
1565 ErrorExit(MEM_ERROR,ARGV0);
1568 info_details_pt->type = type;
1571 os_strdup(data, info_details_pt->data);
1573 info_details_pt->next = NULL;
1576 return(info_details_pt);
1580 RuleInfo *zerorulemember(int id, int level,
1581 int maxsize, int frequency,
1582 int timeframe, int noalert,
1583 int ignore_time, int overwrite)
1585 RuleInfo *ruleinfo_pt = NULL;
1587 /* Allocation memory for structure */
1588 ruleinfo_pt = (RuleInfo *)calloc(1,sizeof(RuleInfo));
1590 if(ruleinfo_pt == NULL)
1592 ErrorExit(MEM_ERROR,ARGV0);
1595 /* Default values */
1596 ruleinfo_pt->level = level;
1598 /* Default category is syslog */
1599 ruleinfo_pt->category = SYSLOG;
1601 ruleinfo_pt->ar = NULL;
1603 ruleinfo_pt->context = 0;
1605 ruleinfo_pt->sigid = id;
1606 ruleinfo_pt->firedtimes = 0;
1607 ruleinfo_pt->maxsize = maxsize;
1608 ruleinfo_pt->frequency = frequency;
1609 if(ruleinfo_pt->frequency > _max_freq)
1611 _max_freq = ruleinfo_pt->frequency;
1613 ruleinfo_pt->ignore_time = ignore_time;
1614 ruleinfo_pt->timeframe = timeframe;
1615 ruleinfo_pt->time_ignored = 0;
1617 ruleinfo_pt->context_opts = 0;
1618 ruleinfo_pt->alert_opts = 0;
1619 ruleinfo_pt->ignore = 0;
1620 ruleinfo_pt->ckignore = 0;
1624 ruleinfo_pt->alert_opts |= NO_ALERT;
1626 if(Config.mailbylevel <= level)
1627 ruleinfo_pt->alert_opts |= DO_MAILALERT;
1628 if(Config.logbylevel <= level)
1629 ruleinfo_pt->alert_opts |= DO_LOGALERT;
1631 /* Overwriting a rule */
1634 ruleinfo_pt->alert_opts |= DO_OVERWRITE;
1637 ruleinfo_pt->day_time = NULL;
1638 ruleinfo_pt->week_day = NULL;
1640 ruleinfo_pt->group = NULL;
1641 ruleinfo_pt->regex = NULL;
1642 ruleinfo_pt->match = NULL;
1643 ruleinfo_pt->decoded_as = 0;
1645 ruleinfo_pt->comment = NULL;
1646 ruleinfo_pt->info = NULL;
1647 ruleinfo_pt->cve = NULL;
1648 ruleinfo_pt->info_details = NULL;
1650 ruleinfo_pt->if_sid = NULL;
1651 ruleinfo_pt->if_group = NULL;
1652 ruleinfo_pt->if_level = NULL;
1654 ruleinfo_pt->if_matched_regex = NULL;
1655 ruleinfo_pt->if_matched_group = NULL;
1656 ruleinfo_pt->if_matched_sid = 0;
1658 ruleinfo_pt->user = NULL;
1659 ruleinfo_pt->srcip = NULL;
1660 ruleinfo_pt->srcport = NULL;
1661 ruleinfo_pt->dstip = NULL;
1662 ruleinfo_pt->dstport = NULL;
1663 ruleinfo_pt->url = NULL;
1664 ruleinfo_pt->id = NULL;
1665 ruleinfo_pt->status = NULL;
1666 ruleinfo_pt->hostname = NULL;
1667 ruleinfo_pt->program_name = NULL;
1668 ruleinfo_pt->action = NULL;
1670 /* Zeroing last matched events */
1671 ruleinfo_pt->__frequency = 0;
1672 ruleinfo_pt->last_events = NULL;
1674 /* zeroing the list of previous matches */
1675 ruleinfo_pt->sid_prev_matched = NULL;
1676 ruleinfo_pt->group_prev_matched = NULL;
1678 ruleinfo_pt->sid_search = NULL;
1679 ruleinfo_pt->group_search = NULL;
1681 ruleinfo_pt->event_search = NULL;
1682 ruleinfo_pt->compiled_rule = NULL;
1683 ruleinfo_pt->lists = NULL;
1685 return(ruleinfo_pt);
1688 int get_info_attributes(char **attributes, char **values)
1690 char *xml_type = "type";
1693 return(RULEINFODETAIL_TEXT);
1695 while(attributes[k])
1699 merror("rules_op: Entry info type \"%s\" does not have a value",
1703 else if(strcasecmp(attributes[k],xml_type) == 0)
1705 if(strcmp(values[k], "text") == 0)
1707 return(RULEINFODETAIL_TEXT);
1709 else if(strcmp(values[k], "link") == 0)
1711 return(RULEINFODETAIL_LINK);
1713 else if(strcmp(values[k], "cve") == 0)
1715 return(RULEINFODETAIL_CVE);
1717 else if(strcmp(values[k], "osvdb") == 0)
1719 return(RULEINFODETAIL_OSVDB);
1723 return(RULEINFODETAIL_TEXT);
1726 /* Get the attributes */
1727 int getattributes(char **attributes, char **values,
1728 int *id, int *level,
1729 int *maxsize, int *timeframe,
1730 int *frequency, int *accuracy,
1731 int *noalert, int *ignore_time, int *overwrite)
1735 char *xml_id = "id";
1736 char *xml_level = "level";
1737 char *xml_maxsize = "maxsize";
1738 char *xml_timeframe = "timeframe";
1739 char *xml_frequency = "frequency";
1740 char *xml_accuracy = "accuracy";
1741 char *xml_noalert = "noalert";
1742 char *xml_ignore_time = "ignore";
1743 char *xml_overwrite = "overwrite";
1746 /* Getting attributes */
1747 while(attributes[k])
1751 merror("rules_op: Attribute \"%s\" without value."
1755 /* Getting rule Id */
1756 else if(strcasecmp(attributes[k],xml_id) == 0)
1758 if(OS_StrIsNum(values[k]))
1760 sscanf(values[k],"%6d",id);
1764 merror("rules_op: Invalid rule id: %s. "
1771 else if(strcasecmp(attributes[k],xml_level) == 0)
1773 if(OS_StrIsNum(values[k]))
1775 sscanf(values[k],"%4d",level);
1779 merror("rules_op: Invalid level: %s. "
1785 /* Getting maxsize */
1786 else if(strcasecmp(attributes[k],xml_maxsize) == 0)
1788 if(OS_StrIsNum(values[k]))
1790 sscanf(values[k],"%4d",maxsize);
1794 merror("rules_op: Invalid maxsize: %s. "
1800 /* Getting timeframe */
1801 else if(strcasecmp(attributes[k],xml_timeframe) == 0)
1803 if(OS_StrIsNum(values[k]))
1805 sscanf(values[k],"%5d",timeframe);
1809 merror("rules_op: Invalid timeframe: %s. "
1815 /* Getting frequency */
1816 else if(strcasecmp(attributes[k],xml_frequency) == 0)
1818 if(OS_StrIsNum(values[k]))
1820 sscanf(values[k],"%4d",frequency);
1824 merror("rules_op: Invalid frequency: %s. "
1831 else if(strcasecmp(attributes[k],xml_accuracy) == 0)
1833 if(OS_StrIsNum(values[k]))
1835 sscanf(values[k],"%4d",accuracy);
1839 merror("rules_op: Invalid accuracy: %s. "
1845 /* Rule ignore_time */
1846 else if(strcasecmp(attributes[k],xml_ignore_time) == 0)
1848 if(OS_StrIsNum(values[k]))
1850 sscanf(values[k],"%6d",ignore_time);
1854 merror("rules_op: Invalid ignore_time: %s. "
1861 else if(strcasecmp(attributes[k],xml_noalert) == 0)
1865 else if(strcasecmp(attributes[k], xml_overwrite) == 0)
1867 if(strcmp(values[k], "yes") == 0)
1871 else if(strcmp(values[k], "no") == 0)
1877 merror("rules_op: Invalid overwrite: %s. "
1878 "Can only by 'yes' or 'no'.", values[k]);
1884 merror("rules_op: Invalid attribute \"%s\". "
1885 "Only id, level, maxsize, accuracy, noalert and timeframe "
1886 "are allowed.", attributes[k]);
1895 /* Bind active responses to the rule.
1898 void Rule_AddAR(RuleInfo *rule_config)
1900 int rule_ar_size = 0;
1902 int rule_real_level = 0;
1904 OSListNode *my_ars_node;
1907 /* Setting the correctly levels
1908 * We play internally with the rules, to set
1909 * the priorities... Rules with 0 of accuracy,
1910 * receive a low level and go down in the list
1912 if(rule_config->level == 9900)
1913 rule_real_level = 0;
1915 else if(rule_config->level >= 100)
1916 rule_real_level = rule_config->level/100;
1919 /* No AR for ignored rules */
1920 if(rule_real_level == 0)
1925 /* No AR when options no_ar is set */
1926 if(rule_config->alert_opts & NO_AR)
1931 if(!active_responses)
1936 /* Looping on all AR */
1937 my_ars_node = OSList_GetFirstNode(active_responses);
1940 active_response *my_ar;
1943 my_ar = (active_response *)my_ars_node->data;
1946 /* Checking if the level for the ar is higher */
1949 if(rule_real_level >= my_ar->level)
1955 /* Checking if group matches */
1956 if(my_ar->rules_group)
1958 if(OS_Regex(my_ar->rules_group, rule_config->group))
1964 /* Checking if rule id matches */
1968 char *str_pt = my_ar->rules_id;
1970 while(*str_pt != '\0')
1972 /* We allow spaces in between */
1979 /* If is digit, we get the value
1980 * and search for the next digit
1983 else if(isdigit((int)*str_pt))
1985 r_id = atoi(str_pt);
1987 /* mark to ar if id matches */
1988 if(r_id == rule_config->sigid)
1993 str_pt = strchr(str_pt, ',');
2004 /* Checking for duplicate commas */
2005 else if(*str_pt == ',')
2016 } /* eof of rules_id */
2019 /* Bind AR to the rule */
2024 rule_config->ar = realloc(rule_config->ar,
2026 *sizeof(active_response *));
2028 /* Always set the last node to NULL */
2029 rule_config->ar[rule_ar_size - 1] = my_ar;
2030 rule_config->ar[rule_ar_size] = NULL;
2033 my_ars_node = OSList_GetNextNode(active_responses);
2041 void printRuleinfo(RuleInfo *rule, int node)
2043 debug1("%d : rule:%d, level %d, timeout: %d",
2052 /* Add Rule to hash. */
2053 int AddHash_Rule(RuleNode *node)
2060 snprintf(_id_key, 14, "%d", node->ruleinfo->sigid);
2061 os_strdup(_id_key, id_key);
2064 /* Adding key to hash. */
2065 OSHash_Add(Config.g_rules_hash, id_key, node->ruleinfo);
2068 AddHash_Rule(node->child);
2080 int _setlevels(RuleNode *node, int nnode)
2085 if(node->ruleinfo->level == 9900)
2086 node->ruleinfo->level = 0;
2088 if(node->ruleinfo->level >= 100)
2089 node->ruleinfo->level/=100;
2093 /* Rule information */
2094 printRuleinfo(node->ruleinfo, nnode);
2099 chl_size = _setlevels(node->child, nnode+1);