1 /* @(#) $Id: ./src/analysisd/rules_list.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
20 /* _OS_Addrule: Internal AddRule */
21 RuleNode *_OS_AddRule(RuleNode *_rulenode, RuleInfo *read_rule);
24 /* Create the RuleList */
25 void OS_CreateRuleList()
33 /* Get first node from rule */
34 RuleNode *OS_GetFirstRule()
36 RuleNode *rulenode_pt = rulenode;
42 /* Search all rules, including childs */
43 int _AddtoRule(int sid, int level, int none, char *group,
44 RuleNode *r_node, RuleInfo *read_rule)
48 /* If we don't have the first node, start from
49 * the beginning of the list
53 r_node = OS_GetFirstRule();
58 /* Checking if the sigid matches */
61 if(r_node->ruleinfo->sigid == sid)
63 /* Assign the category of this rule to the child
66 read_rule->category = r_node->ruleinfo->category;
69 /* If no context for rule, check if the parent has
72 if(!read_rule->last_events && r_node->ruleinfo->last_events)
74 read_rule->last_events = r_node->ruleinfo->last_events;
78 _OS_AddRule(r_node->child, read_rule);
83 /* Checking if the group matches */
86 if(OS_WordMatch(group, r_node->ruleinfo->group) &&
87 (r_node->ruleinfo->sigid != read_rule->sigid))
89 /* If no context for rule, check if the parent has
92 if(!read_rule->last_events && r_node->ruleinfo->last_events)
94 read_rule->last_events = r_node->ruleinfo->last_events;
97 /* We will loop on all rules until we find */
99 _OS_AddRule(r_node->child, read_rule);
104 /* Checking if the level matches */
107 if((r_node->ruleinfo->level >= level) &&
108 (r_node->ruleinfo->sigid != read_rule->sigid))
111 _OS_AddRule(r_node->child, read_rule);
117 /* If we are not searching for the sid/group, the category must
120 else if(read_rule->category != r_node->ruleinfo->category)
122 r_node = r_node->next;
127 /* If none of them is set, add for the category */
130 /* Setting the parent category to it */
131 read_rule->category = r_node->ruleinfo->category;
133 _OS_AddRule(r_node->child, read_rule);
137 /* Checking if the child has a rule */
140 if(_AddtoRule(sid, level, none, group, r_node->child, read_rule))
146 r_node = r_node->next;
154 int OS_AddChild(RuleInfo *read_rule)
158 merror("rules_list: Passing a NULL rule. Inconsistent state");
162 /* Adding for if_sid */
163 if(read_rule->if_sid)
168 sid = read_rule->if_sid;
170 /* Loop to read all the rules (comma or space separated */
174 if((*sid == ',')||(*sid == ' '))
179 else if((isdigit((int)*sid)) || (*sid == '\0'))
184 if(!_AddtoRule(rule_id, 0, 0, NULL, NULL, read_rule))
186 ErrorExit("rules_list: Signature ID '%d' not "
187 "found. Invalid 'if_sid'.", rule_id);
194 ErrorExit("rules_list: Signature ID must be an integer. "
197 }while(*sid++ != '\0');
200 /* Adding for if_level */
201 else if(read_rule->if_level)
205 ilevel = atoi(read_rule->if_level);
208 merror("%s: Invalid level (atoi)",ARGV0);
214 if(!_AddtoRule(0, ilevel, 0, NULL, NULL, read_rule))
216 ErrorExit("rules_list: Level ID '%d' not "
217 "found. Invalid 'if_level'.", ilevel);
221 /* Adding for if_group */
222 else if(read_rule->if_group)
224 if(!_AddtoRule(0, 0, 0, read_rule->if_group, NULL, read_rule))
226 ErrorExit("rules_list: Group '%s' not "
227 "found. Invalid 'if_group'.", read_rule->if_group);
231 /* Just add based on the category */
234 if(!_AddtoRule(0, 0, 0, NULL, NULL, read_rule))
236 ErrorExit("rules_list: Category '%d' not "
237 "found. Invalid 'category'.", read_rule->category);
247 /* Add a rule in the chain */
248 RuleNode *_OS_AddRule(RuleNode *_rulenode, RuleInfo *read_rule)
250 RuleNode *tmp_rulenode = _rulenode;
253 if(tmp_rulenode != NULL)
255 int middle_insertion = 0;
256 RuleNode *prev_rulenode = NULL;
257 RuleNode *new_rulenode = NULL;
259 while(tmp_rulenode != NULL)
261 if(read_rule->level > tmp_rulenode->ruleinfo->level)
263 middle_insertion = 1;
266 prev_rulenode = tmp_rulenode;
267 tmp_rulenode = tmp_rulenode->next;
270 new_rulenode = (RuleNode *)calloc(1,sizeof(RuleNode));
274 ErrorExit(MEM_ERROR,ARGV0);
277 if(middle_insertion == 1)
279 if(prev_rulenode == NULL)
281 _rulenode = new_rulenode;
285 prev_rulenode->next = new_rulenode;
288 new_rulenode->next = tmp_rulenode;
289 new_rulenode->ruleinfo = read_rule;
290 new_rulenode->child = NULL;
295 prev_rulenode->next = new_rulenode;
296 prev_rulenode->next->ruleinfo = read_rule;
297 prev_rulenode->next->next = NULL;
298 prev_rulenode->next->child = NULL;
304 _rulenode = (RuleNode *)calloc(1,sizeof(RuleNode));
305 if(_rulenode == NULL)
307 ErrorExit(MEM_ERROR,ARGV0);
310 _rulenode->ruleinfo = read_rule;
311 _rulenode->next = NULL;
312 _rulenode->child= NULL;
318 /* External AddRule */
319 int OS_AddRule(RuleInfo *read_rule)
321 rulenode = _OS_AddRule(rulenode,read_rule);
327 /* Update rule info for overwritten ones */
328 int OS_AddRuleInfo(RuleNode *r_node, RuleInfo *newrule, int sid)
330 /* If no r_node is given, get first node */
333 r_node = OS_GetFirstRule();
341 /* Checking if the sigid matches */
342 if(r_node->ruleinfo->sigid == sid)
344 r_node->ruleinfo->level = newrule->level;
345 r_node->ruleinfo->maxsize = newrule->maxsize;
346 r_node->ruleinfo->frequency = newrule->frequency;
347 r_node->ruleinfo->timeframe = newrule->timeframe;
348 r_node->ruleinfo->ignore_time = newrule->ignore_time;
350 r_node->ruleinfo->group = newrule->group;
351 r_node->ruleinfo->match = newrule->match;
352 r_node->ruleinfo->regex = newrule->regex;
353 r_node->ruleinfo->day_time = newrule->day_time;
354 r_node->ruleinfo->week_day = newrule->week_day;
355 r_node->ruleinfo->srcip = newrule->srcip;
356 r_node->ruleinfo->dstip = newrule->dstip;
357 r_node->ruleinfo->srcport = newrule->srcport;
358 r_node->ruleinfo->dstport = newrule->dstport;
359 r_node->ruleinfo->user = newrule->user;
360 r_node->ruleinfo->url = newrule->url;
361 r_node->ruleinfo->id = newrule->id;
362 r_node->ruleinfo->status = newrule->status;
363 r_node->ruleinfo->hostname = newrule->hostname;
364 r_node->ruleinfo->program_name = newrule->program_name;
365 r_node->ruleinfo->extra_data = newrule->extra_data;
366 r_node->ruleinfo->action = newrule->action;
367 r_node->ruleinfo->comment = newrule->comment;
368 r_node->ruleinfo->info = newrule->info;
369 r_node->ruleinfo->cve = newrule->cve;
370 r_node->ruleinfo->if_matched_regex = newrule->if_matched_regex;
371 r_node->ruleinfo->if_matched_group = newrule->if_matched_group;
372 r_node->ruleinfo->if_matched_sid = newrule->if_matched_sid;
373 r_node->ruleinfo->alert_opts = newrule->alert_opts;
374 r_node->ruleinfo->context_opts = newrule->context_opts;
375 r_node->ruleinfo->context = newrule->context;
376 r_node->ruleinfo->decoded_as = newrule->decoded_as;
377 r_node->ruleinfo->ar = newrule->ar;
378 r_node->ruleinfo->compiled_rule = newrule->compiled_rule;
379 if((newrule->context_opts & SAME_DODIFF) && r_node->ruleinfo->last_events == NULL)
381 r_node->ruleinfo->last_events = newrule->last_events;
388 /* Checking if the child has a rule */
391 if(OS_AddRuleInfo(r_node->child, newrule, sid))
397 r_node = r_node->next;
404 /* Mark rules that match specific id (for if_matched_sid) */
405 int OS_MarkID(RuleNode *r_node, RuleInfo *orig_rule)
407 /* If no r_node is given, get first node */
410 r_node = OS_GetFirstRule();
415 if(r_node->ruleinfo->sigid == orig_rule->if_matched_sid)
417 /* If child does not have a list, create one */
418 if(!r_node->ruleinfo->sid_prev_matched)
420 r_node->ruleinfo->sid_prev_matched = OSList_Create();
421 if(!r_node->ruleinfo->sid_prev_matched)
423 ErrorExit(MEM_ERROR, ARGV0);
427 /* Assigning the parent pointer to it */
428 orig_rule->sid_search = r_node->ruleinfo->sid_prev_matched;
432 /* Checking if the child has a rule */
435 OS_MarkID(r_node->child, orig_rule);
438 r_node = r_node->next;
446 /* Mark rules that match specific group (for if_matched_group) */
447 int OS_MarkGroup(RuleNode *r_node, RuleInfo *orig_rule)
449 /* If no r_node is given, get first node */
452 r_node = OS_GetFirstRule();
457 if(OSMatch_Execute(r_node->ruleinfo->group,
458 strlen(r_node->ruleinfo->group),
459 orig_rule->if_matched_group))
462 if(r_node->ruleinfo->group_prev_matched)
464 while(r_node->ruleinfo->group_prev_matched[rule_g])
470 os_realloc(r_node->ruleinfo->group_prev_matched,
471 (rule_g + 2)*sizeof(OSList *),
472 r_node->ruleinfo->group_prev_matched);
474 r_node->ruleinfo->group_prev_matched[rule_g] = NULL;
475 r_node->ruleinfo->group_prev_matched[rule_g +1] = NULL;
477 /* Setting the size */
478 r_node->ruleinfo->group_prev_matched_sz = rule_g +1;
480 r_node->ruleinfo->group_prev_matched[rule_g] =
481 orig_rule->group_search;
485 /* Checking if the child has a rule */
488 OS_MarkGroup(r_node->child, orig_rule);
491 r_node = r_node->next;