END_TEST START_TEST(test_osgetattributecontent) { char xml_file_name[256]; create_xml_file("<root attr=\"value\" attr2=\"value1\"></root>", xml_file_name, 256); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_eq(OS_ApplyVariables(&xml), 0); const char *xml_path1[] = { "root", NULL }; const char *xml_path2[] = { NULL }; char *content1, *content2, *content3, *content4; ck_assert_str_eq(content1 = OS_GetAttributeContent(&xml, xml_path1, "attr"), "value"); ck_assert_str_eq(content2 = OS_GetAttributeContent(&xml, xml_path1, "attr2"), "value1"); ck_assert_str_eq(content3 = OS_GetAttributeContent(&xml, xml_path1, "attr3"), ""); ck_assert_str_eq(content4 = OS_GetAttributeContent(&xml, xml_path1, NULL), ""); ck_assert_ptr_eq(OS_GetAttributeContent(&xml, xml_path2, NULL), NULL); free(content1); free(content2); free(content3); free(content4); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_osgetelements) { char xml_file_name[256]; create_xml_file("<root><child1/><child2/></root>", xml_file_name, 256); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_eq(OS_ApplyVariables(&xml), 0); const char *xml_path[] = { "root", NULL }; char **content1, **content2; ck_assert_ptr_ne(content1 = OS_GetElements(&xml, xml_path), NULL); ck_assert_str_eq(content1[0], "child1"); ck_assert_str_eq(content1[1], "child2"); ck_assert_ptr_eq(content1[2], NULL); ck_assert_ptr_ne(content2 = OS_GetElements(&xml, NULL), NULL); ck_assert_str_eq(content2[0], "root"); ck_assert_ptr_eq(content2[1], NULL); const char *xml_path2[] = { NULL }; ck_assert_ptr_eq(OS_GetElements(&xml, xml_path2), NULL); int i = 0; while (content1[i]) { free(content1[i++]); } free(content1); i = 0; while (content2[i]) { free(content2[i++]); } free(content2); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST //TODO /*START_TEST(test_unknownvariable) { char xml_file_name[256]; create_xml_file("<root>$var</root>", xml_file_name, 256); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_ne(OS_ApplyVariables(&xml), 0); ck_assert_str_eq(xml.err, "XML_ERR: Unknown variable: var"); ck_assert_int_eq(xml.err_line, 0); OS_ClearXML(&xml); unlink(xml_file_name); } END_TEST*/ START_TEST(test_oselementsexists) { char xml_file_name[256]; create_xml_file("<root></root><root1/><root/>", xml_file_name, 256); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_eq(OS_ApplyVariables(&xml), 0); ck_assert_int_eq(OS_RootElementExist(&xml, "root"), 2); ck_assert_int_eq(OS_RootElementExist(&xml, "root1"), 1); ck_assert_int_eq(OS_RootElementExist(&xml, "root2"), 0); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_invalidfile) { OS_XML xml; ck_assert_int_ne(OS_ReadXML("invalid_file.inv", &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: File 'invalid_file.inv' not found."); ck_assert_int_eq(xml.err_line, 0); OS_ClearXML(&xml); }
END_TEST START_TEST(test_unclosedattribute) { char xml_file_name[256]; create_xml_file("<root attr=\"attribute></root>", xml_file_name, 256); OS_XML xml; ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' not closed."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_nodenotopened) { char xml_file_name[256]; create_xml_file("</root>", xml_file_name, 256); OS_XML xml; ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Element not opened."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_unclosedcomment) { char xml_file_name[256]; create_xml_file("<!-- comment", xml_file_name, 256); OS_XML xml; ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Comment not closed."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_unclosednode) { char xml_file_name[256]; create_xml_file("<root>", xml_file_name, 256); OS_XML xml; ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: End of file and some elements were not closed."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_infiniteattribute3) { char xml_file_name[256]; create_xml_file("<root attr='", xml_file_name, 256); OS_XML xml; ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: End of file while reading an attribute."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_duplicateattribute) { char xml_file_name[256]; create_xml_file("<root attr='test' attr2='test' attr='test123'></root>", xml_file_name, 256); OS_XML xml; ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' already defined."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_invalidattributeclosing2) { char xml_file_name[256]; create_xml_file("<root attr='test'test/>", xml_file_name, 256); OS_XML xml; ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Bad attribute closing for 'attr'='test'."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_noattributevalue2) { char xml_file_name[256]; create_xml_file("<root attr attr2='test'></root>", xml_file_name, 256); OS_XML xml; ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' has no value."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_invalidattributestart) { char xml_file_name[256]; create_xml_file("<root attr= test\"test\"/>", xml_file_name, 256); OS_XML xml; ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' not followed by a \" or '."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_invalidvariablename) { char xml_file_name[256]; create_xml_file("<var test=\"test\"></var>", xml_file_name, 256); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_ne(OS_ApplyVariables(&xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Only \"name\" is allowed as an attribute for a variable."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_unknownvariable1) { char xml_file_name[256]; create_xml_file("<var name=\"test\">content</var><root>$var</root>", xml_file_name, 256); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_ne(OS_ApplyVariables(&xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Unknown variable: 'var'."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_linecounter) { char xml_file_name[256]; create_xml_file("<root1/>\n<root2/>\n<root3/>" , xml_file_name, 256); OS_XML xml; XML_NODE node; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_eq(OS_ApplyVariables(&xml), 0); ck_assert_ptr_ne(node = OS_GetElementsbyNode(&xml, NULL), NULL); ck_assert_int_eq(xml.ln[0], 1); ck_assert_int_eq(xml.ln[1], 2); ck_assert_int_eq(xml.ln[2], 3); OS_ClearNode(node); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_stringoverflow4) { char xml_file_name[256]; char overflow_string[XML_MAXSIZE + 10]; memset(overflow_string, 'c', XML_MAXSIZE + 9); overflow_string[XML_MAXSIZE + 9] = '\0'; char xml_string[2 * XML_MAXSIZE]; snprintf(xml_string, 2 * XML_MAXSIZE - 1, "<test test=\"%s\">test</test>", overflow_string); create_xml_file(xml_string, xml_file_name, 256); OS_XML xml; ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Overflow attempt at attribute 'test'."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST static void assert_ox_xml_write_eq(const char *xml_str_old, const char *xml_str_new, const char **xml_path, const char *oldval, const char *newval) { char xml_in_file_name[256]; create_xml_file(xml_str_old, xml_in_file_name, 256); char xml_out_file_name[256]; create_xml_file("", xml_out_file_name, 256); ck_assert_int_eq(OS_WriteXML(xml_in_file_name, xml_out_file_name, xml_path, oldval, newval), 0); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_out_file_name, &xml), 0); ck_assert_int_eq(OS_ApplyVariables(&xml), 0); assert_os_xml_eq_str(&xml, xml_str_new); OS_ClearXML(&xml); unlink(xml_in_file_name); unlink(xml_out_file_name); }
END_TEST START_TEST(test_invalidvariable2) { char xml_file_name[256]; char overflow_string[XML_VARIABLE_MAXSIZE + 10]; memset(overflow_string, 'c', XML_VARIABLE_MAXSIZE + 9); overflow_string[XML_VARIABLE_MAXSIZE + 9] = '\0'; char xml_string[3 * XML_VARIABLE_MAXSIZE]; snprintf(xml_string, 3 * XML_VARIABLE_MAXSIZE - 1, "<var name=\"%s\">test</var><test>$%s</test>", overflow_string, overflow_string); create_xml_file(xml_string, xml_file_name, 256); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_ne(OS_ApplyVariables(&xml), 0); ck_assert_str_eq(xml.err, "XMLERR: Invalid variable name size."); ck_assert_int_eq(xml.err_line, 1); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_osgetonecontentforelement) { char xml_file_name[256]; create_xml_file("<root><child>test</child><child>test2</child><child2>test</child2></root>", xml_file_name, 256); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_eq(OS_ApplyVariables(&xml), 0); const char *xml_path1[] = { "root", "child", NULL }; const char *xml_path2[] = { "root", "child2", NULL }; const char *xml_path3[] = { "root", "child3", NULL }; char *content1, *content2; ck_assert_str_eq(content1 = OS_GetOneContentforElement(&xml, xml_path1), "test"); ck_assert_str_eq(content2 = OS_GetOneContentforElement(&xml, xml_path2), "test"); ck_assert_ptr_eq(OS_GetOneContentforElement(&xml, xml_path3), NULL); free(content1); free(content2); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_osgetelementcontent) { char xml_file_name[256]; create_xml_file("<root>value</root>", xml_file_name, 256); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_eq(OS_ApplyVariables(&xml), 0); const char *xml_path[] = { "root", NULL }; char **content; ck_assert_ptr_ne(content = OS_GetElementContent(&xml, xml_path), NULL); ck_assert_str_eq(content[0], "value"); ck_assert_ptr_eq(content[1], NULL); int i = 0; while (content[i]) { free(content[i++]); } free(content); OS_ClearXML(&xml); unlink(xml_file_name); }
END_TEST START_TEST(test_osgetattributes) { char xml_file_name[256]; create_xml_file("<root attr1=\"1\" attr2=\"2\"></root>", xml_file_name, 256); OS_XML xml; ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); ck_assert_int_eq(OS_ApplyVariables(&xml), 0); const char *xml_path[] = { "root", NULL }; char **content; ck_assert_ptr_ne(content = OS_GetAttributes(&xml, xml_path), NULL); ck_assert_str_eq(content[0], "attr1"); ck_assert_str_eq(content[1], "attr2"); ck_assert_ptr_eq(content[2], NULL); int i = 0; while (content[i]) { free(content[i++]); } free(content); OS_ClearXML(&xml); unlink(xml_file_name); }
/* ExecdConfig v0.1, 2006/03/24 * Read the config file */ int ExecdConfig(char * cfgfile) { extern int repeated_offenders_timeout[]; #ifdef WIN32 int is_disabled = 1; #else int is_disabled = 0; #endif const char *(xmlf[]) = {"ossec_config", "active-response", "disabled", NULL}; const char *(blocks[]) = {"ossec_config", "active-response", "repeated_offenders", NULL}; char *disable_entry; char *repeated_t; char **repeated_a; OS_XML xml; /* Reading XML file */ if(OS_ReadXML(cfgfile,&xml) < 0) { ErrorExit(XML_ERROR, ARGV0, cfgfile, xml.err, xml.err_line); } /* We do not validate the xml in here. It is done by other processes */ disable_entry = OS_GetOneContentforElement(&xml, xmlf); if(disable_entry) { if(strcmp(disable_entry, "yes") == 0) { is_disabled = 1; } else if(strcmp(disable_entry, "no") == 0) { is_disabled = 0; } else { merror(XML_VALUEERR, ARGV0, "disabled", disable_entry); return(-1); } } repeated_t = OS_GetOneContentforElement(&xml, blocks); if(repeated_t) { int i = 0; int j = 0; repeated_a = OS_StrBreak(',', repeated_t, 5); if(!repeated_a) { merror(XML_VALUEERR, ARGV0, "repeated_offenders", disable_entry); return(-1); } while(repeated_a[i] != NULL) { char *tmpt = repeated_a[i]; while(*tmpt != '\0') { if(*tmpt == ' ' || *tmpt == '\t') tmpt++; else break; } if(*tmpt == '\0') { i++; continue; } repeated_offenders_timeout[j] = atoi(tmpt); verbose("%s: INFO: Adding offenders timeout: %d (for #%d)", ARGV0, repeated_offenders_timeout[j], j+1); j++; repeated_offenders_timeout[j] = 0; if(j >= 6) break; i++; } } OS_ClearXML(&xml); return(is_disabled); }
int ReadDecodeXML(const char *file) { OS_XML xml; XML_NODE node = NULL; /* XML variables */ /* These are the available options for the rule configuration */ const char *xml_plugindecoder = "plugin_decoder"; const char *xml_decoder = "decoder"; const char *xml_decoder_name = "name"; const char *xml_decoder_status = "status"; const char *xml_usename = "use_own_name"; const char *xml_parent = "parent"; const char *xml_program_name = "program_name"; const char *xml_prematch = "prematch"; const char *xml_regex = "regex"; const char *xml_order = "order"; const char *xml_type = "type"; const char *xml_fts = "fts"; const char *xml_ftscomment = "ftscomment"; const char *xml_accumulate = "accumulate"; int i = 0; OSDecoderInfo *NULL_Decoder_tmp = NULL; /* Read the XML */ if ((i = OS_ReadXML(file, &xml)) < 0) { if ((i == -2) && (strcmp(file, XML_LDECODER) == 0)) { return (-2); } merror(XML_ERROR, ARGV0, file, xml.err, xml.err_line); return (0); } /* Apply any variables found */ if (OS_ApplyVariables(&xml) != 0) { merror(XML_ERROR_VAR, ARGV0, file, xml.err); return (0); } /* Get the root elements */ node = OS_GetElementsbyNode(&xml, NULL); if (!node) { if (strcmp(file, XML_LDECODER) != 0) { merror(XML_ELEMNULL, ARGV0); return (0); } return (-2); } /* Zero NULL_decoder */ if (!NULL_Decoder) { os_calloc(1, sizeof(OSDecoderInfo), NULL_Decoder_tmp); NULL_Decoder_tmp->id = 0; NULL_Decoder_tmp->type = SYSLOG; NULL_Decoder_tmp->name = NULL; NULL_Decoder_tmp->fts = 0; NULL_Decoder = NULL_Decoder_tmp; } i = 0; while (node[i]) { XML_NODE elements = NULL; OSDecoderInfo *pi; int j = 0; char *regex; char *prematch; char *p_name; if (!node[i]->element || strcasecmp(node[i]->element, xml_decoder) != 0) { merror(XML_INVELEM, ARGV0, node[i]->element); return (0); } /* Get name */ if ((!node[i]->attributes) || (!node[i]->values) || (!node[i]->values[0]) || (!node[i]->attributes[0]) || (strcasecmp(node[i]->attributes[0], xml_decoder_name) != 0)) { merror(XML_INVELEM, ARGV0, node[i]->element); return (0); } /* Check for additional entries */ if (node[i]->attributes[1] && node[i]->values[1]) { if (strcasecmp(node[i]->attributes[0], xml_decoder_status) != 0) { merror(XML_INVELEM, ARGV0, node[i]->element); return (0); } if (node[i]->attributes[2]) { merror(XML_INVELEM, ARGV0, node[i]->element); return (0); } } /* Get decoder options */ elements = OS_GetElementsbyNode(&xml, node[i]); if (elements == NULL) { merror(XML_ELEMNULL, ARGV0); return (0); } /* Create the OSDecoderInfo */ pi = (OSDecoderInfo *)calloc(1, sizeof(OSDecoderInfo)); if (pi == NULL) { merror(MEM_ERROR, ARGV0, errno, strerror(errno)); return (0); } /* Default values to the list */ pi->parent = NULL; pi->id = 0; pi->name = strdup(node[i]->values[0]); pi->order = NULL; pi->plugindecoder = NULL; pi->fts = 0; pi->accumulate = 0; pi->type = SYSLOG; pi->prematch = NULL; pi->program_name = NULL; pi->regex = NULL; pi->use_own_name = 0; pi->get_next = 0; pi->regex_offset = 0; pi->prematch_offset = 0; regex = NULL; prematch = NULL; p_name = NULL; /* Check if strdup worked */ if (!pi->name) { merror(MEM_ERROR, ARGV0, errno, strerror(errno)); return (0); } /* Add decoder */ if (!addDecoder2list(pi->name)) { merror(MEM_ERROR, ARGV0, errno, strerror(errno)); free(pi); return (0); } /* Loop over all the elements */ while (elements[j]) { if (!elements[j]->element) { merror(XML_ELEMNULL, ARGV0); return (0); } else if (!elements[j]->content) { merror(XML_VALUENULL, ARGV0, elements[j]->element); return (0); } /* Check if it is a child of a rule */ else if (strcasecmp(elements[j]->element, xml_parent) == 0) { pi->parent = _loadmemory(pi->parent, elements[j]->content); } /* Get the regex */ else if (strcasecmp(elements[j]->element, xml_regex) == 0) { int r_offset; r_offset = ReadDecodeAttrs(elements[j]->attributes, elements[j]->values); if (r_offset & AFTER_ERROR) { merror(DEC_REGEX_ERROR, ARGV0, pi->name); return (0); } /* Only the first regex entry may have an offset */ if (regex && r_offset) { merror(DUP_REGEX, ARGV0, pi->name); merror(DEC_REGEX_ERROR, ARGV0, pi->name); return (0); } /* regex offset */ if (r_offset) { pi->regex_offset = r_offset; } /* Assign regex */ regex = _loadmemory(regex, elements[j]->content); } /* Get the pre match */ else if (strcasecmp(elements[j]->element, xml_prematch) == 0) { int r_offset; r_offset = ReadDecodeAttrs( elements[j]->attributes, elements[j]->values); if (r_offset & AFTER_ERROR) { ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name); } /* Only the first prematch entry may have an offset */ if (prematch && r_offset) { merror(DUP_REGEX, ARGV0, pi->name); ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name); } if (r_offset) { pi->prematch_offset = r_offset; } prematch = _loadmemory(prematch, elements[j]->content); } /* Get program name */ else if (strcasecmp(elements[j]->element, xml_program_name) == 0) { p_name = _loadmemory(p_name, elements[j]->content); } /* Get the FTS comment */ else if (strcasecmp(elements[j]->element, xml_ftscomment) == 0) { } else if (strcasecmp(elements[j]->element, xml_usename) == 0) { if (strcmp(elements[j]->content, "true") == 0) { pi->use_own_name = 1; } } else if (strcasecmp(elements[j]->element, xml_plugindecoder) == 0) { int ed_c = 0; for (ed_c = 0; plugin_decoders[ed_c] != NULL; ed_c++) { if (strcmp(plugin_decoders[ed_c], elements[j]->content) == 0) { /* Initialize plugin */ void (*dec_init)(void) = (void (*)(void)) plugin_decoders_init[ed_c]; dec_init(); pi->plugindecoder = (void (*)(void *)) plugin_decoders_exec[ed_c]; break; } } /* Decoder not found */ if (pi->plugindecoder == NULL) { merror(INV_DECOPTION, ARGV0, elements[j]->element, elements[j]->content); return (0); } } /* Get the type */ else if (strcmp(elements[j]->element, xml_type) == 0) { if (strcmp(elements[j]->content, "firewall") == 0) { pi->type = FIREWALL; } else if (strcmp(elements[j]->content, "ids") == 0) { pi->type = IDS; } else if (strcmp(elements[j]->content, "web-log") == 0) { pi->type = WEBLOG; } else if (strcmp(elements[j]->content, "syslog") == 0) { pi->type = SYSLOG; } else if (strcmp(elements[j]->content, "squid") == 0) { pi->type = SQUID; } else if (strcmp(elements[j]->content, "windows") == 0) { pi->type = DECODER_WINDOWS; } else if (strcmp(elements[j]->content, "host-information") == 0) { pi->type = HOST_INFO; } else if (strcmp(elements[j]->content, "ossec") == 0) { pi->type = OSSEC_RL; } else { merror("%s: Invalid decoder type '%s'.", ARGV0, elements[j]->content); return (0); } } /* Get the order */ else if (strcasecmp(elements[j]->element, xml_order) == 0) { char **norder, **s_norder; int order_int = 0; /* Maximum number is 8 for the order */ norder = OS_StrBreak(',', elements[j]->content, 8); s_norder = norder; os_calloc(8, sizeof(void *), pi->order); /* Initialize the function pointers */ while (order_int < 8) { pi->order[order_int] = NULL; order_int++; } order_int = 0; /* Check the values from the order */ while (*norder) { if (strstr(*norder, "dstuser") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) DstUser_FP; } else if (strstr(*norder, "srcuser") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) SrcUser_FP; } /* User is an alias to dstuser */ else if (strstr(*norder, "user") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) DstUser_FP; } else if (strstr(*norder, "srcip") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) SrcIP_FP; } else if (strstr(*norder, "dstip") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) DstIP_FP; } else if (strstr(*norder, "srcport") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) SrcPort_FP; } else if (strstr(*norder, "dstport") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) DstPort_FP; } else if (strstr(*norder, "protocol") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) Protocol_FP; } else if (strstr(*norder, "action") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) Action_FP; } else if (strstr(*norder, "id") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) ID_FP; } else if (strstr(*norder, "url") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) Url_FP; } else if (strstr(*norder, "data") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) Data_FP; } else if (strstr(*norder, "extra_data") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) Data_FP; } else if (strstr(*norder, "status") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) Status_FP; } else if (strstr(*norder, "system_name") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) SystemName_FP; } else if (strstr(*norder, "filename") != NULL) { pi->order[order_int] = (void (*)(void *, char *)) FileName_FP; } else { ErrorExit("decode-xml: Wrong field '%s' in the order" " of decoder '%s'", *norder, pi->name); } free(*norder); norder++; order_int++; } free(s_norder); } else if (strcasecmp(elements[j]->element, xml_accumulate) == 0) { /* Enable Accumulator */ pi->accumulate = 1; } /* Get the FTS order */ else if (strcasecmp(elements[j]->element, xml_fts) == 0) { char **norder; char **s_norder; /* Maximum number is 8 for the FTS */ norder = OS_StrBreak(',', elements[j]->content, 8); if (norder == NULL) { ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); } /* Save the initial point to free later */ s_norder = norder; /* Check the values from the FTS */ while (*norder) { if (strstr(*norder, "dstuser") != NULL) { pi->fts |= FTS_DSTUSER; } if (strstr(*norder, "user") != NULL) { pi->fts |= FTS_DSTUSER; } else if (strstr(*norder, "srcuser") != NULL) { pi->fts |= FTS_SRCUSER; } else if (strstr(*norder, "srcip") != NULL) { pi->fts |= FTS_SRCIP; } else if (strstr(*norder, "dstip") != NULL) { pi->fts |= FTS_DSTIP; } else if (strstr(*norder, "id") != NULL) { pi->fts |= FTS_ID; } else if (strstr(*norder, "location") != NULL) { pi->fts |= FTS_LOCATION; } else if (strstr(*norder, "data") != NULL) { pi->fts |= FTS_DATA; } else if (strstr(*norder, "extra_data") != NULL) { pi->fts |= FTS_DATA; } else if (strstr(*norder, "system_name") != NULL) { pi->fts |= FTS_SYSTEMNAME; } else if (strstr(*norder, "name") != NULL) { pi->fts |= FTS_NAME; } else { ErrorExit("decode-xml: Wrong field '%s' in the fts" " decoder '%s'", *norder, pi->name); } free(*norder); norder++; } /* Clear memory here */ free(s_norder); } else { merror("%s: Invalid element '%s' for " "decoder '%s'", ARGV0, elements[j]->element, node[i]->element); return (0); } /* NEXT */ j++; } /* while(elements[j]) */ OS_ClearNode(elements); /* Prematch must be set */ if (!prematch && !pi->parent && !p_name) { merror(DECODE_NOPRE, ARGV0, pi->name); merror(DEC_REGEX_ERROR, ARGV0, pi->name); return (0); } /* If pi->regex is not set, fts must not be set too */ if ((!regex && (pi->fts || pi->order)) || (regex && !pi->order)) { merror(DEC_REGEX_ERROR, ARGV0, pi->name); return (0); } /* For the offsets */ if ((pi->regex_offset & AFTER_PARENT) && !pi->parent) { merror(INV_OFFSET, ARGV0, "after_parent"); merror(DEC_REGEX_ERROR, ARGV0, pi->name); return (0); } if (pi->regex_offset & AFTER_PREMATCH) { /* If after_prematch is set, but rule have * no parent, set AFTER_PARENT and unset * pre_match. */ if (!pi->parent) { pi->regex_offset = 0; pi->regex_offset |= AFTER_PARENT; } else if (!prematch) { merror(INV_OFFSET, ARGV0, "after_prematch"); merror(DEC_REGEX_ERROR, ARGV0, pi->name); return (0); } } /* For the after_regex offset */ if (pi->regex_offset & AFTER_PREVREGEX) { if (!pi->parent || !regex) { merror(INV_OFFSET, ARGV0, "after_regex"); merror(DEC_REGEX_ERROR, ARGV0, pi->name); return (0); } } /* Check the prematch offset */ if (pi->prematch_offset) { /* Only the after parent is allowed */ if (pi->prematch_offset & AFTER_PARENT) { if (!pi->parent) { merror(INV_OFFSET, ARGV0, "after_parent"); merror(DEC_REGEX_ERROR, ARGV0, pi->name); return (0); } } else { merror(DEC_REGEX_ERROR, ARGV0, pi->name); return (0); } } /* Compile the regex/prematch */ if (prematch) { os_calloc(1, sizeof(OSRegex), pi->prematch); if (!OSRegex_Compile(prematch, pi->prematch, 0)) { merror(REGEX_COMPILE, ARGV0, prematch, pi->prematch->error); return (0); } free(prematch); } /* Compile the p_name */ if (p_name) { os_calloc(1, sizeof(OSMatch), pi->program_name); if (!OSMatch_Compile(p_name, pi->program_name, 0)) { merror(REGEX_COMPILE, ARGV0, p_name, pi->program_name->error); return (0); } free(p_name); } /* We may not have the pi->regex */ if (regex) { os_calloc(1, sizeof(OSRegex), pi->regex); if (!OSRegex_Compile(regex, pi->regex, OS_RETURN_SUBSTRING)) { merror(REGEX_COMPILE, ARGV0, regex, pi->regex->error); return (0); } /* We must have the sub_strings to retrieve the nodes */ if (!pi->regex->sub_strings) { merror(REGEX_SUBS, ARGV0, regex); return (0); } free(regex); } /* Validate arguments */ if (pi->plugindecoder && (pi->regex || pi->order)) { merror(DECODE_ADD, ARGV0, pi->name); return (0); } /* Add osdecoder to the list */ if (!OS_AddOSDecoder(pi)) { merror(DECODER_ERROR, ARGV0); return (0); } i++; } /* while (node[i]) */ /* Clean node and XML structures */ OS_ClearNode(node); OS_ClearXML(&xml); return (1); }
/* 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); }
/* ReadConfig(int modules, char *cfgfile) * Read the config files */ int ReadConfig(int modules, char *cfgfile, void *d1, void *d2) { int i; OS_XML xml; XML_NODE node; /** XML definitions **/ /* Global */ char *xml_start_ossec = "ossec_config"; char *xml_start_ospatrol = "ospatrol_config"; char *xml_start_agent = "agent_config"; /* Attributes of the <agent_config> tag */ char *xml_agent_name = "name"; char *xml_agent_os = "os"; char *xml_agent_overwrite = "overwrite"; /* cmoraes */ char *xml_agent_profile = "profile"; if(OS_ReadXML(cfgfile,&xml) < 0) { if(modules & CAGENT_CONFIG) { #ifndef CLIENT merror(XML_ERROR, ARGV0, cfgfile, xml.err, xml.err_line); #endif } else { merror(XML_ERROR, ARGV0, cfgfile, xml.err, xml.err_line); } return(OS_INVALID); } node = OS_GetElementsbyNode(&xml, NULL); if(!node) { return(0); } /* Reading the main configuration */ i = 0; while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!(modules & CAGENT_CONFIG) && ( (strcmp(node[i]->element, xml_start_ossec) == 0) || (strcmp(node[i]->element, xml_start_ospatrol) == 0) ) ) { XML_NODE chld_node = NULL; chld_node = OS_GetElementsbyNode(&xml,node[i]); /* Main element does not need to have any child */ if(chld_node) { if(read_main_elements(xml, modules, chld_node, d1, d2) < 0) { merror(CONFIG_ERROR, ARGV0, cfgfile); return(OS_INVALID); } OS_ClearNode(chld_node); } } else if((modules & CAGENT_CONFIG) && (strcmp(node[i]->element, xml_start_agent) == 0)) { int passed_agent_test = 1; int attrs = 0; XML_NODE chld_node = NULL; chld_node = OS_GetElementsbyNode(&xml,node[i]); /* Checking if this is specific to any agent. */ if(node[i]->attributes && node[i]->values) { while(node[i]->attributes[attrs] && node[i]->values[attrs]) { /* Checking if there is an "name=" attribute */ if(strcmp(xml_agent_name, node[i]->attributes[attrs]) == 0) { #ifdef CLIENT char *agentname = os_read_agent_name(); if(!agentname) { passed_agent_test = 0; } else { if(!OS_Match2(node[i]->values[attrs], agentname)) { passed_agent_test = 0; } free(agentname); } #endif } else if(strcmp(xml_agent_os, node[i]->attributes[attrs]) == 0) { #ifdef CLIENT char *agentos = getuname(); if(agentos) { if(!OS_Match2(node[i]->values[attrs], agentos)) { passed_agent_test = 0; } free(agentos); } else { passed_agent_test = 0; merror("%s: ERROR: Unable to retrieve uname.", ARGV0); } #endif } else if(strcmp(xml_agent_profile, node[i]->attributes[attrs]) == 0) { #ifdef CLIENT char *agentprofile = os_read_agent_profile(); debug2("Read agent config profile name [%s]", agentprofile); if(!agentprofile) { passed_agent_test = 0; } else { /* match the profile name of this <agent_config> section * with a comma separated list of values in agent's * <config-profile> tag. */ if(!OS_Match2(node[i]->values[attrs], agentprofile)) { passed_agent_test = 0; debug2("[%s] did not match agent config profile name [%s]", node[i]->values[attrs], agentprofile); } else { debug2("Matched agent config profile name [%s]", agentprofile); } free(agentprofile); } #endif } /* cmoraes: end add */ else if(strcmp(xml_agent_overwrite, node[i]->attributes[attrs]) == 0) { } else { merror(XML_INVATTR, ARGV0, node[i]->attributes[attrs], cfgfile); } attrs++; } } #ifdef CLIENT else { debug2("agent_config element does not have any attributes."); /* if node does not have any attributes, it is a generic config block. * check if agent has a profile name * if agent does not have profile name, then only read this generic * agent_config block */ if (!os_read_agent_profile()) { debug2("but agent has a profile name."); passed_agent_test = 0; } } #endif /* Main element does not need to have any child */ if(chld_node) { if(passed_agent_test && read_main_elements(xml, modules, chld_node, d1, d2) < 0) { merror(CONFIG_ERROR, ARGV0, cfgfile); return(OS_INVALID); } OS_ClearNode(chld_node); } } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } /* Clearing node and xml */ OS_ClearNode(node); 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 main(int argc, char **argv) { int c, test_config = 0, run_foreground = 0; int uid=0,gid=0; char *dir = DEFAULTDIR; char *user = USER; char *group = GROUPGLOBAL; char *cfg = DEFAULTCPATH; /* Initializing global variables */ mond.a_queue = 0; /* Setting the name */ OS_SetName(ARGV0); while((c = getopt(argc, argv, "Vdhtfu:g:D:c:")) != -1){ switch(c){ case 'V': print_version(); break; case 'h': help(ARGV0); break; case 'd': nowDebug(); break; case 'f': run_foreground = 1; break; case 'u': if(!optarg) ErrorExit("%s: -u needs an argument",ARGV0); user=optarg; break; case 'g': if(!optarg) ErrorExit("%s: -g needs an argument",ARGV0); group=optarg; break; case 'D': if(!optarg) ErrorExit("%s: -D needs an argument",ARGV0); dir=optarg; case 'c': if(!optarg) ErrorExit("%s: -c needs an argument",ARGV0); cfg = optarg; break; case 't': test_config = 1; break; default: help(ARGV0); break; } } /* Starting daemon */ debug1(STARTED_MSG,ARGV0); /*Check if the user/group given are valid */ uid = Privsep_GetUser(user); gid = Privsep_GetGroup(group); if((uid < 0)||(gid < 0)) ErrorExit(USER_ERROR,ARGV0,user,group); /* Getting config options */ mond.day_wait = getDefine_Int("monitord", "day_wait", 5,240); mond.compress = getDefine_Int("monitord", "compress", 0,1); mond.sign = getDefine_Int("monitord","sign",0,1); mond.monitor_agents = getDefine_Int("monitord","monitor_agents",0,1); mond.agents = NULL; mond.smtpserver = NULL; mond.emailfrom = NULL; c = 0; c|= CREPORTS; if(ReadConfig(c, cfg, &mond, NULL) < 0) { ErrorExit(CONFIG_ERROR, ARGV0, cfg); } /* If we have any reports configured, read smtp/emailfrom */ if(mond.reports) { OS_XML xml; char *tmpsmtp; char *(xml_smtp[])={"ossec_config", "global", "smtp_server", NULL}; char *(xml_from[])={"ossec_config", "global", "email_from", NULL}; if(OS_ReadXML(cfg, &xml) < 0) { ErrorExit(CONFIG_ERROR, ARGV0, cfg); } tmpsmtp = OS_GetOneContentforElement(&xml,xml_smtp); mond.emailfrom = OS_GetOneContentforElement(&xml,xml_from); if(tmpsmtp && mond.emailfrom) { mond.smtpserver = OS_GetHost(tmpsmtp, 5); if(!mond.smtpserver) { merror(INVALID_SMTP, ARGV0, tmpsmtp); if(mond.emailfrom) free(mond.emailfrom); mond.emailfrom = NULL; merror("%s: Invalid SMTP server. Disabling email reports.", ARGV0); } } else { if(tmpsmtp) free(tmpsmtp); if(mond.emailfrom) free(mond.emailfrom); mond.emailfrom = NULL; merror("%s: SMTP server or 'email from' missing. Disabling email reports.", ARGV0); } OS_ClearXML(&xml); } /* Exit here if test config is set */ if(test_config) exit(0); if (!run_foreground) { /* Going on daemon mode */ nowDaemon(); goDaemon(); } /* Privilege separation */ if(Privsep_SetGroup(gid) < 0) ErrorExit(SETGID_ERROR,ARGV0,group); /* chrooting */ if(Privsep_Chroot(dir) < 0) ErrorExit(CHROOT_ERROR,ARGV0,dir); nowChroot(); /* Changing user */ if(Privsep_SetUser(uid) < 0) ErrorExit(SETUID_ERROR,ARGV0,user); debug1(PRIVSEP_MSG,ARGV0,dir,user); /* Signal manipulation */ StartSIG(ARGV0); /* Creating PID files */ if(CreatePID(ARGV0, getpid()) < 0) ErrorExit(PID_ERROR,ARGV0); /* Start up message */ verbose(STARTUP_MSG, ARGV0, (int)getpid()); /* the real daemon now */ Monitord(); exit(0); }
/* 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); }
/* 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); }