1 /* @(#) $Id: report_op.c,v 1.2 2009/06/24 18:53:08 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
16 /** Helper functions. */
18 /* Sort function used by OSStore sort.
21 void *_os_report_sort_compare(void *d1, void *d2)
23 OSList *d1l = (OSList *)d1;
24 OSList *d2l = (OSList *)d2;
26 if(d1l->currently_size > d2l->currently_size)
35 /* Compares if the id is present in the string. */
36 int _os_report_str_int_compare(char *str, int id)
42 if((*str == ',')||(*str == ' '))
51 else if(isdigit((int)*str))
66 }while(*str++ != '\0');
73 /* Check if the al_data should be filtered. */
74 int _os_report_check_filters(alert_data *al_data, report_filter *r_filter)
76 /* Checking for the filters. */
79 if(!strstr(al_data->group, r_filter->group))
86 if(_os_report_str_int_compare(r_filter->rule, al_data->rule) != 1)
91 if(r_filter->location)
93 if(!OS_Match2(r_filter->location, al_data->location))
100 if(al_data->level < atoi(r_filter->level))
111 /* Sets the proper value for the related entries. */
112 int _report_filter_value(char *filter_by, int prev_filter)
114 if(strcmp(filter_by, "group") == 0)
116 if(!(prev_filter & REPORT_REL_GROUP))
118 prev_filter|=REPORT_REL_GROUP;
122 else if(strcmp(filter_by, "rule") == 0)
124 if(!(prev_filter & REPORT_REL_RULE))
126 prev_filter|=REPORT_REL_RULE;
130 else if(strcmp(filter_by, "level") == 0)
132 if(!(prev_filter & REPORT_REL_LEVEL))
134 prev_filter|=REPORT_REL_LEVEL;
138 else if(strcmp(filter_by, "location") == 0)
140 if(!(prev_filter & REPORT_REL_LOCATION))
142 prev_filter|=REPORT_REL_LOCATION;
146 else if(strcmp(filter_by, "srcip") == 0)
148 if(!(prev_filter & REPORT_REL_SRCIP))
150 prev_filter|=REPORT_REL_SRCIP;
154 else if(strcmp(filter_by, "user") == 0)
156 if(!(prev_filter & REPORT_REL_USER))
158 prev_filter|=REPORT_REL_USER;
164 merror("%s: ERROR: Invalid relation '%s'.", ARGV0, filter_by);
171 /* Prints related entries. */
172 int _os_report_print_related(int print_related, OSList *st_data)
174 OSListNode *list_entry;
175 alert_data *list_aldata;
176 alert_data *saved_aldata;
179 list_entry = OSList_GetFirstNode(st_data);
182 saved_aldata = (alert_data *)list_entry->data;
184 /* Removing duplicates. */
185 list_entry = list_entry->prev;
188 if(print_related & REPORT_REL_LOCATION)
190 list_aldata = (alert_data *)list_entry->data;
191 if(strcmp(list_aldata->location, saved_aldata->location) == 0)
197 else if(print_related & REPORT_REL_GROUP)
199 list_aldata = (alert_data *)list_entry->data;
200 if(strcmp(list_aldata->group, saved_aldata->group) == 0)
206 else if(print_related & REPORT_REL_RULE)
208 list_aldata = (alert_data *)list_entry->data;
209 if(list_aldata->rule == saved_aldata->rule)
215 else if(print_related & REPORT_REL_USER)
217 list_aldata = (alert_data *)list_entry->data;
218 if(strcmp(list_aldata->user, saved_aldata->user) == 0)
224 else if(print_related & REPORT_REL_SRCIP)
226 list_aldata = (alert_data *)list_entry->data;
227 if(strcmp(list_aldata->srcip, saved_aldata->srcip) == 0)
233 else if(print_related & REPORT_REL_LEVEL)
235 list_aldata = (alert_data *)list_entry->data;
236 if(list_aldata->level == saved_aldata->level)
241 list_entry = list_entry->prev;
246 if(print_related & REPORT_REL_LOCATION)
247 print_out(" location: '%s'", saved_aldata->location);
248 else if(print_related & REPORT_REL_GROUP)
249 print_out(" group: '%s'", saved_aldata->group);
250 else if(print_related & REPORT_REL_RULE)
251 print_out(" rule: '%d'", saved_aldata->rule);
252 else if(print_related & REPORT_REL_SRCIP)
253 print_out(" srcip: '%s'", saved_aldata->srcip);
254 else if(print_related & REPORT_REL_USER)
255 print_out(" user: '%s'", saved_aldata->user);
256 else if(print_related & REPORT_REL_LEVEL)
257 print_out(" level: '%d'", saved_aldata->level);
260 list_entry = OSList_GetNextNode(st_data);
268 /* Add the entry to the hash. */
269 int _os_report_add_tostore(char *key, OSStore *top, void *data)
273 /* Adding data to the hash. */
274 top_list = OSStore_Get(top, key);
277 OSList_AddData(top_list, data);
281 top_list = OSList_Create();
284 merror(MEM_ERROR, ARGV0);
287 OSList_AddData(top_list, data);
289 OSStore_Put(top, key, top_list);
297 void os_report_printtop(void *topstore_pt, char *hname, int print_related)
299 OSStore *topstore = (OSStore *)topstore_pt;
300 OSStoreNode *next_node;
304 print_out("Top entries for '%s':", hname);
305 print_out("------------------------------------------------");
309 print_out("Related entries for '%s':", hname);
310 print_out("------------------------------------------------");
314 next_node = OSStore_GetFirstNode(topstore);
317 OSList *st_data = (OSList *)next_node->data;
318 char *lkey = (char *)next_node->key;
321 /* With location we leave more space to be clearer. */
324 if(strlen(lkey) > 46)
331 print_out("%-48s|%-8d|", (char *)next_node->key, st_data->currently_size);
335 /* Print each destination. */
338 print_out("%-48s|%-8d|", (char *)next_node->key, st_data->currently_size);
340 if(print_related & REPORT_REL_LOCATION)
341 _os_report_print_related(REPORT_REL_LOCATION, st_data);
342 if(print_related & REPORT_REL_SRCIP)
343 _os_report_print_related(REPORT_REL_SRCIP, st_data);
344 if(print_related & REPORT_REL_USER)
345 _os_report_print_related(REPORT_REL_USER, st_data);
346 if(print_related & REPORT_REL_RULE)
347 _os_report_print_related(REPORT_REL_RULE, st_data);
348 if(print_related & REPORT_REL_GROUP)
349 _os_report_print_related(REPORT_REL_GROUP, st_data);
350 if(print_related & REPORT_REL_LEVEL)
351 _os_report_print_related(REPORT_REL_LEVEL, st_data);
355 next_node = next_node->next;
366 void os_ReportdStart(report_filter *r_filter)
368 int alerts_processed = 0;
369 int alerts_filtered = 0;
370 char *first_alert = NULL;
371 char *last_alert = NULL;
382 /* Getting current time before starting */
388 /* Creating top hashes. */
389 r_filter->top_user = OSStore_Create();
390 r_filter->top_srcip = OSStore_Create();
391 r_filter->top_level = OSStore_Create();
392 r_filter->top_rule = OSStore_Create();
393 r_filter->top_group = OSStore_Create();
394 r_filter->top_location = OSStore_Create();
398 /* Initating file queue - to read the alerts */
399 os_calloc(1, sizeof(file_queue), fileq);
401 Init_FileQueue(fileq, p, CRALERT_READ_ALL|CRALERT_FP_SET);
404 /* Reading the alerts. */
407 /* Get message if available */
408 al_data = Read_FileMon(fileq, p, 1);
411 verbose("%s: Report completed. Creating output...", ARGV0);
418 /* Checking the filters. */
419 if(!_os_report_check_filters(al_data, r_filter))
421 FreeAlertData(al_data);
429 /* Setting first and last alert for summary. */
431 first_alert = al_data->date;
432 last_alert = al_data->date;
435 /* Adding source ip if it is set properly. */
436 if(strcmp(al_data->srcip, "(none)") != 0)
437 _os_report_add_tostore(al_data->srcip, r_filter->top_srcip, al_data);
440 /* Adding user if it is set properly. */
441 if(strcmp(al_data->user, "(none)") != 0)
442 _os_report_add_tostore(al_data->user, r_filter->top_user, al_data);
445 /* Adding level and severity. */
450 snprintf(mlevel, 16, "Severity %d" , al_data->level);
451 snprintf(mrule, 76, "%d - %s" , al_data->rule, al_data->comment);
453 _os_report_add_tostore(strdup(mlevel), r_filter->top_level,
455 _os_report_add_tostore(strdup(mrule), r_filter->top_rule,
459 /* Dealing with the group. */
464 mgroup = OS_StrBreak(',', al_data->group, 32);
470 while(*tmp_str == ' ')
478 _os_report_add_tostore(tmp_str, r_filter->top_group,
485 tmp_str = al_data->group;
486 while(*tmp_str == ' ')
490 _os_report_add_tostore(tmp_str, r_filter->top_group,
497 /* Adding to the location top filter. */
498 _os_report_add_tostore(al_data->location, r_filter->top_location,
505 if(r_filter->report_name)
506 print_out("Report '%s' completed.", r_filter->report_name);
508 print_out("Report completed. ==");
509 print_out("------------------------------------------------");
511 print_out("->Processed alerts: %d", alerts_processed);
512 print_out("->Post-filtering alerts: %d", alerts_filtered);
513 print_out("->First alert: %s", first_alert);
514 print_out("->Last alert: %s", last_alert);
518 OSStore_Sort(r_filter->top_srcip, _os_report_sort_compare);
519 OSStore_Sort(r_filter->top_user, _os_report_sort_compare);
520 OSStore_Sort(r_filter->top_level, _os_report_sort_compare);
521 OSStore_Sort(r_filter->top_group, _os_report_sort_compare);
522 OSStore_Sort(r_filter->top_location, _os_report_sort_compare);
523 OSStore_Sort(r_filter->top_rule, _os_report_sort_compare);
525 if(r_filter->top_srcip)
526 os_report_printtop(r_filter->top_srcip, "Source ip", 0);
528 if(r_filter->top_user)
529 os_report_printtop(r_filter->top_user, "Username", 0);
531 if(r_filter->top_level)
532 os_report_printtop(r_filter->top_level, "Level", 0);
534 if(r_filter->top_group)
535 os_report_printtop(r_filter->top_group, "Group", 0);
537 if(r_filter->top_location)
538 os_report_printtop(r_filter->top_location, "Location", 0);
540 if(r_filter->top_rule)
541 os_report_printtop(r_filter->top_rule, "Rule", 0);
544 /* Print related events. */
545 if(r_filter->related_srcip)
546 os_report_printtop(r_filter->top_srcip, "Source ip",
547 r_filter->related_srcip);
549 if(r_filter->related_user)
550 os_report_printtop(r_filter->top_user, "Username",
551 r_filter->related_user);
553 if(r_filter->related_level)
554 os_report_printtop(r_filter->top_level, "Level",
555 r_filter->related_level);
557 if(r_filter->related_group)
558 os_report_printtop(r_filter->top_group, "Group",
559 r_filter->related_group);
561 if(r_filter->related_location)
562 os_report_printtop(r_filter->top_location, "Location",
563 r_filter->related_location);
565 if(r_filter->related_rule)
566 os_report_printtop(r_filter->top_rule, "Rule",
567 r_filter->related_rule);
574 /** int os_report_check_filters(char *filter_by, char *filter_value,
575 * report_filter *r_filter)
576 * Checks the configuration filters.
578 int os_report_configfilter(char *filter_by, char *filter_value,
579 report_filter *r_filter, int arg_type)
581 if(!filter_by || !filter_value)
586 if(arg_type == REPORT_FILTER)
588 if(strcmp(filter_by, "group") == 0)
590 r_filter->group = filter_value;
592 else if(strcmp(filter_by, "rule") == 0)
594 r_filter->rule = filter_value;
596 else if(strcmp(filter_by, "level") == 0)
598 r_filter->level = filter_value;
600 else if(strcmp(filter_by, "location") == 0)
602 r_filter->location = filter_value;
606 merror("%s: ERROR: Invalid filter '%s'.", ARGV0, filter_by);
612 if(strcmp(filter_by, "group") == 0)
614 r_filter->related_group =
615 _report_filter_value(filter_value, r_filter->related_group);
617 if(r_filter->related_group == -1)
620 else if(strcmp(filter_by, "rule") == 0)
622 r_filter->related_rule =
623 _report_filter_value(filter_value, r_filter->related_rule);
625 if(r_filter->related_rule == -1)
628 else if(strcmp(filter_by, "level") == 0)
630 r_filter->related_level =
631 _report_filter_value(filter_value, r_filter->related_level);
633 if(r_filter->related_level == -1)
636 else if(strcmp(filter_by, "location") == 0)
638 r_filter->related_location =
639 _report_filter_value(filter_value, r_filter->related_location);
641 if(r_filter->related_location == -1)
644 else if(strcmp(filter_by, "srcip") == 0)
646 r_filter->related_srcip =
647 _report_filter_value(filter_value, r_filter->related_srcip);
649 if(r_filter->related_srcip == -1)
652 else if(strcmp(filter_by, "user") == 0)
654 r_filter->related_user =
655 _report_filter_value(filter_value, r_filter->related_user);
657 if(r_filter->related_user == -1)
662 merror("%s: ERROR: Invalid related entry '%s'.", ARGV0, filter_by);