1 /* @(#) $Id: ./src/config/syscheck-config.c, 2011/09/08 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
7 * This program is a free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General Public
9 * License (version 2) as published by the FSF - Free Software
16 #include "syscheck-config.h"
20 int dump_syscheck_entry(syscheck_config *syscheck, char *entry, int vals, int reg, char *restrictfile)
27 if(syscheck->registry == NULL)
29 os_calloc(2, sizeof(char *), syscheck->registry);
30 syscheck->registry[pl + 1] = NULL;
31 os_strdup(entry, syscheck->registry[pl]);
35 while(syscheck->registry[pl] != NULL)
39 os_realloc(syscheck->registry, (pl +2) * sizeof(char *),
41 syscheck->registry[pl + 1] = NULL;
42 os_strdup(entry, syscheck->registry[pl]);
51 if(syscheck->dir == NULL)
53 os_calloc(2, sizeof(char *), syscheck->dir);
54 syscheck->dir[pl + 1] = NULL;
55 os_strdup(entry, syscheck->dir[pl]);
57 os_calloc(2, sizeof(int), syscheck->opts);
58 syscheck->opts[pl + 1] = 0;
59 syscheck->opts[pl] = vals;
61 os_calloc(2, sizeof(OSMatch *), syscheck->filerestrict);
62 syscheck->filerestrict[pl] = NULL;
63 syscheck->filerestrict[pl + 1] = NULL;
67 while(syscheck->dir[pl] != NULL)
71 os_realloc(syscheck->dir, (pl +2) * sizeof(char *),
73 syscheck->dir[pl + 1] = NULL;
74 os_strdup(entry, syscheck->dir[pl]);
76 os_realloc(syscheck->opts, (pl +2) * sizeof(int),
78 syscheck->opts[pl + 1] = 0;
79 syscheck->opts[pl] = vals;
81 os_realloc(syscheck->filerestrict, (pl +2) * sizeof(char *),
82 syscheck->filerestrict);
83 syscheck->filerestrict[pl] = NULL;
84 syscheck->filerestrict[pl + 1] = NULL;
88 os_calloc(1, sizeof(OSMatch), syscheck->filerestrict[pl]);
89 if(!OSMatch_Compile(restrictfile, syscheck->filerestrict[pl], 0))
93 ptm = syscheck->filerestrict[pl];
95 merror(REGEX_COMPILE, ARGV0, restrictfile,
97 free(syscheck->filerestrict[pl]);
98 syscheck->filerestrict[pl] = NULL;
108 /* Read Windows registry configuration */
110 int read_reg(syscheck_config *syscheck, char *entries)
117 /* Getting each entry separately */
118 entry = OS_StrBreak(',', entries, MAX_DIR_SIZE); /* Max number */
121 /* entry can not be null */
128 /* Doing it for each Entry */
135 /* Removing spaces at the beginning */
136 while(*tmp_entry == ' ')
141 /* Removing spaces at the end */
142 tmp_str = strchr(tmp_entry, ' ');
147 /* Checking if it is really at the end */
148 if((*tmp_str == '\0') || (*tmp_str == ' '))
156 /* Adding entries - looking for the last available */
158 while(syscheck->registry && syscheck->registry[i])
163 str_len_dir = strlen(tmp_entry);
164 str_len_i = strlen(syscheck->registry[i]);
166 if(str_len_dir > str_len_i)
168 str_len_dir = str_len_i;
171 /* Duplicated entry */
172 if(strcmp(syscheck->registry[i], tmp_entry) == 0)
174 merror(SK_DUP, ARGV0, tmp_entry);
180 /* Adding new entry */
181 dump_syscheck_entry(syscheck, tmp_entry, 0, 1, NULL);
190 #endif /* For read_reg */
195 /* Read directories attributes */
196 int read_attr(syscheck_config *syscheck, char *dirs, char **g_attrs, char **g_values)
198 char *xml_check_all = "check_all";
199 char *xml_check_sum = "check_sum";
200 char *xml_check_sha1sum = "check_sha1sum";
201 char *xml_check_md5sum = "check_md5sum";
202 char *xml_check_size = "check_size";
203 char *xml_check_owner = "check_owner";
204 char *xml_check_group = "check_group";
205 char *xml_check_perm = "check_perm";
206 char *xml_real_time = "realtime";
207 char *xml_report_changes = "report_changes";
208 char *xml_restrict = "restrict";
210 char *restrictfile = NULL;
213 dir = OS_StrBreak(',', dirs, MAX_DIR_SIZE); /* Max number */
214 char **dir_org = dir;
218 /* Dir can not be null */
225 /* Doing it for each directory */
233 char **values = NULL;
238 /* Removing spaces at the beginning */
239 while(*tmp_dir == ' ')
244 /* Removing spaces at the end */
245 tmp_str = strchr(tmp_dir, ' ');
250 /* Checking if it is really at the end */
251 if((*tmp_str == '\0') || (*tmp_str == ' '))
259 /* Getting the options */
260 if(!g_attrs || !g_values)
262 merror(SYSCHECK_NO_OPT, ARGV0, dirs);
270 while(*attrs && *values)
273 if(strcmp(*attrs, xml_check_all) == 0)
275 if(strcmp(*values, "yes") == 0)
284 else if(strcmp(*values, "no") == 0)
289 merror(SK_INV_OPT, ARGV0, *values, *attrs);
295 else if(strcmp(*attrs, xml_check_sum) == 0)
297 if(strcmp(*values, "yes") == 0)
302 else if(strcmp(*values, "no") == 0)
307 merror(SK_INV_OPT, ARGV0, *values, *attrs);
312 /* Checking md5sum */
313 else if(strcmp(*attrs, xml_check_md5sum) == 0)
315 if(strcmp(*values, "yes") == 0)
319 else if(strcmp(*values, "no") == 0)
324 merror(SK_INV_OPT, ARGV0, *values, *attrs);
329 /* Checking sha1sum */
330 else if(strcmp(*attrs, xml_check_sha1sum) == 0)
332 if(strcmp(*values, "yes") == 0)
336 else if(strcmp(*values, "no") == 0)
341 merror(SK_INV_OPT, ARGV0, *values, *attrs);
346 /* Checking permission */
347 else if(strcmp(*attrs, xml_check_perm) == 0)
349 if(strcmp(*values, "yes") == 0)
353 else if(strcmp(*values, "no") == 0)
358 merror(SK_INV_OPT, ARGV0, *values, *attrs);
364 else if(strcmp(*attrs, xml_check_size) == 0)
366 if(strcmp(*values, "yes") == 0)
370 else if(strcmp(*values, "no") == 0)
375 merror(SK_INV_OPT, ARGV0, *values, *attrs);
381 else if(strcmp(*attrs, xml_check_owner) == 0)
383 if(strcmp(*values, "yes") == 0)
387 else if(strcmp(*values, "no") == 0)
392 merror(SK_INV_OPT, ARGV0, *values, *attrs);
398 else if(strcmp(*attrs, xml_check_group) == 0)
400 if(strcmp(*values, "yes") == 0)
404 else if(strcmp(*values, "no") == 0)
409 merror(SK_INV_OPT, ARGV0, *values, *attrs);
414 else if(strcmp(*attrs, xml_real_time) == 0)
416 if(strcmp(*values, "yes") == 0)
418 opts|=CHECK_REALTIME;
420 else if(strcmp(*values, "no") == 0)
425 merror(SK_INV_OPT, ARGV0, *values, *attrs);
430 else if(strcmp(*attrs, xml_report_changes) == 0)
432 if(strcmp(*values, "yes") == 0)
434 opts|=CHECK_SEECHANGES;
436 else if(strcmp(*values, "no") == 0)
441 merror(SK_INV_OPT, ARGV0, *values, *attrs);
446 else if(strcmp(*attrs, xml_restrict) == 0)
448 os_strdup(*values, restrictfile);
452 merror(SK_INV_ATTR, ARGV0, *attrs);
460 /* You must have something set */
463 merror(SYSCHECK_NO_OPT, ARGV0, dirs);
464 if(restrictfile) free(restrictfile);
470 /* Adding directory - looking for the last available */
472 while(syscheck->dir && syscheck->dir[i])
477 str_len_dir = strlen(tmp_dir);
478 str_len_i = strlen(syscheck->dir[i]);
480 if(str_len_dir > str_len_i)
482 str_len_dir = str_len_i;
485 /* Duplicate entry */
486 if(strcmp(syscheck->dir[i], tmp_dir) == 0)
488 merror(SK_DUP, ARGV0, tmp_dir);
497 /* Checking for glob. */
499 if(strchr(tmp_dir, '*') ||
500 strchr(tmp_dir, '?') ||
501 strchr(tmp_dir, '['))
506 if(glob(tmp_dir, 0, NULL, &g) != 0)
508 merror(GLOB_ERROR, ARGV0, tmp_dir);
513 if(g.gl_pathv[0] == NULL)
515 merror(GLOB_NFOUND, ARGV0, tmp_dir);
520 while(g.gl_pathv[gindex])
522 dump_syscheck_entry(syscheck, g.gl_pathv[gindex], opts, 0, restrictfile);
531 dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
534 dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
563 int Read_Syscheck(XML_NODE node, void *configp, void *mailp)
567 /* XML Definitions */
568 char *xml_directories = "directories";
569 char *xml_registry = "windows_registry";
570 char *xml_time = "frequency";
571 char *xml_scanday = "scan_day";
572 char *xml_scantime = "scan_time";
573 char *xml_ignore = "ignore";
574 char *xml_registry_ignore = "registry_ignore";
575 char *xml_auto_ignore = "auto_ignore";
576 char *xml_alert_new_files = "alert_new_files";
577 char *xml_disabled = "disabled";
578 char *xml_scan_on_start = "scan_on_start";
579 char *xml_prefilter_cmd = "prefilter_cmd";
581 /* Configuration example
582 <directories check_all="yes">/etc,/usr/bin</directories>
583 <directories check_owner="yes" check_group="yes" check_perm="yes"
584 check_sum="yes">/var/log</directories>
587 syscheck_config *syscheck;
589 syscheck = (syscheck_config *)configp;
594 if(!node[i]->element)
596 merror(XML_ELEMNULL, ARGV0);
599 else if(!node[i]->content)
601 merror(XML_VALUENULL, ARGV0, node[i]->element);
605 /* Getting directories */
606 else if(strcmp(node[i]->element,xml_directories) == 0)
608 char dirs[OS_MAXSTR];
611 ExpandEnvironmentStrings(node[i]->content, dirs, sizeof(dirs) -1);
613 strncpy(dirs, node[i]->content, sizeof(dirs) -1);
616 if(!read_attr(syscheck,
624 /* Getting windows registry */
625 else if(strcmp(node[i]->element,xml_registry) == 0)
628 if(!read_reg(syscheck, node[i]->content))
634 /* Getting frequency */
635 else if(strcmp(node[i]->element,xml_time) == 0)
637 if(!OS_StrIsNum(node[i]->content))
639 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
643 syscheck->time = atoi(node[i]->content);
645 /* Getting scan time */
646 else if(strcmp(node[i]->element,xml_scantime) == 0)
648 syscheck->scan_time = OS_IsValidUniqueTime(node[i]->content);
649 if(!syscheck->scan_time)
651 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
656 /* Getting scan day */
657 else if(strcmp(node[i]->element,xml_scanday) == 0)
659 syscheck->scan_day = OS_IsValidDay(node[i]->content);
660 if(!syscheck->scan_day)
662 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
667 /* Getting if xml_scan_on_start. */
668 else if(strcmp(node[i]->element, xml_scan_on_start) == 0)
670 if(strcmp(node[i]->content, "yes") == 0)
671 syscheck->scan_on_start = 1;
672 else if(strcmp(node[i]->content, "no") == 0)
673 syscheck->scan_on_start = 0;
676 merror(XML_VALUEERR,ARGV0, node[i]->element, node[i]->content);
681 /* Getting if disabled. */
682 else if(strcmp(node[i]->element,xml_disabled) == 0)
684 if(strcmp(node[i]->content, "yes") == 0)
685 syscheck->disabled = 1;
686 else if(strcmp(node[i]->content, "no") == 0)
687 syscheck->disabled = 0;
690 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
695 /* Getting file/dir ignore */
696 else if(strcmp(node[i]->element,xml_ignore) == 0)
700 /* For Windows, we attempt to expand environment variables. */
703 os_calloc(2048, sizeof(char), new_ig);
705 ExpandEnvironmentStrings(node[i]->content, new_ig, 2047);
707 free(node[i]->content);
708 node[i]->content = new_ig;
711 /* Adding if regex */
712 if(node[i]->attributes && node[i]->values)
714 if(node[i]->attributes[0] && node[i]->values[0] &&
715 (strcmp(node[i]->attributes[0], "type") == 0) &&
716 (strcmp(node[i]->values[0], "sregex") == 0))
720 if(!syscheck->ignore_regex)
722 os_calloc(2, sizeof(OSMatch *),syscheck->ignore_regex);
723 syscheck->ignore_regex[0] = NULL;
724 syscheck->ignore_regex[1] = NULL;
728 while(syscheck->ignore_regex[ign_size] != NULL)
731 os_realloc(syscheck->ignore_regex,
732 sizeof(OSMatch *)*(ign_size +2),
733 syscheck->ignore_regex);
734 syscheck->ignore_regex[ign_size +1] = NULL;
736 os_calloc(1, sizeof(OSMatch),
737 syscheck->ignore_regex[ign_size]);
739 if(!OSMatch_Compile(node[i]->content,
740 syscheck->ignore_regex[ign_size], 0))
742 mt_pt = (OSMatch *)syscheck->ignore_regex[ign_size];
743 merror(REGEX_COMPILE, ARGV0, node[i]->content,
750 merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]);
755 /* Adding if simple entry -- checking for duplicates */
756 else if(!os_IsStrOnArray(node[i]->content, syscheck->ignore))
758 if(!syscheck->ignore)
760 os_calloc(2, sizeof(char *), syscheck->ignore);
761 syscheck->ignore[0] = NULL;
762 syscheck->ignore[1] = NULL;
766 while(syscheck->ignore[ign_size] != NULL)
769 os_realloc(syscheck->ignore,
770 sizeof(char *)*(ign_size +2),
772 syscheck->ignore[ign_size +1] = NULL;
774 os_strdup(node[i]->content,syscheck->ignore[ign_size]);
778 /* Getting registry ignore list */
779 else if(strcmp(node[i]->element,xml_registry_ignore) == 0)
784 /* Adding if regex */
785 if(node[i]->attributes && node[i]->values)
787 if(node[i]->attributes[0] && node[i]->values[0] &&
788 (strcmp(node[i]->attributes[0], "type") == 0) &&
789 (strcmp(node[i]->values[0], "sregex") == 0))
793 if(!syscheck->registry_ignore_regex)
795 os_calloc(2, sizeof(OSMatch *),
796 syscheck->registry_ignore_regex);
797 syscheck->registry_ignore_regex[0] = NULL;
798 syscheck->registry_ignore_regex[1] = NULL;
802 while(syscheck->registry_ignore_regex[ign_size] !=NULL)
805 os_realloc(syscheck->registry_ignore_regex,
806 sizeof(OSMatch *)*(ign_size +2),
807 syscheck->registry_ignore_regex);
808 syscheck->registry_ignore_regex[ign_size +1] = NULL;
811 os_calloc(1, sizeof(OSMatch),
812 syscheck->registry_ignore_regex[ign_size]);
814 if(!OSMatch_Compile(node[i]->content,
815 syscheck->registry_ignore_regex[ign_size], 0))
818 syscheck->registry_ignore_regex[ign_size];
819 merror(REGEX_COMPILE, ARGV0, node[i]->content,
826 merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]);
830 /* We do not add duplicated entries */
831 else if(!os_IsStrOnArray(node[i]->content,
832 syscheck->registry_ignore))
834 if(!syscheck->registry_ignore)
836 os_calloc(2, sizeof(char *), syscheck->registry_ignore);
837 syscheck->registry_ignore[0] = NULL;
838 syscheck->registry_ignore[1] = NULL;
842 while(syscheck->registry_ignore[ign_size] != NULL)
845 os_realloc(syscheck->registry_ignore,
846 sizeof(char *)*(ign_size +2),
847 syscheck->registry_ignore);
848 syscheck->registry_ignore[ign_size +1] = NULL;
850 os_strdup(node[i]->content,syscheck->registry_ignore[ign_size]);
854 else if(strcmp(node[i]->element,xml_auto_ignore) == 0)
856 /* auto_ignore is not read here. */
858 else if(strcmp(node[i]->element,xml_alert_new_files) == 0)
860 /* alert_new_files option is not read here. */
862 else if(strcmp(node[i]->element,xml_prefilter_cmd) == 0)
868 ExpandEnvironmentStrings(node[i]->content, cmd, sizeof(cmd) -1);
870 strncpy(cmd, node[i]->content, sizeof(cmd)-1);
873 if (strlen(cmd) > 0) {
874 char statcmd[OS_MAXSTR];
876 strncpy(statcmd, cmd, sizeof(statcmd)-1);
877 if (NULL != (ix = strchr(statcmd, ' '))) { *ix = '\0'; }
878 if (stat(statcmd, &statbuf) == 0) {
879 // More checks needed (perms, owner, etc.)
880 os_calloc(1, strlen(cmd)+1, syscheck->prefilter_cmd);
881 strncpy(syscheck->prefilter_cmd, cmd, strlen(cmd));
885 merror(XML_VALUEERR,ARGV0, node[i]->element, node[i]->content);
892 merror(XML_INVELEM, ARGV0, node[i]->element);