Beispiel #1
0
void OS_InitFwLog()
{
    /* Initialize fw log regexes */
    if (!OSMatch_Compile(FWDROP, &FWDROPpm, 0)) {
        ErrorExit(REGEX_COMPILE, ARGV0, FWDROP,
                  FWDROPpm.error);
    }

    if (!OSMatch_Compile(FWALLOW, &FWALLOWpm, 0)) {
        ErrorExit(REGEX_COMPILE, ARGV0, FWALLOW,
                  FWALLOWpm.error);
    }
}
int dump_registry_ignore_regex(syscheck_config *syscheck, char *regex, int arch) {
    OSMatch *mt_pt;
    int ign_size = 0;

    if (!syscheck->registry_ignore_regex) {
        os_calloc(2, sizeof(registry_regex),
                  syscheck->registry_ignore_regex);
        syscheck->registry_ignore_regex[0].regex = NULL;
        syscheck->registry_ignore_regex[1].regex = NULL;
    } else {
        while (syscheck->registry_ignore_regex[ign_size].regex != NULL) {
            ign_size++;
        }

        os_realloc(syscheck->registry_ignore_regex,
                   sizeof(registry_regex) * (ign_size + 2),
                   syscheck->registry_ignore_regex);
        syscheck->registry_ignore_regex[ign_size + 1].regex = NULL;
    }

    os_calloc(1, sizeof(OSMatch),
              syscheck->registry_ignore_regex[ign_size].regex);

    if (!OSMatch_Compile(regex,
                         syscheck->registry_ignore_regex[ign_size].regex, 0)) {
        mt_pt = syscheck->registry_ignore_regex[ign_size].regex;
        merror(REGEX_COMPILE, __local_name, regex, mt_pt->error);
        return (0);
    }

    syscheck->registry_ignore_regex[ign_size].arch = arch;
    return 1;
}
int Read_CSyslog(XML_NODE node, void *config, void *config2)
{
    int i = 0,s = 0;

    /* XML definitions */
    char *xml_syslog_server = "server";
    char *xml_syslog_port = "port";
    char *xml_syslog_format = "format";
    char *xml_syslog_level = "level";
    char *xml_syslog_id = "rule_id";
    char *xml_syslog_group = "group";
    char *xml_syslog_location = "event_location";


    GeneralConfig *gen_config = (GeneralConfig *)config;
    SyslogConfig **syslog_config = (SyslogConfig **)gen_config->data;


    /* Getting Granular mail_to size */
    if(syslog_config)
    {
        while(syslog_config[s])
            s++;
    }


    /* Allocating the memory for the config. */
    os_realloc(syslog_config, (s + 2) * sizeof(SyslogConfig *), syslog_config);
    os_calloc(1, sizeof(SyslogConfig), syslog_config[s]);
    syslog_config[s + 1] = NULL;


    /* Zeroing the elements. */
    syslog_config[s]->server = NULL;
    syslog_config[s]->rule_id = NULL;
    syslog_config[s]->group = NULL;
    syslog_config[s]->location = NULL;
    syslog_config[s]->level = 0;
    syslog_config[s]->port = "514";
    syslog_config[s]->format = DEFAULT_CSYSLOG;
    /* local 0 facility (16) + severity 4 - warning. --default */
    syslog_config[s]->priority = (16 * 8) + 4;

    while(node[i])
    {
        if(!node[i]->element)
        {
            merror(XML_ELEMNULL, ARGV0);
            return(OS_INVALID);
        }
        else if(!node[i]->content)
        {
            merror(XML_VALUENULL, ARGV0, node[i]->element);
            return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, xml_syslog_level) == 0)
        {
            if(!OS_StrIsNum(node[i]->content))
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }

            syslog_config[s]->level = atoi(node[i]->content);
        }
        else if(strcmp(node[i]->element, xml_syslog_port) == 0)
        {
            if(!OS_StrIsNum(node[i]->content))
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
            os_strdup(node[i]->content, syslog_config[s]->port);
        }
        else if(strcmp(node[i]->element, xml_syslog_server) == 0)
        {
            os_strdup(node[i]->content, syslog_config[s]->server);
        }
        else if(strcmp(node[i]->element, xml_syslog_id) == 0)
        {
            int r_id = 0;
            char *str_pt = node[i]->content;

            while(*str_pt != '\0')
            {
                /* We allow spaces in between */
                if(*str_pt == ' ')
                {
                    str_pt++;
                    continue;
                }

                /* If is digit, we get the value
                 * and search for the next digit
                 * available
                 */
                else if(isdigit((int)*str_pt))
                {
                    int id_i = 0;

                    r_id = atoi(str_pt);
                    debug1("%s: DEBUG: Adding '%d' to syslog alerting",
                           ARGV0, r_id);

                    if(syslog_config[s]->rule_id)
                    {
                        while(syslog_config[s]->rule_id[id_i])
                            id_i++;
                    }

                    os_realloc(syslog_config[s]->rule_id,
                               (id_i +2) * sizeof(int),
                               syslog_config[s]->rule_id);

                    syslog_config[s]->rule_id[id_i + i] = 0;
                    syslog_config[s]->rule_id[id_i] = r_id;

                    str_pt = strchr(str_pt, ',');
                    if(str_pt)
                    {
                        str_pt++;
                    }
                    else
                    {
                        break;
                    }
                }

                /* Checking for duplicate commas */
                else if(*str_pt == ',')
                {
                    str_pt++;
                    continue;
                }

                else
                {
                    break;
                }
            }

        }
        else if(strcmp(node[i]->element, xml_syslog_format) == 0)
        {
            if(strcmp(node[i]->content, "default") == 0)
            {
                /* Default is full format */
            }
            else if (strcmp(node[i]->content, "cef") == 0)
            {
                /* Enable the CEF format */
                syslog_config[s]->format = CEF_CSYSLOG;
            }
            else if (strcmp(node[i]->content, "json") == 0)
            {
                /* Enable the JSON format */
                syslog_config[s]->format = JSON_CSYSLOG;
            }
            else if (strcmp(node[i]->content, "splunk") == 0)
            {
                /* Enable the Splunk Key/Value format */
                syslog_config[s]->format = SPLUNK_CSYSLOG;
            }
            else
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
        }
        else if(strcmp(node[i]->element, xml_syslog_location) == 0)
        {
            os_calloc(1, sizeof(OSMatch),syslog_config[s]->location);
            if(!OSMatch_Compile(node[i]->content,
                                syslog_config[s]->location, 0))
            {
                merror(REGEX_COMPILE, ARGV0, node[i]->content,
                       syslog_config[s]->location->error);
                return(-1);
            }
        }
        else if(strcmp(node[i]->element, xml_syslog_group) == 0)
        {
            os_calloc(1, sizeof(OSMatch),syslog_config[s]->group);
            if(!OSMatch_Compile(node[i]->content,
                                syslog_config[s]->group, 0))
            {
                merror(REGEX_COMPILE, ARGV0, node[i]->content,
                       syslog_config[s]->group->error);
                return(-1);
            }
        }
        else
        {
            merror(XML_INVELEM, ARGV0, node[i]->element);
            return(OS_INVALID);
        }
        i++;
    }


    /* We must have at least one entry set */
    if(!syslog_config[s]->server)
    {
        merror(XML_INV_CSYSLOG, ARGV0);
        return(OS_INVALID);
    }


    gen_config->data = syslog_config;
    return(0);
}
int dump_syscheck_entry(syscheck_config *syscheck, const char *entry, int vals, int reg, const char *restrictfile)
{
    unsigned int pl = 0;

    if (reg == 1) {
#ifdef WIN32
        if (syscheck->registry == NULL) {
            os_calloc(2, sizeof(registry), syscheck->registry);
            syscheck->registry[pl + 1].entry = NULL;
            syscheck->registry[pl].arch = vals;
            os_strdup(entry, syscheck->registry[pl].entry);
        } else {
            while (syscheck->registry[pl].entry != NULL) {
                pl++;
            }
            os_realloc(syscheck->registry, (pl + 2) * sizeof(registry),
                       syscheck->registry);
            syscheck->registry[pl + 1].entry = NULL;
            syscheck->registry[pl].arch = vals;
            os_strdup(entry, syscheck->registry[pl].entry);
        }

#endif
    }

    else {
        if (syscheck->dir == NULL) {
            os_calloc(2, sizeof(char *), syscheck->dir);
            syscheck->dir[pl + 1] = NULL;
            os_strdup(entry, syscheck->dir[pl]);

            os_calloc(2, sizeof(int), syscheck->opts);
            syscheck->opts[pl + 1] = 0;
            syscheck->opts[pl] = vals;

            os_calloc(2, sizeof(OSMatch *), syscheck->filerestrict);
            syscheck->filerestrict[pl] = NULL;
            syscheck->filerestrict[pl + 1] = NULL;
        } else {
            while (syscheck->dir[pl] != NULL) {
                pl++;
            }
            os_realloc(syscheck->dir, (pl + 2) * sizeof(char *),
                       syscheck->dir);
            syscheck->dir[pl + 1] = NULL;
            os_strdup(entry, syscheck->dir[pl]);

            os_realloc(syscheck->opts, (pl + 2) * sizeof(int),
                       syscheck->opts);
            syscheck->opts[pl + 1] = 0;
            syscheck->opts[pl] = vals;

            os_realloc(syscheck->filerestrict, (pl + 2) * sizeof(OSMatch *),
                       syscheck->filerestrict);
            syscheck->filerestrict[pl] = NULL;
            syscheck->filerestrict[pl + 1] = NULL;
        }
        if (restrictfile) {
            os_calloc(1, sizeof(OSMatch), syscheck->filerestrict[pl]);
            if (!OSMatch_Compile(restrictfile, syscheck->filerestrict[pl], 0)) {
                OSMatch *ptm;

                ptm = syscheck->filerestrict[pl];

                merror(REGEX_COMPILE, __local_name, restrictfile,
                       ptm->error);
                free(syscheck->filerestrict[pl]);
                syscheck->filerestrict[pl] = NULL;
            }
        }
    }

    return (1);
}
Beispiel #5
0
int Read_Syscheck(XML_NODE node, void *configp, void *mailp)
{
    int i = 0;

    /* XML Definitions */
    char *xml_directories = "directories";
    char *xml_registry = "windows_registry";
    char *xml_time = "frequency";
    char *xml_scanday = "scan_day";
    char *xml_scantime = "scan_time";
    char *xml_ignore = "ignore";
    char *xml_registry_ignore = "registry_ignore";
    char *xml_auto_ignore = "auto_ignore";
    char *xml_alert_new_files = "alert_new_files";
    char *xml_disabled = "disabled";
    char *xml_scan_on_start = "scan_on_start";
    char *xml_prefilter_cmd = "prefilter_cmd";

    /* Configuration example
    <directories check_all="yes">/etc,/usr/bin</directories>
    <directories check_owner="yes" check_group="yes" check_perm="yes"
    check_sum="yes">/var/log</directories>
    */

    config *syscheck;

    syscheck = (config *)configp;


    while(node[i])
    {
        if(!node[i]->element)
        {
            merror(XML_ELEMNULL, ARGV0);
            return(OS_INVALID);
        }
        else if(!node[i]->content)
        {
            merror(XML_VALUENULL, ARGV0, node[i]->element);
            return(OS_INVALID);
        }

        /* Getting directories */
        else if(strcmp(node[i]->element,xml_directories) == 0)
        {
            char dirs[OS_MAXSTR];

            #ifdef WIN32
            ExpandEnvironmentStrings(node[i]->content, dirs, sizeof(dirs) -1);
            #else
            strncpy(dirs, node[i]->content, sizeof(dirs) -1);
            #endif

            if(!read_attr(syscheck,
                        dirs,
                        node[i]->attributes,
                        node[i]->values))
            {
                return(OS_INVALID);
            }
        }
        /* Getting windows registry */
        else if(strcmp(node[i]->element,xml_registry) == 0)
        {
            #ifdef WIN32
            if(!read_reg(syscheck, node[i]->content))
            {
                return(OS_INVALID);
            }
            #endif
        }
        /* Getting frequency */
        else if(strcmp(node[i]->element,xml_time) == 0)
        {
            if(!OS_StrIsNum(node[i]->content))
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }

            syscheck->time = atoi(node[i]->content);
        }
        /* Getting scan time */
        else if(strcmp(node[i]->element,xml_scantime) == 0)
        {
            syscheck->scan_time = OS_IsValidUniqueTime(node[i]->content);
            if(!syscheck->scan_time)
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
        }

        /* Getting scan day */
        else if(strcmp(node[i]->element,xml_scanday) == 0)
        {
            syscheck->scan_day = OS_IsValidDay(node[i]->content);
            if(!syscheck->scan_day)
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
        }

        /* Getting if xml_scan_on_start. */
        else if(strcmp(node[i]->element, xml_scan_on_start) == 0)
        {
            if(strcmp(node[i]->content, "yes") == 0)
                syscheck->scan_on_start = 1;
            else if(strcmp(node[i]->content, "no") == 0)
                syscheck->scan_on_start = 0;
            else
            {
                merror(XML_VALUEERR,ARGV0, node[i]->element, node[i]->content);
                return(OS_INVALID);
            }
        }

        /* Getting if disabled. */
        else if(strcmp(node[i]->element,xml_disabled) == 0)
        {
            if(strcmp(node[i]->content, "yes") == 0)
                syscheck->disabled = 1;
            else if(strcmp(node[i]->content, "no") == 0)
                syscheck->disabled = 0;
            else
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
        }

        /* Getting file/dir ignore */
        else if(strcmp(node[i]->element,xml_ignore) == 0)
        {
            int ign_size = 0;

            /* For Windows, we attempt to expand environment variables. */
            #ifdef WIN32
            char *new_ig = NULL;
            os_calloc(2048, sizeof(char), new_ig);

            ExpandEnvironmentStrings(node[i]->content, new_ig, 2047);

            free(node[i]->content);
            node[i]->content = new_ig;
            #endif

            /* Adding if regex */
            if(node[i]->attributes && node[i]->values)
            {
                if(node[i]->attributes[0] && node[i]->values[0] &&
                   (strcmp(node[i]->attributes[0], "type") == 0) &&
                   (strcmp(node[i]->values[0], "sregex") == 0))
                {
                    OSMatch *mt_pt;

                    if(!syscheck->ignore_regex)
                    {
                        os_calloc(2, sizeof(OSMatch *),syscheck->ignore_regex);
                        syscheck->ignore_regex[0] = NULL;
                        syscheck->ignore_regex[1] = NULL;
                    }
                    else
                    {
                        while(syscheck->ignore_regex[ign_size] != NULL)
                            ign_size++;

                        os_realloc(syscheck->ignore_regex,
                                sizeof(OSMatch *)*(ign_size +2),
                                syscheck->ignore_regex);
                        syscheck->ignore_regex[ign_size +1] = NULL;
                    }
                    os_calloc(1, sizeof(OSMatch),
                            syscheck->ignore_regex[ign_size]);

                    if(!OSMatch_Compile(node[i]->content,
                                        syscheck->ignore_regex[ign_size], 0))
                    {
                        mt_pt = (OSMatch *)syscheck->ignore_regex[ign_size];
                        merror(REGEX_COMPILE, ARGV0, node[i]->content,
                              mt_pt->error);
                        return(0);
                    }
                }
                else
                {
                    merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]);
                    return(OS_INVALID);
                }
            }

            /* Adding if simple entry -- checking for duplicates */
            else if(!os_IsStrOnArray(node[i]->content, syscheck->ignore))
            {
                if(!syscheck->ignore)
                {
                    os_calloc(2, sizeof(char *), syscheck->ignore);
                    syscheck->ignore[0] = NULL;
                    syscheck->ignore[1] = NULL;
                }
                else
                {
                    while(syscheck->ignore[ign_size] != NULL)
                        ign_size++;

                    os_realloc(syscheck->ignore,
                            sizeof(char *)*(ign_size +2),
                            syscheck->ignore);
                    syscheck->ignore[ign_size +1] = NULL;
                }
                os_strdup(node[i]->content,syscheck->ignore[ign_size]);
            }
        }

        /* Getting registry ignore list */
        else if(strcmp(node[i]->element,xml_registry_ignore) == 0)
        {
            #ifdef WIN32
            int ign_size = 0;

            /* Adding if regex */
            if(node[i]->attributes && node[i]->values)
            {
                if(node[i]->attributes[0] && node[i]->values[0] &&
                   (strcmp(node[i]->attributes[0], "type") == 0) &&
                   (strcmp(node[i]->values[0], "sregex") == 0))
                {
                    OSMatch *mt_pt;

                    if(!syscheck->registry_ignore_regex)
                    {
                        os_calloc(2, sizeof(OSMatch *),
                                     syscheck->registry_ignore_regex);
                        syscheck->registry_ignore_regex[0] = NULL;
                        syscheck->registry_ignore_regex[1] = NULL;
                    }
                    else
                    {
                        while(syscheck->registry_ignore_regex[ign_size] !=NULL)
                            ign_size++;

                        os_realloc(syscheck->registry_ignore_regex,
                                sizeof(OSMatch *)*(ign_size +2),
                                syscheck->registry_ignore_regex);
                        syscheck->registry_ignore_regex[ign_size +1] = NULL;
                    }

                    os_calloc(1, sizeof(OSMatch),
                            syscheck->registry_ignore_regex[ign_size]);

                    if(!OSMatch_Compile(node[i]->content,
                                syscheck->registry_ignore_regex[ign_size], 0))
                    {
                        mt_pt = (OSMatch *)
                                syscheck->registry_ignore_regex[ign_size];
                        merror(REGEX_COMPILE, ARGV0, node[i]->content,
                             mt_pt->error);
                        return(0);
                    }
                }
                else
                {
                    merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]);
                    return(OS_INVALID);
                }
            }
            /* We do not add duplicated entries */
            else if(!os_IsStrOnArray(node[i]->content,
                     syscheck->registry_ignore))
            {
                if(!syscheck->registry_ignore)
                {
                    os_calloc(2, sizeof(char *), syscheck->registry_ignore);
                    syscheck->registry_ignore[0] = NULL;
                    syscheck->registry_ignore[1] = NULL;
                }
                else
                {
                    while(syscheck->registry_ignore[ign_size] != NULL)
                        ign_size++;

                    os_realloc(syscheck->registry_ignore,
                            sizeof(char *)*(ign_size +2),
                            syscheck->registry_ignore);
                    syscheck->registry_ignore[ign_size +1] = NULL;
                }
                os_strdup(node[i]->content,syscheck->registry_ignore[ign_size]);
            }
            #endif
        }
        else if(strcmp(node[i]->element,xml_auto_ignore) == 0)
        {
            /* auto_ignore is not read here. */
        }
        else if(strcmp(node[i]->element,xml_alert_new_files) == 0)
        {
            /* alert_new_files option is not read here. */
        }
        else if(strcmp(node[i]->element,xml_prefilter_cmd) == 0)
        {
            char cmd[OS_MAXSTR];
            struct stat statbuf;

            #ifdef WIN32
            ExpandEnvironmentStrings(node[i]->content, cmd, sizeof(cmd) -1);
            #else
            strncpy(cmd, node[i]->content, sizeof(cmd)-1);
            #endif

            if (strlen(cmd) > 0) {
                char statcmd[OS_MAXSTR];
                char *ix;
                strncpy(statcmd, cmd, sizeof(statcmd)-1);
                if (NULL != (ix = strchr(statcmd, ' '))) { *ix = '\0'; }
                if (stat(statcmd, &statbuf) == 0) {
                    // More checks needed (perms, owner, etc.)
                    os_calloc(1, strlen(cmd)+1, syscheck->prefilter_cmd);
                    strncpy(syscheck->prefilter_cmd, cmd, strlen(cmd));
                }
                else
                {
                    merror(XML_VALUEERR,ARGV0, node[i]->element, node[i]->content);
                    return(OS_INVALID);
                }
            }
        }
        else
        {
            merror(XML_INVELEM, ARGV0, node[i]->element);
            return(OS_INVALID);
        }
        i++;
    }

    return(0);
}
Beispiel #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);
}
Beispiel #7
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);
}
/** main **/
int main(int argc, char **argv)
{
    char *pattern;
    
    char msg[OS_MAXSTR +1];
    memset(msg, '\0', OS_MAXSTR +1);
    OSRegex regex; 
    OSMatch matcher; 

    OS_SetName(ARGV0);
        
    
    /* user arguments */
    if(argc != 2)
    {
        helpmsg();
        return(-1);
    }
    
    /* User options */
    if(strcmp(argv[1], "-h") == 0)
    {
        helpmsg();
        return(-1);
    }

    os_strdup(argv[1], pattern);
    if(!OSRegex_Compile(pattern, &regex, 0)) 
    { 
        printf("pattern does not compile with OSRegex_Compile\n");
        return(-1); 
    }
    if(!OSMatch_Compile(pattern, &matcher, 0))
    {
        printf("pattern does not compile with OSMatch_Compile\n");
        return(-1);
    }


    while((fgets(msg, OS_MAXSTR, stdin)) != NULL)
    {        
        /* Removing new line. */                                                                                                                                       
        if(msg[strlen(msg) -1] == '\n')
            msg[strlen(msg) -1] = '\0';

        /* Make sure we ignore blank lines. */                                                                                                                         
        if(strlen(msg) < 2) { continue; }                                                            

        if(OSRegex_Execute(msg, &regex))
            printf("+OSRegex_Execute: %s\n",msg); 
        /*
        else
            printf("-OSRegex_Execute: \n"); 
            */

        if(OS_Regex(pattern, msg)) 
            printf("+OS_Regex       : %s\n", msg);
        /*
        else
            printf("-OS_Regex: \n"); 
            */

        if(OSMatch_Execute(msg, strlen(msg), &matcher)) 
            printf("+OSMatch_Compile: %s\n", msg); 
        
        if(OS_Match2(pattern, msg)) 
            printf("+OS_Match2      : %s\n", msg); 
    }
    return(0);
}
Beispiel #9
0
int Read_EmailAlerts(XML_NODE node, void *configp, void *mailp)
{
    int i = 0;
    int granto_size = 1;

    /* XML definitions */
    char *xml_email_to = "email_to";
    char *xml_email_format = "format";
    char *xml_email_level = "level";
    char *xml_email_id = "rule_id";
    char *xml_email_group = "group";
    char *xml_email_location = "event_location";
    char *xml_email_donotdelay = "do_not_delay";
    char *xml_email_donotgroup = "do_not_group";

    MailConfig *Mail;

    Mail = (MailConfig *)mailp;
    if(!Mail)
    {
        return(0);
    }


    /* Getting Granular mail_to size */
    if(Mail && Mail->gran_to)
    {
        char **ww;
        ww = Mail->gran_to;
        while(*ww != NULL)
        {
            ww++;
            granto_size++;
        }
    }


    if(Mail)
    {
        os_realloc(Mail->gran_to,
                   sizeof(char *)*(granto_size +1), Mail->gran_to);
        os_realloc(Mail->gran_id,
                   sizeof(int *)*(granto_size +1), Mail->gran_id);
        os_realloc(Mail->gran_level,
                   sizeof(int)*(granto_size +1), Mail->gran_level);
        os_realloc(Mail->gran_set,
                   sizeof(int)*(granto_size +1), Mail->gran_set);
        os_realloc(Mail->gran_format,
                   sizeof(int)*(granto_size +1), Mail->gran_format);
        os_realloc(Mail->gran_location,
                   sizeof(OSMatch)*(granto_size +1), Mail->gran_location);
        os_realloc(Mail->gran_group,
                   sizeof(OSMatch)*(granto_size +1), Mail->gran_group);

        Mail->gran_to[granto_size -1] = NULL;
        Mail->gran_to[granto_size] = NULL;

        Mail->gran_id[granto_size -1] = NULL;
        Mail->gran_id[granto_size] = NULL;

        Mail->gran_location[granto_size -1] = NULL;
        Mail->gran_location[granto_size] = NULL;

        Mail->gran_group[granto_size -1] = NULL;
        Mail->gran_group[granto_size] = NULL;

        Mail->gran_level[granto_size -1] = 0;
        Mail->gran_level[granto_size] = 0;

        Mail->gran_format[granto_size -1] = FULL_FORMAT;
        Mail->gran_format[granto_size] = FULL_FORMAT;

        Mail->gran_set[granto_size -1] = 0;
        Mail->gran_set[granto_size] = 0;
    }


    while(node[i])
    {
        if(!node[i]->element)
        {
            merror(XML_ELEMNULL, ARGV0);
            return(OS_INVALID);
        }
        else if(!node[i]->content)
        {
            merror(XML_VALUENULL, ARGV0, node[i]->element);
            return(OS_INVALID);
        }
        /* Mail notification */
        else if(strcmp(node[i]->element, xml_email_level) == 0)
        {
            if(!OS_StrIsNum(node[i]->content))
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }

            Mail->gran_level[granto_size -1] = atoi(node[i]->content);
        }
        else if(strcmp(node[i]->element, xml_email_to) == 0)
        {
            os_strdup(node[i]->content, Mail->gran_to[granto_size -1]);
        }
        else if(strcmp(node[i]->element, xml_email_id) == 0)
        {
            int r_id = 0;
            char *str_pt = node[i]->content;

            while(*str_pt != '\0')
            {
                /* We allow spaces in between */
                if(*str_pt == ' ')
                {
                    str_pt++;
                    continue;
                }

                /* If is digit, we get the value
                 * and search for the next digit
                 * available
                 */
                else if(isdigit((int)*str_pt))
                {
                    int id_i = 0;

                    r_id = atoi(str_pt);
                    debug1("%s: DEBUG: Adding '%d' to granular e-mail",
                           ARGV0, r_id);

                    if(!Mail->gran_id[granto_size -1])
                    {
                        os_calloc(2,sizeof(int),Mail->gran_id[granto_size -1]);
                        Mail->gran_id[granto_size -1][0] = 0;
                        Mail->gran_id[granto_size -1][1] = 0;
                    }
                    else
                    {
                        while(Mail->gran_id[granto_size -1][id_i] != 0)
                        {
                            id_i++;
                        }

                        os_realloc(Mail->gran_id[granto_size -1],
                                   (id_i +2) * sizeof(int),
                                   Mail->gran_id[granto_size -1]);
                        Mail->gran_id[granto_size -1][id_i +1] = 0;
                    }
                    Mail->gran_id[granto_size -1][id_i] = r_id;


                    str_pt = strchr(str_pt, ',');
                    if(str_pt)
                    {
                        str_pt++;
                    }
                    else
                    {
                        break;
                    }
                }

                /* Checking for duplicate commas */
                else if(*str_pt == ',')
                {
                    str_pt++;
                    continue;
                }

                else
                {
                    break;
                }
            }

        }
        else if(strcmp(node[i]->element, xml_email_format) == 0)
        {
            if(strcmp(node[i]->content, "sms") == 0)
            {
                Mail->gran_format[granto_size -1] = SMS_FORMAT;
            }
            else if(strcmp(node[i]->content, "default") == 0)
            {
                /* Default is full format */
            }
            else
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
        }
        else if(strcmp(node[i]->element, xml_email_donotdelay) == 0)
        {
            if((Mail->gran_format[granto_size -1] != SMS_FORMAT) &&
               (Mail->gran_format[granto_size -1] != DONOTGROUP))
            {
                Mail->gran_format[granto_size -1] = FORWARD_NOW;
            }
        }
        else if(strcmp(node[i]->element, xml_email_donotgroup) == 0)
        {
            if(Mail->gran_format[granto_size -1] != SMS_FORMAT)
            {
                Mail->gran_format[granto_size -1] = DONOTGROUP;
            }
        }
        else if(strcmp(node[i]->element, xml_email_location) == 0)
        {
            os_calloc(1, sizeof(OSMatch),Mail->gran_location[granto_size -1]);
            if(!OSMatch_Compile(node[i]->content,
                                Mail->gran_location[granto_size -1], 0))
            {
                merror(REGEX_COMPILE, ARGV0, node[i]->content,
                        Mail->gran_location[granto_size -1]->error);
                return(-1);
            }
        }
        else if(strcmp(node[i]->element, xml_email_group) == 0)
        {
            os_calloc(1, sizeof(OSMatch),Mail->gran_group[granto_size -1]);
            if(!OSMatch_Compile(node[i]->content,
                                Mail->gran_group[granto_size -1], 0))
            {
                merror(REGEX_COMPILE, ARGV0, node[i]->content,
                        Mail->gran_group[granto_size -1]->error);
                return(-1);
            }
        }
        else
        {
            merror(XML_INVELEM, ARGV0, node[i]->element);
            return(OS_INVALID);
        }
        i++;
    }

    /* We must have at least one entry set */
    if((Mail->gran_location[granto_size -1] == NULL &&
       Mail->gran_level[granto_size -1] == 0 &&
       Mail->gran_group[granto_size -1] == NULL &&
       Mail->gran_id[granto_size -1] == NULL &&
       Mail->gran_format[granto_size -1] == FULL_FORMAT) ||
       Mail->gran_to[granto_size -1] == NULL)
       {
           merror(XML_INV_GRAN_MAIL, ARGV0);
           return(OS_INVALID);
       }

    return(0);
}
Beispiel #10
0
/* GlobalConf v0.2: 2005/03/03
 * v0.2: Changing to support the new OS_XML
 */
