Esempio n. 1
0
END_TEST

START_TEST(test_strbreak)
{
    int i;

    /*
     * Please note that all strings are \ escaped
     */
    const char *tests[][15] = {
        { "X", "testX1234", "4", "test", "1234", NULL},
        { "X", "XtestX1234X", "4", "", "test", "1234", "", NULL},
        { "Y", "testX1234", "4", "testX1234", NULL},
        { "X", "testXX1234", "4", "test", "", "1234", NULL},
        { "X", "testX1234", "1", "testX1234", NULL},
        { "X", "testX1234X5678", "2", "test", "1234X5678", NULL},
        { "X", "testX1234", "0", NULL},
        {NULL},
    };

    for(i=0; tests[i][0] != NULL; i++) {
        char **result = OS_StrBreak(tests[i][0][0], tests[i][1], (unsigned) atoi(tests[i][2]));

        int j = 3;
        if(tests[i][j] == NULL)
        {
            ck_assert_ptr_eq(result, NULL);
            continue;
        }

        int k;
        for(k = 0; tests[i][j] != NULL; j++, k++)
        {
            ck_assert_ptr_ne(result[k], NULL);
            ck_assert_str_eq(result[k], tests[i][j]);
        }
        ck_assert_ptr_eq(result[k], NULL);

        k=0;
        while(result[k])
            free(result[k++]);
        free(result);
    }

}
Esempio n. 2
0
/* Read directories attributes */
static int read_attr(syscheck_config *syscheck, const char *dirs, char **g_attrs, char **g_values)
{
    const char *xml_check_all = "check_all";
    const char *xml_check_sum = "check_sum";
    const char *xml_check_sha1sum = "check_sha1sum";
    const char *xml_check_md5sum = "check_md5sum";
    const char *xml_check_size = "check_size";
    const char *xml_check_owner = "check_owner";
    const char *xml_check_group = "check_group";
    const char *xml_check_perm = "check_perm";
    const char *xml_check_mtime = "check_mtime";
    const char *xml_check_inode = "check_inode";
    const char *xml_real_time = "realtime";
    const char *xml_report_changes = "report_changes";
    const char *xml_restrict = "restrict";

    char *restrictfile = NULL;
    char **dir;
    char *tmp_str;
    dir = OS_StrBreak(',', dirs, MAX_DIR_SIZE); /* Max number */
    char **dir_org = dir;

    int ret = 0, i;

    /* Dir can not be null */
    if (dir == NULL) {
        return (0);
    }

    while (*dir) {
        int j = 0;
        int opts = 0;
        char *tmp_dir;

        char **attrs = NULL;
        char **values = NULL;

        tmp_dir = *dir;
        restrictfile = NULL;

        /* Remove spaces at the beginning */
        while (*tmp_dir == ' ') {
            tmp_dir++;
        }

        /* Remove spaces at the end */
        tmp_str = strchr(tmp_dir, ' ');
        if (tmp_str) {
            tmp_str++;

            /* Check if it is really at the end */
            if ((*tmp_str == '\0') || (*tmp_str == ' ')) {
                tmp_str--;
                *tmp_str = '\0';
            }
        }

        /* Get the options */
        if (!g_attrs || !g_values) {
            merror(SYSCHECK_NO_OPT, __local_name, dirs);
            ret = 0;
            goto out_free;
        }

        attrs = g_attrs;
        values = g_values;

        while (*attrs && *values) {
            /* Check all */
            if (strcmp(*attrs, xml_check_all) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_MD5SUM;
                    opts |= CHECK_SHA1SUM;
                    opts |= CHECK_PERM;
                    opts |= CHECK_SIZE;
                    opts |= CHECK_OWNER;
                    opts |= CHECK_GROUP;
                    opts |= CHECK_MTIME;
                    opts |= CHECK_INODE;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ ( CHECK_MD5SUM | CHECK_SHA1SUM | CHECK_PERM
		       | CHECK_SIZE | CHECK_OWNER | CHECK_GROUP | CHECK_MTIME | CHECK_INODE );
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Check sum */
            else if (strcmp(*attrs, xml_check_sum) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_MD5SUM;
                    opts |= CHECK_SHA1SUM;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ ( CHECK_MD5SUM | CHECK_SHA1SUM );
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Check md5sum */
            else if (strcmp(*attrs, xml_check_md5sum) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_MD5SUM;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ CHECK_MD5SUM;
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Check sha1sum */
            else if (strcmp(*attrs, xml_check_sha1sum) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_SHA1SUM;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ CHECK_SHA1SUM;
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Check permission */
            else if (strcmp(*attrs, xml_check_perm) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_PERM;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ CHECK_PERM;
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Check size */
            else if (strcmp(*attrs, xml_check_size) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_SIZE;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ CHECK_SIZE;
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Check owner */
            else if (strcmp(*attrs, xml_check_owner) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_OWNER;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ CHECK_OWNER;
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Check group */
            else if (strcmp(*attrs, xml_check_group) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_GROUP;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ CHECK_GROUP;
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Check modification time */
            else if (strcmp(*attrs, xml_check_mtime) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_MTIME;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ CHECK_MTIME;
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Check inode */
            else if (strcmp(*attrs, xml_check_inode) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_INODE;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ CHECK_INODE;
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            else if (strcmp(*attrs, xml_real_time) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_REALTIME;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ CHECK_REALTIME;
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            } else if (strcmp(*attrs, xml_report_changes) == 0) {
                if (strcmp(*values, "yes") == 0) {
                    opts |= CHECK_SEECHANGES;
                } else if (strcmp(*values, "no") == 0) {
		    opts &= ~ CHECK_SEECHANGES;
                } else {
                    merror(SK_INV_OPT, __local_name, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            } else if (strcmp(*attrs, xml_restrict) == 0) {
                if (restrictfile) {
                    free(restrictfile);
                    restrictfile = NULL;
                }
                os_strdup(*values, restrictfile);
            } else {
                merror(SK_INV_ATTR, __local_name, *attrs);
                ret = 0;
                goto out_free;
            }
            attrs++;
            values++;
        }

        /* You must have something set */
        if (opts == 0) {
            merror(SYSCHECK_NO_OPT, __local_name, dirs);
            ret = 0;
            goto out_free;
        }

        /* Add directory - look for the last available */
        j = 0;
        while (syscheck->dir && syscheck->dir[j]) {
            /* Duplicate entry */
            if (strcmp(syscheck->dir[j], tmp_dir) == 0) {
                merror(SK_DUP, __local_name, tmp_dir);
                ret = 1;
                goto out_free;
            }

            j++;
        }

        /* Check for glob */
	/* The mingw32 builder used by travis.ci can't find glob.h
	 * Yet glob must work on actual win32.
	 */
#ifndef __MINGW32__
        if (strchr(tmp_dir, '*') ||
                strchr(tmp_dir, '?') ||
                strchr(tmp_dir, '[')) {
            int gindex = 0;
            glob_t g;

            if (glob(tmp_dir, 0, NULL, &g) != 0) {
                merror(GLOB_ERROR, __local_name, tmp_dir);
                ret = 1;
                goto out_free;
            }

            if (g.gl_pathv[0] == NULL) {
                merror(GLOB_NFOUND, __local_name, tmp_dir);
                ret = 1;
                goto out_free;
            }

            while (g.gl_pathv[gindex]) {
                dump_syscheck_entry(syscheck, g.gl_pathv[gindex], opts, 0, restrictfile);
                gindex++;
            }

            globfree(&g);
        }

        else {
            dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
        }
#else
	dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
#endif

        if (restrictfile) {
            free(restrictfile);
            restrictfile = NULL;
        }

        /* Next entry */
        dir++;
    }

    ret = 1;

out_free:

    i = 0;
    while (dir_org[i]) {
        free(dir_org[i++]);
    }

    free(dir_org);
    free(restrictfile);

    return ret;
}
Esempio n. 3
0
/* Read Windows registry configuration */
int read_reg(syscheck_config *syscheck, char *entries, int arch)
{
    int i;
    char **entry;
    char *tmp_str;

    /* Get each entry separately */
    entry = OS_StrBreak(',', entries, MAX_DIR_SIZE); /* Max number */

    if (entry == NULL) {
        return (0);
    }

    while (*entry) {
        char *tmp_entry;

        tmp_entry = *entry;

        /* Remove spaces at the beginning */
        while (*tmp_entry == ' ') {
            tmp_entry++;
        }

        /* Remove spaces at the end */
        tmp_str = strchr(tmp_entry, ' ');
        if (tmp_str) {
            tmp_str++;

            /* Check if it is really at the end */
            if ((*tmp_str == '\0') || (*tmp_str == ' ')) {
                tmp_str--;
                *tmp_str = '\0';
            }
        }

        /* Add entries - look for the last available */
        i = 0;
        while (syscheck->registry && syscheck->registry[i].entry) {
            int str_len_i;
            int str_len_dir;

            str_len_dir = strlen(tmp_entry);
            str_len_i = strlen(syscheck->registry[i].entry);

            if (str_len_dir > str_len_i) {
                str_len_dir = str_len_i;
            }

            /* Duplicated entry */
            if (syscheck->registry[i].arch == arch && strcmp(syscheck->registry[i].entry, tmp_entry) == 0) {
                merror(SK_DUP, __local_name, tmp_entry);
                return (1);
            }
            i++;
        }

        /* Add new entry */
        dump_syscheck_entry(syscheck, tmp_entry, arch, 1, NULL);

        /* Next entry */
        entry++;
    }

    return (1);
}
Esempio n. 4
0
/* Read directories attributes */
int read_attr(config *syscheck, char *dirs, char **g_attrs, char **g_values)
{
    char *xml_check_all = "check_all";
    char *xml_check_sum = "check_sum";
    char *xml_check_sha1sum = "check_sha1sum";
    char *xml_check_md5sum = "check_md5sum";
    char *xml_check_size = "check_size";
    char *xml_check_owner = "check_owner";
    char *xml_check_group = "check_group";
    char *xml_check_perm = "check_perm";
    char *xml_real_time = "realtime";
    char *xml_report_changes = "report_changes";
    char *xml_restrict = "restrict";

    char *restrictfile = NULL;
    char **dir;
    char *tmp_str;
    dir = OS_StrBreak(',', dirs, MAX_DIR_SIZE); /* Max number */
    char **dir_org = dir;

    int ret = 0, i;

    /* Dir can not be null */
    if(dir == NULL)
    {
        return(0);
    }


    /* Doing it for each directory */
    while(*dir)
    {
        int i = 0;
        int opts = 0;
        char *tmp_dir;

        char **attrs = NULL;
        char **values = NULL;

        tmp_dir = *dir;
        restrictfile = NULL;

        /* Removing spaces at the beginning */
        while(*tmp_dir == ' ')
        {
            tmp_dir++;
        }

        /* Removing spaces at the end */
        tmp_str = strchr(tmp_dir, ' ');
        if(tmp_str)
        {
            tmp_str++;

            /* Checking if it is really at the end */
            if((*tmp_str == '\0') || (*tmp_str == ' '))
            {
                tmp_str--;
                *tmp_str = '\0';
            }
        }


        /* Getting the options */
        if(!g_attrs || !g_values)
        {
            merror(SYSCHECK_NO_OPT, ARGV0, dirs);
            ret = 0;
            goto out_free;
        }

        attrs = g_attrs;
        values = g_values;

        while(*attrs && *values)
        {
            /* Checking all */
            if(strcmp(*attrs, xml_check_all) == 0)
            {
                if(strcmp(*values, "yes") == 0)
                {
                    opts|=CHECK_MD5SUM;
                    opts|=CHECK_SHA1SUM;
                    opts|=CHECK_PERM;
                    opts|=CHECK_SIZE;
                    opts|=CHECK_OWNER;
                    opts|=CHECK_GROUP;
                }
                else if(strcmp(*values, "no") == 0)
                {
                }
                else
                {
                    merror(SK_INV_OPT, ARGV0, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Checking sum */
            else if(strcmp(*attrs, xml_check_sum) == 0)
            {
                if(strcmp(*values, "yes") == 0)
                {
                    opts|=CHECK_MD5SUM;
                    opts|=CHECK_SHA1SUM;
                }
                else if(strcmp(*values, "no") == 0)
                {
                }
                else
                {
                    merror(SK_INV_OPT, ARGV0, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Checking md5sum */
            else if(strcmp(*attrs, xml_check_md5sum) == 0)
            {
                if(strcmp(*values, "yes") == 0)
                {
                    opts|=CHECK_MD5SUM;
                }
                else if(strcmp(*values, "no") == 0)
                {
                }
                else
                {
                    merror(SK_INV_OPT, ARGV0, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Checking sha1sum */
            else if(strcmp(*attrs, xml_check_sha1sum) == 0)
            {
                if(strcmp(*values, "yes") == 0)
                {
                    opts|=CHECK_SHA1SUM;
                }
                else if(strcmp(*values, "no") == 0)
                {
                }
                else
                {
                    merror(SK_INV_OPT, ARGV0, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Checking permission */
            else if(strcmp(*attrs, xml_check_perm) == 0)
            {
                if(strcmp(*values, "yes") == 0)
                {
                    opts|=CHECK_PERM;
                }
                else if(strcmp(*values, "no") == 0)
                {
                }
                else
                {
                    merror(SK_INV_OPT, ARGV0, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Checking size */
            else if(strcmp(*attrs, xml_check_size) == 0)
            {
                if(strcmp(*values, "yes") == 0)
                {
                    opts|=CHECK_SIZE;
                }
                else if(strcmp(*values, "no") == 0)
                {
                }
                else
                {
                    merror(SK_INV_OPT, ARGV0, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Checking owner */
            else if(strcmp(*attrs, xml_check_owner) == 0)
            {
                if(strcmp(*values, "yes") == 0)
                {
                    opts|=CHECK_OWNER;
                }
                else if(strcmp(*values, "no") == 0)
                {
                }
                else
                {
                    merror(SK_INV_OPT, ARGV0, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            /* Checking group */
            else if(strcmp(*attrs, xml_check_group) == 0)
            {
                if(strcmp(*values, "yes") == 0)
                {
                    opts|=CHECK_GROUP;
                }
                else if(strcmp(*values, "no") == 0)
                {
                }
                else
                {
                    merror(SK_INV_OPT, ARGV0, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            else if(strcmp(*attrs, xml_real_time) == 0)
            {
                if(strcmp(*values, "yes") == 0)
                {
                    opts|=CHECK_REALTIME;
                }
                else if(strcmp(*values, "no") == 0)
                {
                }
                else
                {
                    merror(SK_INV_OPT, ARGV0, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            else if(strcmp(*attrs, xml_report_changes) == 0)
            {
                if(strcmp(*values, "yes") == 0)
                {
                    opts|=CHECK_SEECHANGES;
                }
                else if(strcmp(*values, "no") == 0)
                {
                }
                else
                {
                    merror(SK_INV_OPT, ARGV0, *values, *attrs);
                    ret = 0;
                    goto out_free;
                }
            }
            else if(strcmp(*attrs, xml_restrict) == 0)
            {
                os_strdup(*values, restrictfile);
            }
            else
            {
                merror(SK_INV_ATTR, ARGV0, *attrs);
                ret = 0;
                goto out_free;
            }
            attrs++; values++;
        }


        /* You must have something set */
        if(opts == 0)
        {
            merror(SYSCHECK_NO_OPT, ARGV0, dirs);
            if(restrictfile) free(restrictfile);
            ret = 0;
            goto out_free;
        }


        /* Adding directory - looking for the last available */
        i = 0;
        while(syscheck->dir && syscheck->dir[i])
        {
            int str_len_i;
            int str_len_dir;

            str_len_dir = strlen(tmp_dir);
            str_len_i = strlen(syscheck->dir[i]);

            if(str_len_dir > str_len_i)
            {
                str_len_dir = str_len_i;
            }

            /* Duplicate entry */
            if(strcmp(syscheck->dir[i], tmp_dir) == 0)
            {
                merror(SK_DUP, ARGV0, tmp_dir);
                ret = 1;
                goto out_free;
            }

            i++;
        }


        /* Checking for glob. */
        #ifndef WIN32
        if(strchr(tmp_dir, '*') ||
           strchr(tmp_dir, '?') ||
           strchr(tmp_dir, '['))
        {
            int gindex = 0;
            glob_t g;

            if(glob(tmp_dir, 0, NULL, &g) != 0)
            {
                merror(GLOB_ERROR, ARGV0, tmp_dir);
                ret = 1;
                goto out_free;
            }

            if(g.gl_pathv[0] == NULL)
            {
                merror(GLOB_NFOUND, ARGV0, tmp_dir);
                ret = 1;
                goto out_free;
            }

            while(g.gl_pathv[gindex])
            {
                dump_syscheck_entry(syscheck, g.gl_pathv[gindex], opts, 0, restrictfile);
                gindex++;
            }

            globfree(&g);
        }

        else
        {
            dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
        }
        #else
        dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
        #endif

        if(restrictfile)
        {
            free(restrictfile);
            restrictfile = NULL;
        }


        /* Next entry */
        dir++;
    }

    ret = 1;

out_free:

    i = 0;
    while(dir_org[i])
        free(dir_org[i++]);

    free(dir_org);

    return ret;
}
Esempio n. 5
0
int read_reg(config *syscheck, char *entries)
{
    int i;
    char **entry;
    char *tmp_str;


    /* Getting each entry separately */
    entry = OS_StrBreak(',', entries, MAX_DIR_SIZE); /* Max number */


    /* entry can not be null */
    if(entry == NULL)
    {
        return(0);
    }


    /* Doing it for each Entry */
    while(*entry)
    {
        char *tmp_entry;

        tmp_entry = *entry;

        /* Removing spaces at the beginning */
        while(*tmp_entry == ' ')
        {
            tmp_entry++;
        }

        /* Removing spaces at the end */
        tmp_str = strchr(tmp_entry, ' ');
        if(tmp_str)
        {
            tmp_str++;

            /* Checking if it is really at the end */
            if((*tmp_str == '\0') || (*tmp_str == ' '))
            {
                tmp_str--;
                *tmp_str = '\0';
            }
        }


        /* Adding entries - looking for the last available */
        i = 0;
        while(syscheck->registry && syscheck->registry[i])
        {
            int str_len_i;
            int str_len_dir;

            str_len_dir = strlen(tmp_entry);
            str_len_i = strlen(syscheck->registry[i]);

            if(str_len_dir > str_len_i)
            {
                str_len_dir = str_len_i;
            }

            /* Duplicated entry */
            if(strcmp(syscheck->registry[i], tmp_entry) == 0)
            {
                merror(SK_DUP, ARGV0, tmp_entry);
                return(1);
            }
            i++;
        }

        /* Adding new entry */
        dump_syscheck_entry(syscheck, tmp_entry, 0, 1, NULL);


        /* Next entry */
        entry++;
    }

    return(1);
}
Esempio n. 6
0
void os_ReportdStart(report_filter *r_filter)
{
    int alerts_processed = 0;
    int alerts_filtered = 0;
    char *first_alert = NULL;
    char *last_alert = NULL;
    void **data_to_clean = NULL;


    time_t tm;
    struct tm *p;


    file_queue *fileq;
    alert_data *al_data;


    /* Getting current time before starting */
    tm = time(NULL);
    p = localtime(&tm);




    /* Initating file queue - to read the alerts */
    os_calloc(1, sizeof(file_queue), fileq);

    if(r_filter->report_type == REPORT_TYPE_DAILY && r_filter->filename)
    {
        fileq->fp = fopen(r_filter->filename, "r");
        if(!fileq->fp)
        {
            merror("%s: ERROR: Unable to open alerts file to generate report.", __local_name);
            return;
        }
        if(r_filter->fp)
        {
            __g_rtype = r_filter->fp;
        }
    }
    else
    {
        fileq->fp = stdin;
    }


    /* Creating top hashes. */
    r_filter->top_user = OSStore_Create();
    r_filter->top_srcip = OSStore_Create();
    r_filter->top_level = OSStore_Create();
    r_filter->top_rule = OSStore_Create();
    r_filter->top_group = OSStore_Create();
    r_filter->top_location = OSStore_Create();
    r_filter->top_files = OSStore_Create();

    Init_FileQueue(fileq, p, CRALERT_READ_ALL|CRALERT_FP_SET);



    /* Reading the alerts. */
    while(1)
    {
        /* Get message if available */
        al_data = Read_FileMon(fileq, p, 1);
        if(!al_data)
        {
            break;
        }

        alerts_processed++;


        /* Checking the filters. */
        if(!_os_report_check_filters(al_data, r_filter))
        {
            FreeAlertData(al_data);
            continue;
        }


        alerts_filtered++;
        data_to_clean = os_AddPtArray(al_data, data_to_clean);


        /* Setting first and last alert for summary. */
        if(!first_alert)
            first_alert = al_data->date;
        last_alert = al_data->date;


        /* Adding source ip if it is set properly. */
        if(al_data->srcip != NULL && strcmp(al_data->srcip, "(none)") != 0)
            _os_report_add_tostore(al_data->srcip, r_filter->top_srcip, al_data);


        /* Adding user if it is set properly. */
        if(al_data->user != NULL && strcmp(al_data->user, "(none)") != 0)
            _os_report_add_tostore(al_data->user, r_filter->top_user, al_data);


        /* Adding level and severity. */
        {
            char mlevel[16];
            char mrule[76 +1];
            mrule[76] = '\0';
            snprintf(mlevel, 16, "Severity %d" , al_data->level);
            snprintf(mrule, 76, "%d - %s" , al_data->rule, al_data->comment);

            _os_report_add_tostore(strdup(mlevel), r_filter->top_level,
                                   al_data);
            _os_report_add_tostore(strdup(mrule), r_filter->top_rule,
                                   al_data);
        }

        /* Dealing with the group. */
        {
            char *tmp_str;
            char **mgroup;

            mgroup = OS_StrBreak(',', al_data->group, 32);
            if(mgroup)
            {
                while(*mgroup)
                {
                    tmp_str = *mgroup;
                    while(*tmp_str == ' ')
                        tmp_str++;
                    if(*tmp_str == '\0')
                    {
                        mgroup++;
                        continue;
                    }

                    _os_report_add_tostore(tmp_str, r_filter->top_group,
                                           al_data);
                    mgroup++;
                }
            }
            else
            {
                tmp_str = al_data->group;
                while(*tmp_str == ' ')
                    tmp_str++;
                if(*tmp_str != '\0')
                {
                    _os_report_add_tostore(tmp_str, r_filter->top_group,
                                           al_data);
                }
            }
        }


        /* Adding to the location top filter. */
        _os_report_add_tostore(al_data->location, r_filter->top_location,
                               al_data);


        if(al_data->filename != NULL)
        {
            _os_report_add_tostore(al_data->filename, r_filter->top_files,
                                   al_data);
        }
    }

    /* No report available */
    if(alerts_filtered == 0)
    {
        if(!r_filter->report_name)
            merror("%s: INFO: Report completed and zero alerts post-filter.", __local_name);
        else
            merror("%s: INFO: Report '%s' completed and zero alerts post-filter.", __local_name, r_filter->report_name);
        return;
    }


    if(r_filter->report_name)
        verbose("%s: INFO: Report '%s' completed. Creating output...", __local_name, r_filter->report_name);
    else
        verbose("%s: INFO: Report completed. Creating output...", __local_name);


    l_print_out(" ");
    if(r_filter->report_name)
        l_print_out("Report '%s' completed.", r_filter->report_name);
    else
        l_print_out("Report completed. ==");
    l_print_out("------------------------------------------------");

    l_print_out("->Processed alerts: %d", alerts_processed);
    l_print_out("->Post-filtering alerts: %d", alerts_filtered);
    l_print_out("->First alert: %s", first_alert);
    l_print_out("->Last alert: %s", last_alert);
    l_print_out(" ");
    l_print_out(" ");

    OSStore_Sort(r_filter->top_srcip, _os_report_sort_compare);
    OSStore_Sort(r_filter->top_user,  _os_report_sort_compare);
    OSStore_Sort(r_filter->top_level, _os_report_sort_compare);
    OSStore_Sort(r_filter->top_group, _os_report_sort_compare);
    OSStore_Sort(r_filter->top_location, _os_report_sort_compare);
    OSStore_Sort(r_filter->top_rule, _os_report_sort_compare);
    OSStore_Sort(r_filter->top_files, _os_report_sort_compare);

    if(r_filter->top_srcip)
        os_report_printtop(r_filter->top_srcip, "Source ip", 0);

    if(r_filter->top_user)
        os_report_printtop(r_filter->top_user, "Username", 0);

    if(r_filter->top_level)
        os_report_printtop(r_filter->top_level, "Level", 0);

    if(r_filter->top_group)
        os_report_printtop(r_filter->top_group, "Group", 0);

    if(r_filter->top_location)
        os_report_printtop(r_filter->top_location, "Location", 0);

    if(r_filter->top_rule)
        os_report_printtop(r_filter->top_rule, "Rule", 0);

    if(r_filter->top_files)
        os_report_printtop(r_filter->top_files, "Filenames", 0);


    /* Print related events. */
    if(r_filter->related_srcip)
        os_report_printtop(r_filter->top_srcip, "Source ip",
                           r_filter->related_srcip);

    if(r_filter->related_user)
        os_report_printtop(r_filter->top_user, "Username",
                           r_filter->related_user);

    if(r_filter->related_level)
        os_report_printtop(r_filter->top_level, "Level",
                           r_filter->related_level);

    if(r_filter->related_group)
        os_report_printtop(r_filter->top_group, "Group",
                           r_filter->related_group);

    if(r_filter->related_location)
        os_report_printtop(r_filter->top_location, "Location",
                           r_filter->related_location);

    if(r_filter->related_rule)
        os_report_printtop(r_filter->top_rule, "Rule",
                           r_filter->related_rule);

    if(r_filter->related_file)
        os_report_printtop(r_filter->top_files, "Filename",
                           r_filter->related_file);


    /* If we have to dump the alerts. */
    if(data_to_clean)
    {
        int i = 0;

        if(r_filter->show_alerts)
        {
            l_print_out("Log dump:");
            l_print_out("------------------------------------------------");
        }
        while(data_to_clean[i])
        {
            alert_data *md = data_to_clean[i];
            if(r_filter->show_alerts)
                l_print_out("%s %s\nRule: %d (level %d) -> '%s'\n%s\n\n", md->date, md->location, md->rule, md->level, md->comment, md->log[0]);
            FreeAlertData(md);
            i++;
        }
        free(data_to_clean);
        data_to_clean = NULL;
    }
}
Esempio n. 7
0
/* ExecdConfig v0.1, 2006/03/24
 * Read the config file
 */
int ExecdConfig(char * cfgfile)
{
    extern int repeated_offenders_timeout[];
    #ifdef WIN32
    int is_disabled = 1;
    #else
    int is_disabled = 0;
    #endif
    const char *(xmlf[]) = {"ossec_config", "active-response", "disabled", NULL};
    const char *(blocks[]) = {"ossec_config", "active-response", "repeated_offenders", NULL};
    char *disable_entry;
    char *repeated_t;
    char **repeated_a;

    OS_XML xml;


    /* Reading XML file */
    if(OS_ReadXML(cfgfile,&xml) < 0)
    {
        ErrorExit(XML_ERROR, ARGV0, cfgfile, xml.err, xml.err_line);
    }

    /* We do not validate the xml in here. It is done by other processes */
    disable_entry = OS_GetOneContentforElement(&xml, xmlf);
    if(disable_entry)
    {
        if(strcmp(disable_entry, "yes") == 0)
        {
            is_disabled = 1;
        }
        else if(strcmp(disable_entry, "no") == 0)
        {
            is_disabled = 0;
        }
        else
        {
            merror(XML_VALUEERR, ARGV0,
                    "disabled",
                    disable_entry);
            return(-1);
        }
    }

    repeated_t = OS_GetOneContentforElement(&xml, blocks);
    if(repeated_t)
    {
        int i = 0;
        int j = 0;
        repeated_a = OS_StrBreak(',', repeated_t, 5);
        if(!repeated_a)
        {
            merror(XML_VALUEERR, ARGV0,
                    "repeated_offenders",
                    disable_entry);
            return(-1);
        }

        while(repeated_a[i] != NULL)
        {
            char *tmpt = repeated_a[i];
            while(*tmpt != '\0')
            {
                if(*tmpt == ' ' || *tmpt == '\t')
                   tmpt++;
    	        else
                   break;
            }

            if(*tmpt == '\0')
            {
                i++;
                continue;
            }

            repeated_offenders_timeout[j] = atoi(tmpt);
            verbose("%s: INFO: Adding offenders timeout: %d (for #%d)",
                    ARGV0, repeated_offenders_timeout[j], j+1);
            j++;
            repeated_offenders_timeout[j] = 0;
            if(j >= 6) break;
            i++;
        }
    }


    OS_ClearXML(&xml);
    return(is_disabled);
}
Esempio n. 8
0
int ReadDecodeXML(const char *file)
{
    OS_XML xml;
    XML_NODE node = NULL;

    /* XML variables */
    /* These are the available options for the rule configuration */

    const char *xml_plugindecoder = "plugin_decoder";
    const char *xml_decoder = "decoder";
    const char *xml_decoder_name = "name";
    const char *xml_decoder_status = "status";
    const char *xml_usename = "use_own_name";
    const char *xml_parent = "parent";
    const char *xml_program_name = "program_name";
    const char *xml_prematch = "prematch";
    const char *xml_regex = "regex";
    const char *xml_order = "order";
    const char *xml_type = "type";
    const char *xml_fts = "fts";
    const char *xml_ftscomment = "ftscomment";
    const char *xml_accumulate = "accumulate";

    int i = 0;
    OSDecoderInfo *NULL_Decoder_tmp = NULL;

    /* Read the XML */
    if ((i = OS_ReadXML(file, &xml)) < 0) {
        if ((i == -2) && (strcmp(file, XML_LDECODER) == 0)) {
            return (-2);
        }

        merror(XML_ERROR, ARGV0, file, xml.err, xml.err_line);
        return (0);
    }

    /* Apply any variables found */
    if (OS_ApplyVariables(&xml) != 0) {
        merror(XML_ERROR_VAR, ARGV0, file, xml.err);
        return (0);
    }

    /* Get the root elements */
    node = OS_GetElementsbyNode(&xml, NULL);
    if (!node) {
        if (strcmp(file, XML_LDECODER) != 0) {
            merror(XML_ELEMNULL, ARGV0);
            return (0);
        }

        return (-2);
    }

    /* Zero NULL_decoder */
    if (!NULL_Decoder) {
        os_calloc(1, sizeof(OSDecoderInfo), NULL_Decoder_tmp);
        NULL_Decoder_tmp->id = 0;
        NULL_Decoder_tmp->type = SYSLOG;
        NULL_Decoder_tmp->name = NULL;
        NULL_Decoder_tmp->fts = 0;
        NULL_Decoder = NULL_Decoder_tmp;
    }

    i = 0;
    while (node[i]) {
        XML_NODE elements = NULL;
        OSDecoderInfo *pi;

        int j = 0;
        char *regex;
        char *prematch;
        char *p_name;

        if (!node[i]->element ||
                strcasecmp(node[i]->element, xml_decoder) != 0) {
            merror(XML_INVELEM, ARGV0, node[i]->element);
            return (0);
        }

        /* Get name */
        if ((!node[i]->attributes) || (!node[i]->values) ||
                (!node[i]->values[0])  || (!node[i]->attributes[0]) ||
                (strcasecmp(node[i]->attributes[0], xml_decoder_name) != 0)) {
            merror(XML_INVELEM, ARGV0, node[i]->element);
            return (0);
        }

        /* Check for additional entries */
        if (node[i]->attributes[1] && node[i]->values[1]) {
            if (strcasecmp(node[i]->attributes[0], xml_decoder_status) != 0) {
                merror(XML_INVELEM, ARGV0, node[i]->element);
                return (0);
            }

            if (node[i]->attributes[2]) {
                merror(XML_INVELEM, ARGV0, node[i]->element);
                return (0);
            }
        }

        /* Get decoder options */
        elements = OS_GetElementsbyNode(&xml, node[i]);
        if (elements == NULL) {
            merror(XML_ELEMNULL, ARGV0);
            return (0);
        }

        /* Create the OSDecoderInfo */
        pi = (OSDecoderInfo *)calloc(1, sizeof(OSDecoderInfo));
        if (pi == NULL) {
            merror(MEM_ERROR, ARGV0, errno, strerror(errno));
            return (0);
        }

        /* Default values to the list */
        pi->parent = NULL;
        pi->id = 0;
        pi->name = strdup(node[i]->values[0]);
        pi->order = NULL;
        pi->plugindecoder = NULL;
        pi->fts = 0;
        pi->accumulate = 0;
        pi->type = SYSLOG;
        pi->prematch = NULL;
        pi->program_name = NULL;
        pi->regex = NULL;
        pi->use_own_name = 0;
        pi->get_next = 0;
        pi->regex_offset = 0;
        pi->prematch_offset = 0;

        regex = NULL;
        prematch = NULL;
        p_name = NULL;

        /* Check if strdup worked */
        if (!pi->name) {
            merror(MEM_ERROR, ARGV0, errno, strerror(errno));
            return (0);
        }

        /* Add decoder */
        if (!addDecoder2list(pi->name)) {
            merror(MEM_ERROR, ARGV0, errno, strerror(errno));
            free(pi);
            return (0);
        }

        /* Loop over all the elements */
        while (elements[j]) {
            if (!elements[j]->element) {
                merror(XML_ELEMNULL, ARGV0);
                return (0);
            } else if (!elements[j]->content) {
                merror(XML_VALUENULL, ARGV0, elements[j]->element);
                return (0);
            }

            /* Check if it is a child of a rule */
            else if (strcasecmp(elements[j]->element, xml_parent) == 0) {
                pi->parent = _loadmemory(pi->parent, elements[j]->content);
            }

            /* Get the regex */
            else if (strcasecmp(elements[j]->element, xml_regex) == 0) {
                int r_offset;
                r_offset = ReadDecodeAttrs(elements[j]->attributes,
                                           elements[j]->values);

                if (r_offset & AFTER_ERROR) {
                    merror(DEC_REGEX_ERROR, ARGV0, pi->name);
                    return (0);
                }

                /* Only the first regex entry may have an offset */
                if (regex && r_offset) {
                    merror(DUP_REGEX, ARGV0, pi->name);
                    merror(DEC_REGEX_ERROR, ARGV0, pi->name);
                    return (0);
                }

                /* regex offset */
                if (r_offset) {
                    pi->regex_offset = r_offset;
                }

                /* Assign regex */
                regex =
                    _loadmemory(regex,
                                elements[j]->content);
            }

            /* Get the pre match */
            else if (strcasecmp(elements[j]->element, xml_prematch) == 0) {
                int r_offset;

                r_offset = ReadDecodeAttrs(
                               elements[j]->attributes,
                               elements[j]->values);

                if (r_offset & AFTER_ERROR) {
                    ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name);
                }

                /* Only the first prematch entry may have an offset */
                if (prematch && r_offset) {
                    merror(DUP_REGEX, ARGV0, pi->name);
                    ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name);
                }

                if (r_offset) {
                    pi->prematch_offset = r_offset;
                }

                prematch =
                    _loadmemory(prematch,
                                elements[j]->content);
            }

            /* Get program name */
            else if (strcasecmp(elements[j]->element, xml_program_name) == 0) {
                p_name = _loadmemory(p_name, elements[j]->content);
            }

            /* Get the FTS comment */
            else if (strcasecmp(elements[j]->element, xml_ftscomment) == 0) {
            }

            else if (strcasecmp(elements[j]->element, xml_usename) == 0) {
                if (strcmp(elements[j]->content, "true") == 0) {
                    pi->use_own_name = 1;
                }
            }

            else if (strcasecmp(elements[j]->element, xml_plugindecoder) == 0) {
                int ed_c = 0;
                for (ed_c = 0; plugin_decoders[ed_c] != NULL; ed_c++) {
                    if (strcmp(plugin_decoders[ed_c],
                               elements[j]->content) == 0) {
                        /* Initialize plugin */
                        void (*dec_init)(void) = (void (*)(void)) plugin_decoders_init[ed_c];
                        dec_init();
                        pi->plugindecoder = (void (*)(void *)) plugin_decoders_exec[ed_c];
                        break;
                    }
                }

                /* Decoder not found */
                if (pi->plugindecoder == NULL) {
                    merror(INV_DECOPTION, ARGV0, elements[j]->element,
                           elements[j]->content);
                    return (0);
                }
            }

            /* Get the type */
            else if (strcmp(elements[j]->element, xml_type) == 0) {
                if (strcmp(elements[j]->content, "firewall") == 0) {
                    pi->type = FIREWALL;
                } else if (strcmp(elements[j]->content, "ids") == 0) {
                    pi->type = IDS;
                } else if (strcmp(elements[j]->content, "web-log") == 0) {
                    pi->type = WEBLOG;
                } else if (strcmp(elements[j]->content, "syslog") == 0) {
                    pi->type = SYSLOG;
                } else if (strcmp(elements[j]->content, "squid") == 0) {
                    pi->type = SQUID;
                } else if (strcmp(elements[j]->content, "windows") == 0) {
                    pi->type = DECODER_WINDOWS;
                } else if (strcmp(elements[j]->content, "host-information") == 0) {
                    pi->type = HOST_INFO;
                } else if (strcmp(elements[j]->content, "ossec") == 0) {
                    pi->type = OSSEC_RL;
                } else {
                    merror("%s: Invalid decoder type '%s'.",
                           ARGV0, elements[j]->content);
                    return (0);
                }
            }

            /* Get the order */
            else if (strcasecmp(elements[j]->element, xml_order) == 0) {
                char **norder, **s_norder;
                int order_int = 0;

                /* Maximum number is 8 for the order */
                norder = OS_StrBreak(',', elements[j]->content, 8);
                s_norder = norder;
                os_calloc(8, sizeof(void *), pi->order);

                /* Initialize the function pointers */
                while (order_int < 8) {
                    pi->order[order_int] = NULL;
                    order_int++;
                }
                order_int = 0;

                /* Check the values from the order */
                while (*norder) {
                    if (strstr(*norder, "dstuser") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) DstUser_FP;
                    } else if (strstr(*norder, "srcuser") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) SrcUser_FP;
                    }
                    /* User is an alias to dstuser */
                    else if (strstr(*norder, "user") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) DstUser_FP;
                    } else if (strstr(*norder, "srcip") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) SrcIP_FP;
                    } else if (strstr(*norder, "dstip") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) DstIP_FP;
                    } else if (strstr(*norder, "srcport") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) SrcPort_FP;
                    } else if (strstr(*norder, "dstport") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) DstPort_FP;
                    } else if (strstr(*norder, "protocol") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) Protocol_FP;
                    } else if (strstr(*norder, "action") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) Action_FP;
                    } else if (strstr(*norder, "id") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) ID_FP;
                    } else if (strstr(*norder, "url") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) Url_FP;
                    } else if (strstr(*norder, "data") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) Data_FP;
                    } else if (strstr(*norder, "extra_data") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) Data_FP;
                    } else if (strstr(*norder, "status") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) Status_FP;
                    } else if (strstr(*norder, "system_name") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) SystemName_FP;
                    } else if (strstr(*norder, "filename") != NULL) {
                        pi->order[order_int] = (void (*)(void *, char *)) FileName_FP;
                    } else {
                        ErrorExit("decode-xml: Wrong field '%s' in the order"
                                  " of decoder '%s'", *norder, pi->name);
                    }

                    free(*norder);
                    norder++;

                    order_int++;
                }

                free(s_norder);
            }

            else if (strcasecmp(elements[j]->element, xml_accumulate) == 0) {
                /* Enable Accumulator */
                pi->accumulate = 1;
            }

            /* Get the FTS order */
            else if (strcasecmp(elements[j]->element, xml_fts) == 0) {
                char **norder;
                char **s_norder;

                /* Maximum number is 8 for the FTS */
                norder = OS_StrBreak(',', elements[j]->content, 8);
                if (norder == NULL) {
                    ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno));
                }

                /* Save the initial point to free later */
                s_norder = norder;

                /* Check the values from the FTS */
                while (*norder) {
                    if (strstr(*norder, "dstuser") != NULL) {
                        pi->fts |= FTS_DSTUSER;
                    }
                    if (strstr(*norder, "user") != NULL) {
                        pi->fts |= FTS_DSTUSER;
                    } else if (strstr(*norder, "srcuser") != NULL) {
                        pi->fts |= FTS_SRCUSER;
                    } else if (strstr(*norder, "srcip") != NULL) {
                        pi->fts |= FTS_SRCIP;
                    } else if (strstr(*norder, "dstip") != NULL) {
                        pi->fts |= FTS_DSTIP;
                    } else if (strstr(*norder, "id") != NULL) {
                        pi->fts |= FTS_ID;
                    } else if (strstr(*norder, "location") != NULL) {
                        pi->fts |= FTS_LOCATION;
                    } else if (strstr(*norder, "data") != NULL) {
                        pi->fts |= FTS_DATA;
                    } else if (strstr(*norder, "extra_data") != NULL) {
                        pi->fts |= FTS_DATA;
                    } else if (strstr(*norder, "system_name") != NULL) {
                        pi->fts |= FTS_SYSTEMNAME;
                    } else if (strstr(*norder, "name") != NULL) {
                        pi->fts |= FTS_NAME;
                    } else {
                        ErrorExit("decode-xml: Wrong field '%s' in the fts"
                                  " decoder '%s'", *norder, pi->name);
                    }

                    free(*norder);
                    norder++;
                }

                /* Clear memory here */
                free(s_norder);
            } else {
                merror("%s: Invalid element '%s' for "
                       "decoder '%s'",
                       ARGV0,
                       elements[j]->element,
                       node[i]->element);
                return (0);
            }

            /* NEXT */
            j++;

        } /* while(elements[j]) */

        OS_ClearNode(elements);


        /* Prematch must be set */
        if (!prematch && !pi->parent && !p_name) {
            merror(DECODE_NOPRE, ARGV0, pi->name);
            merror(DEC_REGEX_ERROR, ARGV0, pi->name);
            return (0);
        }

        /* If pi->regex is not set, fts must not be set too */
        if ((!regex && (pi->fts || pi->order)) || (regex && !pi->order)) {
            merror(DEC_REGEX_ERROR, ARGV0, pi->name);
            return (0);
        }

        /* For the offsets */
        if ((pi->regex_offset & AFTER_PARENT) && !pi->parent) {
            merror(INV_OFFSET, ARGV0, "after_parent");
            merror(DEC_REGEX_ERROR, ARGV0, pi->name);
            return (0);
        }

        if (pi->regex_offset & AFTER_PREMATCH) {
            /* If after_prematch is set, but rule have
             * no parent, set AFTER_PARENT and unset
             * pre_match.
             */
            if (!pi->parent) {
                pi->regex_offset = 0;
                pi->regex_offset |= AFTER_PARENT;
            } else if (!prematch) {
                merror(INV_OFFSET, ARGV0, "after_prematch");
                merror(DEC_REGEX_ERROR, ARGV0, pi->name);
                return (0);
            }
        }

        /* For the after_regex offset */
        if (pi->regex_offset & AFTER_PREVREGEX) {
            if (!pi->parent || !regex) {
                merror(INV_OFFSET, ARGV0, "after_regex");
                merror(DEC_REGEX_ERROR, ARGV0, pi->name);
                return (0);
            }
        }

        /* Check the prematch offset */
        if (pi->prematch_offset) {
            /* Only the after parent is allowed */
            if (pi->prematch_offset & AFTER_PARENT) {
                if (!pi->parent) {
                    merror(INV_OFFSET, ARGV0, "after_parent");
                    merror(DEC_REGEX_ERROR, ARGV0, pi->name);
                    return (0);
                }
            } else {
                merror(DEC_REGEX_ERROR, ARGV0, pi->name);
                return (0);
            }
        }

        /* Compile the regex/prematch */
        if (prematch) {
            os_calloc(1, sizeof(OSRegex), pi->prematch);
            if (!OSRegex_Compile(prematch, pi->prematch, 0)) {
                merror(REGEX_COMPILE, ARGV0, prematch, pi->prematch->error);
                return (0);
            }

            free(prematch);
        }

        /* Compile the p_name */
        if (p_name) {
            os_calloc(1, sizeof(OSMatch), pi->program_name);
            if (!OSMatch_Compile(p_name, pi->program_name, 0)) {
                merror(REGEX_COMPILE, ARGV0, p_name, pi->program_name->error);
                return (0);
            }

            free(p_name);
        }

        /* We may not have the pi->regex */
        if (regex) {
            os_calloc(1, sizeof(OSRegex), pi->regex);
            if (!OSRegex_Compile(regex, pi->regex, OS_RETURN_SUBSTRING)) {
                merror(REGEX_COMPILE, ARGV0, regex, pi->regex->error);
                return (0);
            }

            /* We must have the sub_strings to retrieve the nodes */
            if (!pi->regex->sub_strings) {
                merror(REGEX_SUBS, ARGV0, regex);
                return (0);
            }

            free(regex);
        }

        /* Validate arguments */
        if (pi->plugindecoder && (pi->regex || pi->order)) {
            merror(DECODE_ADD, ARGV0, pi->name);
            return (0);
        }

        /* Add osdecoder to the list */
        if (!OS_AddOSDecoder(pi)) {
            merror(DECODER_ERROR, ARGV0);
            return (0);
        }

        i++;
    } /* while (node[i]) */


    /* Clean node and XML structures */
    OS_ClearNode(node);
    OS_ClearXML(&xml);

    return (1);
}
Esempio n. 9
0
int main(int argc, char **argv)
{
    int key_added = 0;
    int c;
    int test_config = 0;
    int auto_method = 0;
#ifndef WIN32
    gid_t gid = 0;
#endif

    int sock = 0, port = DEFAULT_PORT, ret = 0;
    const char *dir = DEFAULTDIR;
    const char *group = GROUPGLOBAL;
    char *authpass = NULL;
    const char *manager = NULL;
    const char *ipaddress = NULL;
    const char *agentname = NULL;
    const char *agent_cert = NULL;
    const char *agent_key = NULL;
    const char *ca_cert = NULL;
    char lhostname[512 + 1];
    char buf[4096 + 1];
    SSL_CTX *ctx;
    SSL *ssl;
    BIO *sbio;
    bio_err = 0;
    buf[4096] = '\0';

#ifdef WIN32
    WSADATA wsaData;
#endif

    /* Set the name */
    OS_SetName(ARGV0);

    while ((c = getopt(argc, argv, "Vdhtg:m:p:A:v:x:k:D:P:a")) != -1) {
        switch (c) {
            case 'V':
                print_version();
                break;
            case 'h':
                help_agent_auth();
                break;
            case 'd':
                nowDebug();
                break;
            case 'g':
                if (!optarg) {
                    ErrorExit("%s: -g needs an argument", ARGV0);
                }
                group = optarg;
                break;
            case 'D':
            if (!optarg) {
                ErrorExit("%s: -g needs an argument", ARGV0);
            }
            dir = optarg;
            break;
            case 't':
                test_config = 1;
                break;
            case 'm':
                if (!optarg) {
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                }
                manager = optarg;
                break;
            case 'A':
                if (!optarg) {
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                }
                agentname = optarg;
                break;
            case 'p':
                if (!optarg) {
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                }
                port = atoi(optarg);
                if (port <= 0 || port >= 65536) {
                    ErrorExit("%s: Invalid port: %s", ARGV0, optarg);
                }
                break;
            case 'v':
                if (!optarg) {
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                }
                ca_cert = optarg;
                break;
            case 'x':
                if (!optarg) {
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                }
                agent_cert = optarg;
                break;
            case 'k':
                if (!optarg) {
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                }
                agent_key = optarg;
                break;
            case 'P':
                if (!optarg)
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);

                authpass = optarg;
                break;
            case 'a':
                auto_method = 1;
                break;
            default:
                help_agent_auth();
                break;
        }
    }

    /* Start daemon */
    debug1(STARTED_MSG, ARGV0);

#ifndef WIN32
    /* Check if the user/group given are valid */
    gid = Privsep_GetGroup(group);
    if (gid == (gid_t) - 1) {
        ErrorExit(USER_ERROR, ARGV0, "", group);
    }

    /* Exit here if test config is set */
    if (test_config) {
        exit(0);
    }

    /* Privilege separation */
    if (Privsep_SetGroup(gid) < 0) {
        ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno));
    }

    /* Signal manipulation */
    StartSIG(ARGV0);

    /* Create PID files */
    if (CreatePID(ARGV0, getpid()) < 0) {
        ErrorExit(PID_ERROR, ARGV0);
    }
#else
    /* Initialize Windows socket stuff */
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
        ErrorExit("%s: WSAStartup() failed", ARGV0);
    }
#endif /* WIN32 */

    /* Start up message */
    verbose(STARTUP_MSG, ARGV0, (int)getpid());

    if (agentname == NULL) {
        lhostname[512] = '\0';
        if (gethostname(lhostname, 512 - 1) != 0) {
            merror("%s: ERROR: Unable to extract hostname. Custom agent name not set.", ARGV0);
            exit(1);
        }
        agentname = lhostname;
    }

#ifdef LEGACY_SSL
    auto_method = 1;
    merror("WARN: TLS v1.2 method-forcing disabled. This program was compiled to use SSL/TLS auto-negotiation.");
#endif

    /* Start SSL */
    ctx = os_ssl_keys(0, dir, agent_cert, agent_key, ca_cert, auto_method);
    if (!ctx) {
        merror("%s: ERROR: SSL error. Exiting.", ARGV0);
        exit(1);
    }

    if (!manager) {
        merror("%s: ERROR: Manager IP not set.", ARGV0);
        exit(1);
    }

    /* Check to see if the manager to connect to was specified as an IP address
     * or hostname on the command line. If it was given as a hostname then ensure
     * the hostname is preserved so that certificate verification can be done.
     */
    if (!(ipaddress = OS_GetHost(manager, 3))) {
        merror("%s: Could not resolve hostname: %s\n", ARGV0, manager);
        exit(1);
    }

    /* Checking if there is a custom password file */
    if (authpass == NULL) {
        FILE *fp;
        fp = fopen(AUTHDPASS_PATH, "r");
        buf[0] = '\0';

        if (fp) {
            buf[4096] = '\0';
            char *ret = fgets(buf, 4095, fp);

            if (ret && strlen(buf) > 2) {
                authpass = buf;
            }

            fclose(fp);
            printf("INFO: Using password specified on file: %s\n", AUTHDPASS_PATH);
        }
    }
    if (!authpass) {
        printf("WARN: No authentication password provided.\n");
    }

    /* Connect via TCP */
    sock = OS_ConnectTCP(port, ipaddress, 0);
    if (sock <= 0) {
        merror("%s: Unable to connect to %s:%d", ARGV0, ipaddress, port);
        exit(1);
    }

    /* Connect the SSL socket */
    ssl = SSL_new(ctx);
    sbio = BIO_new_socket(sock, BIO_NOCLOSE);
    SSL_set_bio(ssl, sbio, sbio);

    ret = SSL_connect(ssl);
    if (ret <= 0) {
        ERR_print_errors_fp(stderr);
        merror("%s: ERROR: SSL error (%d). Exiting.", ARGV0, ret);
        exit(1);
    }

    printf("INFO: Connected to %s:%d\n", ipaddress, port);

    /* Additional verification of the manager's certificate if a hostname
     * rather than an IP address is given on the command line. Could change
     * this to do the additional validation on IP addresses as well if needed.
     */
    if (ca_cert) {
        printf("INFO: Verifing manager's certificate\n");
        if (check_x509_cert(ssl, manager) != VERIFY_TRUE) {
            debug1("%s: DEBUG: Unable to verify server certificate.", ARGV0);
            exit(1);
        }
    }

    printf("INFO: Using agent name as: %s\n", agentname);

    if (authpass) {
        snprintf(buf, 2048, "OSSEC PASS: %s OSSEC A:'%s'\n", authpass, agentname);
    }
    else {
        snprintf(buf, 2048, "OSSEC A:'%s'\n", agentname);
    }

    ret = SSL_write(ssl, buf, strlen(buf));
    if (ret < 0) {
        printf("SSL write error (unable to send message.)\n");
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    printf("INFO: Send request to manager. Waiting for reply.\n");

    while (1) {
        ret = SSL_read(ssl, buf, sizeof(buf) - 1);
        switch (SSL_get_error(ssl, ret)) {
            case SSL_ERROR_NONE:
                buf[ret] = '\0';
                if (strncmp(buf, "ERROR", 5) == 0) {
                    char *tmpstr;
                    tmpstr = strchr(buf, '\n');
                    if (tmpstr) {
                        *tmpstr = '\0';
                    }
                    printf("%s (from manager)\n", buf);
                } else if (strncmp(buf, "OSSEC K:'", 9) == 0) {
                    char *key;
                    char *tmpstr;
                    char **entry;
                    printf("INFO: Received response with agent key\n");

                    key = buf;
                    key += 9;
                    tmpstr = strchr(key, '\'');
                    if (!tmpstr) {
                        printf("ERROR: Invalid key received. Closing connection.\n");
                        exit(1);
                    }
                    *tmpstr = '\0';
                    entry = OS_StrBreak(' ', key, 4);
                    if (!OS_IsValidID(entry[0]) || !OS_IsValidName(entry[1]) ||
                            !OS_IsValidName(entry[2]) || !OS_IsValidName(entry[3])) {
                        printf("ERROR: Invalid key received (2). Closing connection.\n");
                        exit(1);
                    }

                    {
                        FILE *fp;
                        fp = fopen(KEYSFILE_PATH, "w");
                        if (!fp) {
                            printf("ERROR: Unable to open key file: %s", KEYSFILE_PATH);
                            exit(1);
                        }
                        fprintf(fp, "%s\n", key);
                        fclose(fp);
                    }
                    key_added = 1;
                    printf("INFO: Valid key created. Finished.\n");
                }
                break;
            case SSL_ERROR_ZERO_RETURN:
            case SSL_ERROR_SYSCALL:
                if (key_added == 0) {
                    printf("ERROR: Unable to create key. Either wrong password or connection not accepted by the manager.\n");
                }
                printf("INFO: Connection closed.\n");
                exit(0);
                break;
            default:
                printf("ERROR: SSL read (unable to receive message)\n");
                exit(1);
                break;
        }

    }

    /* Shut down the socket */
    if (key_added == 0) {
        printf("ERROR: Unable to create key. Either wrong password or connection not accepted by the manager.\n");
    }
    SSL_CTX_free(ctx);
    close(sock);

    exit(0);
}
Esempio n. 10
0
int main(int argc, char **argv)
{
    int c, test_config = 0;
#ifndef WIN32
    int gid = 0;
#endif

    int sock = 0, port = 1515, ret = 0;
    char *dir  = DEFAULTDIR;
    char *user = USER;
    char *group = GROUPGLOBAL;
    char *cfg = DEFAULTCPATH;
    char *manager = NULL;
    char *agentname = NULL;
    char lhostname[512 + 1];
    char buf[2048 +1];
    SSL_CTX *ctx;
    SSL *ssl;
    BIO *sbio;


    bio_err = 0;
    buf[2048] = '\0';


    /* Setting the name */
    OS_SetName(ARGV0);

    while((c = getopt(argc, argv, "Vdhu:g:D:c:m:p:A:")) != -1)
    {
        switch(c) {
        case 'V':
            print_version();
            break;
        case 'h':
            report_help();
            break;
        case 'd':
            nowDebug();
            break;
        case 'u':
            if(!optarg)
                ErrorExit("%s: -u needs an argument",ARGV0);
            user=optarg;
            break;
        case 'g':
            if(!optarg)
                ErrorExit("%s: -g needs an argument",ARGV0);
            group=optarg;
            break;
        case 'D':
            if(!optarg)
                ErrorExit("%s: -D needs an argument",ARGV0);
            dir=optarg;
            break;
        case 'c':
            if(!optarg)
                ErrorExit("%s: -c needs an argument",ARGV0);
            cfg = optarg;
            break;
        case 't':
            test_config = 1;
            break;
        case 'm':
            if(!optarg)
                ErrorExit("%s: -%c needs an argument",ARGV0, c);
            manager = optarg;
            break;
        case 'A':
            if(!optarg)
                ErrorExit("%s: -%c needs an argument",ARGV0, c);
            agentname = optarg;
            break;
        case 'p':
            if(!optarg)
                ErrorExit("%s: -%c needs an argument",ARGV0, c);
            port = atoi(optarg);
            if(port <= 0 || port >= 65536)
            {
                ErrorExit("%s: Invalid port: %s", ARGV0, optarg);
            }
            break;
        default:
            report_help();
            break;
        }
    }

    /* Starting daemon */
    debug1(STARTED_MSG,ARGV0);


#ifndef WIN32
    /* Check if the user/group given are valid */
    gid = Privsep_GetGroup(group);
    if(gid < 0)
        ErrorExit(USER_ERROR,ARGV0,user,group);



    /* Privilege separation */
    if(Privsep_SetGroup(gid) < 0)
        ErrorExit(SETGID_ERROR,ARGV0,group);



    /* Signal manipulation */
    StartSIG(ARGV0);



    /* Creating PID files */
    if(CreatePID(ARGV0, getpid()) < 0)
        ErrorExit(PID_ERROR,ARGV0);
#endif


    /* Start up message */
    verbose(STARTUP_MSG, ARGV0, (int)getpid());


    if(agentname == NULL)
    {
        lhostname[512] = '\0';
        if(gethostname(lhostname, 512 -1) != 0)
        {
            merror("%s: ERROR: Unable to extract hostname. Custom agent name not set.", ARGV0);
            exit(1);
        }
        agentname = lhostname;
    }



    /* Starting SSL */
    ctx = os_ssl_keys(1, NULL);
    if(!ctx)
    {
        merror("%s: ERROR: SSL error. Exiting.", ARGV0);
        exit(1);
    }

    if(!manager)
    {
        merror("%s: ERROR: Manager IP not set.", ARGV0);
        exit(1);
    }


    /* Check to see if manager is an IP */
    int is_ip = 1;
    struct sockaddr_in iptest;
    memset(&iptest, 0, sizeof(iptest));

    if(inet_pton(AF_INET, manager, &iptest.sin_addr) != 1)
        is_ip = 0;	/* This is not an IPv4 address */

    /* Not IPv4, IPv6 maybe? */
    if(is_ip == 0)
    {
        struct sockaddr_in6 iptest6;
        memset(&iptest6, 0, sizeof(iptest6));
        if(inet_pton(AF_INET6, manager, &iptest6.sin6_addr) != 1)
            is_ip = 0;
        else
            is_ip = 1;	/* This is an IPv6 address */
    }


    /* If it isn't an ip, try to resolve the IP */
    if(is_ip == 0)
    {
        char *ipaddress;
        ipaddress = OS_GetHost(manager, 3);
        if(ipaddress != NULL)
            strncpy(manager, ipaddress, 16);
        else
        {
            printf("Could not resolve hostname: %s\n", manager);
            return(1);
        }
    }


    /* Connecting via TCP */
    sock = OS_ConnectTCP(port, manager, 0);
    if(sock <= 0)
    {
        merror("%s: Unable to connect to %s:%d", ARGV0, manager, port);
        exit(1);
    }


    /* Connecting the SSL socket */
    ssl = SSL_new(ctx);
    sbio = BIO_new_socket(sock, BIO_NOCLOSE);
    SSL_set_bio(ssl, sbio, sbio);


    ret = SSL_connect(ssl);
    if(ret <= 0)
    {
        ERR_print_errors_fp(stderr);
        merror("%s: ERROR: SSL error (%d). Exiting.", ARGV0, ret);
        exit(1);
    }


    printf("INFO: Connected to %s:%d\n", manager, port);
    printf("INFO: Using agent name as: %s\n", agentname);


    snprintf(buf, 2048, "OSSEC A:'%s'\n", agentname);
    ret = SSL_write(ssl, buf, strlen(buf));
    if(ret < 0)
    {
        printf("SSL write error (unable to send message.)\n");
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    printf("INFO: Send request to manager. Waiting for reply.\n");

    while(1)
    {
        ret = SSL_read(ssl,buf,sizeof(buf) -1);
        switch(SSL_get_error(ssl,ret))
        {
        case SSL_ERROR_NONE:
            buf[ret] = '\0';
            if(strncmp(buf, "ERROR", 5) == 0)
            {
                char *tmpstr;
                tmpstr = strchr(buf, '\n');
                if(tmpstr) *tmpstr = '\0';
                printf("%s (from manager)\n", buf);
            }
            else if(strncmp(buf, "OSSEC K:'",9) == 0)
            {
                char *key;
                char *tmpstr;
                char **entry;
                printf("INFO: Received response with agent key\n");

                key = buf;
                key += 9;
                tmpstr = strchr(key, '\'');
                if(!tmpstr)
                {
                    printf("ERROR: Invalid key received. Closing connection.\n");
                    exit(1);
                }
                *tmpstr = '\0';
                entry = OS_StrBreak(' ', key, 4);
                if(!OS_IsValidID(entry[0]) || !OS_IsValidName(entry[1]) ||
                        !OS_IsValidName(entry[2]) || !OS_IsValidName(entry[3]))
                {
                    printf("ERROR: Invalid key received (2). Closing connection.\n");
                    exit(1);
                }

                {
                    FILE *fp;
                    fp = fopen(KEYSFILE_PATH,"w");
                    if(!fp)
                    {
                        printf("ERROR: Unable to open key file: %s", KEYSFILE_PATH);
                        exit(1);
                    }
                    fprintf(fp, "%s\n", key);
                    fclose(fp);
                }
                printf("INFO: Valid key created. Finished.\n");
            }
            break;
        case SSL_ERROR_ZERO_RETURN:
        case SSL_ERROR_SYSCALL:
            printf("INFO: Connection closed.\n");
            exit(0);
            break;
        default:
            printf("ERROR: SSL read (unable to receive message)\n");
            exit(1);
            break;
        }

    }



    /* Shutdown the socket */
    SSL_CTX_free(ctx);
    close(sock);

    exit(0);
}