new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / os_xml / os_xml_variables.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 <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13
14 #include "os_xml.h"
15 #include "os_xml_internal.h"
16
17
18 int OS_ApplyVariables(OS_XML *_lxml)
19 {
20     unsigned int i, j = 0, s = 0;
21     int retval = 0;
22     char **var = NULL;
23     char **value = NULL;
24     char **tmp = NULL;
25     char *p2 = NULL;
26     char *var_placeh = NULL;
27
28     /* Get all variables */
29     for (i = 0; i < _lxml->cur; i++) {
30         if (_lxml->tp[i] == XML_VARIABLE_BEGIN) {
31             int _found_var = 0;
32
33             for (j = i + 1; j < _lxml->cur; j++) {
34                 if (_lxml->rl[j] < _lxml->rl[i]) {
35                     break;
36                 }
37
38                 else if (_lxml->tp[j] == XML_ATTR) {
39                     if ((_lxml->el[j]) && (strcasecmp(_lxml->el[j], XML_VAR_ATTRIBUTE) == 0)) {
40                         if (!_lxml->ct[j]) {
41                             snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Invalid variable content.");
42                             _lxml->err_line = _lxml->ln[j];
43                             goto fail;
44                         } else if (strlen(_lxml->ct[j]) >= XML_VARIABLE_MAXSIZE) {
45                             snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Invalid variable name size.");
46                             _lxml->err_line = _lxml->ln[j];
47                             goto fail;
48                         }
49
50                         /* If not used, it will be cleaned later */
51                         snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error.");
52
53                         tmp = (char **)realloc(var, (s + 1) * sizeof(char *));
54                         if (tmp == NULL) {
55                             goto fail;
56                         }
57                         var = tmp;
58
59                         var[s] = _lxml->ct[j];
60
61                         /* Clean the lxml->err */
62                         strncpy(_lxml->err, " ", 3);
63
64                         _found_var = 1;
65                         break;
66                     } else {
67                         snprintf(_lxml->err, XML_ERR_LENGTH,
68                                  "XMLERR: Only \""XML_VAR_ATTRIBUTE"\" is allowed"
69                                  " as an attribute for a variable.");
70                         _lxml->err_line = _lxml->ln[j];
71                         goto fail;
72                     }
73                 }
74             } /* Attribute FOR */
75
76
77             if ((_found_var == 0) || (!_lxml->ct[i])) {
78                 snprintf(_lxml->err, XML_ERR_LENGTH,
79                          "XMLERR: No value set for variable.");
80                 _lxml->err_line = _lxml->ln[i];
81                 goto fail;
82             }
83
84             snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error.");
85
86             tmp = (char **)realloc(value, (s + 1) * sizeof(char *));
87             if (tmp == NULL) {
88                 goto fail;
89             }
90             value = tmp;
91
92             value[s] = _lxml->ct[i];
93
94             strncpy(_lxml->err, " ", 3);
95             s++;
96         } else if (((_lxml->tp[i] == XML_ELEM) || (_lxml->tp[i] == XML_ATTR)) &&
97                    (_lxml->ct[i])) {
98             unsigned int tp = 0;
99             size_t init = 0;
100             char *p = NULL;
101             char lvar[XML_VARIABLE_MAXSIZE]; /* MAX Var size */
102
103
104             if (strlen(_lxml->ct[i]) <= 2) {
105                 continue;
106             }
107
108             /* Check if any variable is defined */
109             if (s == 0) {
110                 continue;
111             }
112
113             /* Duplicate string */
114             p = strdup(_lxml->ct[i]);
115             p2 = p;
116
117             if (p == NULL) {
118                 snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error.");
119                 goto fail;
120             }
121
122             /* Read the whole string */
123             while (*p != '\0') {
124                 if (*p == XML_VARIABLE_BEGIN) {
125                     tp = 0;
126                     p++;
127                     memset(lvar, '\0', XML_VARIABLE_MAXSIZE);
128
129                     while (1) {
130                         if ((*p == XML_VARIABLE_BEGIN)
131                                 || (*p == '\0')
132                                 || (*p == '.')
133                                 || (*p == '|')
134                                 || (*p == ',')
135                                 || (*p == ' ')) {
136                             lvar[tp] = '\0';
137
138                             /* Look for var */
139                             for (j = 0; j < s; j++) {
140                                 if (var[j] == NULL) {
141                                     break;
142                                 }
143
144                                 if (strcasecmp(var[j], lvar) != 0) {
145                                     continue;
146                                 }
147
148                                 size_t tsize = strlen(_lxml->ct[i]) +
149                                                strlen(value[j]) - tp + 1;
150                                 var_placeh = strdup(_lxml->ct[i]);
151                                 free(_lxml->ct[i]);
152                                 _lxml->ct[i] = (char *)calloc(tsize + 2,
153                                                               sizeof(char));
154
155                                 if (_lxml->ct[i] == NULL || var_placeh == NULL) {
156                                     snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory "
157                                              "error.");
158                                     goto fail;
159                                 }
160
161                                 strncpy(_lxml->ct[i], var_placeh, tsize);
162
163                                 _lxml->ct[i][init] = '\0';
164                                 strncat(_lxml->ct[i], value[j], tsize - init);
165
166                                 init = strlen(_lxml->ct[i]);
167                                 strncat(_lxml->ct[i], p,
168                                         tsize - strlen(_lxml->ct[i]));
169
170                                 free(var_placeh);
171                                 var_placeh = NULL;
172
173                                 break;
174                             }
175
176                             /* Variable not found */
177                             if ((j == s) && (strlen(lvar) >= 1)) {
178                                 snprintf(_lxml->err, XML_ERR_LENGTH,
179                                          "XMLERR: Unknown variable"
180                                          ": '%s'.", lvar);
181                                 _lxml->err_line = _lxml->ln[i];
182                                 goto fail;
183                             } else if (j == s) {
184                                 init++;
185                             }
186
187                             goto go_next;
188                         }
189
190                         /* Maximum size for a variable */
191                         if (tp >= XML_VARIABLE_MAXSIZE - 1) {
192                             snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Invalid "
193                                      "variable name size: '%u'.", tp);
194                             _lxml->err_line = _lxml->ln[i];
195                             goto fail;
196
197                         }
198
199                         lvar[tp] = *p;
200                         tp++;
201                         p++;
202                     }
203                 } /* IF XML_VAR_BEGIN */
204
205                 p++;
206                 init++;
207
208 go_next:
209                 continue;
210
211             } /* WHILE END */
212
213             if (p2 != NULL) {
214                 free(p2);
215                 p2 = NULL;
216                 p = NULL;
217             }
218         }
219     }
220
221     goto cleanup;
222
223 fail:
224     retval = -1;
225
226 cleanup:
227     /* Clean up the variables */
228     free(var);
229     free(value);
230     free(p2);
231     free(var_placeh);
232
233     return (retval);
234 }
235