new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / analysisd / decoders / decode-xml.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 "analysisd.h"
14 #include "eventinfo.h"
15 #include "decoder.h"
16 #include "plugin_decoders.h"
17 #include "config.h"
18
19
20 #ifdef TESTRULE
21 #undef XML_LDECODER
22 #define XML_LDECODER "etc/local_decoder.xml"
23 #endif
24
25 /* Internal functions */
26 static char *_loadmemory(char *at, char *str);
27 static int addDecoder2list(const char *name);
28 static int os_setdecoderids(const char *p_name);
29 static int ReadDecodeAttrs(char *const *names, char *const *values);
30 static OSStore *os_decoder_store = NULL;
31
32
33 int getDecoderfromlist(const char *name)
34 {
35     if (os_decoder_store) {
36         return (OSStore_GetPosition(os_decoder_store, name));
37     }
38
39     return (0);
40 }
41
42 static int addDecoder2list(const char *name)
43 {
44     if (os_decoder_store == NULL) {
45         os_decoder_store = OSStore_Create();
46         if (os_decoder_store == NULL) {
47             merror(LIST_ERROR, ARGV0);
48             return (0);
49         }
50     }
51
52     /* Store data */
53     if (!OSStore_Put(os_decoder_store, name, NULL)) {
54         merror(LIST_ADD_ERROR, ARGV0);
55         return (0);
56     }
57
58     return (1);
59 }
60
61 static int os_setdecoderids(const char *p_name)
62 {
63     OSDecoderNode *node;
64     OSDecoderNode *child_node;
65     OSDecoderInfo *nnode;
66
67     node = OS_GetFirstOSDecoder(p_name);
68
69     if (!node) {
70         return (0);
71     }
72
73     do {
74         int p_id = 0;
75         char *tmp_name;
76
77         nnode = node->osdecoder;
78         nnode->id = getDecoderfromlist(nnode->name);
79
80         /* Id cannot be 0 */
81         if (nnode->id == 0) {
82             return (0);
83         }
84
85         child_node = node->child;
86
87         if (!child_node) {
88             continue;
89         }
90
91         /* Set parent id */
92         p_id = nnode->id;
93         tmp_name = nnode->name;
94
95         /* Also set on the child nodes */
96         while (child_node) {
97             nnode = child_node->osdecoder;
98
99             if (nnode->use_own_name) {
100                 nnode->id = getDecoderfromlist(nnode->name);
101             } else {
102                 nnode->id = p_id;
103
104                 /* Set parent name */
105                 free(nnode->name);
106                 nnode->name = strdup(tmp_name);
107             }
108
109             /* Id cannot be 0 */
110             if (nnode->id == 0) {
111                 return (0);
112             }
113             child_node = child_node->next;
114         }
115     } while ((node = node->next) != NULL);
116
117     return (1);
118 }
119
120 static int ReadDecodeAttrs(char *const *names, char *const *values)
121 {
122     if (!names || !values) {
123         return (0);
124     }
125
126     if (!names[0] || !values[0]) {
127         return (0);
128     }
129
130     if (strcmp(names[0], "offset") == 0) {
131         int offset = 0;
132
133         /* Offsets can be: after_parent, after_prematch
134          * or after_regex.
135          */
136         if (strcmp(values[0], "after_parent") == 0) {
137             offset |= AFTER_PARENT;
138         } else if (strcmp(values[0], "after_prematch") == 0) {
139             offset |= AFTER_PREMATCH;
140         } else if (strcmp(values[0], "after_regex") == 0) {
141             offset |= AFTER_PREVREGEX;
142         } else {
143             merror(INV_OFFSET, ARGV0, values[0]);
144             offset |= AFTER_ERROR;
145         }
146
147         return (offset);
148     }
149
150     /* Invalid attribute */
151     merror(INV_ATTR, ARGV0, names[0]);
152     return (AFTER_ERROR);
153 }
154
155 int ReadDecodeXML(const char *file)
156 {
157     OS_XML xml;
158     XML_NODE node = NULL;
159
160     /* XML variables */
161     /* These are the available options for the rule configuration */
162
163     const char *xml_plugindecoder = "plugin_decoder";
164     const char *xml_decoder = "decoder";
165     const char *xml_decoder_name = "name";
166     const char *xml_decoder_status = "status";
167     const char *xml_usename = "use_own_name";
168     const char *xml_parent = "parent";
169     const char *xml_program_name = "program_name";
170     const char *xml_prematch = "prematch";
171     const char *xml_regex = "regex";
172     const char *xml_program_name_pcre2 = "program_name_pcre2";
173     const char *xml_prematch_pcre2 = "prematch_pcre2";
174     const char *xml_pcre2 = "pcre2";
175     const char *xml_order = "order";
176     const char *xml_type = "type";
177     const char *xml_fts = "fts";
178     const char *xml_ftscomment = "ftscomment";
179     const char *xml_accumulate = "accumulate";
180
181     int i = 0;
182     OSDecoderInfo *NULL_Decoder_tmp = NULL;
183
184     /* Read the XML */
185     if ((i = OS_ReadXML(file, &xml)) < 0) {
186         if ((i == -2) && (strcmp(file, XML_LDECODER) == 0)) {
187             return (-2);
188         }
189
190         merror(XML_ERROR, ARGV0, file, xml.err, xml.err_line);
191         return (0);
192     }
193
194     /* Apply any variables found */
195     if (OS_ApplyVariables(&xml) != 0) {
196         merror(XML_ERROR_VAR, ARGV0, file, xml.err);
197         return (0);
198     }
199
200     /* Get the root elements */
201     node = OS_GetElementsbyNode(&xml, NULL);
202     if (!node) {
203         if (strcmp(file, XML_LDECODER) != 0) {
204             merror(XML_ELEMNULL, ARGV0);
205             return (0);
206         }
207
208         return (-2);
209     }
210
211     /* Zero NULL_decoder */
212     if (!NULL_Decoder) {
213         os_calloc(1, sizeof(OSDecoderInfo), NULL_Decoder_tmp);
214         NULL_Decoder_tmp->id = 0;
215         NULL_Decoder_tmp->type = SYSLOG;
216         NULL_Decoder_tmp->name = NULL;
217         NULL_Decoder_tmp->fts = 0;
218         NULL_Decoder = NULL_Decoder_tmp;
219     }
220
221     i = 0;
222     while (node[i]) {
223         XML_NODE elements = NULL;
224         OSDecoderInfo *pi;
225
226         int j = 0;
227         char *regex;
228         char *prematch;
229         char *p_name;
230         char *pcre2;
231         char *prematch_pcre2;
232         char *p_name_pcre2;
233
234         if (!node[i]->element ||
235                 strcasecmp(node[i]->element, xml_decoder) != 0) {
236             merror(XML_INVELEM, ARGV0, node[i]->element);
237             return (0);
238         }
239
240         /* Get name */
241         if ((!node[i]->attributes) || (!node[i]->values) ||
242                 (!node[i]->values[0])  || (!node[i]->attributes[0]) ||
243                 (strcasecmp(node[i]->attributes[0], xml_decoder_name) != 0)) {
244             merror(XML_INVELEM, ARGV0, node[i]->element);
245             return (0);
246         }
247
248         /* Check for additional entries */
249         if (node[i]->attributes[1] && node[i]->values[1]) {
250             if (strcasecmp(node[i]->attributes[0], xml_decoder_status) != 0) {
251                 merror(XML_INVELEM, ARGV0, node[i]->element);
252                 return (0);
253             }
254
255             if (node[i]->attributes[2]) {
256                 merror(XML_INVELEM, ARGV0, node[i]->element);
257                 return (0);
258             }
259         }
260
261         /* Get decoder options */
262         elements = OS_GetElementsbyNode(&xml, node[i]);
263         if (elements == NULL) {
264             merror(XML_ELEMNULL, ARGV0);
265             return (0);
266         }
267
268         /* Create the OSDecoderInfo */
269         pi = (OSDecoderInfo *)calloc(1, sizeof(OSDecoderInfo));
270         if (pi == NULL) {
271             merror(MEM_ERROR, ARGV0, errno, strerror(errno));
272             return (0);
273         }
274
275         /* Default values to the list */
276         pi->parent = NULL;
277         pi->id = 0;
278         pi->name = strdup(node[i]->values[0]);
279         pi->order = NULL;
280         pi->plugindecoder = NULL;
281         pi->fts = 0;
282         pi->accumulate = 0;
283         pi->type = SYSLOG;
284         pi->prematch = NULL;
285         pi->program_name = NULL;
286         pi->regex = NULL;
287         pi->prematch_pcre2 = NULL;
288         pi->program_name_pcre2 = NULL;
289         pi->pcre2 = NULL;
290         pi->use_own_name = 0;
291         pi->get_next = 0;
292         pi->regex_offset = 0;
293         pi->prematch_offset = 0;
294
295         regex = NULL;
296         prematch = NULL;
297         p_name = NULL;
298         pcre2 = NULL;
299         prematch_pcre2 = NULL;
300         p_name_pcre2 = NULL;
301
302         /* Check if strdup worked */
303         if (!pi->name) {
304             merror(MEM_ERROR, ARGV0, errno, strerror(errno));
305             return (0);
306         }
307
308         /* Add decoder */
309         if (!addDecoder2list(pi->name)) {
310             merror(MEM_ERROR, ARGV0, errno, strerror(errno));
311             free(pi->name);
312             free(pi);
313             return (0);
314         }
315
316         /* Loop over all the elements */
317         while (elements[j]) {
318             if (!elements[j]->element) {
319                 merror(XML_ELEMNULL, ARGV0);
320                 return (0);
321             } else if (!elements[j]->content) {
322                 merror(XML_VALUENULL, ARGV0, elements[j]->element);
323                 return (0);
324             }
325
326             /* Check if it is a child of a rule */
327             else if (strcasecmp(elements[j]->element, xml_parent) == 0) {
328                 pi->parent = _loadmemory(pi->parent, elements[j]->content);
329             }
330
331             /* Get the regex */
332             else if (strcasecmp(elements[j]->element, xml_regex) == 0) {
333                 int r_offset;
334                 r_offset = ReadDecodeAttrs(elements[j]->attributes,
335                                            elements[j]->values);
336
337                 if (r_offset & AFTER_ERROR) {
338                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
339                     return (0);
340                 }
341
342                 /* Only the first regex entry may have an offset */
343                 if (regex && r_offset) {
344                     merror(DUP_REGEX, ARGV0, pi->name);
345                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
346                     return (0);
347                 }
348
349                 /* regex offset */
350                 if (r_offset) {
351                     pi->regex_offset = r_offset;
352                 }
353
354                 /* Assign regex */
355                 regex =
356                     _loadmemory(regex,
357                                 elements[j]->content);
358             }
359
360             /* Get the PCRE2 */
361             else if (strcasecmp(elements[j]->element, xml_pcre2) == 0) {
362                 int r_offset;
363                 r_offset = ReadDecodeAttrs(elements[j]->attributes,
364                                            elements[j]->values);
365
366                 if (r_offset & AFTER_ERROR) {
367                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
368                     return (0);
369                 }
370
371                 /* Only the first regex entry may have an offset */
372                 if (pcre2 && r_offset) {
373                     merror(DUP_REGEX, ARGV0, pi->name);
374                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
375                     return (0);
376                 }
377
378                 /* regex offset */
379                 if (r_offset) {
380                     pi->regex_offset = r_offset;
381                 }
382
383                 /* Assign regex */
384                 pcre2 =
385                     _loadmemory(pcre2,
386                                 elements[j]->content);
387             }
388
389             /* Get the pre match */
390             else if (strcasecmp(elements[j]->element, xml_prematch) == 0) {
391                 int r_offset;
392
393                 r_offset = ReadDecodeAttrs(
394                                elements[j]->attributes,
395                                elements[j]->values);
396
397                 if (r_offset & AFTER_ERROR) {
398                     ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name);
399                 }
400
401                 /* Only the first prematch entry may have an offset */
402                 if (prematch && r_offset) {
403                     merror(DUP_REGEX, ARGV0, pi->name);
404                     ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name);
405                 }
406
407                 if (r_offset) {
408                     pi->prematch_offset = r_offset;
409                 }
410
411                 prematch =
412                     _loadmemory(prematch,
413                                 elements[j]->content);
414             }
415             else if (strcasecmp(elements[j]->element, xml_prematch_pcre2) == 0) {
416                 int r_offset;
417
418                 r_offset = ReadDecodeAttrs(
419                                elements[j]->attributes,
420                                elements[j]->values);
421
422                 if (r_offset & AFTER_ERROR) {
423                     ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name);
424                 }
425
426                 /* Only the first prematch entry may have an offset */
427                 if (prematch_pcre2 && r_offset) {
428                     merror(DUP_REGEX, ARGV0, pi->name);
429                     ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name);
430                 }
431
432                 if (r_offset) {
433                     pi->prematch_offset = r_offset;
434                 }
435
436                 prematch_pcre2 =
437                     _loadmemory(prematch_pcre2,
438                                 elements[j]->content);
439             }
440
441             /* Get program name */
442             else if (strcasecmp(elements[j]->element, xml_program_name) == 0) {
443                 p_name = _loadmemory(p_name, elements[j]->content);
444             }
445             else if (strcasecmp(elements[j]->element, xml_program_name_pcre2) == 0) {
446                 p_name_pcre2 = _loadmemory(p_name_pcre2, elements[j]->content);
447             }
448
449             /* Get the FTS comment */
450             else if (strcasecmp(elements[j]->element, xml_ftscomment) == 0) {
451             }
452
453             else if (strcasecmp(elements[j]->element, xml_usename) == 0) {
454                 if (strcmp(elements[j]->content, "true") == 0) {
455                     pi->use_own_name = 1;
456                 }
457             }
458
459             else if (strcasecmp(elements[j]->element, xml_plugindecoder) == 0) {
460                 int ed_c = 0;
461                 for (ed_c = 0; plugin_decoders[ed_c] != NULL; ed_c++) {
462                     if (strcmp(plugin_decoders[ed_c],
463                                elements[j]->content) == 0) {
464                         /* Initialize plugin */
465                         void (*dec_init)(void) = (void (*)(void)) plugin_decoders_init[ed_c];
466                         dec_init();
467                         pi->plugindecoder = (void (*)(void *)) plugin_decoders_exec[ed_c];
468                         break;
469                     }
470                 }
471
472                 /* Decoder not found */
473                 if (pi->plugindecoder == NULL) {
474                     merror(INV_DECOPTION, ARGV0, elements[j]->element,
475                            elements[j]->content);
476                     return (0);
477                 }
478             }
479
480             /* Get the type */
481             else if (strcmp(elements[j]->element, xml_type) == 0) {
482                 if (strcmp(elements[j]->content, "firewall") == 0) {
483                     pi->type = FIREWALL;
484                 } else if (strcmp(elements[j]->content, "ids") == 0) {
485                     pi->type = IDS;
486                 } else if (strcmp(elements[j]->content, "web-log") == 0) {
487                     pi->type = WEBLOG;
488                 } else if (strcmp(elements[j]->content, "syslog") == 0) {
489                     pi->type = SYSLOG;
490                 } else if (strcmp(elements[j]->content, "squid") == 0) {
491                     pi->type = SQUID;
492                 } else if (strcmp(elements[j]->content, "windows") == 0) {
493                     pi->type = DECODER_WINDOWS;
494                 } else if (strcmp(elements[j]->content, "host-information") == 0) {
495                     pi->type = HOST_INFO;
496                 } else if (strcmp(elements[j]->content, "ossec") == 0) {
497                     pi->type = OSSEC_RL;
498                 } else {
499                     merror("%s: Invalid decoder type '%s'.",
500                            ARGV0, elements[j]->content);
501                     return (0);
502                 }
503             }
504
505             /* Get the order */
506             else if (strcasecmp(elements[j]->element, xml_order) == 0) {
507                 char **norder, **s_norder;
508                 int order_int = 0;
509
510                 /* Maximum number for the order is limited by decoder_order_size */
511                 norder = OS_StrBreak(',', elements[j]->content, MAX_DECODER_ORDER_SIZE);
512                 s_norder = norder;
513                 os_calloc(Config.decoder_order_size, sizeof(void *), pi->order);
514                 os_calloc(Config.decoder_order_size, sizeof(char *), pi->fields);
515
516                 order_int = 0;
517
518                 /* Check the values from the order */
519                 while (*norder) {
520                     if (order_int >= Config.decoder_order_size) {
521                         ErrorExit("%s: ERROR: Order has too many fields.", ARGV0);
522                     }
523
524                     char *word = &(*norder)[strspn(*norder, " ")];
525                     word[strcspn(word, " ")] = '\0';
526
527                     if (strlen(word) == 0) {
528                         ErrorExit("decode-xml: Wrong field '%s' in the order"
529                                   " of decoder '%s'", *norder, pi->name);
530                     }
531
532                     if (!strcmp(word, "dstuser")) {
533                         pi->order[order_int] = DstUser_FP;
534                     } else if (!strcmp(word, "srcuser")) {
535                         pi->order[order_int] = SrcUser_FP;
536                     }
537                     /* User is an alias to dstuser */
538                     else if (!strcmp(word, "user")) {
539                         pi->order[order_int] = DstUser_FP;
540                     } else if (!strcmp(word, "srcip")) {
541                         pi->order[order_int] = SrcIP_FP;
542                     } else if (!strcmp(word, "dstip")) {
543                         pi->order[order_int] = DstIP_FP;
544                     } else if (!strcmp(word, "srcport")) {
545                         pi->order[order_int] = SrcPort_FP;
546                     } else if (!strcmp(word, "dstport")) {
547                         pi->order[order_int] = DstPort_FP;
548                     } else if (!strcmp(word, "protocol")) {
549                         pi->order[order_int] = Protocol_FP;
550                     } else if (!strcmp(word, "action")) {
551                         pi->order[order_int] = Action_FP;
552                     } else if (!strcmp(word, "id")) {
553                         pi->order[order_int] = ID_FP;
554                     } else if (!strcmp(word, "url")) {
555                         pi->order[order_int] = Url_FP;
556                     } else if (!strcmp(word, "data")) {
557                         pi->order[order_int] = Data_FP;
558                     } else if (!strcmp(word, "extra_data")) {
559                         pi->order[order_int] = Data_FP;
560                     } else if (!strcmp(word, "status")) {
561                         pi->order[order_int] = Status_FP;
562                     } else if (!strcmp(word, "system_name")) {
563                         pi->order[order_int] = SystemName_FP;
564                     } else if (strstr(*norder, "filename") != NULL) {
565                         pi->order[order_int] = FileName_FP;
566                     } else {
567                         pi->order[order_int] = DynamicField_FP;
568                         pi->fields[order_int] = strdup(*norder);
569
570                     }
571
572                     free(*norder);
573                     norder++;
574
575                     order_int++;
576                 }
577
578                 free(s_norder);
579             }
580
581             else if (strcasecmp(elements[j]->element, xml_accumulate) == 0) {
582                 /* Enable Accumulator */
583                 pi->accumulate = 1;
584             }
585
586             /* Get the FTS order */
587             else if (strcasecmp(elements[j]->element, xml_fts) == 0) {
588                 char **norder;
589                 char **s_norder;
590
591                 /* Maximum number is 8 for the FTS */
592                 norder = OS_StrBreak(',', elements[j]->content, 8);
593                 if (norder == NULL) {
594                     ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno));
595                 }
596
597                 /* Save the initial point to free later */
598                 s_norder = norder;
599
600                 /* Check the values from the FTS */
601                 while (*norder) {
602                     if (strstr(*norder, "dstuser") != NULL) {
603                         pi->fts |= FTS_DSTUSER;
604                     }
605                     if (strstr(*norder, "user") != NULL) {
606                         pi->fts |= FTS_DSTUSER;
607                     } else if (strstr(*norder, "srcuser") != NULL) {
608                         pi->fts |= FTS_SRCUSER;
609                     } else if (strstr(*norder, "srcip") != NULL) {
610                         pi->fts |= FTS_SRCIP;
611                     } else if (strstr(*norder, "dstip") != NULL) {
612                         pi->fts |= FTS_DSTIP;
613                     } else if (strstr(*norder, "id") != NULL) {
614                         pi->fts |= FTS_ID;
615                     } else if (strstr(*norder, "location") != NULL) {
616                         pi->fts |= FTS_LOCATION;
617                     } else if (strstr(*norder, "data") != NULL) {
618                         pi->fts |= FTS_DATA;
619                     } else if (strstr(*norder, "extra_data") != NULL) {
620                         pi->fts |= FTS_DATA;
621                     } else if (strstr(*norder, "system_name") != NULL) {
622                         pi->fts |= FTS_SYSTEMNAME;
623                     } else if (strstr(*norder, "name") != NULL) {
624                         pi->fts |= FTS_NAME;
625                     } else {
626                         ErrorExit("decode-xml: Wrong field '%s' in the fts"
627                                   " decoder '%s'", *norder, pi->name);
628                     }
629
630                     free(*norder);
631                     norder++;
632                 }
633
634                 /* Clear memory here */
635                 free(s_norder);
636             } else {
637                 merror("%s: Invalid element '%s' for "
638                        "decoder '%s'",
639                        ARGV0,
640                        elements[j]->element,
641                        node[i]->element);
642                 return (0);
643             }
644
645             /* NEXT */
646             j++;
647
648         } /* while(elements[j]) */
649
650         OS_ClearNode(elements);
651
652
653         /* Prematch must be set */
654         if (!(prematch || prematch_pcre2) && !pi->parent && !(p_name || p_name_pcre2)) {
655             merror(DECODE_NOPRE, ARGV0, pi->name);
656             merror(DEC_REGEX_ERROR, ARGV0, pi->name);
657             return (0);
658         }
659
660         /* If pi->regex is not set, fts must not be set too */
661         if ((!(regex || pcre2) && (pi->fts || pi->order)) || ((regex || pcre2) && !pi->order)) {
662             merror(DEC_REGEX_ERROR, ARGV0, pi->name);
663             return (0);
664         }
665
666         /* For the offsets */
667         if ((pi->regex_offset & AFTER_PARENT) && !pi->parent) {
668             merror(INV_OFFSET, ARGV0, "after_parent");
669             merror(DEC_REGEX_ERROR, ARGV0, pi->name);
670             return (0);
671         }
672
673         if (pi->regex_offset & AFTER_PREMATCH) {
674             /* If after_prematch is set, but rule have
675              * no parent, set AFTER_PARENT and unset
676              * pre_match.
677              */
678             if (!pi->parent) {
679                 pi->regex_offset = 0;
680                 pi->regex_offset |= AFTER_PARENT;
681             } else if (!(prematch || prematch_pcre2)) {
682                 merror(INV_OFFSET, ARGV0, "after_prematch");
683                 merror(DEC_REGEX_ERROR, ARGV0, pi->name);
684                 return (0);
685             }
686         }
687
688         /* For the after_regex offset */
689         if (pi->regex_offset & AFTER_PREVREGEX) {
690             if (!pi->parent || !(regex || pcre2)) {
691                 merror(INV_OFFSET, ARGV0, "after_regex");
692                 merror(DEC_REGEX_ERROR, ARGV0, pi->name);
693                 return (0);
694             }
695         }
696
697         /* Check the prematch offset */
698         if (pi->prematch_offset) {
699             /* Only the after parent is allowed */
700             if (pi->prematch_offset & AFTER_PARENT) {
701                 if (!pi->parent) {
702                     merror(INV_OFFSET, ARGV0, "after_parent");
703                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
704                     return (0);
705                 }
706             } else {
707                 merror(DEC_REGEX_ERROR, ARGV0, pi->name);
708                 return (0);
709             }
710         }
711
712         /* Compile the regex/prematch */
713         if (prematch) {
714             os_calloc(1, sizeof(OSRegex), pi->prematch);
715             if (!OSRegex_Compile(prematch, pi->prematch, 0)) {
716                 merror(REGEX_COMPILE, ARGV0, prematch, pi->prematch->error);
717                 return (0);
718             }
719
720             free(prematch);
721         }
722         else if (prematch_pcre2) {
723             os_calloc(1, sizeof(OSPcre2), pi->prematch_pcre2);
724             if (!OSPcre2_Compile(prematch_pcre2, pi->prematch_pcre2, PCRE2_CASELESS)) {
725                 merror(REGEX_COMPILE, ARGV0, prematch_pcre2, pi->prematch_pcre2->error);
726                 return (0);
727             }
728
729             free(prematch_pcre2);
730         }
731
732         /* Compile the p_name */
733         if (p_name) {
734             os_calloc(1, sizeof(OSMatch), pi->program_name);
735             if (!OSMatch_Compile(p_name, pi->program_name, 0)) {
736                 merror(REGEX_COMPILE, ARGV0, p_name, pi->program_name->error);
737                 return (0);
738             }
739
740             free(p_name);
741         }
742         else if (p_name_pcre2) {
743             os_calloc(1, sizeof(OSPcre2), pi->program_name_pcre2);
744             if (!OSPcre2_Compile(p_name_pcre2, pi->program_name_pcre2, PCRE2_CASELESS)) {
745                 merror(REGEX_COMPILE, ARGV0, p_name_pcre2, pi->program_name_pcre2->error);
746                 return (0);
747             }
748
749             free(p_name_pcre2);
750         }
751
752         /* We may not have the pi->regex */
753         if (regex) {
754             os_calloc(1, sizeof(OSRegex), pi->regex);
755             if (!OSRegex_Compile(regex, pi->regex, OS_RETURN_SUBSTRING)) {
756                 merror(REGEX_COMPILE, ARGV0, regex, pi->regex->error);
757                 return (0);
758             }
759
760             /* We must have the sub_strings to retrieve the nodes */
761             if (!pi->regex->sub_strings) {
762                 merror(REGEX_SUBS, ARGV0, regex);
763                 return (0);
764             }
765
766             free(regex);
767         }
768         else if (pcre2) {
769             os_calloc(1, sizeof(OSPcre2), pi->pcre2);
770             if (!OSPcre2_Compile(pcre2, pi->pcre2, PCRE2_CASELESS)) {
771                 merror(REGEX_COMPILE, ARGV0, pcre2, pi->pcre2->error);
772                 return (0);
773             }
774
775             free(pcre2);
776         }
777
778         /* Validate arguments */
779         if (pi->plugindecoder && (pi->regex || pi->order)) {
780             merror(DECODE_ADD, ARGV0, pi->name);
781             return (0);
782         }
783
784         /* Add osdecoder to the list */
785         if (!OS_AddOSDecoder(pi)) {
786             merror(DECODER_ERROR, ARGV0);
787             return (0);
788         }
789
790         i++;
791     } /* while (node[i]) */
792
793
794     /* Clean node and XML structures */
795     OS_ClearNode(node);
796     OS_ClearXML(&xml);
797
798     return (1);
799 }
800
801 int SetDecodeXML()
802 {
803     /* Add rootcheck decoder to list */
804     addDecoder2list(ROOTCHECK_MOD);
805     addDecoder2list(SYSCHECK_MOD);
806     addDecoder2list(SYSCHECK_MOD2);
807     addDecoder2list(SYSCHECK_MOD3);
808     addDecoder2list(SYSCHECK_NEW);
809     addDecoder2list(SYSCHECK_DEL);
810     addDecoder2list(HOSTINFO_NEW);
811     addDecoder2list(HOSTINFO_MOD);
812
813     /* Set ids - for our two lists */
814     if (!os_setdecoderids(NULL)) {
815         merror(DECODER_ERROR, ARGV0);
816         return (0);
817     }
818     if (!os_setdecoderids(ARGV0)) {
819         merror(DECODER_ERROR, ARGV0);
820         return (0);
821     }
822
823     return (1);
824 }
825
826 /* Allocate memory at "*at" and copy *str to it
827  * If *at already exist, realloc the memory and cat str on it
828  * Returns the new string
829  */
830 char *_loadmemory(char *at, char *str)
831 {
832     if (at == NULL) {
833         size_t strsize = 0;
834         if ((strsize = strlen(str)) < OS_SIZE_8192) {
835             at = (char *) calloc(strsize + 1, sizeof(char));
836             if (at == NULL) {
837                 merror(MEM_ERROR, ARGV0, errno, strerror(errno));
838                 return (NULL);
839             }
840             strncpy(at, str, strsize);
841             return (at);
842         } else {
843             merror(SIZE_ERROR, ARGV0, str);
844             return (NULL);
845         }
846     }
847     /* At is not null. Need to reallocate its memory and copy str to it */
848     else {
849         size_t strsize = strlen(str);
850         size_t atsize = strlen(at);
851         size_t finalsize = atsize + strsize + 1;
852         if (finalsize > OS_SIZE_8192) {
853             merror(SIZE_ERROR, ARGV0, str);
854             return (NULL);
855         }
856         at = (char *) realloc(at, (finalsize + 1) * sizeof(char));
857         if (at == NULL) {
858             merror(MEM_ERROR, ARGV0, errno, strerror(errno));
859             return (NULL);
860         }
861         strncat(at, str, strsize);
862         at[finalsize - 1] = '\0';
863
864         return (at);
865     }
866     return (NULL);
867 }