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