int Read_Global(XML_NODE node, void *configp, void *mailp)
{
    int i = 0;

    /* White list size */
    int white_size = 1;
    int hostname_white_size = 1;
    int mailto_size = 1;


    /* XML definitions */
    char *xml_mailnotify = "email_notification";
    char *xml_logall = "logall";
    char *xml_integrity = "integrity_checking";
    char *xml_rootcheckd = "rootkit_detection";
    char *xml_hostinfo = "host_information";
    char *xml_picviz = "picviz_output";
    char *xml_picviz_socket = "picviz_socket";
    char *xml_prelude = "prelude_output";
    char *xml_prelude_profile = "prelude_profile";
    char *xml_prelude_log_level = "prelude_log_level";
    char *xml_zeromq_output = "zeromq_output";
    char *xml_zeromq_output_uri = "zeromq_uri";
    char *xml_stats = "stats";
    char *xml_memorysize = "memory_size";
    char *xml_white_list = "white_list";
    char *xml_compress_alerts = "compress_alerts";
    char *xml_custom_alert_output = "custom_alert_output";

    char *xml_emailto = "email_to";
    char *xml_emailfrom = "email_from";
    char *xml_emailidsname = "email_idsname";
    char *xml_smtpserver = "smtp_server";
    char *xml_mailmaxperhour = "email_maxperhour";

#ifdef GEOIP
    /* GeoIP */
    char *xml_geoip_db_path = "geoip_db_path";
    char *xml_geoip6_db_path = "geoip6_db_path";
#endif

    _Config *Config;
    MailConfig *Mail;

    Config = (_Config *)configp;
    Mail = (MailConfig *)mailp;

    /* Getting right white_size */
    if(Config && Config->white_list)
    {
        os_ip **ww;
        ww = Config->white_list;

        while(*ww != NULL)
        {
            white_size++;
            ww++;
        }
    }

     /* Getting right white_size */
    if(Config && Config->hostname_white_list)
    {
        OSMatch **ww;
        ww = Config->hostname_white_list;

        while(*ww != NULL)
        {
            hostname_white_size++;
            ww++;
        }
    }

    /* Getting mail_to size */
    if(Mail && Mail->to)
    {
        char **ww;
        ww = Mail->to;
        while(*ww != NULL)
        {
            mailto_size++;
            ww++;
        }
    }

    while(node[i])
    {
        if(!node[i]->element)
        {
            merror(XML_ELEMNULL, ARGV0);
            return(OS_INVALID);
        }
        else if(!node[i]->content)
        {
            merror(XML_VALUENULL, ARGV0, node[i]->element);
            return(OS_INVALID);
        }
        else if(strcmp(node[i]->element, xml_custom_alert_output) == 0)
        {
          if(Config)
          {
            Config->custom_alert_output= 1;
            os_strdup(node[i]->content, Config->custom_alert_output_format);
          }
        }
        /* Mail notification */
        else if(strcmp(node[i]->element, xml_mailnotify) == 0)
        {
            if(strcmp(node[i]->content, "yes") == 0)
            {
                if(Config) Config->mailnotify = 1;
                if(Mail) Mail->mn = 1;
            }
            else if(strcmp(node[i]->content, "no") == 0)
            {
                if(Config) Config->mailnotify = 0;
                if(Mail) Mail->mn = 0;
            }
            else
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
        }
        /* Picviz support */
        else if(strcmp(node[i]->element, xml_picviz) == 0)
        {
            if(strcmp(node[i]->content, "yes") == 0)
            {
                if(Config) Config->picviz = 1;
            }
            else if(strcmp(node[i]->content, "no") == 0)
            {
                if(Config) Config->picviz = 0;
            }
            else
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element, node[i]->content);
                return(OS_INVALID);
            }
        }
        else if(strcmp(node[i]->element, xml_picviz_socket) == 0)
        {
            if(Config)
            {
                os_strdup(node[i]->content, Config->picviz_socket);
            }
        }
        /* Prelude support */
        else if(strcmp(node[i]->element, xml_prelude) == 0)
        {
            if(strcmp(node[i]->content, "yes") == 0)
            {
                if(Config) Config->prelude = 1;
            }
            else if(strcmp(node[i]->content, "no") == 0)
            {
                if(Config) Config->prelude = 0;
            }
            else
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element, node[i]->content);
                return(OS_INVALID);
            }
        }
        else if(strcmp(node[i]->element, xml_prelude_profile) == 0)
        {
            if(Config)
            {
                Config->prelude_profile = strdup(node[i]->content);
            }
        }
        else if(strcmp(node[i]->element, xml_prelude_log_level) == 0)
        {
            if(!OS_StrIsNum(node[i]->content))
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }

            if(Config)
            {
                Config->prelude_log_level = atoi(node[i]->content);
            }
        }
        /* ZeroMQ output */
        else if(strcmp(node[i]->element, xml_zeromq_output) == 0)
        {
            if(strcmp(node[i]->content, "yes") == 0)
            { 
                if(Config) Config->zeromq_output = 1; 
            }
            else if(strcmp(node[i]->content, "no") == 0)
            { 
                if(Config) Config->zeromq_output = 0; 
            }
            else
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element, node[i]->content);
                return(OS_INVALID);
            }
        }
        else if(strcmp(node[i]->element, xml_zeromq_output_uri) == 0)
        {
            if(Config)
            {
                Config->zeromq_output_uri = strdup(node[i]->content);
            }
        }
        /* Log all */
        else if(strcmp(node[i]->element, xml_logall) == 0)
        {
            if(strcmp(node[i]->content, "yes") == 0)
                { if(Config) Config->logall = 1;}
            else if(strcmp(node[i]->content, "no") == 0)
                {if(Config) Config->logall = 0;}
            else
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
        }
        /* compress alerts */
        else if(strcmp(node[i]->element, xml_compress_alerts) == 0)
        {
            /* removed from here -- compatility issues only */
        }
        /* Integrity */
        else if(strcmp(node[i]->element, xml_integrity) == 0)
        {
            if(!OS_StrIsNum(node[i]->content))
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
            if(Config)
            {
                Config->integrity = atoi(node[i]->content);
            }
        }
        /* rootcheck */
        else if(strcmp(node[i]->element, xml_rootcheckd) == 0)
        {
            if(!OS_StrIsNum(node[i]->content))
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
            if(Config)
            {
                Config->rootcheck = atoi(node[i]->content);
            }
        }
        /* hostinfo */
        else if(strcmp(node[i]->element, xml_hostinfo) == 0)
        {
            if(!OS_StrIsNum(node[i]->content))
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
            if(Config)
            {
                Config->hostinfo = atoi(node[i]->content);
            }
        }
        /* stats */
        else if(strcmp(node[i]->element, xml_stats) == 0)
        {
            if(!OS_StrIsNum(node[i]->content))
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
            if(Config)
            {
                Config->stats = atoi(node[i]->content);
            }
        }
        else if(strcmp(node[i]->element, xml_memorysize) == 0)
        {
            if(!OS_StrIsNum(node[i]->content))
            {
                merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                return(OS_INVALID);
            }
            if(Config)
            {
                Config->memorysize = atoi(node[i]->content);
            }
        }
        /* whitelist */
        else if(strcmp(node[i]->element, xml_white_list) == 0)
        {
            /* Windows do not need it */
            #ifndef WIN32

            char *ip_address_regex =
             "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}/?"
             "([0-9]{0,2}|[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})$";

            if(Config && OS_PRegex(node[i]->content, ip_address_regex))
            {
                white_size++;
                Config->white_list =
                    realloc(Config->white_list, sizeof(os_ip *)*white_size);
                if(!Config->white_list)
                {
                    merror(MEM_ERROR, ARGV0);
                    return(OS_INVALID);
                }

                os_calloc(1, sizeof(os_ip), Config->white_list[white_size -2]);
                Config->white_list[white_size -1] = NULL;

                if(!OS_IsValidIP(node[i]->content,
                                 Config->white_list[white_size -2]))
                {
                    merror(INVALID_IP, ARGV0,
                                       node[i]->content);
                    return(OS_INVALID);
                }
            }
            /* Adding hostname */
            else if(Config)
            {
                hostname_white_size++;
                Config->hostname_white_list =
                    realloc(Config->hostname_white_list,
                    sizeof(OSMatch *)*hostname_white_size);

                if(!Config->hostname_white_list)
                {
                    merror(MEM_ERROR, ARGV0);
                    return(OS_INVALID);
                }
                os_calloc(1,
                          sizeof(OSMatch),
                          Config->hostname_white_list[hostname_white_size -2]);
                Config->hostname_white_list[hostname_white_size -1] = NULL;

                if(!OSMatch_Compile(
                        node[i]->content,
                        Config->hostname_white_list[hostname_white_size -2],
                        0))
                {
                    merror(REGEX_COMPILE, ARGV0, node[i]->content,
                           Config->hostname_white_list
                           [hostname_white_size -2]->error);
                    return(-1);
                }
            }

            #endif

        }

        /* For the email now
         * email_to, email_from, idsname, smtp_Server and maxperhour.
         * We will use a separate structure for that.
         */
        else if(strcmp(node[i]->element, xml_emailto) == 0)
        {
            #ifndef WIN32
            if(!OS_PRegex(node[i]->content, "[a-zA-Z0-9\\._-]+@[a-zA-Z0-9\\._-]"))
            {
                merror("%s: ERROR: Invalid Email address: %s.", ARGV0, node[i]->content);
                return(OS_INVALID);
            }
            #endif

            if(Mail)
            {
                mailto_size++;
                Mail->to = realloc(Mail->to, sizeof(char *)*mailto_size);
                if(!Mail->to)
                {
                    merror(MEM_ERROR, ARGV0);
                    return(OS_INVALID);
                }

                os_strdup(node[i]->content, Mail->to[mailto_size - 2]);
                Mail->to[mailto_size - 1] = NULL;
            }
        }
        else if(strcmp(node[i]->element, xml_emailfrom) == 0)
        {
            if(Mail)
            {
                if(Mail->from)
                {
                    free(Mail->from);
                }
                os_strdup(node[i]->content, Mail->from);
            }
        }
        else if(strcmp(node[i]->element, xml_emailidsname) == 0)
        {
            if(Mail)
            {
                if(Mail->idsname)
                {
                    free(Mail->idsname);
                }
                os_strdup(node[i]->content, Mail->idsname);
            }
        }
        else if(strcmp(node[i]->element, xml_smtpserver) == 0)
        {
            #ifndef WIN32
            if(Mail && (Mail->mn))
            {
                Mail->smtpserver = OS_GetHost(node[i]->content, 5);
                if(!Mail->smtpserver)
                {
                    merror(INVALID_SMTP, ARGV0, node[i]->content);
                    return(OS_INVALID);
                }
            }
            #endif
        }
        else if(strcmp(node[i]->element, xml_mailmaxperhour) == 0)
        {
            if(Mail)
            {
                if(!OS_StrIsNum(node[i]->content))
                {
                   merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                   return(OS_INVALID);
                }
                Mail->maxperhour = atoi(node[i]->content);

                if((Mail->maxperhour <= 0) || (Mail->maxperhour > 9999))
                {
                   merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
                   return(OS_INVALID);
                }
            }
        }
#ifdef GEOIP
        /* GeoIP v4 DB location */
        else if(strcmp(node[i]->element, xml_geoip_db_path) == 0)
        {
            if(Config)
            {
                os_strdup(node[i]->content, Config->geoip_db_path);
            }
        }
        /* GeoIP v6 DB location */
        else if(strcmp(node[i]->element, xml_geoip6_db_path) == 0)
        {
            if(Config)
            {
                os_strdup(node[i]->content, Config->geoip6_db_path);
            }
        }
#endif
        else
        {
            merror(XML_INVELEM, ARGV0, node[i]->element);
            return(OS_INVALID);
        }
        i++;
    }

    return(0);
}