static void assert_os_xml_eq_str(OS_XML *xml, const char *xml_str)
{
    XML_NODE node = OS_GetElementsbyNode(xml, NULL);
    if (node == NULL) {
        ck_assert_str_eq(xml_str, "");
        return;
    }

    char *buffer = (char *) malloc(6144 * sizeof(char));
    buffer[0] = '\0';
    nodecat(node, xml, buffer);
    OS_ClearNode(node);

    ck_assert_str_eq(buffer, xml_str);

    free(buffer);
}
static void nodecat(XML_NODE node, OS_XML *xml, char *buffer)
{
    int i = 0;
    /* write node */
    while (node[i]) {
        strncat(buffer, "<", 1);
        ck_assert_ptr_ne(node[i]->element, NULL);
        strncat(buffer, node[i]->element, strlen(node[i]->element));
        /* write attributes */
        if (node[i]->attributes) {
            ck_assert_ptr_ne(node[i]->values, NULL);
            int j = 0;
            while (node[i]->attributes[j]) {
                strncat(buffer, " ", 1);
                ck_assert_ptr_ne(node[i]->values[j], NULL);
                strncat(buffer, node[i]->attributes[j], strlen(node[i]->attributes[j]));
                strncat(buffer, "=", 1);
                strncat(buffer, "\"", 1);
                strncat(buffer, node[i]->values[j], strlen(node[i]->values[j]));
                strncat(buffer, "\"", 1);
                j++;
            }
            ck_assert_ptr_eq(node[i]->values[j], NULL);
        } else {
            ck_assert_ptr_eq(node[i]->values, NULL);
        }
        strncat(buffer, ">", 1);
        ck_assert_ptr_ne(node[i]->content, NULL);
        strncat(buffer, node[i]->content, strlen(node[i]->content));

        /* write children */
        XML_NODE child = OS_GetElementsbyNode(xml, node[i]);
        if (child != NULL) {
            nodecat(child, xml, buffer);
            OS_ClearNode(child);
        }

        /* close node */
        strncat(buffer, "</", 2);
        strncat(buffer, node[i]->element, strlen(node[i]->element));
        strncat(buffer, ">", 1);
        i++;
    }
}
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);
}
Exemple #4
0
/* Read the main elements of the configuration.
 */
