/* Check if IP_address is present in the "list_of_ips". * Returns 1 on success or 0 on failure * The list MUST be NULL terminated */ int OS_IPFoundList(const char *ip_address, os_ip **list_of_ips) { int _true = 1; os_ip temp_ip; memset(&temp_ip, 0, sizeof(struct _os_ip)); /* Extract IP address */ if (OS_IsValidIP(ip_address, &temp_ip) == 0) { return (!_true); } while (*list_of_ips) { os_ip *l_ip = *list_of_ips; if (l_ip->ip[0] == '!') { _true = 0; } /* Checking if ip is in thatip & netmask */ if (sacmp((struct sockaddr *) &temp_ip.ss, (struct sockaddr *) &l_ip->ss, l_ip->prefixlength)) { return (_true); } list_of_ips++; } return (!_true); }
/* Check if IP_address is present at that_IP * Returns 1 on success or 0 on failure */ int OS_IPFound(const char *ip_address, const os_ip *that_ip) { int _true = 1; os_ip temp_ip; memset(&temp_ip, 0, sizeof(struct _os_ip)); /* Extract IP address */ if (OS_IsValidIP(ip_address, &temp_ip) == 0) { return (!_true); } /* If negate is set */ if (that_ip->ip[0] == '!') { _true = 0; } /* Check if IP is in thatip & netmask */ if (sacmp((struct sockaddr *) &temp_ip.ss, (struct sockaddr *) &that_ip->ss, that_ip->prefixlength)) { return (_true); } /* Didn't match */ return (!_true); }
/* Set OSSEC Server IP */ int set_ossec_server(char *ip, HWND hwnd) { char **xml_pt = NULL; char *(xml_serverip[])={"ossec_config","client","server-ip", NULL}; char *(xml_serverhost[])={"ossec_config","client","server-hostname", NULL}; /* Verifying IP Address */ if(OS_IsValidIP(ip, NULL) != 1) { char *s_ip; s_ip = OS_GetHost(ip, 0); if(!s_ip) { MessageBox(hwnd, "Invalid Server IP Address.\r\n" "It must be the valid Ipv4 address of the " "OSSEC server or its resolvable hostname.", "Invalid Server IP Address.",MB_OK); return(0); } config_inst.server_type = SERVER_HOST_USED; xml_pt = xml_serverhost; } else { config_inst.server_type = SERVER_IP_USED; xml_pt = xml_serverip; } /* Reading the XML. Printing error and line number */ if(OS_WriteXML(CONFIG, NEWCONFIG, xml_pt, NULL, NULL, ip, 0) != 0) { MessageBox(hwnd, "Unable to set OSSEC Server IP Address.\r\n" "(Internal error on the XML Write).", "Unable to set Server IP Address.",MB_OK); return(0); } /* Renaming config files */ unlink(LASTCONFIG); rename(CONFIG, LASTCONFIG); rename(NEWCONFIG, CONFIG); return(1); }
int main(int argc, char **argv) { os_ip myip; if(!argv[1]) return(1); if(!OS_IsValidIP(argv[1], &myip)) { printf("Invalid ip\n"); } if(OS_IPFound(argv[2], &myip)) { printf("IP MATCHED!\n"); } return(0); }
/* Set OSSEC Server IP */ int set_ossec_server(char *ip, HWND hwnd) { const char **xml_pt = NULL; const char *(xml_serverip[]) = {"ossec_config", "client", "server-ip", NULL}; const char *(xml_serverhost[]) = {"ossec_config", "client", "server-hostname", NULL}; char config_tmp[] = CONFIG; char *conf_file = basename_ex(config_tmp); char tmp_path[strlen(TMP_DIR) + 1 + strlen(conf_file) + 6 + 1]; snprintf(tmp_path, sizeof(tmp_path), "%s/%sXXXXXX", TMP_DIR, conf_file); /* Verify IP Address */ if (OS_IsValidIP(ip, NULL) != 1) { char *s_ip; s_ip = OS_GetHost(ip, 0); if (!s_ip) { MessageBox(hwnd, "Invalid Server IP Address.\r\n" "It must be the valid IPv4 address of the " "OSSEC server or the resolvable hostname.", "Error -- Failure Setting IP", MB_OK); return (0); } config_inst.server_type = SERVER_HOST_USED; xml_pt = xml_serverhost; } else { config_inst.server_type = SERVER_IP_USED; xml_pt = xml_serverip; } /* Create temporary file */ if (mkstemp_ex(tmp_path) == -1) { MessageBox(hwnd, "Could not create temporary file.", "Error -- Failure Setting IP", MB_OK); return (0); } /* Read the XML. Print error and line number. */ if (OS_WriteXML(CONFIG, tmp_path, xml_pt, NULL, ip) != 0) { MessageBox(hwnd, "Unable to set OSSEC Server IP Address.\r\n" "(Internal error on the XML Write).", "Error -- Failure Setting IP", MB_OK); if (unlink(tmp_path)) { MessageBox(hwnd, "Could not delete temporary file.", "Error -- Failure Deleting Temporary File", MB_OK); } return (0); } /* Rename config files */ if (rename_ex(CONFIG, LASTCONFIG)) { MessageBox(hwnd, "Unable to backup configuration.", "Error -- Failure Backing Up Configuration", MB_OK); if (unlink(tmp_path)) { MessageBox(hwnd, "Could not delete temporary file.", "Error -- Failure Deleting Temporary File", MB_OK); } return (0); } if (rename_ex(tmp_path, CONFIG)) { MessageBox(hwnd, "Unable rename temporary file.", "Error -- Failure Renaming Temporary File", MB_OK); if (unlink(tmp_path)) { MessageBox(hwnd, "Could not delete temporary file.", "Error -- Failure Deleting Temporary File", MB_OK); } return (0); } return (1); }
/* Get OSSEC Server IP */ int get_ossec_server() { OS_XML xml; char *str = NULL; /* Definitions */ const char *(xml_serverip[]) = {"ossec_config", "client", "server-ip", NULL}; const char *(xml_serverhost[]) = {"ossec_config", "client", "server-hostname", NULL}; /* Read XML */ if (OS_ReadXML(CONFIG, &xml) < 0) { return (0); } /* We need to remove the entry for the server */ if (config_inst.server) { free(config_inst.server); config_inst.server = NULL; } config_inst.server_type = 0; /* Get IP */ str = OS_GetOneContentforElement(&xml, xml_serverip); if (str && (OS_IsValidIP(str, NULL) == 1)) { config_inst.server_type = SERVER_IP_USED; config_inst.server = str; OS_ClearXML(&xml); return (1); } /* If we don't find the IP, try the server hostname */ else { if (str) { free(str); str = NULL; } str = OS_GetOneContentforElement(&xml, xml_serverhost); if (str) { char *s_ip; s_ip = OS_GetHost(str, 0); if (s_ip) { /* Clear the host memory */ free(s_ip); /* Assign the hostname to the server info */ config_inst.server_type = SERVER_HOST_USED; config_inst.server = str; OS_ClearXML(&xml); return (1); } free(str); } } /* Set up final server name when not available */ config_inst.server = strdup(FL_NOSERVER); OS_ClearXML(&xml); return (0); }
/* Set OSSEC Server IP */ int set_ossec_server(char *ip, HWND hwnd) { FILE *fp; char **xml_pt = NULL; char *(xml_serverip[])= {"ossec_config","client","server-ip", NULL}; char *(xml_serverhost[])= {"ossec_config","client","server-hostname", NULL}; char *cacls; int cmdlen; /* Build command line to change permissions */ cacls = "echo y|cacls \"%s\" /T /G Administrators:f"; cmdlen = strlen(cacls) + strlen(NEWCONFIG); char cmd[cmdlen]; snprintf(cmd, cmdlen, cacls, NEWCONFIG); /* Verifying IP Address */ if(OS_IsValidIP(ip, NULL) != 1) { char *s_ip; s_ip = OS_GetHost(ip, 0); if(!s_ip) { MessageBox(hwnd, "Invalid Server IP Address.\r\n" "It must be the valid Ipv4 address of the " "OSSEC server or its resolvable hostname.", "Error -- Failure Setting IP",MB_OK); return(0); } config_inst.server_type = SERVER_HOST_USED; xml_pt = xml_serverhost; } else { config_inst.server_type = SERVER_IP_USED; xml_pt = xml_serverip; } /* Create file */ fp = fopen(NEWCONFIG, "w"); if(fp) { fclose(fp); } else { MessageBox(hwnd, "Could not create configuration file.", "Error -- Failure Setting IP",MB_OK); return(0); } /* Change permissions */ if (run_cmd(cmd, hwnd)) { MessageBox(hwnd, "Unable to set permissions on new configuration file.", "Error -- Failure Setting IP",MB_OK); /* Remove config */ if(unlink(NEWCONFIG)) { MessageBox(hwnd, "Unable to remove new configuration file.", "Error -- Failure Setting IP",MB_OK); } return(0); } /* Reading the XML. Printing error and line number. */ if(OS_WriteXML(CONFIG, NEWCONFIG, xml_pt, NULL, ip) != 0) { MessageBox(hwnd, "Unable to set OSSEC Server IP Address.\r\n" "(Internal error on the XML Write).", "Error -- Failure Setting IP",MB_OK); return(0); } /* Renaming config files */ unlink(LASTCONFIG); rename(CONFIG, LASTCONFIG); rename(NEWCONFIG, CONFIG); return(1); }
/* Create the final key */ static void __chash(keystore *keys, const char *id, const char *name, char *ip, const char *key) { os_md5 filesum1; os_md5 filesum2; char *tmp_str; char _finalstr[KEYSIZE]; /* Allocate for the whole structure */ keys->keyentries = (keyentry **)realloc(keys->keyentries, (keys->keysize + 2) * sizeof(keyentry *)); if (!keys->keyentries) { ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)); } os_calloc(1, sizeof(keyentry), keys->keyentries[keys->keysize]); /* Set configured values for id */ os_strdup(id, keys->keyentries[keys->keysize]->id); OSHash_Add(keys->keyhash_id, keys->keyentries[keys->keysize]->id, keys->keyentries[keys->keysize]); /* Agent IP */ os_calloc(1, sizeof(os_ip), keys->keyentries[keys->keysize]->ip); if (OS_IsValidIP(ip, keys->keyentries[keys->keysize]->ip) == 0) { ErrorExit(INVALID_IP, __local_name, ip); } /* We need to remove the "/" from the CIDR */ if ((tmp_str = strchr(keys->keyentries[keys->keysize]->ip->ip, '/')) != NULL) { *tmp_str = '\0'; } OSHash_Add(keys->keyhash_ip, keys->keyentries[keys->keysize]->ip->ip, keys->keyentries[keys->keysize]); /* Agent name */ os_strdup(name, keys->keyentries[keys->keysize]->name); /* Initialize the variables */ keys->keyentries[keys->keysize]->rcvd = 0; keys->keyentries[keys->keysize]->local = 0; keys->keyentries[keys->keysize]->keyid = keys->keysize; keys->keyentries[keys->keysize]->global = 0; keys->keyentries[keys->keysize]->fp = NULL; /** Generate final symmetric key **/ /* MD5 from name, id and key */ OS_MD5_Str(name, filesum1); OS_MD5_Str(id, filesum2); /* Generate new filesum1 */ snprintf(_finalstr, sizeof(_finalstr) - 1, "%s%s", filesum1, filesum2); /* Use just half of the first MD5 (name/id) */ OS_MD5_Str(_finalstr, filesum1); filesum1[15] = '\0'; filesum1[16] = '\0'; /* Second md is just the key */ OS_MD5_Str(key, filesum2); /* Generate final key */ snprintf(_finalstr, 49, "%s%s", filesum2, filesum1); /* Final key is 48 * 4 = 192bits */ os_strdup(_finalstr, keys->keyentries[keys->keysize]->key); /* Clean final string from memory */ memset_secure(_finalstr, '\0', sizeof(_finalstr)); /* Ready for next */ keys->keysize++; return; }
/* Bulk generate client keys from file */ int k_bulkload(const char *cmdbulk) { int i = 1; FILE *fp, *infp; char str1[STR_SIZE + 1]; char str2[STR_SIZE + 1]; os_md5 md1; os_md5 md2; char line[FILE_SIZE + 1]; char name[FILE_SIZE + 1]; char id[FILE_SIZE + 1]; char ip[FILE_SIZE + 1]; char delims[] = ","; char *token = NULL; /* Check if we can open the input file */ printf("Opening: [%s]\n", cmdbulk); infp = fopen(cmdbulk, "r"); if (!infp) { perror("Failed."); ErrorExit(FOPEN_ERROR, ARGV0, cmdbulk, errno, strerror(errno)); } /* Check if we can open the auth_file */ fp = fopen(AUTH_FILE, "a"); if (!fp) { ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); } fclose(fp); while (fgets(line, FILE_SIZE - 1, infp) != NULL) { os_ip c_ip; c_ip.ip = NULL; if (1 >= strlen(trimwhitespace(line))) { continue; } memset(ip, '\0', FILE_SIZE + 1); token = strtok(line, delims); strncpy(ip, trimwhitespace(token), FILE_SIZE - 1); memset(name, '\0', FILE_SIZE + 1); token = strtok(NULL, delims); strncpy(name, trimwhitespace(token), FILE_SIZE - 1); #ifndef WIN32 if (chmod(AUTH_FILE, 0440) == -1) { ErrorExit(CHMOD_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); } #endif /* Set time 2 */ time2 = time(0); srandom_init(); rand1 = random(); /* Zero strings */ memset(str1, '\0', STR_SIZE + 1); memset(str2, '\0', STR_SIZE + 1); /* Check the name */ if (!OS_IsValidName(name)) { printf(INVALID_NAME, name); continue; } /* Search for name -- no duplicates */ if (NameExist(name)) { printf(ADD_ERROR_NAME, name); continue; } if (!OS_IsValidIP(ip, &c_ip)) { printf(IP_ERROR, ip); continue; } /* Default ID */ i = MAX_AGENTS + 32512; snprintf(id, 8, "%03d", i); while (!IDExist(id)) { i--; snprintf(id, 8, "%03d", i); /* No key present, use id 0 */ if (i <= 0) { i = 0; break; } } snprintf(id, 8, "%03d", i + 1); if (!OS_IsValidID(id)) { printf(INVALID_ID, id); goto cleanup; } /* Search for ID KEY -- no duplicates */ if (IDExist(id)) { printf(NO_DEFAULT, i + 1); goto cleanup; } printf(AGENT_INFO, id, name, ip); fflush(stdout); time3 = time(0); rand2 = random(); fp = fopen(AUTH_FILE, "a"); if (!fp) { ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE, errno, strerror(errno)); } #ifndef WIN32 if (chmod(AUTH_FILE, 0440) == -1) { ErrorExit(CHMOD_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); } #endif /* Random 1: Time took to write the agent information * Random 2: Time took to choose the action * Random 3: All of this + time + pid * Random 4: MD5 all of this + the name, key and IP * Random 5: Final key */ snprintf(str1, STR_SIZE, "%d%s%d", (int)(time3 - time2), name, (int)rand1); snprintf(str2, STR_SIZE, "%d%s%s%d", (int)(time2 - time1), ip, id, (int)rand2); OS_MD5_Str(str1, md1); OS_MD5_Str(str2, md2); snprintf(str1, STR_SIZE, "%s%d%d%d", md1, (int)getpid(), (int)random(), (int)time3); OS_MD5_Str(str1, md1); fprintf(fp, "%s %s %s %s%s\n", id, name, c_ip.ip, md1, md2); fclose(fp); printf(AGENT_ADD); restart_necessary = 1; cleanup: free(c_ip.ip); }; fclose(infp); return (0); }
int add_agent() { int i = 1; FILE *fp; char str1[STR_SIZE + 1]; char str2[STR_SIZE + 1]; os_md5 md1; os_md5 md2; char *user_input; char *_name; char *_id; char *_ip; char name[FILE_SIZE + 1]; char id[FILE_SIZE + 1]; char ip[FILE_SIZE + 1]; os_ip *c_ip; /* Check if we can open the auth_file */ fp = fopen(AUTH_FILE, "a"); if (!fp) { ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); } fclose(fp); /* Allocate for c_ip */ os_calloc(1, sizeof(os_ip), c_ip); #ifndef WIN32 if (chmod(AUTH_FILE, 0440) == -1) { ErrorExit(CHMOD_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); } #endif /* Set time 2 */ time2 = time(0); rand1 = random(); /* Zero strings */ memset(str1, '\0', STR_SIZE + 1); memset(str2, '\0', STR_SIZE + 1); printf(ADD_NEW); /* Get the name */ memset(name, '\0', FILE_SIZE + 1); do { printf(ADD_NAME); fflush(stdout); /* Read the agent's name from user environment. If it is invalid * we should force user to provide a name from input device. */ _name = getenv("OSSEC_AGENT_NAME"); if (_name == NULL || NameExist(_name) || !OS_IsValidName(_name)) { _name = read_from_user(); } if (strcmp(_name, QUIT) == 0) { return (0); } strncpy(name, _name, FILE_SIZE - 1); /* Check the name */ if (!OS_IsValidName(name)) { printf(INVALID_NAME, name); } /* Search for name -- no duplicates */ if (NameExist(name)) { printf(ADD_ERROR_NAME, name); } } while (NameExist(name) || !OS_IsValidName(name)); /* Get IP */ memset(ip, '\0', FILE_SIZE + 1); do { printf(ADD_IP); fflush(stdout); /* Read IP address from user's environment. If that IP is invalid, * force user to provide IP from input device */ _ip = getenv("OSSEC_AGENT_IP"); if (_ip == NULL || !OS_IsValidIP(_ip, c_ip)) { _ip = read_from_user(); } /* Quit */ if (strcmp(_ip, QUIT) == 0) { return (0); } strncpy(ip, _ip, FILE_SIZE - 1); if (!OS_IsValidIP(ip, c_ip)) { printf(IP_ERROR, ip); _ip = NULL; } } while (!_ip); do { /* Default ID */ i = MAX_AGENTS + 32512; snprintf(id, 8, "%03d", i); while (!IDExist(id)) { i--; snprintf(id, 8, "%03d", i); /* No key present, use id 0 */ if (i <= 0) { i = 0; break; } } snprintf(id, 8, "%03d", i + 1); /* Get ID */ printf(ADD_ID, id); fflush(stdout); /* Get Agent ID from environment. If 0, use default ID. If null, * get from user input. If value from environment is invalid, * we force user to specify an ID from the terminal. Otherwise, * our program goes to infinite loop. */ _id = getenv("OSSEC_AGENT_ID"); if (_id == NULL || IDExist(_id) || !OS_IsValidID(_id)) { _id = read_from_user(); } /* If user specified 0 as Agent ID, he meant use default value. * NOTE: a bad condition can cause infinite loop. */ if (strcmp(_id, "0") == 0) { strncpy(_id, id, FILE_SIZE - 1); } /* Quit */ if (strcmp(_id, QUIT) == 0) { return (0); } if (_id[0] != '\0') { strncpy(id, _id, FILE_SIZE - 1); } if (!OS_IsValidID(id)) { printf(INVALID_ID, id); } /* Search for ID KEY -- no duplicates */ if (IDExist(id)) { printf(ADD_ERROR_ID, id); } } while (IDExist(id) || !OS_IsValidID(id)); printf(AGENT_INFO, id, name, ip); fflush(stdout); do { printf(ADD_CONFIRM); /* Confirmation by an environment variable. The valid value is y/Y. * If the user provides anything other string, it is considered as * n/N; please note that the old code only accepts y/Y/n/N. So if * the variable OSSEC_ACTION_CONFIRMED is 'foobar', the program will * go into an infinite loop. */ user_input = getenv("OSSEC_ACTION_CONFIRMED"); if (user_input == NULL) { user_input = read_from_user(); } /* If user accepts to add */ if (user_input[0] == 'y' || user_input[0] == 'Y') { time3 = time(0); rand2 = random(); fp = fopen(AUTH_FILE, "a"); if (!fp) { ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE, errno, strerror(errno)); } #ifndef WIN32 chmod(AUTH_FILE, 0440); #endif /* Random 1: Time took to write the agent information * Random 2: Time took to choose the action * Random 3: All of this + time + pid * Random 4: Md5 all of this + the name, key and IP * Random 5: Final key */ snprintf(str1, STR_SIZE, "%d%s%d", (int)(time3 - time2), name, (int)rand1); snprintf(str2, STR_SIZE, "%d%s%s%d", (int)(time2 - time1), ip, id, (int)rand2); OS_MD5_Str(str1, md1); OS_MD5_Str(str2, md2); snprintf(str1, STR_SIZE, "%s%d%d%d", md1, (int)getpid(), (int)random(), (int)time3); OS_MD5_Str(str1, md1); fprintf(fp, "%s %s %s %s%s\n", id, name, c_ip->ip, md1, md2); fclose(fp); printf(AGENT_ADD); restart_necessary = 1; break; } else { /* if(user_input[0] == 'n' || user_input[0] == 'N') */ printf(ADD_NOT); break; } } while (1); 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); }
/* 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); }