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 2) 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, char *restrictfile)
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;
60 os_calloc(2, sizeof(OSMatch *), syscheck->filerestrict);
61 syscheck->filerestrict[pl] = NULL;
62 syscheck->filerestrict[pl + 1] = NULL;
66 while(syscheck->dir[pl] != NULL)
70 os_realloc(syscheck->dir, (pl +2) * sizeof(char *),
72 syscheck->dir[pl + 1] = NULL;
73 os_strdup(entry, syscheck->dir[pl]);
75 os_realloc(syscheck->opts, (pl +2) * sizeof(int),
77 syscheck->opts[pl + 1] = 0;
78 syscheck->opts[pl] = vals;
80 os_realloc(syscheck->filerestrict, (pl +2) * sizeof(char *),
81 syscheck->filerestrict);
82 syscheck->filerestrict[pl] = NULL;
83 syscheck->filerestrict[pl + 1] = NULL;
87 os_calloc(1, sizeof(OSMatch), syscheck->filerestrict[pl]);
88 if(!OSMatch_Compile(restrictfile, syscheck->filerestrict[pl], 0))
92 ptm = syscheck->filerestrict[pl];
94 merror(REGEX_COMPILE, ARGV0, restrictfile,
96 free(syscheck->filerestrict[pl]);
97 syscheck->filerestrict[pl] = NULL;
107 /* Read Windows registry configuration */
109 int read_reg(config *syscheck, char *entries)
116 /* Getting each entry separately */
117 entry = OS_StrBreak(',', entries, MAX_DIR_SIZE); /* Max number */
120 /* entry can not be null */
127 /* Doing it for each Entry */
134 /* Removing spaces at the beginning */
135 while(*tmp_entry == ' ')
140 /* Removing spaces at the end */
141 tmp_str = strchr(tmp_entry, ' ');
146 /* Checking if it is really at the end */
147 if((*tmp_str == '\0') || (*tmp_str == ' '))
155 /* Adding entries - looking for the last available */
157 while(syscheck->registry && syscheck->registry[i])
162 str_len_dir = strlen(tmp_entry);
163 str_len_i = strlen(syscheck->registry[i]);
165 if(str_len_dir > str_len_i)
167 str_len_dir = str_len_i;
170 /* Duplicated entry */
171 if(strcmp(syscheck->registry[i], tmp_entry) == 0)
173 merror(SK_DUP, ARGV0, tmp_entry);
179 /* Adding new entry */
180 dump_syscheck_entry(syscheck, tmp_entry, 0, 1, NULL);
189 #endif /* For read_reg */
194 /* Read directories attributes */
195 int read_attr(config *syscheck, char *dirs, char **g_attrs, char **g_values)
197 char *xml_check_all = "check_all";
198 char *xml_check_sum = "check_sum";
199 char *xml_check_sha1sum = "check_sha1sum";
200 char *xml_check_md5sum = "check_md5sum";
201 char *xml_check_size = "check_size";
202 char *xml_check_owner = "check_owner";
203 char *xml_check_group = "check_group";
204 char *xml_check_perm = "check_perm";
205 char *xml_real_time = "realtime";
206 char *xml_report_changes = "report_changes";
207 char *xml_restrict = "restrict";
209 char *restrictfile = NULL;
212 dir = OS_StrBreak(',', dirs, MAX_DIR_SIZE); /* Max number */
214 /* Dir can not be null */
221 /* Doing it for each directory */
229 char **values = NULL;
234 /* Removing spaces at the beginning */
235 while(*tmp_dir == ' ')
240 /* Removing spaces at the end */
241 tmp_str = strchr(tmp_dir, ' ');
246 /* Checking if it is really at the end */
247 if((*tmp_str == '\0') || (*tmp_str == ' '))
255 /* Getting the options */
256 if(!g_attrs || !g_values)
258 merror(SYSCHECK_NO_OPT, ARGV0, dirs);
265 while(*attrs && *values)
268 if(strcmp(*attrs, xml_check_all) == 0)
270 if(strcmp(*values, "yes") == 0)
279 else if(strcmp(*values, "no") == 0)
284 merror(SK_INV_OPT, ARGV0, *values, *attrs);
289 else if(strcmp(*attrs, xml_check_sum) == 0)
291 if(strcmp(*values, "yes") == 0)
296 else if(strcmp(*values, "no") == 0)
301 merror(SK_INV_OPT, ARGV0, *values, *attrs);
305 /* Checking md5sum */
306 else if(strcmp(*attrs, xml_check_md5sum) == 0)
308 if(strcmp(*values, "yes") == 0)
312 else if(strcmp(*values, "no") == 0)
317 merror(SK_INV_OPT, ARGV0, *values, *attrs);
321 /* Checking sha1sum */
322 else if(strcmp(*attrs, xml_check_sha1sum) == 0)
324 if(strcmp(*values, "yes") == 0)
328 else if(strcmp(*values, "no") == 0)
333 merror(SK_INV_OPT, ARGV0, *values, *attrs);
337 /* Checking permission */
338 else if(strcmp(*attrs, xml_check_perm) == 0)
340 if(strcmp(*values, "yes") == 0)
344 else if(strcmp(*values, "no") == 0)
349 merror(SK_INV_OPT, ARGV0, *values, *attrs);
354 else if(strcmp(*attrs, xml_check_size) == 0)
356 if(strcmp(*values, "yes") == 0)
360 else if(strcmp(*values, "no") == 0)
365 merror(SK_INV_OPT, ARGV0, *values, *attrs);
370 else if(strcmp(*attrs, xml_check_owner) == 0)
372 if(strcmp(*values, "yes") == 0)
376 else if(strcmp(*values, "no") == 0)
381 merror(SK_INV_OPT, ARGV0, *values, *attrs);
386 else if(strcmp(*attrs, xml_check_group) == 0)
388 if(strcmp(*values, "yes") == 0)
392 else if(strcmp(*values, "no") == 0)
397 merror(SK_INV_OPT, ARGV0, *values, *attrs);
401 else if(strcmp(*attrs, xml_real_time) == 0)
403 if(strcmp(*values, "yes") == 0)
405 opts|=CHECK_REALTIME;
407 else if(strcmp(*values, "no") == 0)
412 merror(SK_INV_OPT, ARGV0, *values, *attrs);
416 else if(strcmp(*attrs, xml_report_changes) == 0)
418 if(strcmp(*values, "yes") == 0)
420 opts|=CHECK_SEECHANGES;
422 else if(strcmp(*values, "no") == 0)
427 merror(SK_INV_OPT, ARGV0, *values, *attrs);
431 else if(strcmp(*attrs, xml_restrict) == 0)
433 os_strdup(*values, restrictfile);
437 merror(SK_INV_ATTR, ARGV0, *attrs);
444 /* You must have something set */
447 merror(SYSCHECK_NO_OPT, ARGV0, dirs);
448 if(restrictfile) free(restrictfile);
453 /* Adding directory - looking for the last available */
455 while(syscheck->dir && syscheck->dir[i])
460 str_len_dir = strlen(tmp_dir);
461 str_len_i = strlen(syscheck->dir[i]);
463 if(str_len_dir > str_len_i)
465 str_len_dir = str_len_i;
468 /* Duplicate entry */
469 if(strcmp(syscheck->dir[i], tmp_dir) == 0)
471 merror(SK_DUP, ARGV0, tmp_dir);
479 /* Checking for glob. */
481 if(strchr(tmp_dir, '*') ||
482 strchr(tmp_dir, '?') ||
483 strchr(tmp_dir, '['))
488 if(glob(tmp_dir, 0, NULL, &g) != 0)
490 merror(GLOB_ERROR, ARGV0, tmp_dir);
494 if(g.gl_pathv[0] == NULL)
496 merror(GLOB_NFOUND, ARGV0, tmp_dir);
500 while(g.gl_pathv[gindex])
502 dump_syscheck_entry(syscheck, g.gl_pathv[gindex], opts, 0, restrictfile);
511 dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
514 dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
533 int Read_Syscheck(XML_NODE node, void *configp, void *mailp)
537 /* XML Definitions */
538 char *xml_directories = "directories";
539 char *xml_registry = "windows_registry";
540 char *xml_time = "frequency";
541 char *xml_scanday = "scan_day";
542 char *xml_scantime = "scan_time";
543 char *xml_ignore = "ignore";
544 char *xml_registry_ignore = "registry_ignore";
545 char *xml_auto_ignore = "auto_ignore";
546 char *xml_alert_new_files = "alert_new_files";
547 char *xml_disabled = "disabled";
548 char *xml_scan_on_start = "scan_on_start";
550 /* Configuration example
551 <directories check_all="yes">/etc,/usr/bin</directories>
552 <directories check_owner="yes" check_group="yes" check_perm="yes"
553 check_sum="yes">/var/log</directories>
558 syscheck = (config *)configp;
563 if(!node[i]->element)
565 merror(XML_ELEMNULL, ARGV0);
568 else if(!node[i]->content)
570 merror(XML_VALUENULL, ARGV0, node[i]->element);
574 /* Getting directories */
575 else if(strcmp(node[i]->element,xml_directories) == 0)
577 char dirs[OS_MAXSTR];
580 ExpandEnvironmentStrings(node[i]->content, dirs, sizeof(dirs) -1);
582 strncpy(dirs, node[i]->content, sizeof(dirs) -1);
585 if(!read_attr(syscheck,
593 /* Getting windows registry */
594 else if(strcmp(node[i]->element,xml_registry) == 0)
597 if(!read_reg(syscheck, node[i]->content))
603 /* Getting frequency */
604 else if(strcmp(node[i]->element,xml_time) == 0)
606 if(!OS_StrIsNum(node[i]->content))
608 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
612 syscheck->time = atoi(node[i]->content);
614 /* Getting scan time */
615 else if(strcmp(node[i]->element,xml_scantime) == 0)
617 syscheck->scan_time = OS_IsValidUniqueTime(node[i]->content);
618 if(!syscheck->scan_time)
620 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
625 /* Getting scan day */
626 else if(strcmp(node[i]->element,xml_scanday) == 0)
628 syscheck->scan_day = OS_IsValidDay(node[i]->content);
629 if(!syscheck->scan_day)
631 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
636 /* Getting if xml_scan_on_start. */
637 else if(strcmp(node[i]->element, xml_scan_on_start) == 0)
639 if(strcmp(node[i]->content, "yes") == 0)
640 syscheck->scan_on_start = 1;
641 else if(strcmp(node[i]->content, "no") == 0)
642 syscheck->scan_on_start = 0;
645 merror(XML_VALUEERR,ARGV0, node[i]->element, node[i]->content);
650 /* Getting if disabled. */
651 else if(strcmp(node[i]->element,xml_disabled) == 0)
653 if(strcmp(node[i]->content, "yes") == 0)
654 syscheck->disabled = 1;
655 else if(strcmp(node[i]->content, "no") == 0)
656 syscheck->disabled = 0;
659 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
664 /* Getting file/dir ignore */
665 else if(strcmp(node[i]->element,xml_ignore) == 0)
669 /* For Windows, we attempt to expand environment variables. */
672 os_calloc(2048, sizeof(char), new_ig);
674 ExpandEnvironmentStrings(node[i]->content, new_ig, 2047);
676 free(node[i]->content);
677 node[i]->content = new_ig;
680 /* Adding if regex */
681 if(node[i]->attributes && node[i]->values)
683 if(node[i]->attributes[0] && node[i]->values[0] &&
684 (strcmp(node[i]->attributes[0], "type") == 0) &&
685 (strcmp(node[i]->values[0], "sregex") == 0))
689 if(!syscheck->ignore_regex)
691 os_calloc(2, sizeof(OSMatch *),syscheck->ignore_regex);
692 syscheck->ignore_regex[0] = NULL;
693 syscheck->ignore_regex[1] = NULL;
697 while(syscheck->ignore_regex[ign_size] != NULL)
700 os_realloc(syscheck->ignore_regex,
701 sizeof(OSMatch *)*(ign_size +2),
702 syscheck->ignore_regex);
703 syscheck->ignore_regex[ign_size +1] = NULL;
705 os_calloc(1, sizeof(OSMatch),
706 syscheck->ignore_regex[ign_size]);
708 if(!OSMatch_Compile(node[i]->content,
709 syscheck->ignore_regex[ign_size], 0))
711 mt_pt = (OSMatch *)syscheck->ignore_regex[ign_size];
712 merror(REGEX_COMPILE, ARGV0, node[i]->content,
719 merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]);
724 /* Adding if simple entry -- checking for duplicates */
725 else if(!os_IsStrOnArray(node[i]->content, syscheck->ignore))
727 if(!syscheck->ignore)
729 os_calloc(2, sizeof(char *), syscheck->ignore);
730 syscheck->ignore[0] = NULL;
731 syscheck->ignore[1] = NULL;
735 while(syscheck->ignore[ign_size] != NULL)
738 os_realloc(syscheck->ignore,
739 sizeof(char *)*(ign_size +2),
741 syscheck->ignore[ign_size +1] = NULL;
743 os_strdup(node[i]->content,syscheck->ignore[ign_size]);
747 /* Getting registry ignore list */
748 else if(strcmp(node[i]->element,xml_registry_ignore) == 0)
753 /* Adding if regex */
754 if(node[i]->attributes && node[i]->values)
756 if(node[i]->attributes[0] && node[i]->values[0] &&
757 (strcmp(node[i]->attributes[0], "type") == 0) &&
758 (strcmp(node[i]->values[0], "sregex") == 0))
762 if(!syscheck->registry_ignore_regex)
764 os_calloc(2, sizeof(OSMatch *),
765 syscheck->registry_ignore_regex);
766 syscheck->registry_ignore_regex[0] = NULL;
767 syscheck->registry_ignore_regex[1] = NULL;
771 while(syscheck->registry_ignore_regex[ign_size] !=NULL)
774 os_realloc(syscheck->registry_ignore_regex,
775 sizeof(OSMatch *)*(ign_size +2),
776 syscheck->registry_ignore_regex);
777 syscheck->registry_ignore_regex[ign_size +1] = NULL;
780 os_calloc(1, sizeof(OSMatch),
781 syscheck->registry_ignore_regex[ign_size]);
783 if(!OSMatch_Compile(node[i]->content,
784 syscheck->registry_ignore_regex[ign_size], 0))
787 syscheck->registry_ignore_regex[ign_size];
788 merror(REGEX_COMPILE, ARGV0, node[i]->content,
795 merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]);
799 /* We do not add duplicated entries */
800 else if(!os_IsStrOnArray(node[i]->content,
801 syscheck->registry_ignore))
803 if(!syscheck->registry_ignore)
805 os_calloc(2, sizeof(char *), syscheck->registry_ignore);
806 syscheck->registry_ignore[0] = NULL;
807 syscheck->registry_ignore[1] = NULL;
811 while(syscheck->registry_ignore[ign_size] != NULL)
814 os_realloc(syscheck->registry_ignore,
815 sizeof(char *)*(ign_size +2),
816 syscheck->registry_ignore);
817 syscheck->registry_ignore[ign_size +1] = NULL;
819 os_strdup(node[i]->content,syscheck->registry_ignore[ign_size]);
823 else if(strcmp(node[i]->element,xml_auto_ignore) == 0)
825 /* auto_ignore is not read here. */
827 else if(strcmp(node[i]->element,xml_alert_new_files) == 0)
829 /* alert_new_files option is not read here. */
833 merror(XML_INVELEM, ARGV0, node[i]->element);