new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / analysisd / decoders / decoder.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All rights reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation.
8  */
9
10 #include "shared.h"
11 #include "os_regex/os_regex.h"
12 #include "os_xml/os_xml.h"
13 #include "eventinfo.h"
14 #include "decoder.h"
15 #include "config.h"
16
17
18
19 /* Use the osdecoders to decode the received event */
20 void DecodeEvent(Eventinfo *lf)
21 {
22     OSDecoderNode *node;
23     OSDecoderNode *child_node;
24     OSDecoderInfo *nnode;
25
26     const char *llog = NULL;
27     const char *pmatch = NULL;
28     const char *cmatch = NULL;
29     const char *regex_prev = NULL;
30
31     node = OS_GetFirstOSDecoder(lf->program_name);
32
33     if (!node) {
34         return;
35     }
36
37 #ifdef TESTRULE
38     if (!alert_only) {
39         print_out("\n**Phase 2: Completed decoding.");
40     }
41 #endif
42
43     do {
44         nnode = node->osdecoder;
45
46         /* First check program name */
47         if (lf->program_name) {
48             if (nnode->program_name) {
49                 if (!OSMatch_Execute(lf->program_name, lf->p_name_size,
50                                      nnode->program_name)) {
51                     continue;
52                 }
53                 pmatch = lf->log;
54             } else if (nnode->program_name_pcre2) {
55                 if (!OSPcre2_Execute(lf->program_name, nnode->program_name_pcre2)) {
56                     continue;
57                 }
58                 pmatch = lf->log;
59             }
60         }
61
62         /* If prematch fails, go to the next osdecoder in the list */
63         if (nnode->prematch) {
64             if (!(pmatch = OSRegex_Execute(lf->log, nnode->prematch))) {
65                 continue;
66             }
67         }
68         else if (nnode->prematch_pcre2) {
69             if (!(pmatch = OSPcre2_Execute(lf->log, nnode->prematch_pcre2))) {
70                 continue;
71             }
72         }
73
74 #ifdef TESTRULE
75         if (!alert_only) {
76             print_out("       decoder: '%s'", nnode->name);
77         }
78 #endif
79
80         lf->decoder_info = nnode;
81         child_node = node->child;
82
83         /* If no child node is set, set the child node
84          * as if it were the child (ugh)
85          */
86         if (!child_node) {
87             child_node = node;
88         }
89
90         else {
91             /* Check if we have any child osdecoder */
92             while (child_node) {
93                 nnode = child_node->osdecoder;
94
95                 /* If we have a pre match and it matches, keep
96                  * going. If we don't have a prematch, stop
97                  * and go for the regexes.
98                  */
99                 if (nnode->prematch) {
100                     const char *llog2;
101
102                     /* If we have an offset set, use it */
103                     if (nnode->prematch_offset & AFTER_PARENT) {
104                         llog2 = pmatch;
105                     } else {
106                         llog2 = lf->log;
107                     }
108
109                     if ((cmatch = OSRegex_Execute(llog2, nnode->prematch))) {
110                         lf->decoder_info = nnode;
111
112                         break;
113                     }
114                 } else if (nnode->prematch_pcre2) {
115                     const char *llog2;
116
117                     /* If we have an offset set, use it */
118                     if (nnode->prematch_offset & AFTER_PARENT) {
119                         llog2 = pmatch;
120                     } else {
121                         llog2 = lf->log;
122                     }
123
124                     if ((cmatch = OSPcre2_Execute(llog2, nnode->prematch_pcre2))) {
125                         lf->decoder_info = nnode;
126
127                         break;
128                     }
129                 } else {
130                     cmatch = pmatch;
131                     break;
132                 }
133
134                 /* If we have multiple regex-only childs,
135                  * do not attempt to go any further with them.
136                  */
137                 if (child_node->osdecoder->get_next) {
138                     do {
139                         child_node = child_node->next;
140                     } while (child_node && child_node->osdecoder->get_next);
141
142                     if (!child_node) {
143                         return;
144                     }
145
146                     child_node = child_node->next;
147                     nnode = NULL;
148                 } else {
149                     child_node = child_node->next;
150                     nnode = NULL;
151                 }
152             }
153         }
154
155         /* Nothing matched */
156         if (!nnode) {
157             return;
158         }
159
160         /* If we have an external decoder, execute it */
161         if (nnode->plugindecoder) {
162             nnode->plugindecoder(lf);
163             return;
164         }
165
166         /* Get the regex */
167         while (child_node) {
168             if (nnode->regex) {
169                 int i;
170
171                 /* With regex we have multiple options
172                  * regarding the offset:
173                  * after the prematch,
174                  * after the parent,
175                  * after some previous regex,
176                  * or any offset
177                  */
178                 if (nnode->regex_offset) {
179                     if (nnode->regex_offset & AFTER_PARENT) {
180                         llog = pmatch;
181                     } else if (nnode->regex_offset & AFTER_PREMATCH) {
182                         llog = cmatch;
183                     } else if (nnode->regex_offset & AFTER_PREVREGEX) {
184                         if (!regex_prev) {
185                             llog = cmatch;
186                         } else {
187                             llog = regex_prev;
188                         }
189                     }
190                 } else {
191                     llog = lf->log;
192                 }
193
194                 /* If Regex does not match, return */
195                 if (!(regex_prev = OSRegex_Execute(llog, nnode->regex))) {
196                     if (nnode->get_next) {
197                         child_node = child_node->next;
198                         nnode = child_node->osdecoder;
199                         continue;
200                     }
201                     return;
202                 }
203
204                 lf->decoder_info = nnode;
205
206                 for (i = 0; nnode->regex->sub_strings[i]; i++) {
207                     if (i >= Config.decoder_order_size) {
208                         ErrorExit("%s: ERROR: Regex has too many groups.", ARGV0);
209                     }
210
211                     if (nnode->order[i])
212                         nnode->order[i](lf, nnode->regex->sub_strings[i], i);
213                     else
214                         /* We do not free any memory used above */
215                         os_free(nnode->regex->sub_strings[i]);
216
217                     nnode->regex->sub_strings[i] = NULL;
218                 }
219
220                 /* If we have a next regex, try getting it */
221                 if (nnode->get_next) {
222                     child_node = child_node->next;
223                     nnode = child_node->osdecoder;
224                     continue;
225                 }
226
227                 break;
228             }
229             else if (nnode->pcre2) {
230                 int i;
231
232                 /* With regex we have multiple options
233                  * regarding the offset:
234                  * after the prematch,
235                  * after the parent,
236                  * after some previous regex,
237                  * or any offset
238                  */
239                 if (nnode->regex_offset) {
240                     if (nnode->regex_offset & AFTER_PARENT) {
241                         llog = pmatch;
242                     } else if (nnode->regex_offset & AFTER_PREMATCH) {
243                         llog = cmatch;
244                     } else if (nnode->regex_offset & AFTER_PREVREGEX) {
245                         if (!regex_prev) {
246                             llog = cmatch;
247                         } else {
248                             llog = regex_prev;
249                         }
250                     }
251                 } else {
252                     llog = lf->log;
253                 }
254
255                 /* If Regex does not match, return */
256                 if (!(regex_prev = OSPcre2_Execute(llog, nnode->pcre2))) {
257                     if (nnode->get_next) {
258                         child_node = child_node->next;
259                         nnode = child_node->osdecoder;
260                         continue;
261                     }
262                     return;
263                 }
264
265
266                 lf->decoder_info = nnode;
267
268                 for (i = 0; nnode->pcre2->sub_strings[i]; i++) {
269                     if (i >= Config.decoder_order_size) {
270                         ErrorExit("%s: ERROR: Regex has too many groups.", ARGV0);
271                     }
272
273                     if (nnode->order[i])
274                         nnode->order[i](lf, nnode->pcre2->sub_strings[i], i);
275                     else
276                         /* We do not free any memory used above */
277                         os_free(nnode->pcre2->sub_strings[i]);
278
279                     nnode->pcre2->sub_strings[i] = NULL;
280                 }
281
282                 /* If we have a next regex, try getting it */
283                 if (nnode->get_next) {
284                     child_node = child_node->next;
285                     nnode = child_node->osdecoder;
286                     continue;
287                 }
288
289                 break;
290             }
291
292
293             /* If we don't have a regex, we may leave now */
294             return;
295         }
296
297         /* ok to return  */
298         return;
299     } while ((node = node->next) != NULL);
300
301 #ifdef TESTRULE
302     if (!alert_only) {
303         print_out("       No decoder matched.");
304     }
305 #endif
306 }
307
308 /*** Event decoders ****/
309
310 void *DstUser_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
311 {
312 #ifdef TESTRULE
313     if (!alert_only) {
314         print_out("       dstuser: '%s'", field);
315     }
316 #endif
317
318     lf->dstuser = field;
319     return (NULL);
320 }
321
322 void *SrcUser_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
323 {
324 #ifdef TESTRULE
325     if (!alert_only) {
326         print_out("       srcuser: '%s'", field);
327     }
328 #endif
329
330     lf->srcuser = field;
331     return (NULL);
332 }
333
334 void *SrcIP_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
335 {
336 #ifdef TESTRULE
337     if (!alert_only) {
338         print_out("       srcip: '%s'", field);
339     }
340 #endif
341
342     lf->srcip = field;
343
344 #ifdef LIBGEOIP_ENABLED
345
346     if(!lf->srcgeoip) { 
347         lf->srcgeoip = GetGeoInfobyIP(lf->srcip);
348     }
349
350     #ifdef TESTRULE
351         if (lf->srcgeoip && !alert_only)
352             print_out("       srcgeoip: '%s'", lf->srcgeoip);
353     #endif
354
355 #endif
356     return (NULL);
357
358 }
359
360 void *DstIP_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
361 {
362 #ifdef TESTRULE
363     if (!alert_only) {
364         print_out("       dstip: '%s'", field);
365     }
366 #endif
367
368     lf->dstip = field;
369 #ifdef LIBGEOIP_ENABLED
370
371     if(!lf->dstgeoip) { 
372         lf->dstgeoip = GetGeoInfobyIP(lf->dstip);
373     }
374     #ifdef TESTRULE
375         if (lf->dstgeoip && !alert_only)
376             print_out("       dstgeoip: '%s'", lf->dstgeoip);
377     #endif
378
379 #endif
380     return (NULL);
381
382 }
383
384 void *SrcPort_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
385 {
386 #ifdef TESTRULE
387     if (!alert_only) {
388         print_out("       srcport: '%s'", field);
389     }
390 #endif
391
392     lf->srcport = field;
393     return (NULL);
394 }
395
396 void *DstPort_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
397 {
398 #ifdef TESTRULE
399     if (!alert_only) {
400         print_out("       dstport: '%s'", field);
401     }
402 #endif
403
404     lf->dstport = field;
405     return (NULL);
406 }
407
408 void *Protocol_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
409 {
410 #ifdef TESTRULE
411     if (!alert_only) {
412         print_out("       proto: '%s'", field);
413     }
414 #endif
415
416     lf->protocol = field;
417     return (NULL);
418 }
419
420 void *Action_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
421 {
422 #ifdef TESTRULE
423     if (!alert_only) {
424         print_out("       action: '%s'", field);
425     }
426 #endif
427
428     lf->action = field;
429     return (NULL);
430 }
431
432 void *ID_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
433 {
434 #ifdef TESTRULE
435     if (!alert_only) {
436         print_out("       id: '%s'", field);
437     }
438 #endif
439
440     lf->id = field;
441     return (NULL);
442 }
443
444 void *Url_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
445 {
446 #ifdef TESTRULE
447     if (!alert_only) {
448         print_out("       url: '%s'", field);
449     }
450 #endif
451
452     lf->url = field;
453     return (NULL);
454 }
455
456 void *Data_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
457 {
458 #ifdef TESTRULE
459     if (!alert_only) {
460         print_out("       extra_data: '%s'", field);
461     }
462 #endif
463
464     lf->data = field;
465     return (NULL);
466 }
467
468 void *Status_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
469 {
470 #ifdef TESTRULE
471     if (!alert_only) {
472         print_out("       status: '%s'", field);
473     }
474 #endif
475
476     lf->status = field;
477     return (NULL);
478 }
479
480 void *SystemName_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
481 {
482 #ifdef TESTRULE
483     if (!alert_only) {
484         print_out("       system_name: '%s'", field);
485     }
486 #endif
487
488     lf->systemname = field;
489     return (NULL);
490 }
491
492 void *FileName_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order)
493 {
494 #ifdef TESTRULE
495     if (!alert_only) {
496         print_out("       filename: '%s'", field);
497     }
498 #endif
499
500     lf->filename = field;
501     return (NULL);
502 }
503
504
505 void *DynamicField_FP(Eventinfo *lf, char *field, int order)
506 {
507 #ifdef TESTRULE
508     if (!alert_only) {
509         print_out("       %s: '%s'", lf->decoder_info->fields[order], field);
510     }
511 #endif
512
513     lf->fields[order] = field;
514
515     return (NULL);
516 }
517
518 void *None_FP(__attribute__((unused)) Eventinfo *lf, char *field, __attribute__((unused)) int order)
519 {
520     free(field);
521     return (NULL);
522 }
523