Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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);
}
Esempio n. 12
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);
}
Esempio n. 13
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);
}
Esempio n. 14
0
int main(int argc, char **argv)
{
    int i = 0;
    OS_XML xml;
    XML_NODE node = NULL;

    /* File name must be given */
    if (argc < 2) {
        printf("Usage: %s file\n", argv[0]);
        return (-1);
    }

    /* Read the XML. Print error and line number */
    if (OS_ReadXML(argv[1], &xml) < 0) {
        printf("OS_ReadXML error: %s, line :%d\n", xml.err, xml.err_line);
        return (1);
    }

    if (OS_ApplyVariables(&xml) != 0) {
        printf("OS_ReadXML error: Applying variables: %s\n", xml.err);
        return (1);
    }

    /* Get all nodes */
    node = OS_GetElementsbyNode(&xml, NULL);
    if (node == NULL) {
        printf("OS_GetElementsbyNode error: %s, line: %d\n", xml.err, xml.err_line);
        return (1);
    }

    i = 0;

    while (node[i]) {
        int j = 0;
        XML_NODE cnode;

        cnode = OS_GetElementsbyNode(&xml, node[i]);
        if (cnode == NULL) {
            i++;
            continue;
        }

        while (cnode[j]) {
            printf("Element: %s -> %s\n",
                   cnode[j]->element,
                   cnode[j]->content);
            if (cnode[j]->attributes && cnode[j]->values) {
                int k = 0;
                while (cnode[j]->attributes[k]) {
                    printf("attr %s:%s\n",
                           cnode[j]->attributes[k],
                           cnode[j]->values[k]);
                    k++;
                }
            }
            j++;
        }

        OS_ClearNode(cnode);
        i++;
    }

    /* Clear the nodes */
    OS_ClearNode(node);

    node = NULL;

    OS_ClearXML(&xml);

    return (0);
}