1 /* @(#) $Id: syscheck-config.c,v 1.25 2009/11/04 15:18:59 dcid Exp $ */
3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 3) as published by the FSF - Free Software
15 #include "syscheck-config.h"
19 int dump_syscheck_entry(config *syscheck, char *entry, int vals, int reg)
26 if(syscheck->registry == NULL)
28 os_calloc(2, sizeof(char *), syscheck->registry);
29 syscheck->registry[pl + 1] = NULL;
30 os_strdup(entry, syscheck->registry[pl]);
34 while(syscheck->registry[pl] != NULL)
38 os_realloc(syscheck->registry, (pl +2) * sizeof(char *),
40 syscheck->registry[pl + 1] = NULL;
41 os_strdup(entry, syscheck->registry[pl]);
50 if(syscheck->dir == NULL)
52 os_calloc(2, sizeof(char *), syscheck->dir);
53 syscheck->dir[pl + 1] = NULL;
54 os_strdup(entry, syscheck->dir[pl]);
56 os_calloc(2, sizeof(int), syscheck->opts);
57 syscheck->opts[pl + 1] = 0;
58 syscheck->opts[pl] = vals;
62 while(syscheck->dir[pl] != NULL)
66 os_realloc(syscheck->dir, (pl +2) * sizeof(char *),
68 syscheck->dir[pl + 1] = NULL;
69 os_strdup(entry, syscheck->dir[pl]);
71 os_realloc(syscheck->opts, (pl +2) * sizeof(int),
73 syscheck->opts[pl + 1] = 0;
74 syscheck->opts[pl] = vals;
83 /* Read Windows registry configuration */
85 int read_reg(config *syscheck, char *entries)
92 /* Getting each entry separately */
93 entry = OS_StrBreak(',', entries, MAX_DIR_SIZE); /* Max number */
96 /* entry can not be null */
103 /* Doing it for each Entry */
110 /* Removing spaces at the beginning */
111 while(*tmp_entry == ' ')
116 /* Removing spaces at the end */
117 tmp_str = strchr(tmp_entry, ' ');
122 /* Checking if it is really at the end */
123 if((*tmp_str == '\0') || (*tmp_str == ' '))
131 /* Adding entries - looking for the last available */
133 while(syscheck->registry && syscheck->registry[i])
138 str_len_dir = strlen(tmp_entry);
139 str_len_i = strlen(syscheck->registry[i]);
141 if(str_len_dir > str_len_i)
143 str_len_dir = str_len_i;
146 /* Duplicated entry */
147 if(strcmp(syscheck->registry[i], tmp_entry) == 0)
149 merror(SK_DUP, ARGV0, tmp_entry);
155 /* Adding new entry */
156 dump_syscheck_entry(syscheck, tmp_entry, 0, 1);
165 #endif /* For read_reg */
170 /* Read directories attributes */
171 int read_attr(config *syscheck, char *dirs, char **g_attrs, char **g_values)
173 char *xml_check_all = "check_all";
174 char *xml_check_sum = "check_sum";
175 char *xml_check_sha1sum = "check_sha1sum";
176 char *xml_check_md5sum = "check_md5sum";
177 char *xml_check_size = "check_size";
178 char *xml_check_owner = "check_owner";
179 char *xml_check_group = "check_group";
180 char *xml_check_perm = "check_perm";
181 char *xml_real_time = "realtime";
185 dir = OS_StrBreak(',', dirs, MAX_DIR_SIZE); /* Max number */
187 /* Dir can not be null */
194 /* Doing it for each directory */
202 char **values = NULL;
206 /* Removing spaces at the beginning */
207 while(*tmp_dir == ' ')
212 /* Removing spaces at the end */
213 tmp_str = strchr(tmp_dir, ' ');
218 /* Checking if it is really at the end */
219 if((*tmp_str == '\0') || (*tmp_str == ' '))
227 /* Getting the options */
228 if(!g_attrs || !g_values)
230 merror(SYSCHECK_NO_OPT, ARGV0, dirs);
237 while(*attrs && *values)
240 if(strcmp(*attrs, xml_check_all) == 0)
242 if(strcmp(*values, "yes") == 0)
251 else if(strcmp(*values, "no") == 0)
256 merror(SK_INV_OPT, ARGV0, *values, *attrs);
261 else if(strcmp(*attrs, xml_check_sum) == 0)
263 if(strcmp(*values, "yes") == 0)
268 else if(strcmp(*values, "no") == 0)
273 merror(SK_INV_OPT, ARGV0, *values, *attrs);
277 /* Checking md5sum */
278 else if(strcmp(*attrs, xml_check_md5sum) == 0)
280 if(strcmp(*values, "yes") == 0)
284 else if(strcmp(*values, "no") == 0)
289 merror(SK_INV_OPT, ARGV0, *values, *attrs);
293 /* Checking sha1sum */
294 else if(strcmp(*attrs, xml_check_sha1sum) == 0)
296 if(strcmp(*values, "yes") == 0)
300 else if(strcmp(*values, "no") == 0)
305 merror(SK_INV_OPT, ARGV0, *values, *attrs);
309 /* Checking permission */
310 else if(strcmp(*attrs, xml_check_perm) == 0)
312 if(strcmp(*values, "yes") == 0)
316 else if(strcmp(*values, "no") == 0)
321 merror(SK_INV_OPT, ARGV0, *values, *attrs);
326 else if(strcmp(*attrs, xml_check_size) == 0)
328 if(strcmp(*values, "yes") == 0)
332 else if(strcmp(*values, "no") == 0)
337 merror(SK_INV_OPT, ARGV0, *values, *attrs);
342 else if(strcmp(*attrs, xml_check_owner) == 0)
344 if(strcmp(*values, "yes") == 0)
348 else if(strcmp(*values, "no") == 0)
353 merror(SK_INV_OPT, ARGV0, *values, *attrs);
358 else if(strcmp(*attrs, xml_check_group) == 0)
360 if(strcmp(*values, "yes") == 0)
364 else if(strcmp(*values, "no") == 0)
369 merror(SK_INV_OPT, ARGV0, *values, *attrs);
373 else if(strcmp(*attrs, xml_real_time) == 0)
375 if(strcmp(*values, "yes") == 0)
377 opts|=CHECK_REALTIME;
379 else if(strcmp(*values, "no") == 0)
384 merror(SK_INV_OPT, ARGV0, *values, *attrs);
390 merror(SK_INV_ATTR, ARGV0, *attrs);
397 /* You must have something set */
400 merror(SYSCHECK_NO_OPT, ARGV0, dirs);
405 /* Adding directory - looking for the last available */
407 while(syscheck->dir && syscheck->dir[i])
412 str_len_dir = strlen(tmp_dir);
413 str_len_i = strlen(syscheck->dir[i]);
415 if(str_len_dir > str_len_i)
417 str_len_dir = str_len_i;
420 /* Duplicate entry */
421 if(strcmp(syscheck->dir[i], tmp_dir) == 0)
423 merror(SK_DUP, ARGV0, tmp_dir);
431 /* Checking for glob. */
433 if(strchr(tmp_dir, '*') ||
434 strchr(tmp_dir, '?') ||
435 strchr(tmp_dir, '['))
440 if(glob(tmp_dir, 0, NULL, &g) != 0)
442 merror(GLOB_ERROR, ARGV0, tmp_dir);
446 if(g.gl_pathv[0] == NULL)
448 merror(GLOB_NFOUND, ARGV0, tmp_dir);
452 while(g.gl_pathv[gindex])
454 dump_syscheck_entry(syscheck, g.gl_pathv[gindex], opts, 0);
463 dump_syscheck_entry(syscheck, tmp_dir, opts, 0);
466 dump_syscheck_entry(syscheck, tmp_dir, opts, 0);
479 int Read_Syscheck(XML_NODE node, void *configp, void *mailp)
483 /* XML Definitions */
484 char *xml_directories = "directories";
485 char *xml_registry = "windows_registry";
486 char *xml_time = "frequency";
487 char *xml_scanday = "scan_day";
488 char *xml_scantime = "scan_time";
489 char *xml_ignore = "ignore";
490 char *xml_registry_ignore = "registry_ignore";
491 char *xml_auto_ignore = "auto_ignore";
492 char *xml_alert_new_files = "alert_new_files";
493 char *xml_disabled = "disabled";
494 char *xml_scan_on_start = "scan_on_start";
496 /* Configuration example
497 <directories check_all="yes">/etc,/usr/bin</directories>
498 <directories check_owner="yes" check_group="yes" check_perm="yes"
499 check_sum="yes">/var/log</directories>
504 syscheck = (config *)configp;
509 if(!node[i]->element)
511 merror(XML_ELEMNULL, ARGV0);
514 else if(!node[i]->content)
516 merror(XML_VALUENULL, ARGV0, node[i]->element);
520 /* Getting directories */
521 else if(strcmp(node[i]->element,xml_directories) == 0)
523 char dirs[OS_MAXSTR];
526 ExpandEnvironmentStrings(node[i]->content, dirs, sizeof(dirs) -1);
528 strncpy(dirs, node[i]->content, sizeof(dirs) -1);
531 if(!read_attr(syscheck,
539 /* Getting windows registry */
540 else if(strcmp(node[i]->element,xml_registry) == 0)
543 if(!read_reg(syscheck, node[i]->content))
549 /* Getting frequency */
550 else if(strcmp(node[i]->element,xml_time) == 0)
552 if(!OS_StrIsNum(node[i]->content))
554 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
558 syscheck->time = atoi(node[i]->content);
560 /* Getting scan time */
561 else if(strcmp(node[i]->element,xml_scantime) == 0)
563 syscheck->scan_time = OS_IsValidUniqueTime(node[i]->content);
564 if(!syscheck->scan_time)
566 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
571 /* Getting scan day */
572 else if(strcmp(node[i]->element,xml_scanday) == 0)
574 syscheck->scan_day = OS_IsValidDay(node[i]->content);
575 if(!syscheck->scan_day)
577 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
582 /* Getting if xml_scan_on_start. */
583 else if(strcmp(node[i]->element, xml_scan_on_start) == 0)
585 if(strcmp(node[i]->content, "yes") == 0)
586 syscheck->scan_on_start = 1;
587 else if(strcmp(node[i]->content, "no") == 0)
588 syscheck->scan_on_start = 0;
591 merror(XML_VALUEERR,ARGV0, node[i]->element, node[i]->content);
596 /* Getting if disabled. */
597 else if(strcmp(node[i]->element,xml_disabled) == 0)
599 if(strcmp(node[i]->content, "yes") == 0)
600 syscheck->disabled = 1;
601 else if(strcmp(node[i]->content, "no") == 0)
602 syscheck->disabled = 0;
605 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
610 /* Getting file/dir ignore */
611 else if(strcmp(node[i]->element,xml_ignore) == 0)
615 /* For Windows, we attempt to expand environment variables. */
618 os_calloc(2048, sizeof(char), new_ig);
620 ExpandEnvironmentStrings(node[i]->content, new_ig, 2047);
622 free(node[i]->content);
623 node[i]->content = new_ig;
626 /* Adding if regex */
627 if(node[i]->attributes && node[i]->values)
629 if(node[i]->attributes[0] && node[i]->values[0] &&
630 (strcmp(node[i]->attributes[0], "type") == 0) &&
631 (strcmp(node[i]->values[0], "sregex") == 0))
635 if(!syscheck->ignore_regex)
637 os_calloc(2, sizeof(OSMatch *),syscheck->ignore_regex);
638 syscheck->ignore_regex[0] = NULL;
639 syscheck->ignore_regex[1] = NULL;
643 while(syscheck->ignore_regex[ign_size] != NULL)
646 os_realloc(syscheck->ignore_regex,
647 sizeof(OSMatch *)*(ign_size +2),
648 syscheck->ignore_regex);
649 syscheck->ignore_regex[ign_size +1] = NULL;
651 os_calloc(1, sizeof(OSMatch),
652 syscheck->ignore_regex[ign_size]);
654 if(!OSMatch_Compile(node[i]->content,
655 syscheck->ignore_regex[ign_size], 0))
657 mt_pt = (OSMatch *)syscheck->ignore_regex[ign_size];
658 merror(REGEX_COMPILE, ARGV0, node[i]->content,
665 merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]);
670 /* Adding if simple entry -- checking for duplicates */
671 else if(!os_IsStrOnArray(node[i]->content, syscheck->ignore))
673 if(!syscheck->ignore)
675 os_calloc(2, sizeof(char *), syscheck->ignore);
676 syscheck->ignore[0] = NULL;
677 syscheck->ignore[1] = NULL;
681 while(syscheck->ignore[ign_size] != NULL)
684 os_realloc(syscheck->ignore,
685 sizeof(char *)*(ign_size +2),
687 syscheck->ignore[ign_size +1] = NULL;
689 os_strdup(node[i]->content,syscheck->ignore[ign_size]);
693 /* Getting registry ignore list */
694 else if(strcmp(node[i]->element,xml_registry_ignore) == 0)
699 /* Adding if regex */
700 if(node[i]->attributes && node[i]->values)
702 if(node[i]->attributes[0] && node[i]->values[0] &&
703 (strcmp(node[i]->attributes[0], "type") == 0) &&
704 (strcmp(node[i]->values[0], "sregex") == 0))
708 if(!syscheck->registry_ignore_regex)
710 os_calloc(2, sizeof(OSMatch *),
711 syscheck->registry_ignore_regex);
712 syscheck->registry_ignore_regex[0] = NULL;
713 syscheck->registry_ignore_regex[1] = NULL;
717 while(syscheck->registry_ignore_regex[ign_size] !=NULL)
720 os_realloc(syscheck->registry_ignore_regex,
721 sizeof(OSMatch *)*(ign_size +2),
722 syscheck->registry_ignore_regex);
723 syscheck->registry_ignore_regex[ign_size +1] = NULL;
726 os_calloc(1, sizeof(OSMatch),
727 syscheck->registry_ignore_regex[ign_size]);
729 if(!OSMatch_Compile(node[i]->content,
730 syscheck->registry_ignore_regex[ign_size], 0))
733 syscheck->registry_ignore_regex[ign_size];
734 merror(REGEX_COMPILE, ARGV0, node[i]->content,
741 merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]);
745 /* We do not add duplicated entries */
746 else if(!os_IsStrOnArray(node[i]->content,
747 syscheck->registry_ignore))
749 if(!syscheck->registry_ignore)
751 os_calloc(2, sizeof(char *), syscheck->registry_ignore);
752 syscheck->registry_ignore[0] = NULL;
753 syscheck->registry_ignore[1] = NULL;
757 while(syscheck->registry_ignore[ign_size] != NULL)
760 os_realloc(syscheck->registry_ignore,
761 sizeof(char *)*(ign_size +2),
762 syscheck->registry_ignore);
763 syscheck->registry_ignore[ign_size +1] = NULL;
765 os_strdup(node[i]->content,syscheck->registry_ignore[ign_size]);
769 else if(strcmp(node[i]->element,xml_auto_ignore) == 0)
771 /* auto_ignore is not read here. */
773 else if(strcmp(node[i]->element,xml_alert_new_files) == 0)
775 /* alert_new_files option is not read here. */
779 merror(XML_INVELEM, ARGV0, node[i]->element);