new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / config / global-config.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right 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_net/os_net.h"
12 #include "global-config.h"
13 #include "mail-config.h"
14 #include "config.h"
15
16
17 int Read_GlobalSK(XML_NODE node, void *configp, __attribute__((unused)) void *mailp)
18 {
19     int i = 0;
20     unsigned int ign_size = 1;
21     const char *xml_ignore = "ignore";
22     const char *xml_auto_ignore = "auto_ignore";
23     const char *xml_alert_new_files = "alert_new_files";
24
25     _Config *Config;
26     Config = (_Config *)configp;
27
28     if (!Config) {
29         return (0);
30     }
31
32     /* Get right allow_size */
33     if (Config && Config->syscheck_ignore) {
34         char **ww;
35         ww = Config->syscheck_ignore;
36
37         while (*ww != NULL) {
38             ign_size++;
39             ww++;
40         }
41     }
42
43     while (node[i]) {
44         if (!node[i]->element) {
45             merror(XML_ELEMNULL, __local_name);
46             return (OS_INVALID);
47         } else if (!node[i]->content) {
48             merror(XML_VALUENULL, __local_name, node[i]->element);
49             return (OS_INVALID);
50         } else if (strcmp(node[i]->element, xml_auto_ignore) == 0) {
51             if (strcmp(node[i]->content, "yes") == 0) {
52                 Config->syscheck_auto_ignore = 1;
53             } else if (strcmp(node[i]->content, "no") == 0) {
54                 Config->syscheck_auto_ignore = 0;
55             } else {
56                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
57                 return (OS_INVALID);
58             }
59         } else if (strcmp(node[i]->element, xml_alert_new_files) == 0) {
60             if (strcmp(node[i]->content, "yes") == 0) {
61                 Config->syscheck_alert_new = 1;
62             } else if (strcmp(node[i]->content, "no") == 0) {
63                 Config->syscheck_alert_new = 0;
64             } else {
65                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
66                 return (OS_INVALID);
67             }
68         } else if (strcmp(node[i]->element, xml_ignore) == 0) {
69             ign_size++;
70             Config->syscheck_ignore = (char **)
71                                       realloc(Config->syscheck_ignore, sizeof(char *)*ign_size);
72             if (!Config->syscheck_ignore) {
73                 merror(MEM_ERROR, __local_name, errno, strerror(errno));
74                 return (OS_INVALID);
75             }
76
77             os_strdup(node[i]->content, Config->syscheck_ignore[ign_size - 2]);
78             Config->syscheck_ignore[ign_size - 1] = NULL;
79         }
80         i++;
81     }
82
83     return (0);
84 }
85
86 int Read_Global(XML_NODE node, void *configp, void *mailp)
87 {
88     int i = 0;
89
90     /* allowlist size */
91     unsigned int allow_size = 1;
92     unsigned int hostname_allow_size = 1;
93     unsigned int mailto_size = 1;
94
95     /* XML definitions */
96     const char *xml_mailnotify = "email_notification";
97     const char *xml_logall = "logall";
98     const char *xml_logall_json = "logall_json";
99     const char *xml_integrity = "integrity_checking";
100     const char *xml_rootcheckd = "rootkit_detection";
101     const char *xml_hostinfo = "host_information";
102     const char *xml_prelude = "prelude_output";
103     const char *xml_prelude_profile = "prelude_profile";
104     const char *xml_prelude_log_level = "prelude_log_level";
105     const char *xml_geoipdb_file = "geoipdb";
106     const char *xml_zeromq_output = "zeromq_output";
107     const char *xml_zeromq_output_uri = "zeromq_uri";
108     const char *xml_zeromq_output_server_cert = "zeromq_server_cert";
109     const char *xml_zeromq_output_client_cert = "zeromq_client_cert";
110     const char *xml_jsonout_output = "jsonout_output";
111     const char *xml_stats = "stats";
112     const char *xml_memorysize = "memory_size";
113     const char *xml_white_list = "white_list";
114     const char *xml_allow_list = "allow_list";
115     const char *xml_compress_alerts = "compress_alerts";
116     const char *xml_custom_alert_output = "custom_alert_output";
117
118     const char *xml_emailto = "email_to";
119     const char *xml_emailfrom = "email_from";
120     const char *xml_emailreplyto = "email_reply_to";
121     const char *xml_emailidsname = "email_idsname";
122     const char *xml_smtpserver = "smtp_server";
123     const char *xml_heloserver = "helo_server";
124     const char *xml_mailmaxperhour = "email_maxperhour";
125
126 #ifdef LIBGEOIP_ENABLED
127     const char *xml_geoip_db_path = "geoip_db_path";
128     const char *xml_geoip6_db_path = "geoip6_db_path";
129 #endif
130
131 #ifdef SQLITE_ENABLED
132     /* MD5 DB */
133     char *xml_md5_whitelist = "md5_whitelist";
134     char *xml_md5_allowlist = "md5_allowlist";
135 #endif
136
137     _Config *Config;
138     MailConfig *Mail;
139
140     Config = (_Config *)configp;
141     Mail = (MailConfig *)mailp;
142
143     /* Get right allow_size */
144     if (Config && Config->allow_list) {
145         os_ip **ww;
146         ww = Config->allow_list;
147
148         while (*ww != NULL) {
149             allow_size++;
150             ww++;
151         }
152     }
153
154     /* Get right allow_size */
155     if (Config && Config->hostname_allow_list) {
156         char **ww;
157         ww = Config->hostname_allow_list;
158
159         while (*ww != NULL) {
160             hostname_allow_size++;
161             ww++;
162         }
163     }
164
165     /* Get mail_to size */
166     if (Mail && Mail->to) {
167         char **ww;
168         ww = Mail->to;
169         while (*ww != NULL) {
170             mailto_size++;
171             ww++;
172         }
173     }
174
175     while (node[i]) {
176         if (!node[i]->element) {
177             merror(XML_ELEMNULL, __local_name);
178             return (OS_INVALID);
179         } else if (!node[i]->content) {
180             merror(XML_VALUENULL, __local_name, node[i]->element);
181             return (OS_INVALID);
182         } else if (strcmp(node[i]->element, xml_custom_alert_output) == 0) {
183             if (Config) {
184                 Config->custom_alert_output = 1;
185                 os_strdup(node[i]->content, Config->custom_alert_output_format);
186             }
187         }
188         /* Mail notification */
189         else if (strcmp(node[i]->element, xml_mailnotify) == 0) {
190             if (strcmp(node[i]->content, "yes") == 0) {
191                 if (Config) {
192                     Config->mailnotify = 1;
193                 }
194                 if (Mail) {
195                     Mail->mn = 1;
196                 }
197             } else if (strcmp(node[i]->content, "no") == 0) {
198                 if (Config) {
199                     Config->mailnotify = 0;
200                 }
201                 if (Mail) {
202                     Mail->mn = 0;
203                 }
204             } else {
205                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
206                 return (OS_INVALID);
207             }
208         }
209         /* Prelude support */
210         else if (strcmp(node[i]->element, xml_prelude) == 0) {
211             if (strcmp(node[i]->content, "yes") == 0) {
212                 if (Config) {
213                     Config->prelude = 1;
214                 }
215             } else if (strcmp(node[i]->content, "no") == 0) {
216                 if (Config) {
217                     Config->prelude = 0;
218                 }
219             } else {
220                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
221                 return (OS_INVALID);
222             }
223         /* GeoIP */
224         } else if(strcmp(node[i]->element, xml_geoipdb_file) == 0) {
225             if(Config)
226             {
227                 Config->geoipdb_file = strdup(node[i]->content);
228             }
229         } else if (strcmp(node[i]->element, xml_prelude_profile) == 0) {
230             if (Config) {
231                 Config->prelude_profile = strdup(node[i]->content);
232             }
233         } else if (strcmp(node[i]->element, xml_prelude_log_level) == 0) {
234             if (!OS_StrIsNum(node[i]->content)) {
235                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
236                 return (OS_INVALID);
237             }
238
239             if (Config) {
240                 Config->prelude_log_level = (u_int8_t) atoi(node[i]->content);
241             }
242         }
243         /* ZeroMQ output */
244         else if (strcmp(node[i]->element, xml_zeromq_output) == 0) {
245             if (strcmp(node[i]->content, "yes") == 0) {
246                 if (Config) {
247                     Config->zeromq_output = 1;
248                 }
249             } else if (strcmp(node[i]->content, "no") == 0) {
250                 if (Config) {
251                     Config->zeromq_output = 0;
252                 }
253             } else {
254                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
255                 return (OS_INVALID);
256             }
257         } else if (strcmp(node[i]->element, xml_zeromq_output_uri) == 0) {
258             if (Config) {
259                 Config->zeromq_output_uri = strdup(node[i]->content);
260             }
261         } else if (strcmp(node[i]->element, xml_zeromq_output_server_cert) == 0) {
262             if (Config) {
263                 Config->zeromq_output_server_cert = strdup(node[i]->content);
264             }
265         } else if (strcmp(node[i]->element, xml_zeromq_output_client_cert) == 0) {
266             if (Config) {
267                 Config->zeromq_output_client_cert = strdup(node[i]->content);
268             }
269         }
270         /* jsonout output */
271         else if (strcmp(node[i]->element, xml_jsonout_output) == 0) {
272             if (strcmp(node[i]->content, "yes") == 0) {
273                 if (Config) {
274                     Config->jsonout_output = 1;
275                 }
276             } else if (strcmp(node[i]->content, "no") == 0) {
277                 if (Config) {
278                     Config->jsonout_output = 0;
279                 }
280             } else {
281                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
282                 return (OS_INVALID);
283             }
284         }
285         /* Log all */
286         else if (strcmp(node[i]->element, xml_logall) == 0) {
287             if (strcmp(node[i]->content, "yes") == 0) {
288                 if (Config) {
289                     Config->logall = 1;
290                 }
291             } else if (strcmp(node[i]->content, "no") == 0) {
292                 if (Config) {
293                     Config->logall = 0;
294                 }
295             } else {
296                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
297                 return (OS_INVALID);
298             }
299         }
300         /* Log all JSON*/
301         else if (strcmp(node[i]->element, xml_logall_json) == 0) {
302             if (strcmp(node[i]->content, "yes") == 0) {
303                 if (Config) {
304                     Config->logall_json = 1;
305                 }
306             } else if (strcmp(node[i]->content, "no") == 0) {
307                 if (Config) {
308                     Config->logall_json = 0;
309                 }
310             } else {
311                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
312                 return (OS_INVALID);
313             }
314         }           
315         /* Compress alerts */
316         else if (strcmp(node[i]->element, xml_compress_alerts) == 0) {
317             /* removed from here -- compatibility issues only */
318         }
319         /* Integrity */
320         else if (strcmp(node[i]->element, xml_integrity) == 0) {
321             if (!OS_StrIsNum(node[i]->content)) {
322                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
323                 return (OS_INVALID);
324             }
325             if (Config) {
326                 Config->integrity = (u_int8_t) atoi(node[i]->content);
327             }
328         }
329         /* rootcheck */
330         else if (strcmp(node[i]->element, xml_rootcheckd) == 0) {
331             if (!OS_StrIsNum(node[i]->content)) {
332                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
333                 return (OS_INVALID);
334             }
335             if (Config) {
336                 Config->rootcheck = (u_int8_t) atoi(node[i]->content);
337             }
338         }
339         /* hostinfo */
340         else if (strcmp(node[i]->element, xml_hostinfo) == 0) {
341             if (!OS_StrIsNum(node[i]->content)) {
342                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
343                 return (OS_INVALID);
344             }
345             if (Config) {
346                 Config->hostinfo = (u_int8_t) atoi(node[i]->content);
347             }
348         }
349         /* stats */
350         else if (strcmp(node[i]->element, xml_stats) == 0) {
351             if (!OS_StrIsNum(node[i]->content)) {
352                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
353                 return (OS_INVALID);
354             }
355             if (Config) {
356                 Config->stats = (u_int8_t) atoi(node[i]->content);
357             }
358         } else if (strcmp(node[i]->element, xml_memorysize) == 0) {
359             if (!OS_StrIsNum(node[i]->content)) {
360                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
361                 return (OS_INVALID);
362             }
363             if (Config) {
364                 Config->memorysize = atoi(node[i]->content);
365             }
366         }
367         /* allowlist */
368         else if ((strcmp(node[i]->element, xml_white_list) == 0) || (strcmp(node[i]->element, xml_allow_list) == 0)) {
369             /* Windows do not need it */
370 #ifndef WIN32
371
372             const char *ip_address_regex =
373                 "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}/?"
374                 "([0-9]{0,2}|[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})$";
375
376             if (Config && OS_PRegex(node[i]->content, ip_address_regex)) {
377                 allow_size++;
378                 Config->allow_list = (os_ip **)
379                                      realloc(Config->allow_list, sizeof(os_ip *)*allow_size);
380                 if (!Config->allow_list) {
381                     merror(MEM_ERROR, __local_name, errno, strerror(errno));
382                     return (OS_INVALID);
383                 }
384
385                 os_calloc(1, sizeof(os_ip), Config->allow_list[allow_size - 2]);
386                 Config->allow_list[allow_size - 1] = NULL;
387
388                 if (!OS_IsValidIP(node[i]->content,
389                                   Config->allow_list[allow_size - 2])) {
390                     merror(INVALID_IP, __local_name,
391                            node[i]->content);
392                     return (OS_INVALID);
393                 }
394             }
395             /* Add hostname */
396             else if (Config) {
397                 hostname_allow_size++;
398                 Config->hostname_allow_list = (char **)
399                                               realloc(Config->hostname_allow_list,
400                                                       sizeof(char *)*hostname_allow_size);
401
402                 if (!Config->hostname_allow_list) {
403                     merror(MEM_ERROR, __local_name, errno, strerror(errno));
404                     return (OS_INVALID);
405                 }
406                 os_strdup(node[i]->content, Config->hostname_allow_list[hostname_allow_size - 2]);
407                 Config->hostname_allow_list[hostname_allow_size - 1] = NULL;
408             }
409 #endif
410
411         }
412
413         /* For the email now
414          * email_to, email_from, email_replyto, idsname, smtp_Server and maxperhour.
415          * We will use a separate structure for that.
416          */
417         else if (strcmp(node[i]->element, xml_emailto) == 0) {
418 #ifndef WIN32
419             if (!OS_PRegex(node[i]->content, "[a-zA-Z0-9\\._-]+@[a-zA-Z0-9\\._-]")) {
420                 merror("%s: ERROR: Invalid Email address: %s.", __local_name, node[i]->content);
421                 return (OS_INVALID);
422             }
423 #endif
424             if (Mail) {
425                 mailto_size++;
426                 Mail->to = (char **) realloc(Mail->to, sizeof(char *)*mailto_size);
427                 if (!Mail->to) {
428                     merror(MEM_ERROR, __local_name, errno, strerror(errno));
429                     return (OS_INVALID);
430                 }
431
432                 os_strdup(node[i]->content, Mail->to[mailto_size - 2]);
433                 Mail->to[mailto_size - 1] = NULL;
434             }
435         } else if (strcmp(node[i]->element, xml_emailfrom) == 0) {
436             if (Mail) {
437                 if (Mail->from) {
438                     free(Mail->from);
439                 }
440                 os_strdup(node[i]->content, Mail->from);
441             }
442         } else if (strcmp(node[i]->element, xml_emailreplyto) == 0) {
443             if (Mail) {
444                 if (Mail->reply_to) {
445                     free(Mail->reply_to);
446                 }
447                 os_strdup(node[i]->content, Mail->reply_to);
448             }
449         } else if (strcmp(node[i]->element, xml_emailidsname) == 0) {
450             if (Mail) {
451                 if (Mail->idsname) {
452                     free(Mail->idsname);
453                 }
454                 os_strdup(node[i]->content, Mail->idsname);
455             }
456         } else if (strcmp(node[i]->element, xml_smtpserver) == 0) {
457 #ifndef WIN32
458             if (Mail && (Mail->mn)) {
459                 if (node[i]->content[0] == '/') {
460                     os_strdup(node[i]->content, Mail->smtpserver);
461                 } else {
462                     Mail->smtpserver = OS_GetHost(node[i]->content, 5);
463                     if (!Mail->smtpserver) {
464                         merror(INVALID_SMTP, __local_name, node[i]->content);
465                         return (OS_INVALID);
466                     }
467                 }
468                 free(Mail->smtpserver);
469                 os_strdup(node[i]->content, Mail->smtpserver);
470             }
471 #endif
472         } else if (strcmp(node[i]->element, xml_heloserver) == 0) {
473             if (Mail && (Mail->mn)) {
474                 os_strdup(node[i]->content, Mail->heloserver);
475             }
476         } else if (strcmp(node[i]->element, xml_mailmaxperhour) == 0) {
477             if (Mail) {
478                 if (!OS_StrIsNum(node[i]->content)) {
479                     merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
480                     return (OS_INVALID);
481                 }
482                 Mail->maxperhour = atoi(node[i]->content);
483
484                 if ((Mail->maxperhour <= 0) || (Mail->maxperhour > 9999)) {
485                     merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
486                     return (OS_INVALID);
487                 }
488             }
489         }
490 #ifdef LIBGEOIP_ENABLED
491         /* GeoIP v4 DB location */
492         else if (strcmp(node[i]->element, xml_geoip_db_path) == 0) {
493             if (Config) {
494                 os_strdup(node[i]->content, Config->geoip_db_path);
495             }
496         }
497         /* GeoIP v6 DB location */
498         else if (strcmp(node[i]->element, xml_geoip6_db_path) == 0) {
499             if (Config) {
500                 os_strdup(node[i]->content, Config->geoip6_db_path);
501             }
502         }
503 #endif
504
505 #ifdef SQLITE_ENABLED
506         /* MD5 DB */
507         else if((strcmp(node[i]->element, xml_md5_allowlist) == 0) || (strcmp(node[i]->element, xml_md5_whitelist) == 0)) {
508             if(Config) {
509                 os_strdup(node[i]->content, Config->md5_allowlist);
510             }
511         }
512 #endif
513
514         else {
515             merror(XML_INVELEM, __local_name, node[i]->element);
516             return (OS_INVALID);
517         }
518         i++;
519     }
520
521     return (0);
522 }
523