int read_main_elements(OS_XML xml, int modules,
                                   XML_NODE node,
                                   void *d1,
                                   void *d2)
{
    int i = 0;
    char *osglobal = "global";                    /*Server Config*/
    char *osrules = "rules";                      /*Server Config*/
    char *ossyscheck = "syscheck";                /*Agent Config*/
    char *osrootcheck = "rootcheck";              /*Agent Config*/
    char *osalerts = "alerts";                    /*Server Config*/
    char *osemailalerts = "email_alerts";         /*Server Config*/
    char *osdbd = "database_output";              /*Server Config*/
    char *oscsyslogd = "syslog_output";           /*Server Config*/
    char *oscagentless = "agentless";             /*Server Config*/
    char *oslocalfile = "localfile";              /*Agent Config*/
    char *osremote = "remote";                    /*Agent Config*/
    char *osclient = "client";                    /*Agent Config*/
    char *oscommand = "command";                  /*? Config*/
    char *osreports = "reports";                  /*Server Config*/
    char *osactive_response = "active-response";  /*Agent Config*/


    while(node[i])
    {
        XML_NODE chld_node = NULL;

        chld_node = OS_GetElementsbyNode(&xml,node[i]);

        if(!node[i]->element)
        {
            merror(XML_ELEMNULL, ARGV0);
            return(OS_INVALID);
        }
        else if(!chld_node)
        {
            merror(XML_INVELEM, ARGV0, node[i]->element);
            return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, osglobal) == 0)
        {
            if(((modules & CGLOBAL) || (modules & CMAIL))
                && (Read_Global(chld_node, d1, d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, osemailalerts) == 0)
        {
            if((modules & CMAIL) && (Read_EmailAlerts(chld_node, d1, d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, osdbd) == 0)
        {
            if((modules & CDBD) && (Read_DB(chld_node, d1, d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, oscsyslogd) == 0)
        {
            if((modules & CSYSLOGD) && (Read_CSyslog(chld_node, d1, d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, oscagentless) == 0)
        {
            if((modules & CAGENTLESS) && (Read_CAgentless(chld_node, d1, d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, osrules) == 0)
        {
            if((modules & CRULES) && (Read_Rules(chld_node, d1, d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, ossyscheck) == 0)
        {
            if((modules & CSYSCHECK) && (Read_Syscheck(chld_node, d1,d2) < 0))
                return(OS_INVALID);
            if((modules & CGLOBAL) && (Read_GlobalSK(chld_node, d1, d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, osrootcheck) == 0)
        {
            if((modules & CROOTCHECK) && (Read_Rootcheck(chld_node, d1,d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, osalerts) == 0)
        {
            if((modules & CALERTS) && (Read_Alerts(chld_node, d1,d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, oslocalfile) == 0)
        {
            if((modules & CLOCALFILE) && (Read_Localfile(chld_node, d1,d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, osremote) == 0)
        {
            if((modules & CREMOTE) && (Read_Remote(chld_node, d1,d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, osclient) == 0)
        {
            if((modules & CCLIENT) && (Read_Client(chld_node, d1,d2) < 0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, oscommand) == 0)
        {
            if((modules & CAR)&&(ReadActiveCommands(chld_node, d1, d2)<0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, osactive_response) == 0)
        {
            if((modules & CAR)&&(ReadActiveResponses(chld_node, d1, d2)<0))
                return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, osreports) == 0)
        {
            if((modules & CREPORTS)&&(Read_CReports(chld_node, d1, d2)<0))
                return(OS_INVALID);
        }
        else
        {
            merror(XML_INVELEM, ARGV0, node[i]->element);
            return(OS_INVALID);
        }

        //printf("before\n");
        OS_ClearNode(chld_node);
        //printf("after\n");
        i++;
    }

    return(0);
}
Exemple #5
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 #6
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);
}
END_TEST

START_TEST(test_osclearnode)
{
    OS_ClearNode(NULL);
}
Exemple #8
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 #9
0
int main(int argc, char ** argv)
{
    OS_XML xml;
    xml_node **node=NULL;
    int i = 0;

    if(argc < 2)
    {
        printf("usage: %s file\n",argv[0]);
        return(-1);
    }

    while(1)
    {
        usleep(10);
        printf(".");
        fflush(stdout);

        if(OS_ReadXML(argv[1],&xml) < 0)
        {
            printf("Error reading XML!%s\n",xml.err);
            return(1);
        }

        node = OS_GetElementsbyNode(&xml,NULL);
        if(node == NULL)
        {
            printf("error reading xml\n");
            return(1);
        }

        i = 0;

        while(node[i])
        {
            xml_node **cnode = NULL;
            int j=0;
            cnode = OS_GetElementsbyNode(&xml,node[i]);
            if(cnode == NULL)
            {
                i++;
                continue;
            }
            while(cnode[j])
            {
                /* */
                j++;
            }

            OS_ClearNode(cnode);
            i++;
        }

//        OS_ClearNode(node);

        node = NULL;

//        OS_ClearXML(&xml);
    }
    return(0);
}
Exemple #10
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);
}
Exemple #11
0
/* Read the main elements of the configuration */
static int read_main_elements(const OS_XML *xml, int modules,
                              XML_NODE node,
                              void *d1,
                              void *d2)
{
    int i = 0;
    const char *osglobal = "global";                    /* Server Config */
    const char *osrules = "rules";                      /* Server Config */
    const char *ossyscheck = "syscheck";                /* Agent Config  */
    const char *osrootcheck = "rootcheck";              /* Agent Config  */
    const char *osalerts = "alerts";                    /* Server Config */
    const char *osemailalerts = "email_alerts";         /* Server Config */
    const char *osdbd = "database_output";              /* Server Config */
    const char *oscsyslogd = "syslog_output";           /* Server Config */
    const char *oscagentless = "agentless";             /* Server Config */
    const char *oslocalfile = "localfile";              /* Agent Config  */
    const char *osremote = "remote";                    /* Agent Config  */
    const char *osclient = "client";                    /* Agent Config  */
    const char *oscommand = "command";                  /* ? Config      */
    const char *osreports = "reports";                  /* Server Config */
    const char *osintegratord = "integration";          /* Server Config */
    const char *osactive_response = "active-response";  /* Agent Config  */
    const char *oswmodule = "wodle";  /* Wodle - Wazuh Module  */

    while (node[i]) {
        XML_NODE chld_node = NULL;

        if (!node[i]->element) {
            merror(XML_ELEMNULL, __local_name);
            goto fail;
        } else if (!(chld_node = OS_GetElementsbyNode(xml, node[i]))) {
            merror(XML_INVELEM, __local_name, node[i]->element);
            goto fail;
        } else if (strcmp(node[i]->element, osglobal) == 0) {
            if (((modules & CGLOBAL) || (modules & CMAIL))
                    && (Read_Global(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, osemailalerts) == 0) {
            if ((modules & CMAIL) && (Read_EmailAlerts(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, osdbd) == 0) {
            if ((modules & CDBD) && (Read_DB(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, oscsyslogd) == 0) {
            if ((modules & CSYSLOGD) && (Read_CSyslog(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if(strcmp(node[i]->element, osintegratord) == 0) {
            if((modules & CINTEGRATORD) && (Read_Integrator(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, oscagentless) == 0) {
            if ((modules & CAGENTLESS) && (Read_CAgentless(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, osrules) == 0) {
            if ((modules & CRULES) && (Read_Rules(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, ossyscheck) == 0) {
            if ((modules & CSYSCHECK) && (Read_Syscheck(chld_node, d1, d2) < 0)) {
                goto fail;
            }
            if ((modules & CGLOBAL) && (Read_GlobalSK(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, osrootcheck) == 0) {
            if ((modules & CROOTCHECK) && (Read_Rootcheck(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, osalerts) == 0) {
            if ((modules & CALERTS) && (Read_Alerts(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, oslocalfile) == 0) {
            if ((modules & CLOCALFILE) && (Read_Localfile(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, osremote) == 0) {
            if ((modules & CREMOTE) && (Read_Remote(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, osclient) == 0) {
            if ((modules & CCLIENT) && (Read_Client(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, oscommand) == 0) {
            if ((modules & CAR) && (ReadActiveCommands(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, osactive_response) == 0) {
            if ((modules & CAR) && (ReadActiveResponses(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, osreports) == 0) {
            if ((modules & CREPORTS) && (Read_CReports(chld_node, d1, d2) < 0)) {
                goto fail;
            }
        } else if (strcmp(node[i]->element, oswmodule) == 0) {
            if ((modules & CWMODULE) && (Read_WModule(xml, node[i], d1, d2) < 0)) {
                goto fail;
            }
        } else {
            merror(XML_INVELEM, __local_name, node[i]->element);
            goto fail;
        }

        OS_ClearNode(chld_node);
        i++;

        continue;

        fail:
        OS_ClearNode(chld_node);
        return (OS_INVALID);
    }

    return (0);
}