1 /* @(#) $Id: rules_list.c,v 1.28 2009/06/24 17:06:22 dcid Exp $ */
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 3) as published by the FSF - Free Software
19 /* _OS_Addrule: Internal AddRule */
20 RuleNode *_OS_AddRule(RuleNode *_rulenode, RuleInfo *read_rule);
23 /* Create the RuleList */
24 void OS_CreateRuleList()
32 /* Get first node from rule */
33 RuleNode *OS_GetFirstRule()
35 RuleNode *rulenode_pt = rulenode;
41 /* Search all rules, including childs */
42 int _AddtoRule(int sid, int level, int none, char *group,
43 RuleNode *r_node, RuleInfo *read_rule)
47 /* If we don't have the first node, start from
48 * the beginning of the list
52 r_node = OS_GetFirstRule();
57 /* Checking if the sigid matches */
60 if(r_node->ruleinfo->sigid == sid)
62 /* Assign the category of this rule to the child
65 read_rule->category = r_node->ruleinfo->category;
68 /* If no context for rule, check if the parent has
71 if(!read_rule->last_events && r_node->ruleinfo->last_events)
73 read_rule->last_events = r_node->ruleinfo->last_events;
77 _OS_AddRule(r_node->child, read_rule);
82 /* Checking if the group matches */
85 if(OS_WordMatch(group, r_node->ruleinfo->group) &&
86 (r_node->ruleinfo->sigid != read_rule->sigid))
88 /* If no context for rule, check if the parent has
91 if(!read_rule->last_events && r_node->ruleinfo->last_events)
93 read_rule->last_events = r_node->ruleinfo->last_events;
96 /* We will loop on all rules until we find */
98 _OS_AddRule(r_node->child, read_rule);
103 /* Checking if the level matches */
106 if((r_node->ruleinfo->level >= level) &&
107 (r_node->ruleinfo->sigid != read_rule->sigid))
110 _OS_AddRule(r_node->child, read_rule);
116 /* If we are not searching for the sid/group, the category must
119 else if(read_rule->category != r_node->ruleinfo->category)
121 r_node = r_node->next;
126 /* If none of them is set, add for the category */
129 /* Setting the parent category to it */
130 read_rule->category = r_node->ruleinfo->category;
132 _OS_AddRule(r_node->child, read_rule);
136 /* Checking if the child has a rule */
139 if(_AddtoRule(sid, level, none, group, r_node->child, read_rule))
145 r_node = r_node->next;
153 int OS_AddChild(RuleInfo *read_rule)
157 merror("rules_list: Passing a NULL rule. Inconsistent state");
161 /* Adding for if_sid */
162 if(read_rule->if_sid)
167 sid = read_rule->if_sid;
169 /* Loop to read all the rules (comma or space separated */
173 if((*sid == ',')||(*sid == ' '))
178 else if((isdigit((int)*sid)) || (*sid == '\0'))
183 if(!_AddtoRule(rule_id, 0, 0, NULL, NULL, read_rule))
185 ErrorExit("rules_list: Signature ID '%d' not "
186 "found. Invalid 'if_sid'.", rule_id);
193 ErrorExit("rules_list: Signature ID must be an integer. "
196 }while(*sid++ != '\0');
199 /* Adding for if_level */
200 else if(read_rule->if_level)
204 ilevel = atoi(read_rule->if_level);
207 merror("%s: Invalid level (atoi)",ARGV0);
213 if(!_AddtoRule(0, ilevel, 0, NULL, NULL, read_rule))
215 ErrorExit("rules_list: Level ID '%d' not "
216 "found. Invalid 'if_level'.", ilevel);
220 /* Adding for if_group */
221 else if(read_rule->if_group)
223 if(!_AddtoRule(0, 0, 0, read_rule->if_group, NULL, read_rule))
225 ErrorExit("rules_list: Group '%s' not "
226 "found. Invalid 'if_group'.", read_rule->if_group);
230 /* Just add based on the category */
233 if(!_AddtoRule(0, 0, 0, NULL, NULL, read_rule))
235 ErrorExit("rules_list: Category '%d' not "
236 "found. Invalid 'category'.", read_rule->category);
246 /* Add a rule in the chain */
247 RuleNode *_OS_AddRule(RuleNode *_rulenode, RuleInfo *read_rule)
249 RuleNode *tmp_rulenode = _rulenode;
252 if(tmp_rulenode != NULL)
254 int middle_insertion = 0;
255 RuleNode *prev_rulenode = NULL;
256 RuleNode *new_rulenode = NULL;
258 while(tmp_rulenode != NULL)
260 if(read_rule->level > tmp_rulenode->ruleinfo->level)
262 middle_insertion = 1;
265 prev_rulenode = tmp_rulenode;
266 tmp_rulenode = tmp_rulenode->next;
269 new_rulenode = (RuleNode *)calloc(1,sizeof(RuleNode));
273 ErrorExit(MEM_ERROR,ARGV0);
276 if(middle_insertion == 1)
278 if(prev_rulenode == NULL)
280 _rulenode = new_rulenode;
284 prev_rulenode->next = new_rulenode;
287 new_rulenode->next = tmp_rulenode;
288 new_rulenode->ruleinfo = read_rule;
289 new_rulenode->child = NULL;
294 prev_rulenode->next = new_rulenode;
295 prev_rulenode->next->ruleinfo = read_rule;
296 prev_rulenode->next->next = NULL;
297 prev_rulenode->next->child = NULL;
303 _rulenode = (RuleNode *)calloc(1,sizeof(RuleNode));
304 if(_rulenode == NULL)
306 ErrorExit(MEM_ERROR,ARGV0);
309 _rulenode->ruleinfo = read_rule;
310 _rulenode->next = NULL;
311 _rulenode->child= NULL;
317 /* External AddRule */
318 int OS_AddRule(RuleInfo *read_rule)
320 rulenode = _OS_AddRule(rulenode,read_rule);
326 /* Update rule info for overwritten ones */
327 int OS_AddRuleInfo(RuleNode *r_node, RuleInfo *newrule, int sid)
329 /* If no r_node is given, get first node */
332 r_node = OS_GetFirstRule();
340 /* Checking if the sigid matches */
341 if(r_node->ruleinfo->sigid == sid)
343 r_node->ruleinfo->level = newrule->level;
344 r_node->ruleinfo->maxsize = newrule->maxsize;
345 r_node->ruleinfo->frequency = newrule->frequency;
346 r_node->ruleinfo->timeframe = newrule->timeframe;
348 r_node->ruleinfo->group = newrule->group;
349 r_node->ruleinfo->match = newrule->match;
350 r_node->ruleinfo->regex = newrule->regex;
351 r_node->ruleinfo->day_time = newrule->day_time;
352 r_node->ruleinfo->week_day = newrule->week_day;
353 r_node->ruleinfo->srcip = newrule->srcip;
354 r_node->ruleinfo->dstip = newrule->dstip;
355 r_node->ruleinfo->srcport = newrule->srcport;
356 r_node->ruleinfo->dstport = newrule->dstport;
357 r_node->ruleinfo->user = newrule->user;
358 r_node->ruleinfo->url = newrule->url;
359 r_node->ruleinfo->id = newrule->id;
360 r_node->ruleinfo->status = newrule->status;
361 r_node->ruleinfo->hostname = newrule->hostname;
362 r_node->ruleinfo->program_name = newrule->program_name;
363 r_node->ruleinfo->extra_data = newrule->extra_data;
364 r_node->ruleinfo->action = newrule->action;
365 r_node->ruleinfo->comment = newrule->comment;
366 r_node->ruleinfo->info = newrule->info;
367 r_node->ruleinfo->cve = newrule->cve;
368 r_node->ruleinfo->if_matched_regex = newrule->if_matched_regex;
369 r_node->ruleinfo->if_matched_group = newrule->if_matched_group;
370 r_node->ruleinfo->if_matched_sid = newrule->if_matched_sid;
371 r_node->ruleinfo->alert_opts = newrule->alert_opts;
372 r_node->ruleinfo->context_opts = newrule->context_opts;
373 r_node->ruleinfo->context = newrule->context;
374 r_node->ruleinfo->decoded_as = newrule->decoded_as;
375 r_node->ruleinfo->ar = newrule->ar;
376 r_node->ruleinfo->compiled_rule = newrule->compiled_rule;
382 /* Checking if the child has a rule */
385 if(OS_AddRuleInfo(r_node->child, newrule, sid))
391 r_node = r_node->next;
398 /* Mark rules that match specific id (for if_matched_sid) */
399 int OS_MarkID(RuleNode *r_node, RuleInfo *orig_rule)
401 /* If no r_node is given, get first node */
404 r_node = OS_GetFirstRule();
409 if(r_node->ruleinfo->sigid == orig_rule->if_matched_sid)
411 /* If child does not have a list, create one */
412 if(!r_node->ruleinfo->sid_prev_matched)
414 r_node->ruleinfo->sid_prev_matched = OSList_Create();
415 if(!r_node->ruleinfo->sid_prev_matched)
417 ErrorExit(MEM_ERROR, ARGV0);
421 /* Assigning the parent pointer to it */
422 orig_rule->sid_search = r_node->ruleinfo->sid_prev_matched;
426 /* Checking if the child has a rule */
429 OS_MarkID(r_node->child, orig_rule);
432 r_node = r_node->next;
440 /* Mark rules that match specific group (for if_matched_group) */
441 int OS_MarkGroup(RuleNode *r_node, RuleInfo *orig_rule)
443 /* If no r_node is given, get first node */
446 r_node = OS_GetFirstRule();
451 if(OSMatch_Execute(r_node->ruleinfo->group,
452 strlen(r_node->ruleinfo->group),
453 orig_rule->if_matched_group))
456 if(r_node->ruleinfo->group_prev_matched)
458 while(r_node->ruleinfo->group_prev_matched[rule_g])
464 os_realloc(r_node->ruleinfo->group_prev_matched,
465 (rule_g + 2)*sizeof(OSList *),
466 r_node->ruleinfo->group_prev_matched);
468 r_node->ruleinfo->group_prev_matched[rule_g] = NULL;
469 r_node->ruleinfo->group_prev_matched[rule_g +1] = NULL;
471 /* Setting the size */
472 r_node->ruleinfo->group_prev_matched_sz = rule_g +1;
474 r_node->ruleinfo->group_prev_matched[rule_g] =
475 orig_rule->group_search;
479 /* Checking if the child has a rule */
482 OS_MarkGroup(r_node->child, orig_rule);
485 r_node = r_node->next;