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 "syscheck-config.h"
12 #include "config.h"
13
14
dump_syscheck_entry(syscheck_config * syscheck,const char * entry,int vals,int reg,const char * restrictfile)15 int dump_syscheck_entry(syscheck_config *syscheck, const char *entry, int vals, int reg, const char *restrictfile)
16 {
17 unsigned int pl = 0;
18
19 if (reg == 1) {
20 #ifdef WIN32
21 if (syscheck->registry == NULL) {
22 os_calloc(2, sizeof(char *), syscheck->registry);
23 syscheck->registry[pl + 1] = NULL;
24 os_strdup(entry, syscheck->registry[pl]);
25 } else {
26 while (syscheck->registry[pl] != NULL) {
27 pl++;
28 }
29 os_realloc(syscheck->registry, (pl + 2) * sizeof(char *),
30 syscheck->registry);
31 syscheck->registry[pl + 1] = NULL;
32 os_strdup(entry, syscheck->registry[pl]);
33 }
34 #endif
35 }
36
37 else {
38 if (syscheck->dir == NULL) {
39 os_calloc(2, sizeof(char *), syscheck->dir);
40 syscheck->dir[pl + 1] = NULL;
41 os_strdup(entry, syscheck->dir[pl]);
42
43 os_calloc(2, sizeof(int), syscheck->opts);
44 syscheck->opts[pl + 1] = 0;
45 syscheck->opts[pl] = vals;
46
47 os_calloc(2, sizeof(OSMatch *), syscheck->filerestrict);
48 syscheck->filerestrict[pl] = NULL;
49 syscheck->filerestrict[pl + 1] = NULL;
50 } else {
51 while (syscheck->dir[pl] != NULL) {
52 pl++;
53 }
54 os_realloc(syscheck->dir, (pl + 2) * sizeof(char *),
55 syscheck->dir);
56 syscheck->dir[pl + 1] = NULL;
57 os_strdup(entry, syscheck->dir[pl]);
58
59 os_realloc(syscheck->opts, (pl + 2) * sizeof(int),
60 syscheck->opts);
61 syscheck->opts[pl + 1] = 0;
62 syscheck->opts[pl] = vals;
63
64 os_realloc(syscheck->filerestrict, (pl + 2) * sizeof(OSMatch *),
65 syscheck->filerestrict);
66 syscheck->filerestrict[pl] = NULL;
67 syscheck->filerestrict[pl + 1] = NULL;
68 }
69 if (restrictfile) {
70 os_calloc(1, sizeof(OSMatch), syscheck->filerestrict[pl]);
71 if (!OSMatch_Compile(restrictfile, syscheck->filerestrict[pl], 0)) {
72 OSMatch *ptm;
73
74 ptm = syscheck->filerestrict[pl];
75
76 merror(REGEX_COMPILE, __local_name, restrictfile,
77 ptm->error);
78 free(syscheck->filerestrict[pl]);
79 syscheck->filerestrict[pl] = NULL;
80 }
81 }
82 }
83
84 return (1);
85 }
86
87 #ifdef WIN32
88 /* Read Windows registry configuration */
read_reg(syscheck_config * syscheck,char * entries)89 int read_reg(syscheck_config *syscheck, char *entries)
90 {
91 int i;
92 char **entry;
93 char *tmp_str;
94
95 /* Get each entry separately */
96 entry = OS_StrBreak(',', entries, MAX_DIR_SIZE); /* Max number */
97
98 if (entry == NULL) {
99 return (0);
100 }
101
102 while (*entry) {
103 char *tmp_entry;
104
105 tmp_entry = *entry;
106
107 /* Remove spaces at the beginning */
108 while (*tmp_entry == ' ') {
109 tmp_entry++;
110 }
111
112 /* Remove spaces at the end */
113 tmp_str = strchr(tmp_entry, ' ');
114 if (tmp_str) {
115 tmp_str++;
116
117 /* Check if it is really at the end */
118 if ((*tmp_str == '\0') || (*tmp_str == ' ')) {
119 tmp_str--;
120 *tmp_str = '\0';
121 }
122 }
123
124 /* Add entries - look for the last available */
125 i = 0;
126 while (syscheck->registry && syscheck->registry[i]) {
127 int str_len_i;
128 int str_len_dir;
129
130 str_len_dir = strlen(tmp_entry);
131 str_len_i = strlen(syscheck->registry[i]);
132
133 if (str_len_dir > str_len_i) {
134 str_len_dir = str_len_i;
135 }
136
137 /* Duplicated entry */
138 if (strcmp(syscheck->registry[i], tmp_entry) == 0) {
139 merror(SK_DUP, __local_name, tmp_entry);
140 return (1);
141 }
142 i++;
143 }
144
145 /* Add new entry */
146 dump_syscheck_entry(syscheck, tmp_entry, 0, 1, NULL);
147
148 /* Next entry */
149 entry++;
150 }
151
152 return (1);
153 }
154 #endif /* WIN32 */
155
156 /* Read directories attributes */
read_attr(syscheck_config * syscheck,const char * dirs,char ** g_attrs,char ** g_values)157 static int read_attr(syscheck_config *syscheck, const char *dirs, char **g_attrs, char **g_values)
158 {
159 const char *xml_check_all = "check_all";
160 const char *xml_check_sum = "check_sum";
161 const char *xml_check_sha1sum = "check_sha1sum";
162 const char *xml_check_md5sum = "check_md5sum";
163 const char *xml_check_size = "check_size";
164 const char *xml_check_owner = "check_owner";
165 const char *xml_check_group = "check_group";
166 const char *xml_check_perm = "check_perm";
167 const char *xml_real_time = "realtime";
168 const char *xml_report_changes = "report_changes";
169 const char *xml_restrict = "restrict";
170 const char *xml_no_recurse = "no_recurse";
171
172 char *restrictfile = NULL;
173 char **dir;
174 char *tmp_str;
175 dir = OS_StrBreak(',', dirs, MAX_DIR_SIZE); /* Max number */
176 char **dir_org = dir;
177
178 int ret = 0, i;
179
180 /* Dir can not be null */
181 if (dir == NULL) {
182 return (0);
183 }
184
185 while (*dir) {
186 int j = 0;
187 int opts = 0;
188 char *tmp_dir;
189
190 char **attrs = NULL;
191 char **values = NULL;
192
193 tmp_dir = *dir;
194 restrictfile = NULL;
195
196 /* Remove spaces at the beginning */
197 while (*tmp_dir == ' ') {
198 tmp_dir++;
199 }
200
201 /* Remove spaces at the end */
202 tmp_str = strchr(tmp_dir, ' ');
203 if (tmp_str) {
204 tmp_str++;
205
206 /* Check if it is really at the end */
207 if ((*tmp_str == '\0') || (*tmp_str == ' ')) {
208 tmp_str--;
209 *tmp_str = '\0';
210 }
211 }
212
213 /* Get the options */
214 if (!g_attrs || !g_values) {
215 merror(SYSCHECK_NO_OPT, __local_name, dirs);
216 ret = 0;
217 goto out_free;
218 }
219
220 attrs = g_attrs;
221 values = g_values;
222
223 while (*attrs && *values) {
224 /* Check all */
225 if (strcmp(*attrs, xml_check_all) == 0) {
226 if (strcmp(*values, "yes") == 0) {
227 opts |= CHECK_MD5SUM;
228 opts |= CHECK_SHA1SUM;
229 opts |= CHECK_PERM;
230 opts |= CHECK_SIZE;
231 opts |= CHECK_OWNER;
232 opts |= CHECK_GROUP;
233 } else if (strcmp(*values, "no") == 0) {
234 opts &= ~ ( CHECK_MD5SUM | CHECK_SHA1SUM | CHECK_PERM
235 | CHECK_SIZE | CHECK_OWNER | CHECK_GROUP );
236 } else {
237 merror(SK_INV_OPT, __local_name, *values, *attrs);
238 ret = 0;
239 goto out_free;
240 }
241 }
242 /* Check sum */
243 else if (strcmp(*attrs, xml_check_sum) == 0) {
244 if (strcmp(*values, "yes") == 0) {
245 opts |= CHECK_MD5SUM;
246 opts |= CHECK_SHA1SUM;
247 } else if (strcmp(*values, "no") == 0) {
248 opts &= ~ ( CHECK_MD5SUM | CHECK_SHA1SUM );
249 } else {
250 merror(SK_INV_OPT, __local_name, *values, *attrs);
251 ret = 0;
252 goto out_free;
253 }
254 }
255 /* Check md5sum */
256 else if (strcmp(*attrs, xml_check_md5sum) == 0) {
257 if (strcmp(*values, "yes") == 0) {
258 opts |= CHECK_MD5SUM;
259 } else if (strcmp(*values, "no") == 0) {
260 opts &= ~ CHECK_MD5SUM;
261 } else {
262 merror(SK_INV_OPT, __local_name, *values, *attrs);
263 ret = 0;
264 goto out_free;
265 }
266 }
267 /* Check sha1sum */
268 else if (strcmp(*attrs, xml_check_sha1sum) == 0) {
269 if (strcmp(*values, "yes") == 0) {
270 opts |= CHECK_SHA1SUM;
271 } else if (strcmp(*values, "no") == 0) {
272 opts &= ~ CHECK_SHA1SUM;
273 } else {
274 merror(SK_INV_OPT, __local_name, *values, *attrs);
275 ret = 0;
276 goto out_free;
277 }
278 }
279 /* Check permission */
280 else if (strcmp(*attrs, xml_check_perm) == 0) {
281 if (strcmp(*values, "yes") == 0) {
282 opts |= CHECK_PERM;
283 } else if (strcmp(*values, "no") == 0) {
284 opts &= ~ CHECK_PERM;
285 } else {
286 merror(SK_INV_OPT, __local_name, *values, *attrs);
287 ret = 0;
288 goto out_free;
289 }
290 }
291 /* Check size */
292 else if (strcmp(*attrs, xml_check_size) == 0) {
293 if (strcmp(*values, "yes") == 0) {
294 opts |= CHECK_SIZE;
295 } else if (strcmp(*values, "no") == 0) {
296 opts &= ~ CHECK_SIZE;
297 } else {
298 merror(SK_INV_OPT, __local_name, *values, *attrs);
299 ret = 0;
300 goto out_free;
301 }
302 }
303 /* Check owner */
304 else if (strcmp(*attrs, xml_check_owner) == 0) {
305 if (strcmp(*values, "yes") == 0) {
306 opts |= CHECK_OWNER;
307 } else if (strcmp(*values, "no") == 0) {
308 opts &= ~ CHECK_OWNER;
309 } else {
310 merror(SK_INV_OPT, __local_name, *values, *attrs);
311 ret = 0;
312 goto out_free;
313 }
314 }
315 /* Check group */
316 else if (strcmp(*attrs, xml_check_group) == 0) {
317 if (strcmp(*values, "yes") == 0) {
318 opts |= CHECK_GROUP;
319 } else if (strcmp(*values, "no") == 0) {
320 opts &= ~ CHECK_GROUP;
321 } else {
322 merror(SK_INV_OPT, __local_name, *values, *attrs);
323 ret = 0;
324 goto out_free;
325 }
326 } else if (strcmp(*attrs, xml_real_time) == 0) {
327 if (strcmp(*values, "yes") == 0) {
328 opts |= CHECK_REALTIME;
329 } else if (strcmp(*values, "no") == 0) {
330 opts &= ~ CHECK_REALTIME;
331 } else {
332 merror(SK_INV_OPT, __local_name, *values, *attrs);
333 ret = 0;
334 goto out_free;
335 }
336 } else if (strcmp(*attrs, xml_report_changes) == 0) {
337 if (strcmp(*values, "yes") == 0) {
338 opts |= CHECK_SEECHANGES;
339 } else if (strcmp(*values, "no") == 0) {
340 opts &= ~ CHECK_SEECHANGES;
341 } else {
342 merror(SK_INV_OPT, __local_name, *values, *attrs);
343 ret = 0;
344 goto out_free;
345 }
346 } else if (strcmp(*attrs, xml_restrict) == 0) {
347 if (restrictfile) {
348 free(restrictfile);
349 restrictfile = NULL;
350 }
351 os_strdup(*values, restrictfile);
352 } else if (strcmp(*attrs, xml_no_recurse) == 0) {
353 if(strcmp(*values, "yes") == 0) {
354 opts |= CHECK_NORECURSE;
355 } else {
356 merror(SK_INV_OPT, __local_name, *values, *attrs);
357 ret = 0;
358 goto out_free;
359 }
360 } else {
361 merror(SK_INV_ATTR, __local_name, *attrs);
362 ret = 0;
363 goto out_free;
364 }
365 attrs++;
366 values++;
367 }
368
369 /* You must have something set */
370 if (opts == 0) {
371 merror(SYSCHECK_NO_OPT, __local_name, dirs);
372 ret = 0;
373 goto out_free;
374 }
375
376 /* Add directory - look for the last available */
377 j = 0;
378 while (syscheck->dir && syscheck->dir[j]) {
379 /* Duplicate entry */
380 if (strcmp(syscheck->dir[j], tmp_dir) == 0) {
381 merror(SK_DUP, __local_name, tmp_dir);
382 ret = 1;
383 goto out_free;
384 }
385
386 j++;
387 }
388
389 /* Check for glob */
390 /* The mingw32 builder used by travis.ci can't find glob.h
391 * Yet glob must work on actual win32.
392 */
393 #ifndef __MINGW32__
394 if (strchr(tmp_dir, '*') ||
395 strchr(tmp_dir, '?') ||
396 strchr(tmp_dir, '[')) {
397 int gindex = 0;
398 glob_t g;
399
400 if (glob(tmp_dir, 0, NULL, &g) != 0) {
401 merror(GLOB_ERROR, __local_name, tmp_dir);
402 ret = 1;
403 goto out_free;
404 }
405
406 if (g.gl_pathv[0] == NULL) {
407 merror(GLOB_NFOUND, __local_name, tmp_dir);
408 ret = 1;
409 goto out_free;
410 }
411
412 while (g.gl_pathv[gindex]) {
413 dump_syscheck_entry(syscheck, g.gl_pathv[gindex], opts, 0, restrictfile);
414 gindex++;
415 }
416
417 globfree(&g);
418 }
419
420 else {
421 dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
422 }
423 #else
424 dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
425 #endif
426
427 if (restrictfile) {
428 free(restrictfile);
429 restrictfile = NULL;
430 }
431
432 /* Next entry */
433 dir++;
434 }
435
436 ret = 1;
437
438 out_free:
439
440 i = 0;
441 while (dir_org[i]) {
442 free(dir_org[i++]);
443 }
444
445 free(dir_org);
446 free(restrictfile);
447
448 return ret;
449 }
450
Read_Syscheck(XML_NODE node,void * configp,void * mailp)451 int Read_Syscheck(XML_NODE node, void *configp, __attribute__((unused)) void *mailp)
452 {
453 int i = 0;
454
455 /* XML Definitions */
456 const char *xml_directories = "directories";
457 const char *xml_registry = "windows_registry";
458 const char *xml_time = "frequency";
459 const char *xml_scanday = "scan_day";
460 const char *xml_scantime = "scan_time";
461 const char *xml_ignore = "ignore";
462 const char *xml_registry_ignore = "registry_ignore";
463 const char *xml_auto_ignore = "auto_ignore";
464 const char *xml_alert_new_files = "alert_new_files";
465 const char *xml_disabled = "disabled";
466 const char *xml_scan_on_start = "scan_on_start";
467 const char *xml_prefilter_cmd = "prefilter_cmd";
468 const char *xml_skip_nfs = "skip_nfs";
469 const char *xml_nodiff = "nodiff";
470
471 /* Configuration example
472 <directories check_all="yes">/etc,/usr/bin</directories>
473 <directories check_owner="yes" check_group="yes" check_perm="yes"
474 check_sum="yes">/var/log</directories>
475 */
476
477 syscheck_config *syscheck;
478 syscheck = (syscheck_config *)configp;
479 unsigned int nodiff_size = 0;
480
481 while (node[i]) {
482 if (!node[i]->element) {
483 merror(XML_ELEMNULL, __local_name);
484 return (OS_INVALID);
485 } else if (!node[i]->content) {
486 merror(XML_VALUENULL, __local_name, node[i]->element);
487 return (OS_INVALID);
488 }
489
490 /* Get directories */
491 else if (strcmp(node[i]->element, xml_directories) == 0) {
492 char dirs[OS_MAXSTR];
493
494 #ifdef WIN32
495 ExpandEnvironmentStrings(node[i]->content, dirs, sizeof(dirs) - 1);
496 #else
497 strncpy(dirs, node[i]->content, sizeof(dirs) - 1);
498 #endif
499
500 if (!read_attr(syscheck,
501 dirs,
502 node[i]->attributes,
503 node[i]->values)) {
504 return (OS_INVALID);
505 }
506 }
507 /* Get Windows registry */
508 else if (strcmp(node[i]->element, xml_registry) == 0) {
509 #ifdef WIN32
510 if (!read_reg(syscheck, node[i]->content)) {
511 return (OS_INVALID);
512 }
513 #endif
514 }
515 /* Get frequency */
516 else if (strcmp(node[i]->element, xml_time) == 0) {
517 if (!OS_StrIsNum(node[i]->content)) {
518 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
519 return (OS_INVALID);
520 }
521
522 syscheck->time = atoi(node[i]->content);
523 }
524 /* Get scan time */
525 else if (strcmp(node[i]->element, xml_scantime) == 0) {
526 syscheck->scan_time = OS_IsValidUniqueTime(node[i]->content);
527 if (!syscheck->scan_time) {
528 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
529 return (OS_INVALID);
530 }
531 }
532
533 /* Get scan day */
534 else if (strcmp(node[i]->element, xml_scanday) == 0) {
535 syscheck->scan_day = OS_IsValidDay(node[i]->content);
536 if (!syscheck->scan_day) {
537 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
538 return (OS_INVALID);
539 }
540 }
541
542 /* Get if xml_scan_on_start */
543 else if (strcmp(node[i]->element, xml_scan_on_start) == 0) {
544 if (strcmp(node[i]->content, "yes") == 0) {
545 syscheck->scan_on_start = 1;
546 } else if (strcmp(node[i]->content, "no") == 0) {
547 syscheck->scan_on_start = 0;
548 } else {
549 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
550 return (OS_INVALID);
551 }
552 }
553
554 /* Get if disabled */
555 else if (strcmp(node[i]->element, xml_disabled) == 0) {
556 if (strcmp(node[i]->content, "yes") == 0) {
557 syscheck->disabled = 1;
558 } else if (strcmp(node[i]->content, "no") == 0) {
559 syscheck->disabled = 0;
560 } else {
561 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
562 return (OS_INVALID);
563 }
564 }
565
566 /* Getting if skip_nfs. */
567 else if (strcmp(node[i]->element,xml_skip_nfs) == 0)
568 {
569 if(strcmp(node[i]->content, "yes") == 0)
570 syscheck->skip_nfs = 1;
571 else if(strcmp(node[i]->content, "no") == 0)
572 syscheck->skip_nfs = 0;
573 else
574 {
575 merror(XML_VALUEERR,__local_name,node[i]->element,node[i]->content);
576 return(OS_INVALID);
577 }
578 }
579
580 /* Getting file/dir ignore */
581 else if (strcmp(node[i]->element,xml_ignore) == 0)
582 {
583 unsigned int ign_size = 0;
584
585 #ifdef WIN32
586 /* For Windows, we attempt to expand environment variables */
587 char *new_ig = NULL;
588 os_calloc(2048, sizeof(char), new_ig);
589
590 ExpandEnvironmentStrings(node[i]->content, new_ig, 2047);
591
592 free(node[i]->content);
593 node[i]->content = new_ig;
594 #endif
595 /* Add if regex */
596 if (node[i]->attributes && node[i]->values) {
597 if (node[i]->attributes[0] && node[i]->values[0] &&
598 (strcmp(node[i]->attributes[0], "type") == 0) &&
599 (strcmp(node[i]->values[0], "sregex") == 0)) {
600 OSMatch *mt_pt;
601
602 if (!syscheck->ignore_regex) {
603 os_calloc(2, sizeof(OSMatch *), syscheck->ignore_regex);
604 syscheck->ignore_regex[0] = NULL;
605 syscheck->ignore_regex[1] = NULL;
606 } else {
607 while (syscheck->ignore_regex[ign_size] != NULL) {
608 ign_size++;
609 }
610
611 os_realloc(syscheck->ignore_regex,
612 sizeof(OSMatch *) * (ign_size + 2),
613 syscheck->ignore_regex);
614 syscheck->ignore_regex[ign_size + 1] = NULL;
615 }
616 os_calloc(1, sizeof(OSMatch),
617 syscheck->ignore_regex[ign_size]);
618
619 if (!OSMatch_Compile(node[i]->content,
620 syscheck->ignore_regex[ign_size], 0)) {
621 mt_pt = (OSMatch *)syscheck->ignore_regex[ign_size];
622 merror(REGEX_COMPILE, __local_name, node[i]->content,
623 mt_pt->error);
624 return (0);
625 }
626 } else {
627 merror(SK_INV_ATTR, __local_name, node[i]->attributes[0]);
628 return (OS_INVALID);
629 }
630 }
631
632 /* Add if simple entry -- check for duplicates */
633 else if (!os_IsStrOnArray(node[i]->content, syscheck->ignore)) {
634 if (!syscheck->ignore) {
635 os_calloc(2, sizeof(char *), syscheck->ignore);
636 syscheck->ignore[0] = NULL;
637 syscheck->ignore[1] = NULL;
638 } else {
639 while (syscheck->ignore[ign_size] != NULL) {
640 ign_size++;
641 }
642
643 os_realloc(syscheck->ignore,
644 sizeof(char *) * (ign_size + 2),
645 syscheck->ignore);
646 syscheck->ignore[ign_size + 1] = NULL;
647 }
648 os_strdup(node[i]->content, syscheck->ignore[ign_size]);
649 }
650 }
651
652 /* Get registry ignore list */
653 else if (strcmp(node[i]->element, xml_registry_ignore) == 0) {
654 #ifdef WIN32
655 int ign_size = 0;
656
657 /* Add if regex */
658 if (node[i]->attributes && node[i]->values) {
659 if (node[i]->attributes[0] && node[i]->values[0] &&
660 (strcmp(node[i]->attributes[0], "type") == 0) &&
661 (strcmp(node[i]->values[0], "sregex") == 0)) {
662 OSMatch *mt_pt;
663
664 if (!syscheck->registry_ignore_regex) {
665 os_calloc(2, sizeof(OSMatch *),
666 syscheck->registry_ignore_regex);
667 syscheck->registry_ignore_regex[0] = NULL;
668 syscheck->registry_ignore_regex[1] = NULL;
669 } else {
670 while (syscheck->registry_ignore_regex[ign_size] != NULL) {
671 ign_size++;
672 }
673
674 os_realloc(syscheck->registry_ignore_regex,
675 sizeof(OSMatch *) * (ign_size + 2),
676 syscheck->registry_ignore_regex);
677 syscheck->registry_ignore_regex[ign_size + 1] = NULL;
678 }
679
680 os_calloc(1, sizeof(OSMatch),
681 syscheck->registry_ignore_regex[ign_size]);
682
683 if (!OSMatch_Compile(node[i]->content,
684 syscheck->registry_ignore_regex[ign_size], 0)) {
685 mt_pt = (OSMatch *)
686 syscheck->registry_ignore_regex[ign_size];
687 merror(REGEX_COMPILE, __local_name, node[i]->content,
688 mt_pt->error);
689 return (0);
690 }
691 } else {
692 merror(SK_INV_ATTR, __local_name, node[i]->attributes[0]);
693 return (OS_INVALID);
694 }
695 }
696 /* We do not add duplicated entries */
697 else if (!os_IsStrOnArray(node[i]->content,
698 syscheck->registry_ignore)) {
699 if (!syscheck->registry_ignore) {
700 os_calloc(2, sizeof(char *), syscheck->registry_ignore);
701 syscheck->registry_ignore[0] = NULL;
702 syscheck->registry_ignore[1] = NULL;
703 } else {
704 while (syscheck->registry_ignore[ign_size] != NULL) {
705 ign_size++;
706 }
707
708 os_realloc(syscheck->registry_ignore,
709 sizeof(char *) * (ign_size + 2),
710 syscheck->registry_ignore);
711 syscheck->registry_ignore[ign_size + 1] = NULL;
712 }
713 os_strdup(node[i]->content, syscheck->registry_ignore[ign_size]);
714 }
715 #endif
716 /* Getting file/dir nodiff */
717 } else if (strcmp(node[i]->element,xml_nodiff) == 0) {
718 #ifdef WIN32
719 /* For Windows, we attempt to expand environment variables */
720 char *new_nodiff = NULL;
721 os_calloc(2048, sizeof(char), new_nodiff);
722
723 ExpandEnvironmentStrings(node[i]->content, new_nodiff, 2047);
724
725 free(node[i]->content);
726 node[i]->content = new_nodiff;
727 #endif
728 /* Add if regex */
729 if (node[i]->attributes && node[i]->values) {
730 if (node[i]->attributes[0] && node[i]->values[0] &&
731 (strcmp(node[i]->attributes[0], "type") == 0) &&
732 (strcmp(node[i]->values[0], "sregex") == 0)) {
733 OSMatch *mt_pt;
734 if (!syscheck->nodiff_regex) {
735 os_calloc(2, sizeof(OSMatch *), syscheck->nodiff_regex);
736 syscheck->nodiff_regex[0] = NULL;
737 syscheck->nodiff_regex[1] = NULL;
738 } else {
739 while (syscheck->nodiff_regex[nodiff_size] != NULL) {
740 nodiff_size++;
741 }
742
743 os_realloc(syscheck->nodiff_regex,
744 sizeof(OSMatch *) * (nodiff_size + 2),
745 syscheck->nodiff_regex);
746 syscheck->nodiff_regex[nodiff_size + 1] = NULL;
747 }
748 os_calloc(1, sizeof(OSMatch),
749 syscheck->nodiff_regex[nodiff_size]);
750 debug1("Found nodiff regex node %s", node[i]->content);
751 if (!OSMatch_Compile(node[i]->content,
752 syscheck->nodiff_regex[nodiff_size], 0)) {
753 mt_pt = (OSMatch *)syscheck->nodiff_regex[nodiff_size];
754 merror(REGEX_COMPILE, __local_name, node[i]->content,
755 mt_pt->error);
756 return (0);
757 }
758 debug1("Found nodiff regex node %s OK?", node[i]->content);
759 debug1("Found nodiff regex size %d", nodiff_size);
760 } else {
761 merror(SK_INV_ATTR, __local_name, node[i]->attributes[0]);
762 return (OS_INVALID);
763 }
764 }
765
766 /* Add if simple entry -- check for duplicates */
767 else if (!os_IsStrOnArray(node[i]->content, syscheck->nodiff)) {
768 if (!syscheck->nodiff) {
769 os_calloc(2, sizeof(char *), syscheck->nodiff);
770 syscheck->nodiff[0] = NULL;
771 syscheck->nodiff[1] = NULL;
772 } else {
773 while (syscheck->nodiff[nodiff_size] != NULL) {
774 nodiff_size++;
775 }
776
777 os_realloc(syscheck->nodiff,
778 sizeof(char *) * (nodiff_size + 2),
779 syscheck->nodiff);
780 syscheck->nodiff[nodiff_size + 1] = NULL;
781 }
782 os_strdup(node[i]->content, syscheck->nodiff[nodiff_size]);
783 }
784 } else if (strcmp(node[i]->element, xml_auto_ignore) == 0) {
785 /* auto_ignore is not read here */
786 } else if (strcmp(node[i]->element, xml_alert_new_files) == 0) {
787 /* alert_new_files option is not read here */
788 } else if (strcmp(node[i]->element, xml_prefilter_cmd) == 0) {
789 char cmd[OS_MAXSTR];
790 struct stat statbuf;
791
792 #ifdef WIN32
793 ExpandEnvironmentStrings(node[i]->content, cmd, sizeof(cmd) - 1);
794 #else
795 strncpy(cmd, node[i]->content, sizeof(cmd) - 1);
796 #endif
797
798 if (strlen(cmd) > 0) {
799 char statcmd[OS_MAXSTR];
800 char *ix;
801 strncpy(statcmd, cmd, sizeof(statcmd) - 1);
802 if (NULL != (ix = strchr(statcmd, ' '))) {
803 *ix = '\0';
804 }
805 if (stat(statcmd, &statbuf) == 0) {
806 /* More checks needed (perms, owner, etc.) */
807 os_calloc(1, strlen(cmd) + 1, syscheck->prefilter_cmd);
808 strncpy(syscheck->prefilter_cmd, cmd, strlen(cmd));
809 } else {
810 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
811 return (OS_INVALID);
812 }
813 }
814 } else {
815 merror(XML_INVELEM, __local_name, node[i]->element);
816 return (OS_INVALID);
817 }
818 i++;
819 }
820
821 return (0);
822 }
823
824
825 /* return a text version of the directory check option bits,
826 * in a provided string buffer
827 */
syscheck_opts2str(char * buf,int buflen,int opts)828 char *syscheck_opts2str(char *buf, int buflen, int opts) {
829 int left = buflen;
830 int i;
831 int check_bits[] = {
832 CHECK_PERM,
833 CHECK_SIZE,
834 CHECK_OWNER,
835 CHECK_GROUP,
836 CHECK_MD5SUM,
837 CHECK_SHA1SUM,
838 CHECK_REALTIME,
839 CHECK_SEECHANGES,
840 CHECK_NORECURSE,
841 0
842 };
843 char *check_strings[] = {
844 "perm",
845 "size",
846 "owner",
847 "group",
848 "md5sum",
849 "sha1sum",
850 "realtime",
851 "report_changes",
852 "no_recurse",
853 NULL
854 };
855
856 buf[0] = '\0';
857 for ( i = 0; check_bits[ i ]; i++ ) {
858 if ( opts & check_bits[ i ] ) {
859 if ( left < buflen ) {
860 strncat( buf, " | ", left );
861 left -= 3;
862 }
863 strncat( buf, check_strings[ i ], left );
864 left = buflen - strlen( buf );
865 }
866 }
867
868 return buf;
869 }
870
871