Imported Upstream version 2.3
[ossec-hids.git] / src / analysisd / eventinfo.c
1 /* @(#) $Id: eventinfo.c,v 1.41 2009/06/24 17:06:22 dcid Exp $ */
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 3) 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     return;
522 }
523
524 /* Free the loginfo structure */
525 void Free_Eventinfo(Eventinfo *lf)
526 {
527     if(!lf)
528     {
529         merror("%s: Trying to free NULL event. Inconsistent..",ARGV0);
530         return;
531     }
532     
533     if(lf->full_log)
534         free(lf->full_log);    
535     if(lf->location)
536         free(lf->location);    
537
538     if(lf->srcip)
539         free(lf->srcip);
540     if(lf->dstip)
541         free(lf->dstip);
542     if(lf->srcport)
543         free(lf->srcport);
544     if(lf->dstport)
545         free(lf->dstport);
546     if(lf->protocol)
547         free(lf->protocol);
548     if(lf->action)
549         free(lf->action);            
550     if(lf->status)
551         free(lf->status);
552     if(lf->srcuser)
553         free(lf->srcuser);
554     if(lf->dstuser)
555         free(lf->dstuser);    
556     if(lf->id)
557         free(lf->id);
558     if(lf->command)
559         free(lf->command);
560     if(lf->url)
561         free(lf->url);
562
563     if(lf->data)
564         free(lf->data);    
565     if(lf->systemname)
566         free(lf->systemname);    
567
568
569     /* Freeing node to delete */
570     if(lf->sid_node_to_delete)
571     {
572         OSList_DeleteThisNode(lf->generated_rule->sid_prev_matched, 
573                               lf->sid_node_to_delete);
574     }
575     else if(lf->generated_rule && lf->generated_rule->group_prev_matched)
576     {
577         int i = 0;
578
579         while(i < lf->generated_rule->group_prev_matched_sz)
580         {
581             OSList_DeleteOldestNode(lf->generated_rule->group_prev_matched[i]);
582             i++;
583         } 
584     }
585     
586     /* We dont need to free:
587      * fts
588      * comment
589      */
590     free(lf);
591     lf = NULL; 
592     
593     return;
594 }       
595
596 /* EOF */