END_TEST START_TEST(test_success_strisnum) { int i; /* * Please note that all strings are \ escaped */ const char *tests[] = { "1", "0123", NULL, }; for(i=0; tests[i] != NULL ; i++) { ck_assert_msg(OS_StrIsNum(tests[i]), "%s should match positive by OS_StrIsNum", tests[i]); } }
END_TEST START_TEST(test_fail_strisnum) { int i; /* * Please note that all strings are \ escaped */ const char *tests[] = { "test", "1234e", "-1", "+1", NULL, }; for(i=0; tests[i] != NULL ; i++) { ck_assert_msg(!OS_StrIsNum(tests[i]), "%s should not match positive by OS_StrIsNum", tests[i]); } }
/** int ReadActiveResponses(XML_NODE node, void *d1, void *d2) * Generates a list with all active responses. */ int ReadActiveResponses(XML_NODE node, void *d1, void *d2) { FILE *fp; int i = 0; int r_ar = 0; int l_ar = 0; int rpt = 0; /* Xml options */ char *xml_ar_command = "command"; char *xml_ar_location = "location"; char *xml_ar_agent_id = "agent_id"; char *xml_ar_rules_id = "rules_id"; char *xml_ar_rules_group = "rules_group"; char *xml_ar_level = "level"; char *xml_ar_timeout = "timeout"; char *xml_ar_disabled = "disabled"; char *xml_ar_repeated = "repeated_offenders"; char *tmp_location; /* Currently active response */ active_response *tmp_ar; /* Opening shared ar file */ fp = fopen(DEFAULTARPATH, "a"); if(!fp) { merror(FOPEN_ERROR, ARGV0, DEFAULTARPATH); return(-1); } chmod(DEFAULTARPATH, 0444); /* Allocating for the active-response */ tmp_ar = calloc(1, sizeof(active_response)); if(!tmp_ar) { merror(MEM_ERROR, ARGV0); return(-1); } /* Initializing variables */ tmp_ar->name = NULL; tmp_ar->command = NULL; tmp_ar->location = 0; tmp_ar->timeout = 0; tmp_ar->level = 0; tmp_ar->agent_id = NULL; tmp_ar->rules_id = NULL; tmp_ar->rules_group = NULL; tmp_ar->ar_cmd = NULL; tmp_location = NULL; /* Searching for the commands */ while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } /* Command */ if(strcmp(node[i]->element, xml_ar_command) == 0) { tmp_ar->command = strdup(node[i]->content); } /* Target */ else if(strcmp(node[i]->element, xml_ar_location) == 0) { tmp_location = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_agent_id) == 0) { tmp_ar->agent_id = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_rules_id) == 0) { tmp_ar->rules_id = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_rules_group) == 0) { tmp_ar->rules_group = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_level) == 0) { /* Level must be numeric */ if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } tmp_ar->level = atoi(node[i]->content); /* Making sure the level is valid */ if((tmp_ar->level < 0) || (tmp_ar->level > 20)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_ar_timeout) == 0) { tmp_ar->timeout = atoi(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_disabled) == 0) { if(strcmp(node[i]->content, "yes") == 0) { ar_flag = -1; } else if(strcmp(node[i]->content, "no") == 0) { /* Don't do anything if disabled is set to "no" */ } else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_ar_repeated) == 0) { /* Nothing - we deal with it on execd. */ rpt = 1; } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } /* Checking if ar is disabled */ if(ar_flag == -1) { fclose(fp); return(0); } /* Command and location must be there */ if(!tmp_ar->command || !tmp_location) { if(rpt == 1) { fclose(fp); return(0); } merror(AR_MISS, ARGV0); return(-1); } /* analysisd */ if(OS_Regex("AS|analysisd|analysis-server|server", tmp_location)) { tmp_ar->location|= AS_ONLY; } if(OS_Regex("local", tmp_location)) { tmp_ar->location|= REMOTE_AGENT; } if(OS_Regex("defined-agent", tmp_location)) { if(!tmp_ar->agent_id) { merror(AR_DEF_AGENT, ARGV0); return(-1); } tmp_ar->location|= SPECIFIC_AGENT; } if(OS_Regex("all|any", tmp_location)) { tmp_ar->location|=ALL_AGENTS; } /* If we didn't set any value for the location */ if(tmp_ar->location == 0) { merror(AR_INV_LOC, ARGV0, tmp_location); return(-1); } /* cleaning tmp_location */ free(tmp_location); tmp_location = NULL; /* Checking if command name is valid */ { OSListNode *my_commands_node; my_commands_node = OSList_GetFirstNode(d1); while(my_commands_node) { ar_command *my_command; my_command = (ar_command *)my_commands_node->data; if(strcmp(my_command->name, tmp_ar->command) == 0) { tmp_ar->ar_cmd = my_command; break; } my_commands_node = OSList_GetNextNode(d1); } /* Didn't find a valid command */ if(tmp_ar->ar_cmd == NULL) { merror(AR_INV_CMD, ARGV0, tmp_ar->command); return(-1); } } /* Checking if timeout is allowed */ if(tmp_ar->timeout && !tmp_ar->ar_cmd->timeout_allowed) { merror(AR_NO_TIMEOUT, ARGV0, tmp_ar->ar_cmd->name); return(-1); } /* d1 is the active response list */ if(!OSList_AddData(d2, (void *)tmp_ar)) { merror(LIST_ADD_ERROR, ARGV0); return(-1); } /* Setting a unique active response name */ tmp_ar->name = calloc(OS_FLSIZE +1, sizeof(char)); if(!tmp_ar->name) { ErrorExit(MEM_ERROR, ARGV0); } snprintf(tmp_ar->name, OS_FLSIZE, "%s%d", tmp_ar->ar_cmd->name, tmp_ar->timeout); /* Adding to shared file */ fprintf(fp, "%s - %s - %d\n", tmp_ar->name, tmp_ar->ar_cmd->executable, tmp_ar->timeout); /* Setting the configs to start the right queues */ if(tmp_ar->location & AS_ONLY) { l_ar = 1; } if(tmp_ar->location & ALL_AGENTS) { r_ar = 1; } if(tmp_ar->location & REMOTE_AGENT) { r_ar = 1; l_ar = 1; } if(tmp_ar->location & SPECIFIC_AGENT) { r_ar = 1; } /* Setting the configuration for the active response */ if(r_ar && (!(ar_flag & REMOTE_AR))) { ar_flag|= REMOTE_AR; } if(l_ar && (!(ar_flag & LOCAL_AR))) { ar_flag|= LOCAL_AR; } /* Closing shared file for active response */ fclose(fp); /* Done over here */ return(0); }
int Read_Localfile(XML_NODE node, void *d1, void *d2) { int pl = 0; int i = 0; int glob_set = 0; #ifndef WIN32 int glob_offset = 0; #endif /* XML Definitions */ char *xml_localfile_location = "location"; char *xml_localfile_command = "command"; char *xml_localfile_logformat = "log_format"; char *xml_localfile_frequency = "frequency"; char *xml_localfile_alias = "alias"; logreader *logf; logreader_config *log_config; log_config = (logreader_config *)d1; /* If config is not set, we need to create it */ if(!log_config->config) { os_calloc(2, sizeof(logreader), log_config->config); logf = log_config->config; logf[0].file = NULL; logf[0].command = NULL; logf[0].alias = NULL; logf[0].logformat = NULL; logf[1].file = NULL; logf[1].command = NULL; logf[1].alias = NULL; logf[1].logformat = NULL; } else { logf = log_config->config; while(logf[pl].file != NULL) { pl++; } /* Allocating more memory */ os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config); logf = log_config->config; logf[pl +1].file = NULL; logf[pl +1].command = NULL; logf[pl +1].alias = NULL; logf[pl +1].logformat = NULL; } logf[pl].file = NULL; logf[pl].command = NULL; logf[pl].alias = NULL; logf[pl].logformat = NULL; logf[pl].fp = NULL; logf[pl].ffile = NULL; logf[pl].djb_program_name = NULL; logf[pl].ign = 360; /* Searching for entries related to files */ i = 0; while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } else if(strcmp(node[i]->element,xml_localfile_command) == 0) { /* We don't accept remote commands from the manager - just in case. */ if(log_config->agent_cfg == 1 && log_config->accept_remote == 0) { merror("%s: Remote commands are not accepted from the manager. " "Ignoring it on the agent.conf", ARGV0); logf[pl].file = NULL; logf[pl].ffile = NULL; logf[pl].command = NULL; logf[pl].alias = NULL; logf[pl].logformat = NULL; logf[pl].fp = NULL; return(OS_INVALID); } os_strdup(node[i]->content, logf[pl].file); logf[pl].command = logf[pl].file; } else if(strcmp(node[i]->element,xml_localfile_frequency) == 0) { if(strcmp(node[i]->content, "hourly") == 0) { logf[pl].ign = 3600; } else if(strcmp(node[i]->content, "daily") == 0) { logf[pl].ign = 86400; } else { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } logf[pl].ign = atoi(node[i]->content); } } else if(strcmp(node[i]->element,xml_localfile_location) == 0) { #ifdef WIN32 /* Expand variables on Windows. */ if(strchr(node[i]->content, '%')) { int expandreturn = 0; char newfile[OS_MAXSTR +1]; newfile[OS_MAXSTR] = '\0'; expandreturn = ExpandEnvironmentStrings(node[i]->content, newfile, OS_MAXSTR); if((expandreturn > 0) && (expandreturn < OS_MAXSTR)) { free(node[i]->content); os_strdup(newfile, node[i]->content); } } #endif /* This is a glob*. * We will call this file multiple times until * there is no one else available. */ #ifndef WIN32 /* No windows support for glob */ if(strchr(node[i]->content, '*') || strchr(node[i]->content, '?') || strchr(node[i]->content, '[')) { glob_t g; /* Setting ot the first entry of the glob */ if(glob_set == 0) glob_set = pl +1; if(glob(node[i]->content, 0, NULL, &g) != 0) { merror(GLOB_ERROR, ARGV0, node[i]->content); os_strdup(node[i]->content, logf[pl].file); i++; continue; } /* Checking for the last entry */ if((g.gl_pathv[glob_offset]) == NULL) { /* Checking when nothing is found. */ if(glob_offset == 0) { merror(GLOB_NFOUND, ARGV0, node[i]->content); return(OS_INVALID); } i++; continue; } /* Checking for strftime on globs too. */ if(strchr(g.gl_pathv[glob_offset], '%')) { struct tm *p; time_t l_time = time(0); char lfile[OS_FLSIZE + 1]; size_t ret; p = localtime(&l_time); lfile[OS_FLSIZE] = '\0'; ret = strftime(lfile, OS_FLSIZE, g.gl_pathv[glob_offset], p); if(ret == 0) { merror(PARSE_ERROR, ARGV0, g.gl_pathv[glob_offset]); return(OS_INVALID); } os_strdup(g.gl_pathv[glob_offset], logf[pl].ffile); os_strdup(g.gl_pathv[glob_offset], logf[pl].file); } else { os_strdup(g.gl_pathv[glob_offset], logf[pl].file); } glob_offset++; globfree(&g); /* Now we need to create another file entry */ pl++; os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config); logf = log_config->config; logf[pl].file = NULL; logf[pl].alias = NULL; logf[pl].logformat = NULL; logf[pl].fp = NULL; logf[pl].ffile = NULL; logf[pl +1].file = NULL; logf[pl +1].alias = NULL; logf[pl +1].logformat = NULL; /* We can not increment the file count in here */ continue; } else if(strchr(node[i]->content, '%')) #else if(strchr(node[i]->content, '%')) #endif /* WIN32 */ /* We need the format file (based on date) */ { struct tm *p; time_t l_time = time(0); char lfile[OS_FLSIZE + 1]; size_t ret; p = localtime(&l_time); lfile[OS_FLSIZE] = '\0'; ret = strftime(lfile, OS_FLSIZE, node[i]->content, p); if(ret == 0) { merror(PARSE_ERROR, ARGV0, node[i]->content); return(OS_INVALID); } os_strdup(node[i]->content, logf[pl].ffile); os_strdup(node[i]->content, logf[pl].file); } /* Normal file */ else { os_strdup(node[i]->content, logf[pl].file); } } /* Getting log format */ else if(strcasecmp(node[i]->element,xml_localfile_logformat) == 0) { os_strdup(node[i]->content, logf[pl].logformat); if(strcmp(logf[pl].logformat, "syslog") == 0) { } else if(strcmp(logf[pl].logformat, "generic") == 0) { } else if(strcmp(logf[pl].logformat, "snort-full") == 0) { } else if(strcmp(logf[pl].logformat, "snort-fast") == 0) { } else if(strcmp(logf[pl].logformat, "apache") == 0) { } else if(strcmp(logf[pl].logformat, "iis") == 0) { } else if(strcmp(logf[pl].logformat, "squid") == 0) { } else if(strcmp(logf[pl].logformat, "nmapg") == 0) { } else if(strcmp(logf[pl].logformat, "mysql_log") == 0) { } else if(strcmp(logf[pl].logformat, "ossecalert") == 0) { } else if(strcmp(logf[pl].logformat, "mssql_log") == 0) { } else if(strcmp(logf[pl].logformat, "postgresql_log") == 0) { } else if(strcmp(logf[pl].logformat, "djb-multilog") == 0) { } else if(strcmp(logf[pl].logformat, "syslog-pipe") == 0) { } else if(strcmp(logf[pl].logformat, "command") == 0) { } else if(strcmp(logf[pl].logformat, "full_command") == 0) { } else if(strncmp(logf[pl].logformat, "multi-line", 10) == 0) { int x = 0; logf[pl].logformat+=10; while(logf[pl].logformat[0] == ' ') logf[pl].logformat++; if(logf[pl].logformat[0] != ':') { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } logf[pl].logformat++; while(*logf[pl].logformat == ' ') logf[pl].logformat++; while(logf[pl].logformat[x] >= '0' && logf[pl].logformat[x] <= '9') x++; while(logf[pl].logformat[x] == ' ') x++; if(logf[pl].logformat[x] != '\0') { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcmp(logf[pl].logformat, EVENTLOG) == 0) { } else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcasecmp(node[i]->element,xml_localfile_alias) == 0) { os_strdup(node[i]->content, logf[pl].alias); } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } /* Validating glob entries */ if(glob_set) { char *format; /* Getting log format */ if(logf[pl].logformat) { format = logf[pl].logformat; } else if(logf[glob_set -1].logformat) { format = logf[glob_set -1].logformat; } else { merror(MISS_LOG_FORMAT, ARGV0); return(OS_INVALID); } /* The last entry is always null on glob */ pl--; /* Setting format for all entries */ for(i = (glob_set -1); i<= pl; i++) { /* Every entry must be valid */ if(!logf[i].file) { merror(MISS_FILE, ARGV0); return(OS_INVALID); } if(logf[i].logformat == NULL) { logf[i].logformat = format; } } } /* Missing log format */ if(!logf[pl].logformat) { merror(MISS_LOG_FORMAT, ARGV0); return(OS_INVALID); } /* Missing file */ if(!logf[pl].file) { merror(MISS_FILE, ARGV0); return(OS_INVALID); } /* Verifying a valid event log config */ if(strcmp(logf[pl].logformat, EVENTLOG) == 0) { if((strcmp(logf[pl].file, "Application") != 0)&& (strcmp(logf[pl].file, "System") != 0)&& (strcmp(logf[pl].file, "Security") != 0)) { /* Invalid event log */ merror(NSTD_EVTLOG, ARGV0, logf[pl].file); return(0); } } if((strcmp(logf[pl].logformat, "command") == 0)|| (strcmp(logf[pl].logformat, "full_command") == 0)) { if(!logf[pl].command) { merror("%s: ERROR: Missing 'command' argument. " "This option will be ignored.", ARGV0); } } return(0); }
int Read_CSyslog(XML_NODE node, void *config, void *config2) { int i = 0,s = 0; /* XML definitions */ char *xml_syslog_server = "server"; char *xml_syslog_port = "port"; char *xml_syslog_format = "format"; char *xml_syslog_level = "level"; char *xml_syslog_id = "rule_id"; char *xml_syslog_group = "group"; char *xml_syslog_location = "event_location"; GeneralConfig *gen_config = (GeneralConfig *)config; SyslogConfig **syslog_config = (SyslogConfig **)gen_config->data; /* Getting Granular mail_to size */ if(syslog_config) { while(syslog_config[s]) s++; } /* Allocating the memory for the config. */ os_realloc(syslog_config, (s + 2) * sizeof(SyslogConfig *), syslog_config); os_calloc(1, sizeof(SyslogConfig), syslog_config[s]); syslog_config[s + 1] = NULL; /* Zeroing the elements. */ syslog_config[s]->server = NULL; syslog_config[s]->rule_id = NULL; syslog_config[s]->group = NULL; syslog_config[s]->location = NULL; syslog_config[s]->level = 0; syslog_config[s]->port = "514"; syslog_config[s]->format = DEFAULT_CSYSLOG; /* local 0 facility (16) + severity 4 - warning. --default */ syslog_config[s]->priority = (16 * 8) + 4; while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } else if(strcmp(node[i]->element, xml_syslog_level) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } syslog_config[s]->level = atoi(node[i]->content); } else if(strcmp(node[i]->element, xml_syslog_port) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } os_strdup(node[i]->content, syslog_config[s]->port); } else if(strcmp(node[i]->element, xml_syslog_server) == 0) { os_strdup(node[i]->content, syslog_config[s]->server); } else if(strcmp(node[i]->element, xml_syslog_id) == 0) { int r_id = 0; char *str_pt = node[i]->content; while(*str_pt != '\0') { /* We allow spaces in between */ if(*str_pt == ' ') { str_pt++; continue; } /* If is digit, we get the value * and search for the next digit * available */ else if(isdigit((int)*str_pt)) { int id_i = 0; r_id = atoi(str_pt); debug1("%s: DEBUG: Adding '%d' to syslog alerting", ARGV0, r_id); if(syslog_config[s]->rule_id) { while(syslog_config[s]->rule_id[id_i]) id_i++; } os_realloc(syslog_config[s]->rule_id, (id_i +2) * sizeof(int), syslog_config[s]->rule_id); syslog_config[s]->rule_id[id_i + i] = 0; syslog_config[s]->rule_id[id_i] = r_id; str_pt = strchr(str_pt, ','); if(str_pt) { str_pt++; } else { break; } } /* Checking for duplicate commas */ else if(*str_pt == ',') { str_pt++; continue; } else { break; } } } else if(strcmp(node[i]->element, xml_syslog_format) == 0) { if(strcmp(node[i]->content, "default") == 0) { /* Default is full format */ } else if (strcmp(node[i]->content, "cef") == 0) { /* Enable the CEF format */ syslog_config[s]->format = CEF_CSYSLOG; } else if (strcmp(node[i]->content, "json") == 0) { /* Enable the JSON format */ syslog_config[s]->format = JSON_CSYSLOG; } else if (strcmp(node[i]->content, "splunk") == 0) { /* Enable the Splunk Key/Value format */ syslog_config[s]->format = SPLUNK_CSYSLOG; } else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_syslog_location) == 0) { os_calloc(1, sizeof(OSMatch),syslog_config[s]->location); if(!OSMatch_Compile(node[i]->content, syslog_config[s]->location, 0)) { merror(REGEX_COMPILE, ARGV0, node[i]->content, syslog_config[s]->location->error); return(-1); } } else if(strcmp(node[i]->element, xml_syslog_group) == 0) { os_calloc(1, sizeof(OSMatch),syslog_config[s]->group); if(!OSMatch_Compile(node[i]->content, syslog_config[s]->group, 0)) { merror(REGEX_COMPILE, ARGV0, node[i]->content, syslog_config[s]->group->error); return(-1); } } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } /* We must have at least one entry set */ if(!syslog_config[s]->server) { merror(XML_INV_CSYSLOG, ARGV0); return(OS_INVALID); } gen_config->data = syslog_config; return(0); }
int Read_Syscheck(XML_NODE node, void *configp, void *mailp) { int i = 0; /* XML Definitions */ char *xml_directories = "directories"; char *xml_registry = "windows_registry"; char *xml_time = "frequency"; char *xml_scanday = "scan_day"; char *xml_scantime = "scan_time"; char *xml_ignore = "ignore"; char *xml_registry_ignore = "registry_ignore"; char *xml_auto_ignore = "auto_ignore"; char *xml_alert_new_files = "alert_new_files"; char *xml_disabled = "disabled"; char *xml_scan_on_start = "scan_on_start"; char *xml_prefilter_cmd = "prefilter_cmd"; /* Configuration example <directories check_all="yes">/etc,/usr/bin</directories> <directories check_owner="yes" check_group="yes" check_perm="yes" check_sum="yes">/var/log</directories> */ config *syscheck; syscheck = (config *)configp; while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } /* Getting directories */ else if(strcmp(node[i]->element,xml_directories) == 0) { char dirs[OS_MAXSTR]; #ifdef WIN32 ExpandEnvironmentStrings(node[i]->content, dirs, sizeof(dirs) -1); #else strncpy(dirs, node[i]->content, sizeof(dirs) -1); #endif if(!read_attr(syscheck, dirs, node[i]->attributes, node[i]->values)) { return(OS_INVALID); } } /* Getting windows registry */ else if(strcmp(node[i]->element,xml_registry) == 0) { #ifdef WIN32 if(!read_reg(syscheck, node[i]->content)) { return(OS_INVALID); } #endif } /* Getting frequency */ else if(strcmp(node[i]->element,xml_time) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } syscheck->time = atoi(node[i]->content); } /* Getting scan time */ else if(strcmp(node[i]->element,xml_scantime) == 0) { syscheck->scan_time = OS_IsValidUniqueTime(node[i]->content); if(!syscheck->scan_time) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } /* Getting scan day */ else if(strcmp(node[i]->element,xml_scanday) == 0) { syscheck->scan_day = OS_IsValidDay(node[i]->content); if(!syscheck->scan_day) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } /* Getting if xml_scan_on_start. */ else if(strcmp(node[i]->element, xml_scan_on_start) == 0) { if(strcmp(node[i]->content, "yes") == 0) syscheck->scan_on_start = 1; else if(strcmp(node[i]->content, "no") == 0) syscheck->scan_on_start = 0; else { merror(XML_VALUEERR,ARGV0, node[i]->element, node[i]->content); return(OS_INVALID); } } /* Getting if disabled. */ else if(strcmp(node[i]->element,xml_disabled) == 0) { if(strcmp(node[i]->content, "yes") == 0) syscheck->disabled = 1; else if(strcmp(node[i]->content, "no") == 0) syscheck->disabled = 0; else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } /* Getting file/dir ignore */ else if(strcmp(node[i]->element,xml_ignore) == 0) { int ign_size = 0; /* For Windows, we attempt to expand environment variables. */ #ifdef WIN32 char *new_ig = NULL; os_calloc(2048, sizeof(char), new_ig); ExpandEnvironmentStrings(node[i]->content, new_ig, 2047); free(node[i]->content); node[i]->content = new_ig; #endif /* Adding if regex */ if(node[i]->attributes && node[i]->values) { if(node[i]->attributes[0] && node[i]->values[0] && (strcmp(node[i]->attributes[0], "type") == 0) && (strcmp(node[i]->values[0], "sregex") == 0)) { OSMatch *mt_pt; if(!syscheck->ignore_regex) { os_calloc(2, sizeof(OSMatch *),syscheck->ignore_regex); syscheck->ignore_regex[0] = NULL; syscheck->ignore_regex[1] = NULL; } else { while(syscheck->ignore_regex[ign_size] != NULL) ign_size++; os_realloc(syscheck->ignore_regex, sizeof(OSMatch *)*(ign_size +2), syscheck->ignore_regex); syscheck->ignore_regex[ign_size +1] = NULL; } os_calloc(1, sizeof(OSMatch), syscheck->ignore_regex[ign_size]); if(!OSMatch_Compile(node[i]->content, syscheck->ignore_regex[ign_size], 0)) { mt_pt = (OSMatch *)syscheck->ignore_regex[ign_size]; merror(REGEX_COMPILE, ARGV0, node[i]->content, mt_pt->error); return(0); } } else { merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]); return(OS_INVALID); } } /* Adding if simple entry -- checking for duplicates */ else if(!os_IsStrOnArray(node[i]->content, syscheck->ignore)) { if(!syscheck->ignore) { os_calloc(2, sizeof(char *), syscheck->ignore); syscheck->ignore[0] = NULL; syscheck->ignore[1] = NULL; } else { while(syscheck->ignore[ign_size] != NULL) ign_size++; os_realloc(syscheck->ignore, sizeof(char *)*(ign_size +2), syscheck->ignore); syscheck->ignore[ign_size +1] = NULL; } os_strdup(node[i]->content,syscheck->ignore[ign_size]); } } /* Getting registry ignore list */ else if(strcmp(node[i]->element,xml_registry_ignore) == 0) { #ifdef WIN32 int ign_size = 0; /* Adding if regex */ if(node[i]->attributes && node[i]->values) { if(node[i]->attributes[0] && node[i]->values[0] && (strcmp(node[i]->attributes[0], "type") == 0) && (strcmp(node[i]->values[0], "sregex") == 0)) { OSMatch *mt_pt; if(!syscheck->registry_ignore_regex) { os_calloc(2, sizeof(OSMatch *), syscheck->registry_ignore_regex); syscheck->registry_ignore_regex[0] = NULL; syscheck->registry_ignore_regex[1] = NULL; } else { while(syscheck->registry_ignore_regex[ign_size] !=NULL) ign_size++; os_realloc(syscheck->registry_ignore_regex, sizeof(OSMatch *)*(ign_size +2), syscheck->registry_ignore_regex); syscheck->registry_ignore_regex[ign_size +1] = NULL; } os_calloc(1, sizeof(OSMatch), syscheck->registry_ignore_regex[ign_size]); if(!OSMatch_Compile(node[i]->content, syscheck->registry_ignore_regex[ign_size], 0)) { mt_pt = (OSMatch *) syscheck->registry_ignore_regex[ign_size]; merror(REGEX_COMPILE, ARGV0, node[i]->content, mt_pt->error); return(0); } } else { merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]); return(OS_INVALID); } } /* We do not add duplicated entries */ else if(!os_IsStrOnArray(node[i]->content, syscheck->registry_ignore)) { if(!syscheck->registry_ignore) { os_calloc(2, sizeof(char *), syscheck->registry_ignore); syscheck->registry_ignore[0] = NULL; syscheck->registry_ignore[1] = NULL; } else { while(syscheck->registry_ignore[ign_size] != NULL) ign_size++; os_realloc(syscheck->registry_ignore, sizeof(char *)*(ign_size +2), syscheck->registry_ignore); syscheck->registry_ignore[ign_size +1] = NULL; } os_strdup(node[i]->content,syscheck->registry_ignore[ign_size]); } #endif } else if(strcmp(node[i]->element,xml_auto_ignore) == 0) { /* auto_ignore is not read here. */ } else if(strcmp(node[i]->element,xml_alert_new_files) == 0) { /* alert_new_files option is not read here. */ } else if(strcmp(node[i]->element,xml_prefilter_cmd) == 0) { char cmd[OS_MAXSTR]; struct stat statbuf; #ifdef WIN32 ExpandEnvironmentStrings(node[i]->content, cmd, sizeof(cmd) -1); #else strncpy(cmd, node[i]->content, sizeof(cmd)-1); #endif if (strlen(cmd) > 0) { char statcmd[OS_MAXSTR]; char *ix; strncpy(statcmd, cmd, sizeof(statcmd)-1); if (NULL != (ix = strchr(statcmd, ' '))) { *ix = '\0'; } if (stat(statcmd, &statbuf) == 0) { // More checks needed (perms, owner, etc.) os_calloc(1, strlen(cmd)+1, syscheck->prefilter_cmd); strncpy(syscheck->prefilter_cmd, cmd, strlen(cmd)); } else { merror(XML_VALUEERR,ARGV0, node[i]->element, node[i]->content); return(OS_INVALID); } } } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } return(0); }
int Read_Alerts(XML_NODE node, void *configp, void *mailp) { int i = 0; /* XML definitions */ char *xml_email_level = "email_alert_level"; char *xml_log_level = "log_alert_level"; #ifdef GEOIP /* GeoIP */ char *xml_log_geoip = "use_geoip"; #endif _Config *Config; Config = (_Config *)configp; while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } /* Mail notification */ else if(strcmp(node[i]->element, xml_email_level) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } Config->mailbylevel = atoi(node[i]->content); } /* Log alerts */ else if(strcmp(node[i]->element, xml_log_level) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } Config->logbylevel = atoi(node[i]->content); } #ifdef GEOIP /* Enable GeoIP */ else if(strcmp(node[i]->element, xml_log_geoip) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->loggeoip = 1;} else if(strcmp(node[i]->content, "no") == 0) {if(Config) Config->loggeoip = 0;} else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } #endif else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } return(0); }
/* Read the rootcheck config */ int Read_Rootcheck_Config(const char *cfgfile) { OS_XML xml; #ifdef OSSECHIDS char *str = NULL; #endif /* XML Definitions */ const char *(xml_base_dir[]) = {xml_rootcheck, "base_directory", NULL}; const char *(xml_workdir[]) = {xml_rootcheck, "work_directory", NULL}; const char *(xml_rootkit_files[]) = {xml_rootcheck, "rootkit_files", NULL}; const char *(xml_rootkit_trojans[]) = {xml_rootcheck, "rootkit_trojans", NULL}; const char *(xml_rootkit_unixaudit[]) = {xml_rootcheck, "system_audit", NULL}; const char *(xml_rootkit_winaudit[]) = {xml_rootcheck, "windows_audit", NULL}; const char *(xml_rootkit_winapps[]) = {xml_rootcheck, "windows_apps", NULL}; const char *(xml_rootkit_winmalware[]) = {xml_rootcheck, "windows_malware", NULL}; const char *(xml_scanall[]) = {xml_rootcheck, "scanall", NULL}; const char *(xml_readall[]) = {xml_rootcheck, "readall", NULL}; #ifdef OSSECHIDS const char *(xml_time[]) = {xml_rootcheck, "frequency", NULL}; #endif const char *(xml_check_dev[]) = {xml_rootcheck, "check_dev", NULL}; const char *(xml_check_files[]) = {xml_rootcheck, "check_files", NULL}; const char *(xml_check_if[]) = {xml_rootcheck, "check_if", NULL}; const char *(xml_check_pids[]) = {xml_rootcheck, "check_pids", NULL}; const char *(xml_check_ports[]) = {xml_rootcheck, "check_ports", NULL}; const char *(xml_check_sys[]) = {xml_rootcheck, "check_sys", NULL}; const char *(xml_check_trojans[]) = {xml_rootcheck, "check_trojans", NULL}; #ifdef WIN32 const char *(xml_check_winapps[]) = {xml_rootcheck, "check_winapps", NULL}; const char *(xml_check_winaudit[]) = {xml_rootcheck, "check_winaudit", NULL}; const char *(xml_check_winmalware[]) = {xml_rootcheck, "check_winmalware", NULL}; #else const char *(xml_check_unixaudit[]) = {xml_rootcheck, "check_unixaudit", NULL}; #endif #ifdef OSSECHIDS /* :) */ xml_time[2] = NULL; #endif if (OS_ReadXML(cfgfile, &xml) < 0) { merror("config_op: XML error: %s", xml.err); return (OS_INVALID); } if (!OS_RootElementExist(&xml, xml_rootcheck)) { OS_ClearXML(&xml); merror("%s: Rootcheck configuration not found. ", ARGV0); return (-1); } #ifdef OSSECHIDS /* time */ str = OS_GetOneContentforElement(&xml, xml_time); if (str) { if (!OS_StrIsNum(str)) { merror("Invalid frequency time '%s' for the rootkit " "detection (must be int).", str); return (OS_INVALID); } rootcheck.time = atoi(str); free(str); str = NULL; } #endif /* OSSECHIDS */ /* Scan all flags */ if (!rootcheck.scanall) { rootcheck.scanall = eval_bool2(OS_GetOneContentforElement(&xml, xml_scanall), 0); } /* Read all flags */ if (!rootcheck.readall) { rootcheck.readall = eval_bool2(OS_GetOneContentforElement(&xml, xml_readall), 0); } /* Get work directory */ if (!rootcheck.workdir) { rootcheck.workdir = OS_GetOneContentforElement(&xml, xml_workdir); } rootcheck.rootkit_files = OS_GetOneContentforElement (&xml, xml_rootkit_files); rootcheck.rootkit_trojans = OS_GetOneContentforElement (&xml, xml_rootkit_trojans); rootcheck.unixaudit = OS_GetContents (&xml, xml_rootkit_unixaudit); rootcheck.winaudit = OS_GetOneContentforElement (&xml, xml_rootkit_winaudit); rootcheck.winapps = OS_GetOneContentforElement (&xml, xml_rootkit_winapps); rootcheck.winmalware = OS_GetOneContentforElement (&xml, xml_rootkit_winmalware); rootcheck.basedir = OS_GetOneContentforElement(&xml, xml_base_dir); rootcheck.checks.rc_dev = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_dev), 1); rootcheck.checks.rc_files = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_files), 1); rootcheck.checks.rc_if = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_if), 1); rootcheck.checks.rc_pids = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_pids), 1); rootcheck.checks.rc_ports = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_ports), 1); rootcheck.checks.rc_sys = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_sys), 1); rootcheck.checks.rc_trojans = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_trojans), 1); #ifdef WIN32 rootcheck.checks.rc_winapps = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_winapps), 1); rootcheck.checks.rc_winaudit = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_winaudit), 1); rootcheck.checks.rc_winmalware = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_winmalware), 1); #else rootcheck.checks.rc_unixaudit = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_unixaudit), 1); #endif /* WIN32 */ OS_ClearXML(&xml); return (0); }
/* Rules_OP_ReadRules, v0.3, 2005/03/21 * Read the log rules. * v0.3: Fixed many memory problems. */ int OS_ReadXMLRules(char *rulefile, void *(*ruleact_function)(RuleInfo *rule, void *data), void *data) { OS_XML xml; XML_NODE node = NULL; /** XML variables **/ /* These are the available options for the rule configuration */ char *xml_group = "group"; char *xml_rule = "rule"; char *xml_regex = "regex"; char *xml_match = "match"; char *xml_decoded = "decoded_as"; char *xml_category = "category"; char *xml_cve = "cve"; char *xml_info = "info"; char *xml_day_time = "time"; char *xml_week_day = "weekday"; char *xml_comment = "description"; char *xml_ignore = "ignore"; char *xml_check_if_ignored = "check_if_ignored"; char *xml_srcip = "srcip"; char *xml_srcport = "srcport"; char *xml_dstip = "dstip"; char *xml_dstport = "dstport"; char *xml_user = "******"; char *xml_url = "url"; char *xml_id = "id"; char *xml_data = "extra_data"; char *xml_hostname = "hostname"; char *xml_program_name = "program_name"; char *xml_status = "status"; char *xml_action = "action"; char *xml_compiled = "compiled_rule"; char *xml_if_sid = "if_sid"; char *xml_if_group = "if_group"; char *xml_if_level = "if_level"; char *xml_fts = "if_fts"; char *xml_if_matched_regex = "if_matched_regex"; char *xml_if_matched_group = "if_matched_group"; char *xml_if_matched_sid = "if_matched_sid"; char *xml_same_source_ip = "same_source_ip"; char *xml_same_src_port = "same_src_port"; char *xml_same_dst_port = "same_dst_port"; char *xml_same_user = "******"; char *xml_same_location = "same_location"; char *xml_same_id = "same_id"; char *xml_dodiff = "check_diff"; char *xml_different_url = "different_url"; char *xml_notsame_source_ip = "not_same_source_ip"; char *xml_notsame_user = "******"; char *xml_notsame_agent = "not_same_agent"; char *xml_notsame_id = "not_same_id"; char *xml_options = "options"; char *rulepath; int i; /* If no directory in the rulefile add the default */ if((strchr(rulefile, '/')) == NULL) { /* Building the rule file name + path */ i = strlen(RULEPATH) + strlen(rulefile) + 2; rulepath = (char *)calloc(i,sizeof(char)); if(!rulepath) { ErrorExit(MEM_ERROR,ARGV0); } snprintf(rulepath,i,"%s/%s",RULEPATH,rulefile); } else { os_strdup(rulefile, rulepath); debug1("%s is the rulefile", rulefile); debug1("Not modifing the rule path"); } /* Reading the XML */ if(OS_ReadXML(rulepath,&xml) < 0) { merror(XML_ERROR, __local_name, rulepath, xml.err, xml.err_line); free(rulepath); return(-1); } /* Debug wrapper */ debug1("%s: DEBUG: read xml for rule '%s'.", __local_name, rulepath); /* Applying any variable found */ if(OS_ApplyVariables(&xml) != 0) { merror(XML_ERROR_VAR, __local_name, rulepath, xml.err); return(-1); } /* Debug wrapper */ debug1("%s: DEBUG: XML Variables applied.", __local_name); /* Getting the root elements */ node = OS_GetElementsbyNode(&xml, NULL); if(!node) { merror(CONFIG_ERROR, __local_name, rulepath); OS_ClearXML(&xml); return(-1); } /* Zeroing the rule memory -- not used anymore */ free(rulepath); /* Checking if there is any invalid global option */ i = 0; while(node[i]) { if(node[i]->element) { /* Verifying group */ if(strcasecmp(node[i]->element,xml_group) != 0) { merror(RL_INV_ROOT, __local_name, node[i]->element); OS_ClearXML(&xml); return(-1); } /* Checking group attribute -- only name is allowed */ if((!node[i]->attributes) || (!node[i]->values)|| (!node[i]->values[0]) || (!node[i]->attributes[0]) || (strcasecmp(node[i]->attributes[0],"name") != 0) || (node[i]->attributes[1])) { merror(RL_INV_ROOT, __local_name, node[i]->element); OS_ClearXML(&xml); return(-1); } } else { merror(XML_READ_ERROR, __local_name); OS_ClearXML(&xml); return(-1); } i++; } /* Getting the rules now */ i = 0; while(node[i]) { int j = 0; XML_NODE rule = NULL; /* Getting all rules for a global group */ rule = OS_GetElementsbyNode(&xml,node[i]); if(rule == NULL) { i++; continue; } /* Looping on the rules node */ while(rule[j]) { /* Rules options */ int k = 0; char *regex = NULL, *match = NULL, *url = NULL, *if_matched_regex = NULL, *if_matched_group = NULL, *user = NULL, *id = NULL, *srcport = NULL, *dstport = NULL, *status = NULL, *hostname = NULL, *extra_data = NULL, *program_name = NULL; RuleInfo *config_ruleinfo = NULL; XML_NODE rule_opt = NULL; /* Checking if the rule element is correct */ if((!rule[j]->element)|| (strcasecmp(rule[j]->element,xml_rule) != 0)) { merror(RL_INV_RULE, __local_name, node[i]->element); OS_ClearXML(&xml); return(-1); } /* Checking for the attributes of the rule */ if((!rule[j]->attributes) || (!rule[j]->values)) { merror(RL_INV_RULE, __local_name, rulefile); OS_ClearXML(&xml); return(-1); } /* Attribute block */ config_ruleinfo = _OS_AllocateRule(); if(_OS_GetRulesAttributes(rule[j]->attributes, rule[j]->values, config_ruleinfo) < 0) { merror(RL_INV_ATTR, __local_name, rulefile); OS_ClearXML(&xml); return(-1); } /* We must have an id or level */ if((config_ruleinfo->sigid == -1)||(config_ruleinfo->level == -1)) { merror(RL_INV_ATTR, __local_name, rulefile); OS_ClearXML(&xml); return(-1); } /* Here we can assign the group name to the rule. * The level is correct so the rule is probably going to * be fine */ os_strdup(node[i]->values[0], config_ruleinfo->group); /* Getting rules options */ rule_opt = OS_GetElementsbyNode(&xml, rule[j]); if(rule_opt == NULL) { merror(RL_NO_OPT, __local_name, config_ruleinfo->sigid); OS_ClearXML(&xml); return(-1); } /* Reading the whole rule block */ while(rule_opt[k]) { if((!rule_opt[k]->element)||(!rule_opt[k]->content)) { break; } else if(strcasecmp(rule_opt[k]->element,xml_regex)==0) { regex = os_LoadString(regex, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element,xml_match)==0) { match = os_LoadString(match, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element, xml_decoded) == 0) { } else if(strcasecmp(rule_opt[k]->element,xml_info) == 0) { config_ruleinfo->info= os_LoadString(config_ruleinfo->info, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element,xml_day_time) == 0) { config_ruleinfo->day_time = OS_IsValidTime(rule_opt[k]->content); if(!config_ruleinfo->day_time) { merror(INVALID_CONFIG, __local_name, rule_opt[k]->element, rule_opt[k]->content); return(-1); } if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) config_ruleinfo->alert_opts |= DO_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element,xml_week_day) == 0) { config_ruleinfo->week_day = OS_IsValidDay(rule_opt[k]->content); if(!config_ruleinfo->week_day) { merror(INVALID_CONFIG, __local_name, rule_opt[k]->element, rule_opt[k]->content); return(-1); } if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) config_ruleinfo->alert_opts |= DO_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element,xml_group) == 0) { config_ruleinfo->group = os_LoadString(config_ruleinfo->group, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element,xml_cve) == 0) { config_ruleinfo->cve= os_LoadString(config_ruleinfo->cve, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element,xml_comment) == 0) { char *newline; newline = strchr(rule_opt[k]->content, '\n'); if(newline) { *newline = ' '; } config_ruleinfo->comment= os_LoadString(config_ruleinfo->comment, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element,xml_srcip)==0) { int ip_s = 0; /* Getting size of source ip list */ while(config_ruleinfo->srcip && config_ruleinfo->srcip[ip_s]) { ip_s++; } config_ruleinfo->srcip = realloc(config_ruleinfo->srcip, (ip_s + 2) * sizeof(os_ip *)); /* Allocating memory for the individual entries */ os_calloc(1, sizeof(os_ip), config_ruleinfo->srcip[ip_s]); config_ruleinfo->srcip[ip_s +1] = NULL; /* Checking if the ip is valid */ if(!OS_IsValidIP(rule_opt[k]->content, config_ruleinfo->srcip[ip_s])) { merror(INVALID_IP, __local_name, rule_opt[k]->content); return(-1); } if(!(config_ruleinfo->alert_opts & DO_PACKETINFO)) config_ruleinfo->alert_opts |= DO_PACKETINFO; } else if(strcasecmp(rule_opt[k]->element,xml_dstip)==0) { int ip_s = 0; /* Getting size of source ip list */ while(config_ruleinfo->dstip && config_ruleinfo->dstip[ip_s]) { ip_s++; } config_ruleinfo->dstip = realloc(config_ruleinfo->dstip, (ip_s + 2) * sizeof(os_ip *)); /* Allocating memory for the individual entries */ os_calloc(1, sizeof(os_ip), config_ruleinfo->dstip[ip_s]); config_ruleinfo->dstip[ip_s +1] = NULL; /* Checking if the ip is valid */ if(!OS_IsValidIP(rule_opt[k]->content, config_ruleinfo->dstip[ip_s])) { merror(INVALID_IP, __local_name, rule_opt[k]->content); return(-1); } if(!(config_ruleinfo->alert_opts & DO_PACKETINFO)) config_ruleinfo->alert_opts |= DO_PACKETINFO; } else if(strcasecmp(rule_opt[k]->element,xml_user) == 0) { user = os_LoadString(user, rule_opt[k]->content); if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) config_ruleinfo->alert_opts |= DO_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element,xml_id) == 0) { id = os_LoadString(id, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element,xml_srcport) == 0) { srcport = os_LoadString(srcport, rule_opt[k]->content); if(!(config_ruleinfo->alert_opts & DO_PACKETINFO)) config_ruleinfo->alert_opts |= DO_PACKETINFO; } else if(strcasecmp(rule_opt[k]->element,xml_dstport) == 0) { dstport = os_LoadString(dstport, rule_opt[k]->content); if(!(config_ruleinfo->alert_opts & DO_PACKETINFO)) config_ruleinfo->alert_opts |= DO_PACKETINFO; } else if(strcasecmp(rule_opt[k]->element,xml_status)==0) { status = os_LoadString(status, rule_opt[k]->content); if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) config_ruleinfo->alert_opts |= DO_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element,xml_hostname) == 0) { hostname = os_LoadString(hostname, rule_opt[k]->content); if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) config_ruleinfo->alert_opts |= DO_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element,xml_data)==0) { extra_data = os_LoadString(extra_data, rule_opt[k]->content); if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) config_ruleinfo->alert_opts |= DO_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element, xml_program_name)==0) { program_name = os_LoadString(program_name, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element,xml_action) == 0) { config_ruleinfo->action = os_LoadString(config_ruleinfo->action, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element,xml_url) == 0) { url= os_LoadString(url, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element, xml_compiled)==0) { /* Not using this in here. */ } /* We allow these categories so far */ else if(strcasecmp(rule_opt[k]->element, xml_category)==0) { if(strcmp(rule_opt[k]->content, "firewall") == 0) { config_ruleinfo->category = FIREWALL; } else if(strcmp(rule_opt[k]->content, "ids") == 0) { config_ruleinfo->category = IDS; } else if(strcmp(rule_opt[k]->content, "syslog") == 0) { config_ruleinfo->category = SYSLOG; } else if(strcmp(rule_opt[k]->content, "web-log") == 0) { config_ruleinfo->category = WEBLOG; } else if(strcmp(rule_opt[k]->content, "squid") == 0) { config_ruleinfo->category = SQUID; } else if(strcmp(rule_opt[k]->content,"windows") == 0) { config_ruleinfo->category = WINDOWS; } else if(strcmp(rule_opt[k]->content,"ossec") == 0) { config_ruleinfo->category = OSSEC_RL; } else { merror(INVALID_CAT, __local_name, rule_opt[k]->content); return(-1); } } else if(strcasecmp(rule_opt[k]->element,xml_if_sid)==0) { config_ruleinfo->if_sid= os_LoadString(config_ruleinfo->if_sid, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element,xml_if_level)==0) { if(!OS_StrIsNum(rule_opt[k]->content)) { merror(INVALID_CONFIG, __local_name, xml_if_level, rule_opt[k]->content); return(-1); } config_ruleinfo->if_level= os_LoadString(config_ruleinfo->if_level, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element,xml_if_group)==0) { config_ruleinfo->if_group= os_LoadString(config_ruleinfo->if_group, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element, xml_if_matched_regex) == 0) { config_ruleinfo->context = 1; if_matched_regex= os_LoadString(if_matched_regex, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element, xml_if_matched_group) == 0) { config_ruleinfo->context = 1; if_matched_group= os_LoadString(if_matched_group, rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element, xml_if_matched_sid) == 0) { config_ruleinfo->context = 1; if(!OS_StrIsNum(rule_opt[k]->content)) { merror(INVALID_CONFIG, __local_name, rule_opt[k]->element, rule_opt[k]->content); return(-1); } config_ruleinfo->if_matched_sid = atoi(rule_opt[k]->content); } else if(strcasecmp(rule_opt[k]->element, xml_same_source_ip)==0) { config_ruleinfo->context_opts|= SAME_SRCIP; } else if(strcasecmp(rule_opt[k]->element, xml_same_src_port)==0) { config_ruleinfo->context_opts|= SAME_SRCPORT; if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) config_ruleinfo->alert_opts |= SAME_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element, xml_dodiff)==0) { config_ruleinfo->context++; config_ruleinfo->context_opts|= SAME_DODIFF; if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { config_ruleinfo->alert_opts |= DO_EXTRAINFO; } } else if(strcasecmp(rule_opt[k]->element, xml_same_dst_port) == 0) { config_ruleinfo->context_opts|= SAME_DSTPORT; if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) config_ruleinfo->alert_opts |= SAME_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element, xml_notsame_source_ip)==0) { config_ruleinfo->context_opts&= NOT_SAME_SRCIP; } else if(strcmp(rule_opt[k]->element, xml_same_id) == 0) { config_ruleinfo->context_opts|= SAME_ID; } else if(strcmp(rule_opt[k]->element, xml_different_url) == 0) { config_ruleinfo->context_opts|= DIFFERENT_URL; if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) config_ruleinfo->alert_opts |= SAME_EXTRAINFO; } else if(strcmp(rule_opt[k]->element,xml_notsame_id) == 0) { config_ruleinfo->context_opts&= NOT_SAME_ID; } else if(strcasecmp(rule_opt[k]->element, xml_fts) == 0) { config_ruleinfo->alert_opts |= DO_FTS; } else if(strcasecmp(rule_opt[k]->element, xml_same_user)==0) { config_ruleinfo->context_opts|= SAME_USER; if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) config_ruleinfo->alert_opts |= SAME_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element, xml_notsame_user)==0) { config_ruleinfo->context_opts&= NOT_SAME_USER; } else if(strcasecmp(rule_opt[k]->element, xml_same_location)==0) { config_ruleinfo->context_opts|= SAME_LOCATION; if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) config_ruleinfo->alert_opts |= SAME_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element, xml_notsame_agent)==0) { config_ruleinfo->context_opts&= NOT_SAME_AGENT; } else if(strcasecmp(rule_opt[k]->element, xml_options) == 0) { if(strcmp("alert_by_email", rule_opt[k]->content) == 0) { if(!(config_ruleinfo->alert_opts & DO_MAILALERT)) { config_ruleinfo->alert_opts|= DO_MAILALERT; } } else if(strcmp("no_email_alert", rule_opt[k]->content) == 0) { if(config_ruleinfo->alert_opts & DO_MAILALERT) { config_ruleinfo->alert_opts&=0xfff-DO_MAILALERT; } } else if(strcmp("log_alert", rule_opt[k]->content) == 0) { if(!(config_ruleinfo->alert_opts & DO_LOGALERT)) { config_ruleinfo->alert_opts|= DO_LOGALERT; } } else if(strcmp("no_log", rule_opt[k]->content) == 0) { if(config_ruleinfo->alert_opts & DO_LOGALERT) { config_ruleinfo->alert_opts &=0xfff-DO_LOGALERT; } } else if(strcmp("no_ar", rule_opt[k]->content) == 0) { if(!(config_ruleinfo->alert_opts & NO_AR)) { config_ruleinfo->alert_opts|= NO_AR; } } else { merror(XML_VALUEERR, __local_name, xml_options, rule_opt[k]->content); merror(INVALID_ELEMENT, __local_name, rule_opt[k]->element, rule_opt[k]->content); OS_ClearXML(&xml); return(-1); } } else if(strcasecmp(rule_opt[k]->element, xml_ignore) == 0) { if(strstr(rule_opt[k]->content, "user") != NULL) { config_ruleinfo->ignore|=FTS_USER; } if(strstr(rule_opt[k]->content, "srcip") != NULL) { config_ruleinfo->ignore|=FTS_SRCIP; } if(strstr(rule_opt[k]->content, "dstip") != NULL) { config_ruleinfo->ignore|=FTS_DSTIP; } if(strstr(rule_opt[k]->content, "id") != NULL) { config_ruleinfo->ignore|=FTS_ID; } if(strstr(rule_opt[k]->content,"location")!= NULL) { config_ruleinfo->ignore|=FTS_LOCATION; } if(strstr(rule_opt[k]->content,"data")!= NULL) { config_ruleinfo->ignore|=FTS_DATA; } if(strstr(rule_opt[k]->content, "name") != NULL) { config_ruleinfo->ignore|=FTS_NAME; } if(!config_ruleinfo->ignore) { merror(INVALID_ELEMENT, __local_name, rule_opt[k]->element, rule_opt[k]->content); return(-1); } } else if(strcasecmp(rule_opt[k]->element, xml_check_if_ignored) == 0) { if(strstr(rule_opt[k]->content, "user") != NULL) { config_ruleinfo->ckignore|=FTS_USER; } if(strstr(rule_opt[k]->content, "srcip") != NULL) { config_ruleinfo->ckignore|=FTS_SRCIP; } if(strstr(rule_opt[k]->content, "dstip") != NULL) { config_ruleinfo->ckignore|=FTS_DSTIP; } if(strstr(rule_opt[k]->content, "id") != NULL) { config_ruleinfo->ckignore|=FTS_ID; } if(strstr(rule_opt[k]->content,"location")!= NULL) { config_ruleinfo->ckignore|=FTS_LOCATION; } if(strstr(rule_opt[k]->content,"data")!= NULL) { config_ruleinfo->ignore|=FTS_DATA; } if(strstr(rule_opt[k]->content, "name") != NULL) { config_ruleinfo->ckignore|=FTS_NAME; } if(!config_ruleinfo->ckignore) { merror(INVALID_ELEMENT, __local_name, rule_opt[k]->element, rule_opt[k]->content); return(-1); } } /* XXX As new features are added into ../analysisd/rules.c * This code needs to be updated to match, but is out of date * it's become a nightmare to correct with out just make the * problem for someone later. * * This hack will allow any crap xml to pass without an * error. The correct fix is to refactor the code so that * ../analysisd/rules* and this code are not duplicates * else { merror(XML_INVELEM, __local_name, rule_opt[k]->element); OS_ClearXML(&xml); return(-1); } */ k++; } /* Checking for a valid use of frequency */ if((config_ruleinfo->context_opts || config_ruleinfo->frequency) && !config_ruleinfo->context) { merror("%s: Invalid use of frequency/context options. " "Missing if_matched on rule '%d'.", __local_name, config_ruleinfo->sigid); OS_ClearXML(&xml); return(-1); } /* If if_matched_group we must have a if_sid or if_group */ if(if_matched_group) { if(!config_ruleinfo->if_sid && !config_ruleinfo->if_group) { os_strdup(if_matched_group, config_ruleinfo->if_group); } } /* If_matched_sid, we need to get the if_sid */ if(config_ruleinfo->if_matched_sid && !config_ruleinfo->if_sid && !config_ruleinfo->if_group) { os_calloc(16, sizeof(char), config_ruleinfo->if_sid); snprintf(config_ruleinfo->if_sid, 15, "%d", config_ruleinfo->if_matched_sid); } /* Checking the regexes */ if(regex) { os_calloc(1, sizeof(OSRegex), config_ruleinfo->regex); if(!OSRegex_Compile(regex, config_ruleinfo->regex, 0)) { merror(REGEX_COMPILE, __local_name, regex, config_ruleinfo->regex->error); return(-1); } free(regex); regex = NULL; } /* Adding in match */ if(match) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->match); if(!OSMatch_Compile(match, config_ruleinfo->match, 0)) { merror(REGEX_COMPILE, __local_name, match, config_ruleinfo->match->error); return(-1); } free(match); match = NULL; } /* Adding in id */ if(id) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->id); if(!OSMatch_Compile(id, config_ruleinfo->id, 0)) { merror(REGEX_COMPILE, __local_name, id, config_ruleinfo->id->error); return(-1); } free(id); id = NULL; } /* Adding srcport */ if(srcport) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->srcport); if(!OSMatch_Compile(srcport, config_ruleinfo->srcport, 0)) { merror(REGEX_COMPILE, __local_name, srcport, config_ruleinfo->id->error); return(-1); } free(srcport); srcport = NULL; } /* Adding dstport */ if(dstport) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->dstport); if(!OSMatch_Compile(dstport, config_ruleinfo->dstport, 0)) { merror(REGEX_COMPILE, __local_name, dstport, config_ruleinfo->id->error); return(-1); } free(dstport); dstport = NULL; } /* Adding in status */ if(status) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->status); if(!OSMatch_Compile(status, config_ruleinfo->status, 0)) { merror(REGEX_COMPILE, __local_name, status, config_ruleinfo->status->error); return(-1); } free(status); status = NULL; } /* Adding in hostname */ if(hostname) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->hostname); if(!OSMatch_Compile(hostname, config_ruleinfo->hostname,0)) { merror(REGEX_COMPILE, __local_name, hostname, config_ruleinfo->hostname->error); return(-1); } free(hostname); hostname = NULL; } /* Adding extra data */ if(extra_data) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->extra_data); if(!OSMatch_Compile(extra_data, config_ruleinfo->extra_data, 0)) { merror(REGEX_COMPILE, __local_name, extra_data, config_ruleinfo->extra_data->error); return(-1); } free(extra_data); extra_data = NULL; } /* Adding in program name */ if(program_name) { os_calloc(1,sizeof(OSMatch),config_ruleinfo->program_name); if(!OSMatch_Compile(program_name, config_ruleinfo->program_name,0)) { merror(REGEX_COMPILE, __local_name, program_name, config_ruleinfo->program_name->error); return(-1); } free(program_name); program_name = NULL; } /* Adding in user */ if(user) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->user); if(!OSMatch_Compile(user, config_ruleinfo->user, 0)) { merror(REGEX_COMPILE, __local_name, user, config_ruleinfo->user->error); return(-1); } free(user); user = NULL; } /* Adding in url */ if(url) { os_calloc(1, sizeof(OSMatch), config_ruleinfo->url); if(!OSMatch_Compile(url, config_ruleinfo->url, 0)) { merror(REGEX_COMPILE, __local_name, url, config_ruleinfo->url->error); return(-1); } free(url); url = NULL; } /* Adding matched_group */ if(if_matched_group) { os_calloc(1,sizeof(OSMatch),config_ruleinfo->if_matched_group); if(!OSMatch_Compile(if_matched_group, config_ruleinfo->if_matched_group,0)) { merror(REGEX_COMPILE, __local_name, if_matched_group, config_ruleinfo->if_matched_group->error); return(-1); } free(if_matched_group); if_matched_group = NULL; } /* Adding matched_regex */ if(if_matched_regex) { os_calloc(1, sizeof(OSRegex), config_ruleinfo->if_matched_regex); if(!OSRegex_Compile(if_matched_regex, config_ruleinfo->if_matched_regex, 0)) { merror(REGEX_COMPILE, __local_name, if_matched_regex, config_ruleinfo->if_matched_regex->error); return(-1); } free(if_matched_regex); if_matched_regex = NULL; } /* Calling the function provided. */ ruleact_function(config_ruleinfo, data); j++; /* next rule */ } /* while(rule[j]) */ OS_ClearNode(rule); i++; } /* while (node[i]) */ /* Cleaning global node */ OS_ClearNode(node); OS_ClearXML(&xml); /* Done over here */ return(0); }
/** int _OS_GetRulesAttributes * Reads the rules attributes and assign them. */ int _OS_GetRulesAttributes(char **attributes, char **values, RuleInfo *ruleinfo_pt) { int k = 0; char *xml_id = "id"; char *xml_level = "level"; char *xml_maxsize = "maxsize"; char *xml_timeframe = "timeframe"; char *xml_frequency = "frequency"; char *xml_accuracy = "accuracy"; char *xml_noalert = "noalert"; char *xml_ignore_time = "ignore"; char *xml_overwrite = "overwrite"; /* Getting attributes */ while(attributes[k]) { if(!values[k]) { merror(RL_EMPTY_ATTR, __local_name, attributes[k]); return(-1); } /* Getting rule Id */ else if(strcasecmp(attributes[k], xml_id) == 0) { if(OS_StrIsNum(values[k]) && (strlen(values[k]) <= 6 )) { ruleinfo_pt->sigid = atoi(values[k]); } else { merror(XML_VALUEERR,__local_name, attributes[k], values[k]); return(-1); } } /* Getting level */ else if(strcasecmp(attributes[k],xml_level) == 0) { if(OS_StrIsNum(values[k]) && (strlen(values[k]) <= 3)) { ruleinfo_pt->level = atoi(values[k]); } else { merror(XML_VALUEERR,__local_name, attributes[k], values[k]); return(-1); } } /* Getting maxsize */ else if(strcasecmp(attributes[k],xml_maxsize) == 0) { if(OS_StrIsNum(values[k]) && (strlen(values[k]) <= 4)) { ruleinfo_pt->maxsize = atoi(values[k]); /* adding EXTRAINFO options */ if(ruleinfo_pt->maxsize > 0 && !(ruleinfo_pt->alert_opts & DO_EXTRAINFO)) { ruleinfo_pt->alert_opts |= DO_EXTRAINFO; } } else { merror(XML_VALUEERR,__local_name, attributes[k], values[k]); return(-1); } } /* Getting timeframe */ else if(strcasecmp(attributes[k],xml_timeframe) == 0) { if(OS_StrIsNum(values[k]) && (strlen(values[k]) <= 5)) { ruleinfo_pt->timeframe = atoi(values[k]); } else { merror(XML_VALUEERR,__local_name, attributes[k], values[k]); return(-1); } } /* Getting frequency */ else if(strcasecmp(attributes[k],xml_frequency) == 0) { if(OS_StrIsNum(values[k]) && (strlen(values[k]) <= 4)) { ruleinfo_pt->frequency = atoi(values[k]); } else { merror(XML_VALUEERR,__local_name, attributes[k], values[k]); return(-1); } } /* Rule accuracy */ else if(strcasecmp(attributes[k],xml_accuracy) == 0) { merror("%s: XXX: Use of 'accuracy' isn't supported. Ignoring.", __local_name); } /* Rule ignore_time */ else if(strcasecmp(attributes[k],xml_ignore_time) == 0) { if(OS_StrIsNum(values[k]) && (strlen(values[k]) <= 4)) { ruleinfo_pt->ignore_time = atoi(values[k]); } else { merror(XML_VALUEERR,__local_name, attributes[k], values[k]); return(-1); } } /* Rule noalert */ else if(strcasecmp(attributes[k],xml_noalert) == 0) { ruleinfo_pt->alert_opts |= NO_ALERT; } else if(strcasecmp(attributes[k], xml_overwrite) == 0) { if(strcmp(values[k], "yes") == 0) { ruleinfo_pt->alert_opts |= DO_OVERWRITE; } else if(strcmp(values[k], "no") == 0) { } else { merror(XML_VALUEERR,__local_name, attributes[k], values[k]); return(-1); } } else { merror(XML_INVELEM, __local_name, attributes[k]); return(-1); } k++; } return(0); }
int Read_EmailAlerts(XML_NODE node, void *configp, void *mailp) { int i = 0; int granto_size = 1; /* XML definitions */ char *xml_email_to = "email_to"; char *xml_email_format = "format"; char *xml_email_level = "level"; char *xml_email_id = "rule_id"; char *xml_email_group = "group"; char *xml_email_location = "event_location"; char *xml_email_donotdelay = "do_not_delay"; char *xml_email_donotgroup = "do_not_group"; MailConfig *Mail; Mail = (MailConfig *)mailp; if(!Mail) { return(0); } /* Getting Granular mail_to size */ if(Mail && Mail->gran_to) { char **ww; ww = Mail->gran_to; while(*ww != NULL) { ww++; granto_size++; } } if(Mail) { os_realloc(Mail->gran_to, sizeof(char *)*(granto_size +1), Mail->gran_to); os_realloc(Mail->gran_id, sizeof(int *)*(granto_size +1), Mail->gran_id); os_realloc(Mail->gran_level, sizeof(int)*(granto_size +1), Mail->gran_level); os_realloc(Mail->gran_set, sizeof(int)*(granto_size +1), Mail->gran_set); os_realloc(Mail->gran_format, sizeof(int)*(granto_size +1), Mail->gran_format); os_realloc(Mail->gran_location, sizeof(OSMatch)*(granto_size +1), Mail->gran_location); os_realloc(Mail->gran_group, sizeof(OSMatch)*(granto_size +1), Mail->gran_group); Mail->gran_to[granto_size -1] = NULL; Mail->gran_to[granto_size] = NULL; Mail->gran_id[granto_size -1] = NULL; Mail->gran_id[granto_size] = NULL; Mail->gran_location[granto_size -1] = NULL; Mail->gran_location[granto_size] = NULL; Mail->gran_group[granto_size -1] = NULL; Mail->gran_group[granto_size] = NULL; Mail->gran_level[granto_size -1] = 0; Mail->gran_level[granto_size] = 0; Mail->gran_format[granto_size -1] = FULL_FORMAT; Mail->gran_format[granto_size] = FULL_FORMAT; Mail->gran_set[granto_size -1] = 0; Mail->gran_set[granto_size] = 0; } while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } /* Mail notification */ else if(strcmp(node[i]->element, xml_email_level) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } Mail->gran_level[granto_size -1] = atoi(node[i]->content); } else if(strcmp(node[i]->element, xml_email_to) == 0) { os_strdup(node[i]->content, Mail->gran_to[granto_size -1]); } else if(strcmp(node[i]->element, xml_email_id) == 0) { int r_id = 0; char *str_pt = node[i]->content; while(*str_pt != '\0') { /* We allow spaces in between */ if(*str_pt == ' ') { str_pt++; continue; } /* If is digit, we get the value * and search for the next digit * available */ else if(isdigit((int)*str_pt)) { int id_i = 0; r_id = atoi(str_pt); debug1("%s: DEBUG: Adding '%d' to granular e-mail", ARGV0, r_id); if(!Mail->gran_id[granto_size -1]) { os_calloc(2,sizeof(int),Mail->gran_id[granto_size -1]); Mail->gran_id[granto_size -1][0] = 0; Mail->gran_id[granto_size -1][1] = 0; } else { while(Mail->gran_id[granto_size -1][id_i] != 0) { id_i++; } os_realloc(Mail->gran_id[granto_size -1], (id_i +2) * sizeof(int), Mail->gran_id[granto_size -1]); Mail->gran_id[granto_size -1][id_i +1] = 0; } Mail->gran_id[granto_size -1][id_i] = r_id; str_pt = strchr(str_pt, ','); if(str_pt) { str_pt++; } else { break; } } /* Checking for duplicate commas */ else if(*str_pt == ',') { str_pt++; continue; } else { break; } } } else if(strcmp(node[i]->element, xml_email_format) == 0) { if(strcmp(node[i]->content, "sms") == 0) { Mail->gran_format[granto_size -1] = SMS_FORMAT; } else if(strcmp(node[i]->content, "default") == 0) { /* Default is full format */ } else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_email_donotdelay) == 0) { if((Mail->gran_format[granto_size -1] != SMS_FORMAT) && (Mail->gran_format[granto_size -1] != DONOTGROUP)) { Mail->gran_format[granto_size -1] = FORWARD_NOW; } } else if(strcmp(node[i]->element, xml_email_donotgroup) == 0) { if(Mail->gran_format[granto_size -1] != SMS_FORMAT) { Mail->gran_format[granto_size -1] = DONOTGROUP; } } else if(strcmp(node[i]->element, xml_email_location) == 0) { os_calloc(1, sizeof(OSMatch),Mail->gran_location[granto_size -1]); if(!OSMatch_Compile(node[i]->content, Mail->gran_location[granto_size -1], 0)) { merror(REGEX_COMPILE, ARGV0, node[i]->content, Mail->gran_location[granto_size -1]->error); return(-1); } } else if(strcmp(node[i]->element, xml_email_group) == 0) { os_calloc(1, sizeof(OSMatch),Mail->gran_group[granto_size -1]); if(!OSMatch_Compile(node[i]->content, Mail->gran_group[granto_size -1], 0)) { merror(REGEX_COMPILE, ARGV0, node[i]->content, Mail->gran_group[granto_size -1]->error); return(-1); } } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } /* We must have at least one entry set */ if((Mail->gran_location[granto_size -1] == NULL && Mail->gran_level[granto_size -1] == 0 && Mail->gran_group[granto_size -1] == NULL && Mail->gran_id[granto_size -1] == NULL && Mail->gran_format[granto_size -1] == FULL_FORMAT) || Mail->gran_to[granto_size -1] == NULL) { merror(XML_INV_GRAN_MAIL, ARGV0); return(OS_INVALID); } return(0); }
/* GlobalConf v0.2: 2005/03/03 * v0.2: Changing to support the new OS_XML */ int Read_Global(XML_NODE node, void *configp, void *mailp) { int i = 0; /* White list size */ int white_size = 1; int hostname_white_size = 1; int mailto_size = 1; /* XML definitions */ char *xml_mailnotify = "email_notification"; char *xml_logall = "logall"; char *xml_integrity = "integrity_checking"; char *xml_rootcheckd = "rootkit_detection"; char *xml_hostinfo = "host_information"; char *xml_picviz = "picviz_output"; char *xml_picviz_socket = "picviz_socket"; char *xml_prelude = "prelude_output"; char *xml_prelude_profile = "prelude_profile"; char *xml_prelude_log_level = "prelude_log_level"; char *xml_zeromq_output = "zeromq_output"; char *xml_zeromq_output_uri = "zeromq_uri"; char *xml_stats = "stats"; char *xml_memorysize = "memory_size"; char *xml_white_list = "white_list"; char *xml_compress_alerts = "compress_alerts"; char *xml_custom_alert_output = "custom_alert_output"; char *xml_emailto = "email_to"; char *xml_emailfrom = "email_from"; char *xml_emailidsname = "email_idsname"; char *xml_smtpserver = "smtp_server"; char *xml_mailmaxperhour = "email_maxperhour"; #ifdef GEOIP /* GeoIP */ char *xml_geoip_db_path = "geoip_db_path"; char *xml_geoip6_db_path = "geoip6_db_path"; #endif _Config *Config; MailConfig *Mail; Config = (_Config *)configp; Mail = (MailConfig *)mailp; /* Getting right white_size */ if(Config && Config->white_list) { os_ip **ww; ww = Config->white_list; while(*ww != NULL) { white_size++; ww++; } } /* Getting right white_size */ if(Config && Config->hostname_white_list) { OSMatch **ww; ww = Config->hostname_white_list; while(*ww != NULL) { hostname_white_size++; ww++; } } /* Getting mail_to size */ if(Mail && Mail->to) { char **ww; ww = Mail->to; while(*ww != NULL) { mailto_size++; ww++; } } while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } else if(strcmp(node[i]->element, xml_custom_alert_output) == 0) { if(Config) { Config->custom_alert_output= 1; os_strdup(node[i]->content, Config->custom_alert_output_format); } } /* Mail notification */ else if(strcmp(node[i]->element, xml_mailnotify) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->mailnotify = 1; if(Mail) Mail->mn = 1; } else if(strcmp(node[i]->content, "no") == 0) { if(Config) Config->mailnotify = 0; if(Mail) Mail->mn = 0; } else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } /* Picviz support */ else if(strcmp(node[i]->element, xml_picviz) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->picviz = 1; } else if(strcmp(node[i]->content, "no") == 0) { if(Config) Config->picviz = 0; } else { merror(XML_VALUEERR,ARGV0,node[i]->element, node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_picviz_socket) == 0) { if(Config) { os_strdup(node[i]->content, Config->picviz_socket); } } /* Prelude support */ else if(strcmp(node[i]->element, xml_prelude) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->prelude = 1; } else if(strcmp(node[i]->content, "no") == 0) { if(Config) Config->prelude = 0; } else { merror(XML_VALUEERR,ARGV0,node[i]->element, node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_prelude_profile) == 0) { if(Config) { Config->prelude_profile = strdup(node[i]->content); } } else if(strcmp(node[i]->element, xml_prelude_log_level) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->prelude_log_level = atoi(node[i]->content); } } /* ZeroMQ output */ else if(strcmp(node[i]->element, xml_zeromq_output) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->zeromq_output = 1; } else if(strcmp(node[i]->content, "no") == 0) { if(Config) Config->zeromq_output = 0; } else { merror(XML_VALUEERR,ARGV0,node[i]->element, node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_zeromq_output_uri) == 0) { if(Config) { Config->zeromq_output_uri = strdup(node[i]->content); } } /* Log all */ else if(strcmp(node[i]->element, xml_logall) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->logall = 1;} else if(strcmp(node[i]->content, "no") == 0) {if(Config) Config->logall = 0;} else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } /* compress alerts */ else if(strcmp(node[i]->element, xml_compress_alerts) == 0) { /* removed from here -- compatility issues only */ } /* Integrity */ else if(strcmp(node[i]->element, xml_integrity) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->integrity = atoi(node[i]->content); } } /* rootcheck */ else if(strcmp(node[i]->element, xml_rootcheckd) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->rootcheck = atoi(node[i]->content); } } /* hostinfo */ else if(strcmp(node[i]->element, xml_hostinfo) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->hostinfo = atoi(node[i]->content); } } /* stats */ else if(strcmp(node[i]->element, xml_stats) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->stats = atoi(node[i]->content); } } else if(strcmp(node[i]->element, xml_memorysize) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->memorysize = atoi(node[i]->content); } } /* whitelist */ else if(strcmp(node[i]->element, xml_white_list) == 0) { /* Windows do not need it */ #ifndef WIN32 char *ip_address_regex = "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}/?" "([0-9]{0,2}|[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})$"; if(Config && OS_PRegex(node[i]->content, ip_address_regex)) { white_size++; Config->white_list = realloc(Config->white_list, sizeof(os_ip *)*white_size); if(!Config->white_list) { merror(MEM_ERROR, ARGV0); return(OS_INVALID); } os_calloc(1, sizeof(os_ip), Config->white_list[white_size -2]); Config->white_list[white_size -1] = NULL; if(!OS_IsValidIP(node[i]->content, Config->white_list[white_size -2])) { merror(INVALID_IP, ARGV0, node[i]->content); return(OS_INVALID); } } /* Adding hostname */ else if(Config) { hostname_white_size++; Config->hostname_white_list = realloc(Config->hostname_white_list, sizeof(OSMatch *)*hostname_white_size); if(!Config->hostname_white_list) { merror(MEM_ERROR, ARGV0); return(OS_INVALID); } os_calloc(1, sizeof(OSMatch), Config->hostname_white_list[hostname_white_size -2]); Config->hostname_white_list[hostname_white_size -1] = NULL; if(!OSMatch_Compile( node[i]->content, Config->hostname_white_list[hostname_white_size -2], 0)) { merror(REGEX_COMPILE, ARGV0, node[i]->content, Config->hostname_white_list [hostname_white_size -2]->error); return(-1); } } #endif } /* For the email now * email_to, email_from, idsname, smtp_Server and maxperhour. * We will use a separate structure for that. */ else if(strcmp(node[i]->element, xml_emailto) == 0) { #ifndef WIN32 if(!OS_PRegex(node[i]->content, "[a-zA-Z0-9\\._-]+@[a-zA-Z0-9\\._-]")) { merror("%s: ERROR: Invalid Email address: %s.", ARGV0, node[i]->content); return(OS_INVALID); } #endif if(Mail) { mailto_size++; Mail->to = realloc(Mail->to, sizeof(char *)*mailto_size); if(!Mail->to) { merror(MEM_ERROR, ARGV0); return(OS_INVALID); } os_strdup(node[i]->content, Mail->to[mailto_size - 2]); Mail->to[mailto_size - 1] = NULL; } } else if(strcmp(node[i]->element, xml_emailfrom) == 0) { if(Mail) { if(Mail->from) { free(Mail->from); } os_strdup(node[i]->content, Mail->from); } } else if(strcmp(node[i]->element, xml_emailidsname) == 0) { if(Mail) { if(Mail->idsname) { free(Mail->idsname); } os_strdup(node[i]->content, Mail->idsname); } } else if(strcmp(node[i]->element, xml_smtpserver) == 0) { #ifndef WIN32 if(Mail && (Mail->mn)) { Mail->smtpserver = OS_GetHost(node[i]->content, 5); if(!Mail->smtpserver) { merror(INVALID_SMTP, ARGV0, node[i]->content); return(OS_INVALID); } } #endif } else if(strcmp(node[i]->element, xml_mailmaxperhour) == 0) { if(Mail) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } Mail->maxperhour = atoi(node[i]->content); if((Mail->maxperhour <= 0) || (Mail->maxperhour > 9999)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } } #ifdef GEOIP /* GeoIP v4 DB location */ else if(strcmp(node[i]->element, xml_geoip_db_path) == 0) { if(Config) { os_strdup(node[i]->content, Config->geoip_db_path); } } /* GeoIP v6 DB location */ else if(strcmp(node[i]->element, xml_geoip6_db_path) == 0) { if(Config) { os_strdup(node[i]->content, Config->geoip6_db_path); } } #endif else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } return(0); }
int Read_Client(XML_NODE node, void *d1, void *d2) { int i = 0; /* XML definitions */ char *xml_client_ip = "server-ip"; char *xml_client_hostname = "server-hostname"; char *xml_local_ip = "local_ip"; char *xml_client_port = "port"; char *xml_ar_disabled = "disable-active-response"; char *xml_notify_time = "notify_time"; char *xml_max_time_reconnect_try = "time-reconnect"; /* cmoraes */ char *xml_profile_name = "config-profile"; agent *logr; logr = (agent *)d1; logr->notify_time = 0; logr->max_time_reconnect_try = 0; while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } /* Getting local ip. */ else if(strcmp(node[i]->element, xml_local_ip) == 0) { os_strdup(node[i]->content, logr->lip); if(OS_IsValidIP(logr->lip, NULL) != 1) { merror(INVALID_IP, ARGV0, logr->lip); return(OS_INVALID); } } /* Getting server ip */ else if(strcmp(node[i]->element,xml_client_ip) == 0) { int ip_id = 0; /* Getting last ip */ if(logr->rip) { while(logr->rip[ip_id]) { ip_id++; } } os_realloc(logr->rip, (ip_id + 2) * sizeof(char*), logr->rip); logr->rip[ip_id] = NULL; logr->rip[ip_id +1] = NULL; os_strdup(node[i]->content, logr->rip[ip_id]); if(OS_IsValidIP(logr->rip[ip_id], NULL) != 1) { merror(INVALID_IP, ARGV0, logr->rip[ip_id]); return(OS_INVALID); } logr->rip_id++; } else if(strcmp(node[i]->element,xml_client_hostname) == 0) { int ip_id = 0; char *s_ip; char f_ip[128]; /* Getting last ip. */ if(logr->rip) { while(logr->rip[ip_id]) { ip_id++; } } os_realloc(logr->rip, (ip_id + 2) * sizeof(char*), logr->rip); s_ip = OS_GetHost(node[i]->content, 5); if(!s_ip) { merror("%s: WARN: Unable to get hostname for '%s'.", ARGV0, node[i]->content); merror(AG_INV_HOST, ARGV0, node[i]->content); os_strdup("invalid_ip", s_ip); } f_ip[127] = '\0'; snprintf(f_ip, 127, "%s/%s", node[i]->content, s_ip); os_strdup(f_ip, logr->rip[ip_id]); logr->rip[ip_id +1] = NULL; free(s_ip); logr->rip_id++; } else if(strcmp(node[i]->element,xml_client_port) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } logr->port = atoi(node[i]->content); if(logr->port <= 0 || logr->port > 65535) { merror(PORT_ERROR, ARGV0, logr->port); return(OS_INVALID); } } else if(strcmp(node[i]->element,xml_notify_time) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } logr->notify_time = atoi(node[i]->content); } else if(strcmp(node[i]->element,xml_max_time_reconnect_try) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } logr->max_time_reconnect_try = atoi(node[i]->content); } else if(strcmp(node[i]->element,xml_ar_disabled) == 0) { if(strcmp(node[i]->content, "yes") == 0) logr->execdq = -1; else if(strcmp(node[i]->content, "no") == 0) logr->execdq = 0; else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } /* cmoraes */ else if(strcmp(node[i]->element,xml_profile_name) == 0) { /* profile name can be anything hence no validation */ os_strdup(node[i]->content, logr->profile); } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } if(!logr->rip) { return(OS_INVALID); } return(0); }
/* Read_Rootcheck_Config: Reads the rootcheck config */ int Read_Rootcheck_Config(char * cfgfile) { OS_XML xml; char *str = NULL; /* XML Definitions */ char *(xml_daemon[])={xml_rootcheck,"daemon", NULL}; char *(xml_notify[])={xml_rootcheck, "notify", NULL}; char *(xml_base_dir[])={xml_rootcheck, "base_directory", NULL}; char *(xml_workdir[])={xml_rootcheck, "work_directory", NULL}; char *(xml_rootkit_files[])={xml_rootcheck, "rootkit_files", NULL}; char *(xml_rootkit_trojans[])={xml_rootcheck, "rootkit_trojans", NULL}; char *(xml_rootkit_unixaudit[])={xml_rootcheck, "system_audit", NULL}; char *(xml_rootkit_winaudit[])={xml_rootcheck, "windows_audit", NULL}; char *(xml_rootkit_winapps[])={xml_rootcheck, "windows_apps", NULL}; char *(xml_rootkit_winmalware[])={xml_rootcheck, "windows_malware", NULL}; char *(xml_scanall[])={xml_rootcheck, "scanall", NULL}; char *(xml_readall[])={xml_rootcheck, "readall", NULL}; char *(xml_time[])={xml_rootcheck, "frequency", NULL}; /* :) */ xml_time[2] = NULL; if(OS_ReadXML(cfgfile,&xml) < 0) { merror("config_op: XML error: %s",xml.err); return(OS_INVALID); } if(!OS_RootElementExist(&xml,xml_rootcheck)) { OS_ClearXML(&xml); merror("%s: Rootcheck configuration not found. ",ARGV0); return(-1); } /* run as a daemon */ str = OS_GetOneContentforElement(&xml,xml_daemon); if(str) { if(str[0] == 'n') rootcheck.daemon = 0; free(str); str = NULL; } /* time */ #ifdef OSSECHIDS str = OS_GetOneContentforElement(&xml,xml_time); if(str) { if(!OS_StrIsNum(str)) { merror("Invalid frequency time '%s' for the rootkit " "detection (must be int).", str); return(OS_INVALID); } rootcheck.time = atoi(str); free(str); str = NULL; } #endif /* Scan all flag */ if(!rootcheck.scanall) { str = OS_GetOneContentforElement(&xml,xml_scanall); if(str) { if(str[0] == 'y') rootcheck.scanall = 1; free(str); str = NULL; } } /* read all flag */ if(!rootcheck.readall) { str = OS_GetOneContentforElement(&xml,xml_readall); if(str) { if(str[0] == 'y') rootcheck.readall = 1; free(str); str = NULL; } } /* Notifications type */ str = OS_GetOneContentforElement(&xml,xml_notify); if(str) { if(strcasecmp(str,"queue") == 0) rootcheck.notify = QUEUE; else if(strcasecmp(str,"syslog") == 0) rootcheck.notify = SYSLOG; else { merror("%s: Invalid notification option. Only " "'syslog' or 'queue' are allowed.",ARGV0); return(-1); } free(str); str = NULL; } else { /* Default to SYSLOG */ rootcheck.notify = SYSLOG; } /* Getting work directory */ if(!rootcheck.workdir) rootcheck.workdir = OS_GetOneContentforElement(&xml,xml_workdir); rootcheck.rootkit_files = OS_GetOneContentforElement (&xml,xml_rootkit_files); rootcheck.rootkit_trojans = OS_GetOneContentforElement (&xml,xml_rootkit_trojans); rootcheck.unixaudit = OS_GetContents (&xml,xml_rootkit_unixaudit); rootcheck.winaudit = OS_GetOneContentforElement (&xml,xml_rootkit_winaudit); rootcheck.winapps = OS_GetOneContentforElement (&xml,xml_rootkit_winapps); rootcheck.winmalware = OS_GetOneContentforElement (&xml,xml_rootkit_winmalware); rootcheck.basedir = OS_GetOneContentforElement(&xml, xml_base_dir); OS_ClearXML(&xml); debug1("%s: DEBUG: Daemon set to '%d'",ARGV0, rootcheck.daemon); debug1("%s: DEBUG: alert set to '%d'",ARGV0, rootcheck.notify); return(0); }