Imported Upstream version 2.7
[ossec-hids.git] / src / analysisd / eventinfo.c
1 /* @(#) $Id: ./src/analysisd/eventinfo.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All rights reserved.
6  *
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
10  * Foundation.
11  *
12  * License details at the LICENSE file included with OSSEC or
13  * online at: http://www.ossec.net/en/licensing.html
14  */
15
16
17 /* Part of the OSSEC.
18  * Available at http://www.ossec.net
19  */
20
21
22
23 #include "config.h"
24 #include "analysisd.h"
25 #include "eventinfo.h"
26 #include "os_regex/os_regex.h"
27
28
29 /* Search last times a signature fired
30  * Will look for only that specific signature.
31  */
32 Eventinfo *Search_LastSids(Eventinfo *my_lf, RuleInfo *currently_rule)
33 {
34     Eventinfo *lf;
35     Eventinfo *first_lf;
36     OSListNode *lf_node;
37
38
39     /* Setting frequency to 0 */
40     currently_rule->__frequency = 0;
41
42
43     /* checking sid search is valid */
44     if(!currently_rule->sid_search)
45     {
46         merror("%s: No sid search!! XXX", ARGV0);
47     }
48
49     /* Getting last node */
50     lf_node = OSList_GetLastNode(currently_rule->sid_search);
51     if(!lf_node)
52     {
53         return(NULL);
54     }
55     first_lf = (Eventinfo *)lf_node->data;
56
57
58     do
59     {
60         lf = (Eventinfo *)lf_node->data;
61
62         /* If time is outside the timeframe, return */
63         if((c_time - lf->time) > currently_rule->timeframe)
64         {
65             return(NULL);
66         }
67
68         /* We avoid multiple triggers for the same rule
69          * or rules with a lower level.
70          */
71         else if(lf->matched >= currently_rule->level)
72         {
73             return(NULL);
74         }
75
76
77
78         /* Checking for same id */
79         if(currently_rule->context_opts & SAME_ID)
80         {
81             if((!lf->id) || (!my_lf->id))
82                 continue;
83
84             if(strcmp(lf->id,my_lf->id) != 0)
85                 continue;
86         }
87
88         /* Checking for repetitions from same src_ip */
89         if(currently_rule->context_opts & SAME_SRCIP)
90         {
91             if((!lf->srcip)||(!my_lf->srcip))
92                 continue;
93
94             if(strcmp(lf->srcip,my_lf->srcip) != 0)
95                 continue;
96         }
97
98
99         /* Grouping of additional data */
100         if(currently_rule->alert_opts & SAME_EXTRAINFO)
101         {
102             /* Checking for same source port */
103             if(currently_rule->context_opts & SAME_SRCPORT)
104             {
105                 if((!lf->srcport)||(!my_lf->srcport))
106                     continue;
107
108                 if(strcmp(lf->srcport, my_lf->srcport) != 0)
109                     continue;
110             }
111
112             /* Checking for same dst port */
113             if(currently_rule->context_opts & SAME_DSTPORT)
114             {
115                 if((!lf->dstport)||(!my_lf->dstport))
116                     continue;
117
118                 if(strcmp(lf->dstport, my_lf->dstport) != 0)
119                     continue;
120             }
121
122             /* Checking for repetitions on user error */
123             if(currently_rule->context_opts & SAME_USER)
124             {
125                 if((!lf->dstuser)||(!my_lf->dstuser))
126                     continue;
127
128                 if(strcmp(lf->dstuser,my_lf->dstuser) != 0)
129                     continue;
130             }
131
132             /* Checking for same location */
133             if(currently_rule->context_opts & SAME_LOCATION)
134             {
135                 if(strcmp(lf->hostname, my_lf->hostname) != 0)
136                     continue;
137             }
138
139
140             /* Checking for different urls */
141             if(currently_rule->context_opts & DIFFERENT_URL)
142             {
143                 if((!lf->url)||(!my_lf->url))
144                 {
145                     continue;
146                 }
147
148                 if(strcmp(lf->url, my_lf->url) == 0)
149                 {
150                     continue;
151                 }
152             }
153
154         }
155
156
157         /* Checking if the number of matches worked */
158         if(currently_rule->__frequency <= 10)
159         {
160             currently_rule->last_events[currently_rule->__frequency]
161                 = lf->full_log;
162             currently_rule->last_events[currently_rule->__frequency+1]
163                 = NULL;
164         }
165
166         if(currently_rule->__frequency < currently_rule->frequency)
167         {
168             currently_rule->__frequency++;
169             continue;
170         }
171         currently_rule->__frequency++;
172
173
174         /* If reached here, we matched */
175         my_lf->matched = currently_rule->level;
176         lf->matched = currently_rule->level;
177         first_lf->matched = currently_rule->level;
178
179         return(lf);
180
181
182     }while((lf_node = lf_node->prev) != NULL);
183
184     return(NULL);
185 }
186
187
188
189 /* Search last times a group fired
190  * Will look for only that specific group on that rule.
191  */
192 Eventinfo *Search_LastGroups(Eventinfo *my_lf, RuleInfo *currently_rule)
193 {
194     Eventinfo *lf;
195     Eventinfo *first_lf;
196     OSListNode *lf_node;
197
198
199     /* Setting frequency to 0 */
200     currently_rule->__frequency = 0;
201
202
203     /* checking sid search is valid */
204     if(!currently_rule->group_search)
205     {
206         merror("%s: No group search!! XXX", ARGV0);
207     }
208
209     /* Getting last node */
210     lf_node = OSList_GetLastNode(currently_rule->group_search);
211     if(!lf_node)
212     {
213         return(NULL);
214     }
215     first_lf = (Eventinfo *)lf_node->data;
216
217
218     do
219     {
220         lf = (Eventinfo *)lf_node->data;
221
222         /* If time is outside the timeframe, return */
223         if((c_time - lf->time) > currently_rule->timeframe)
224         {
225             return(NULL);
226         }
227
228         /* We avoid multiple triggers for the same rule
229          * or rules with a lower level.
230          */
231         else if(lf->matched >= currently_rule->level)
232         {
233             return(NULL);
234         }
235
236
237
238         /* Checking for same id */
239         if(currently_rule->context_opts & SAME_ID)
240         {
241             if((!lf->id) || (!my_lf->id))
242                 continue;
243
244             if(strcmp(lf->id,my_lf->id) != 0)
245                 continue;
246         }
247
248         /* Checking for repetitions from same src_ip */
249         if(currently_rule->context_opts & SAME_SRCIP)
250         {
251             if((!lf->srcip)||(!my_lf->srcip))
252                 continue;
253
254             if(strcmp(lf->srcip,my_lf->srcip) != 0)
255                 continue;
256         }
257
258
259         /* Grouping of additional data */
260         if(currently_rule->alert_opts & SAME_EXTRAINFO)
261         {
262             /* Checking for same source port */
263             if(currently_rule->context_opts & SAME_SRCPORT)
264             {
265                 if((!lf->srcport)||(!my_lf->srcport))
266                     continue;
267
268                 if(strcmp(lf->srcport, my_lf->srcport) != 0)
269                     continue;
270             }
271
272             /* Checking for same dst port */
273             if(currently_rule->context_opts & SAME_DSTPORT)
274             {
275                 if((!lf->dstport)||(!my_lf->dstport))
276                     continue;
277
278                 if(strcmp(lf->dstport, my_lf->dstport) != 0)
279                     continue;
280             }
281
282             /* Checking for repetitions on user error */
283             if(currently_rule->context_opts & SAME_USER)
284             {
285                 if((!lf->dstuser)||(!my_lf->dstuser))
286                     continue;
287
288                 if(strcmp(lf->dstuser,my_lf->dstuser) != 0)
289                     continue;
290             }
291
292             /* Checking for same location */
293             if(currently_rule->context_opts & SAME_LOCATION)
294             {
295                 if(strcmp(lf->hostname, my_lf->hostname) != 0)
296                     continue;
297             }
298
299
300             /* Checking for different urls */
301             if(currently_rule->context_opts & DIFFERENT_URL)
302             {
303                 if((!lf->url)||(!my_lf->url))
304                 {
305                     continue;
306                 }
307
308                 if(strcmp(lf->url, my_lf->url) == 0)
309                 {
310                     continue;
311                 }
312             }
313
314         }
315
316
317         /* Checking if the number of matches worked */
318         if(currently_rule->__frequency < currently_rule->frequency)
319         {
320             if(currently_rule->__frequency <= 10)
321             {
322                 currently_rule->last_events[currently_rule->__frequency]
323                     = lf->full_log;
324                 currently_rule->last_events[currently_rule->__frequency+1]
325                     = NULL;
326             }
327
328             currently_rule->__frequency++;
329             continue;
330         }
331
332
333         /* If reached here, we matched */
334         my_lf->matched = currently_rule->level;
335         lf->matched = currently_rule->level;
336         first_lf->matched = currently_rule->level;
337
338         return(lf);
339
340
341     }while((lf_node = lf_node->prev) != NULL);
342
343     return(NULL);
344 }
345
346
347 /* Search LastEvents.
348  * Will look if any of the last events (inside the timeframe)
349  * match the specified rule.
350  */
351 Eventinfo *Search_LastEvents(Eventinfo *my_lf, RuleInfo *currently_rule)
352 {
353     EventNode *eventnode_pt;
354     Eventinfo *lf;
355     Eventinfo *first_lf;
356
357
358     merror("XXXX : remove me!");
359
360
361     /* Last events */
362     eventnode_pt = OS_GetLastEvent();
363     if(!eventnode_pt)
364     {
365         /* Nothing found */
366         return(NULL);
367     }
368
369     /* Setting frequency to 0 */
370     currently_rule->__frequency = 0;
371     first_lf = (Eventinfo *)eventnode_pt->event;
372
373
374     /* Searching all previous events */
375     do
376     {
377         lf = eventnode_pt->event;
378
379         /* If time is outside the timeframe, return */
380         if((c_time - lf->time) > currently_rule->timeframe)
381         {
382             return(NULL);
383         }
384
385
386         /* We avoid multiple triggers for the same rule
387          * or rules with a lower level.
388          */
389         else if(lf->matched >= currently_rule->level)
390         {
391             return(NULL);
392         }
393
394
395         /* The category must be the same */
396         else if(lf->decoder_info->type != my_lf->decoder_info->type)
397         {
398             continue;
399         }
400
401
402         /* If regex does not match, go to next */
403         if(currently_rule->if_matched_regex)
404         {
405             if(!OSRegex_Execute(lf->log, currently_rule->if_matched_regex))
406             {
407                 /* Didn't match */
408                 continue;
409             }
410         }
411
412         /* Checking for repetitions on user error */
413         if(currently_rule->context_opts & SAME_USER)
414         {
415             if((!lf->dstuser)||(!my_lf->dstuser))
416                 continue;
417
418             if(strcmp(lf->dstuser,my_lf->dstuser) != 0)
419                 continue;
420         }
421
422         /* Checking for same id */
423         if(currently_rule->context_opts & SAME_ID)
424         {
425             if((!lf->id) || (!my_lf->id))
426                 continue;
427
428             if(strcmp(lf->id,my_lf->id) != 0)
429                 continue;
430         }
431
432         /* Checking for repetitions from same src_ip */
433         if(currently_rule->context_opts & SAME_SRCIP)
434         {
435             if((!lf->srcip)||(!my_lf->srcip))
436                 continue;
437
438             if(strcmp(lf->srcip,my_lf->srcip) != 0)
439                 continue;
440         }
441
442         /* Checking for different urls */
443         if(currently_rule->context_opts & DIFFERENT_URL)
444         {
445             if((!lf->url)||(!my_lf->url))
446             {
447                 continue;
448             }
449
450             if(strcmp(lf->url, my_lf->url) == 0)
451             {
452                 continue;
453             }
454         }
455
456
457         /* Checking if the number of matches worked */
458         if(currently_rule->__frequency < currently_rule->frequency)
459         {
460             if(currently_rule->__frequency <= 10)
461             {
462                 currently_rule->last_events[currently_rule->__frequency]
463                             = lf->full_log;
464                 currently_rule->last_events[currently_rule->__frequency+1]
465                             = NULL;
466             }
467
468             currently_rule->__frequency++;
469             continue;
470         }
471
472
473         /* If reached here, we matched */
474         my_lf->matched = currently_rule->level;
475         lf->matched = currently_rule->level;
476         first_lf->matched = currently_rule->level;
477
478         return(lf);
479
480     }while((eventnode_pt = eventnode_pt->next) != NULL);
481
482
483     return(NULL);
484 }
485
486
487 /* Zero the loginfo structure */
488 void Zero_Eventinfo(Eventinfo *lf)
489 {
490     lf->log = NULL;
491     lf->full_log = NULL;
492     lf->hostname = NULL;
493     lf->program_name = NULL;
494     lf->location = NULL;
495
496     lf->srcip = NULL;
497     lf->dstip = NULL;
498     lf->srcport = NULL;
499     lf->dstport = NULL;
500     lf->protocol = NULL;
501     lf->action = NULL;
502     lf->srcuser = NULL;
503     lf->dstuser = NULL;
504     lf->id = NULL;
505     lf->status = NULL;
506     lf->command = NULL;
507     lf->url = NULL;
508     lf->data = NULL;
509     lf->systemname = NULL;
510
511     lf->time = 0;
512     lf->matched = 0;
513
514     lf->year = 0;
515     lf->mon[3] = '\0';
516     lf->hour[9] = '\0';
517     lf->day = 0;
518
519     lf->generated_rule = NULL;
520     lf->sid_node_to_delete = NULL;
521     lf->decoder_info = NULL_Decoder;
522
523     #ifdef PRELUDE
524     lf->filename = NULL;
525     lf->perm_before = 0;
526     lf->perm_after = 0;
527     lf->md5_before = NULL;
528     lf->md5_after = NULL;
529     lf->sha1_before = NULL;
530     lf->sha1_after = NULL;
531     lf->size_before = NULL;
532     lf->size_after = NULL;
533     lf->owner_before = NULL;
534     lf->owner_after = NULL;
535     lf->gowner_before = NULL;
536     lf->gowner_after = NULL;
537     #endif
538
539     return;
540 }
541
542 /* Free the loginfo structure */
543 void Free_Eventinfo(Eventinfo *lf)
544 {
545     if(!lf)
546     {
547         merror("%s: Trying to free NULL event. Inconsistent..",ARGV0);
548         return;
549     }
550
551     if(lf->full_log)
552         free(lf->full_log);
553     if(lf->location)
554         free(lf->location);
555
556     if(lf->srcip)
557         free(lf->srcip);
558     if(lf->dstip)
559         free(lf->dstip);
560     if(lf->srcport)
561         free(lf->srcport);
562     if(lf->dstport)
563         free(lf->dstport);
564     if(lf->protocol)
565         free(lf->protocol);
566     if(lf->action)
567         free(lf->action);
568     if(lf->status)
569         free(lf->status);
570     if(lf->srcuser)
571         free(lf->srcuser);
572     if(lf->dstuser)
573         free(lf->dstuser);
574     if(lf->id)
575         free(lf->id);
576     if(lf->command)
577         free(lf->command);
578     if(lf->url)
579         free(lf->url);
580
581     if(lf->data)
582         free(lf->data);
583     if(lf->systemname)
584         free(lf->systemname);
585
586     #ifdef PRELUDE
587     if(lf->filename)
588         free(lf->filename);
589     if (lf->md5_before)
590         free(lf->md5_before);
591     if (lf->md5_after)
592         free(lf->md5_after);
593     if (lf->sha1_before)
594         free(lf->sha1_before);
595     if (lf->sha1_after)
596         free(lf->sha1_after);
597     if (lf->size_before)
598         free(lf->size_before);
599     if (lf->size_after)
600         free(lf->size_after);
601     if (lf->owner_before)
602         free(lf->owner_before);
603     if (lf->owner_after)
604         free(lf->owner_after);
605     if (lf->gowner_before)
606         free(lf->gowner_before);
607     if (lf->gowner_after)
608         free(lf->gowner_after);
609     #endif
610
611     /* Freeing node to delete */
612     if(lf->sid_node_to_delete)
613     {
614         OSList_DeleteThisNode(lf->generated_rule->sid_prev_matched,
615                               lf->sid_node_to_delete);
616     }
617     else if(lf->generated_rule && lf->generated_rule->group_prev_matched)
618     {
619         int i = 0;
620
621         while(i < lf->generated_rule->group_prev_matched_sz)
622         {
623             OSList_DeleteOldestNode(lf->generated_rule->group_prev_matched[i]);
624             i++;
625         }
626     }
627
628     /* We dont need to free:
629      * fts
630      * comment
631      */
632     free(lf);
633     lf = NULL;
634
635     return;
636 }       
637
638 /* EOF */