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