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);
}
Exemple #23
0
/* 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);
}
Exemple #24
0
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);
}
Exemple #26
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);
}
Exemple #27
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);
}
Exemple #28
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);
}
Exemple #29
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);
}