Imported Upstream version 2.5.1
[ossec-hids.git] / src / analysisd / decoders / decoder.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 #include "shared.h"
17 #include "os_regex/os_regex.h"
18 #include "os_xml/os_xml.h"
19
20
21 #include "eventinfo.h"
22 #include "decoder.h"
23
24
25
26 /* DecodeEvent.
27  * Will use the osdecoders to decode the received event.
28  */
29 void DecodeEvent(Eventinfo *lf)
30 {
31     OSDecoderNode *node;
32     OSDecoderNode *child_node;
33     OSDecoderInfo *nnode;
34
35     char *llog;
36     char *pmatch;
37     char *cmatch;
38     char *regex_prev = NULL;
39
40
41     node = OS_GetFirstOSDecoder(lf->program_name);
42
43
44     /* Return if no node...
45      * This shouldn't happen here anyways.
46      */
47     if(!node)
48         return;
49
50
51     #ifdef TESTRULE
52     if(!alert_only)
53     {
54         print_out("\n**Phase 2: Completed decoding.");
55     }
56     #endif    
57
58     do 
59     {
60         nnode = node->osdecoder;
61
62
63         /* First checking program name */
64         if(lf->program_name)
65         {
66             if(!OSMatch_Execute(lf->program_name, lf->p_name_size, 
67                         nnode->program_name))
68             {
69                 continue;
70             }
71             pmatch = lf->log;
72         }
73
74
75         /* If prematch fails, go to the next osdecoder in the list */
76         if(nnode->prematch)
77         {
78             if(!(pmatch = OSRegex_Execute(lf->log, nnode->prematch)))
79             {
80                 continue;
81             }
82
83             /* Next character */
84             if(*pmatch != '\0')
85                 pmatch++;
86         }
87
88
89         #ifdef TESTRULE
90         if(!alert_only)print_out("       decoder: '%s'", nnode->name);
91         #endif    
92         
93
94         lf->decoder_info = nnode;
95         
96
97         child_node = node->child;
98
99
100         /* If no child node is set, set the child node
101          * as if it were the child (ugh)
102          */
103         if(!child_node)
104         {
105             child_node = node;
106         }
107
108         else
109         {
110             /* Check if we have any child osdecoder */
111             while(child_node)
112             {
113                 nnode = child_node->osdecoder;
114
115
116                 /* If we have a pre match and it matches, keep
117                  * going. If we don't have a prematch, stop
118                  * and go for the regexes.
119                  */
120                 if(nnode->prematch)
121                 {
122                     char *llog;
123
124                     /* If we have an offset set, use it */     
125                     if(nnode->prematch_offset & AFTER_PARENT)
126                     {
127                         llog = pmatch;
128                     }
129                     else
130                     {
131                         llog = lf->log;
132                     }
133
134                     if((cmatch = OSRegex_Execute(llog, nnode->prematch)))
135                     {
136                         if(*cmatch != '\0')
137                             cmatch++;
138
139                         lf->decoder_info = nnode;
140
141                         break;
142                     }
143                 }
144                 else
145                 {
146                     cmatch = pmatch;
147                     break;
148                 }
149
150
151                 /* If we have multiple regex-only childs,
152                  * do not attempt to go any further with them.
153                  */
154                 if(child_node->osdecoder->get_next)
155                 {
156                     do
157                     {
158                         child_node = child_node->next;
159                     }while(child_node && child_node->osdecoder->get_next);
160
161                     if(!child_node)
162                         return;
163
164                     child_node = child_node->next;
165                     nnode = NULL;   
166                 }
167                 else
168                 {
169                     child_node = child_node->next;
170                     nnode = NULL;
171                 }
172             }
173         }
174
175
176         /* Nothing matched */
177         if(!nnode)
178             return;
179
180
181         /* If we have a external decoder, execute it */
182         if(nnode->plugindecoder)
183         {
184             nnode->plugindecoder(lf);
185             return;
186         }
187         
188         
189         /* Getting the regex */
190         while(child_node)
191         {
192             if(nnode->regex)
193             {
194                 int i = 0;
195
196                 /* With regex we have multiple options
197                  * regarding the offset:
198                  * after the prematch,
199                  * after the parent,
200                  * after some previous regex,
201                  * or any offset
202                  */
203                 if(nnode->regex_offset)
204                 {
205                     if(nnode->regex_offset & AFTER_PARENT)
206                     {
207                         llog = pmatch;
208                     }
209                     else if(nnode->regex_offset & AFTER_PREMATCH)
210                     {
211                         llog = cmatch;
212                     }
213                     else if(nnode->regex_offset & AFTER_PREVREGEX)
214                     {
215                         if(!regex_prev)
216                             llog = cmatch;
217                         else
218                             llog = regex_prev;
219                     }
220                 }
221                 else
222                 {
223                     llog = lf->log;
224                 }
225
226                 /* If Regex does not match, return */
227                 if(!(regex_prev = OSRegex_Execute(llog, nnode->regex)))
228                 {
229                     if(nnode->get_next)
230                     {
231                         child_node = child_node->next;
232                         nnode = child_node->osdecoder;
233                         continue;
234                     }
235                     return;
236                 }
237
238
239                 /* Fixing next pointer */
240                 if(*regex_prev != '\0')
241                     regex_prev++;
242
243                 while(nnode->regex->sub_strings[i])
244                 {
245                     if(nnode->order[i])
246                     {
247                         nnode->order[i](lf, nnode->regex->sub_strings[i]);
248                         nnode->regex->sub_strings[i] = NULL;
249                         i++;
250                         continue;
251                     }
252
253                     /* We do not free any memory used above */
254                     os_free(nnode->regex->sub_strings[i]);
255                     nnode->regex->sub_strings[i] = NULL;
256                     i++;
257                 }
258
259                 /* If we have a next regex, try getting it */
260                 if(nnode->get_next)
261                 {
262                     child_node = child_node->next;
263                     nnode = child_node->osdecoder;
264                     continue;
265                 }
266
267                 break;
268             }
269
270             /* If we don't have a regex, we may leave now */
271             return;
272         }
273
274         /* ok to return  */
275         return;         
276     }while((node=node->next) != NULL);
277
278     #ifdef TESTRULE
279     if(!alert_only)
280     {
281         print_out("       No decoder matched.");
282     }
283     #endif
284                 
285 }
286
287
288 /*** Event decoders ****/
289 void *DstUser_FP(Eventinfo *lf, char *field)
290 {
291     #ifdef TESTRULE
292     if(!alert_only)print_out("       dstuser: '%s'", field);
293     #endif
294                     
295     lf->dstuser = field;
296     return(NULL);
297 }
298 void *SrcUser_FP(Eventinfo *lf, char *field)
299 {
300     #ifdef TESTRULE
301     if(!alert_only)print_out("       srcuser: '%s'", field);
302     #endif
303                     
304     lf->srcuser = field;
305     return(NULL);
306 }
307 void *SrcIP_FP(Eventinfo *lf, char *field)
308 {
309     #ifdef TESTRULE
310     if(!alert_only)print_out("       srcip: '%s'", field);
311     #endif
312                     
313     lf->srcip = field;
314     return(NULL);
315 }
316 void *DstIP_FP(Eventinfo *lf, char *field)
317 {
318     #ifdef TESTRULE
319     if(!alert_only)print_out("       dstip: '%s'", field);
320     #endif
321                     
322     lf->dstip = field;
323     return(NULL);
324 }
325 void *SrcPort_FP(Eventinfo *lf, char *field)
326 {
327     #ifdef TESTRULE
328     if(!alert_only)print_out("       srcport: '%s'", field);
329     #endif
330                     
331     lf->srcport = field;
332     return(NULL);
333 }
334 void *DstPort_FP(Eventinfo *lf, char *field)
335 {
336     #ifdef TESTRULE
337     if(!alert_only)print_out("       dstport: '%s'", field);
338     #endif
339                     
340     lf->dstport = field;
341     return(NULL);
342 }
343 void *Protocol_FP(Eventinfo *lf, char *field)
344 {
345     #ifdef TESTRULE
346     if(!alert_only)print_out("       proto: '%s'", field);
347     #endif
348                     
349     lf->protocol = field;
350     return(NULL);
351 }
352 void *Action_FP(Eventinfo *lf, char *field)
353 {
354     #ifdef TESTRULE
355     if(!alert_only)print_out("       action: '%s'", field);
356     #endif
357                     
358     lf->action = field;
359     return(NULL);
360 }
361 void *ID_FP(Eventinfo *lf, char *field)
362 {
363     #ifdef TESTRULE
364     if(!alert_only)print_out("       id: '%s'", field);
365     #endif
366                     
367     lf->id = field;
368     return(NULL);
369 }
370 void *Url_FP(Eventinfo *lf, char *field)
371 {
372     #ifdef TESTRULE
373     if(!alert_only)print_out("       url: '%s'", field);
374     #endif
375                     
376     lf->url = field;
377     return(NULL);
378 }
379 void *Data_FP(Eventinfo *lf, char *field)
380 {
381     #ifdef TESTRULE
382     if(!alert_only)print_out("       extra_data: '%s'", field);
383     #endif
384                     
385     lf->data = field;
386     return(NULL);
387 }
388 void *Status_FP(Eventinfo *lf, char *field)
389 {
390     #ifdef TESTRULE
391     if(!alert_only)print_out("       status: '%s'", field);
392     #endif
393                     
394     lf->status = field;
395     return(NULL);
396 }
397 void *SystemName_FP(Eventinfo *lf, char *field)
398 {
399     #ifdef TESTRULE
400     if(!alert_only)print_out("       system_name: '%s'", field);
401     #endif
402
403     lf->systemname = field;
404     return(NULL);
405 }
406 void *None_FP(Eventinfo *lf, char *field)
407 {
408     free(field);
409     return(NULL);
410 }
411
412
413 /* EOF */