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 */
DecodeEvent(Eventinfo * lf)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
DstUser_FP(Eventinfo * lf,char * field,int order)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
SrcUser_FP(Eventinfo * lf,char * field,int order)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
SrcIP_FP(Eventinfo * lf,char * field,int order)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
DstIP_FP(Eventinfo * lf,char * field,int order)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
SrcPort_FP(Eventinfo * lf,char * field,int order)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
DstPort_FP(Eventinfo * lf,char * field,int order)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
Protocol_FP(Eventinfo * lf,char * field,int order)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
Action_FP(Eventinfo * lf,char * field,int order)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
ID_FP(Eventinfo * lf,char * field,int order)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
Url_FP(Eventinfo * lf,char * field,int order)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
Data_FP(Eventinfo * lf,char * field,int order)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
Status_FP(Eventinfo * lf,char * field,int order)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
SystemName_FP(Eventinfo * lf,char * field,int order)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
FileName_FP(Eventinfo * lf,char * field,int order)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
DynamicField_FP(Eventinfo * lf,char * field,int order)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
None_FP(Eventinfo * lf,char * field,int order)518 void *None_FP(__attribute__((unused)) Eventinfo *lf, char *field, __attribute__((unused)) int order)
519 {
520 free(field);
521 return (NULL);
522 }
523
524