예제 #1
0
/* OS_DBD: Monitor the alerts and insert them into the database.
 * Only return in case of error.
 */
void OS_DBD(DBConfig *db_config)
{
    time_t tm;     
    struct tm *p;       

    file_queue *fileq;
    alert_data *al_data;


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


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


    /* Creating location hash */
    db_config->location_hash = OSHash_Create();
    if(!db_config->location_hash)
    {
        ErrorExit(MEM_ERROR, ARGV0);
    }


    /* Getting maximum ID */
    db_config->alert_id = OS_SelectMaxID(db_config);
    db_config->alert_id++;


    /* Infinite loop reading the alerts and inserting them. */
    while(1)
    {
        tm = time(NULL);
        p = localtime(&tm);


        /* Get message if available (timeout of 5 seconds) */
        al_data = Read_FileMon(fileq, p, 5);
        if(!al_data)
        {
            continue;
        }


        /* Inserting into the db */
        OS_Alert_InsertDB(al_data, db_config);


        /* Clearing the memory */
        FreeAlertData(al_data);
    }
}
예제 #2
0
/* Receive a Message on the Mail queue */
MailMsg *OS_RecvMailQ(file_queue *fileq, struct tm *p,
                      MailConfig *Mail, MailMsg **msg_sms)
{
    int i = 0, sms_set = 0, donotgroup = 0;
    size_t body_size = OS_MAXSTR - 3, log_size;
    char logs[OS_MAXSTR + 1];
    char extra_data[OS_MAXSTR + 1];
    char log_string[OS_MAXSTR / 4 + 1];
    char *subject_host;
#ifdef LIBGEOIP_ENABLED
    char geoip_msg_src[OS_SIZE_1024 + 1];
    char geoip_msg_dst[OS_SIZE_1024 + 1];
#endif

    MailMsg *mail;
    alert_data *al_data;

    Mail->priority = 0;

    /* Get message if available */
    al_data = Read_FileMon(fileq, p, mail_timeout);
    if (!al_data) {
        return (NULL);
    }

    /* If e-mail came correctly, generate the e-mail body/subject */
    os_calloc(1, sizeof(MailMsg), mail);
    os_calloc(BODY_SIZE, sizeof(char), mail->body);
    os_calloc(SUBJECT_SIZE, sizeof(char), mail->subject);

    /* Generate the logs */
    logs[0] = '\0';
    extra_data[0] = '\0';
    logs[OS_MAXSTR] = '\0';

    while (al_data->log[i]) {
        log_size = strlen(al_data->log[i]) + 4;

        /* If size left is small than the size of the log, stop it */
        if (body_size <= log_size) {
            break;
        }

        strncat(logs, al_data->log[i], body_size);
        strncat(logs, "\r\n", body_size);
        body_size -= log_size;
        i++;
    }

    if (al_data->old_md5) {
        log_size = strlen(al_data->old_md5) + 16 + 4;
        if (body_size > log_size) {
            strncat(logs, "Old md5sum was: ", 16);
            strncat(logs, al_data->old_md5, body_size);
            strncat(logs, "\r\n", 4);
            body_size -= log_size;
        }
    }
    if (al_data->new_md5) {
        log_size = strlen(al_data->new_md5) + 16 + 4;
        if (body_size > log_size) {
            strncat(logs, "New md5sum is : ", 16);
            strncat(logs, al_data->new_md5, body_size);
            strncat(logs, "\r\n", 4);
            body_size -= log_size;
        }
    }
    if (al_data->old_sha1) {
        log_size = strlen(al_data->old_sha1) + 17 + 4;
        if (body_size > log_size) {
            strncat(logs, "Old sha1sum was: ", 17);
            strncat(logs, al_data->old_sha1, body_size);
            strncat(logs, "\r\n", 4);
            body_size -= log_size;
        }
    }
    if (al_data->new_sha1) {
        log_size = strlen(al_data->new_sha1) + 17 + 4;
        if (body_size > log_size) {
            strncat(logs, "New sha1sum is : ", 17);
            strncat(logs, al_data->new_sha1, body_size);
            strncat(logs, "\r\n", 4);
            body_size -= log_size;
        }
    }

    /* EXTRA DATA */
    if (al_data->srcip) {
        log_size = snprintf(log_string, sizeof(log_string) - 1, "Src IP: %s\r\n", al_data->srcip );
        if (body_size > log_size) {
            if ( strncat(extra_data, log_string, log_size) != NULL ) {
                body_size -= log_size;
            }
        }
    }
    if (al_data->dstip) {
        log_size = snprintf(log_string, sizeof(log_string) - 1, "Dst IP: %s\r\n", al_data->dstip );
        if (body_size > log_size) {
            if ( strncat(extra_data, log_string, log_size) != NULL ) {
                body_size -= log_size;
            }
        }
    }
    if (al_data->user) {
        log_size = snprintf(log_string, sizeof(log_string) - 1, "User: %s\r\n", al_data->user );
        if (body_size > log_size) {
            if ( strncat(extra_data, log_string, log_size) != NULL ) {
                body_size -= log_size;
            }
        }
    }

    /* Subject */
    subject_host = strchr(al_data->location, '>');
    if (subject_host) {
        subject_host--;
        *subject_host = '\0';
    }

    /* We have two subject options - full and normal */
    if (Mail->subject_full) {
        /* Option for a clean full subject (without ossec in the name) */
#ifdef CLEANFULL
        snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT_FULL2,
                 al_data->level,
                 al_data->comment,
                 al_data->location);
#else
        snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT_FULL,
                 al_data->location,
                 al_data->level,
                 al_data->comment);
#endif
    } else {
        snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT,
                 al_data->location,
                 al_data->level);
    }


    /* Fix subject back */
    if (subject_host) {
        *subject_host = '-';
    }

#ifdef LIBGEOIP_ENABLED
    /* Get GeoIP information */
    if (Mail->geoip) {
        if (al_data->srcgeoip) {
            snprintf(geoip_msg_src, OS_SIZE_1024, "Src Location: %s\r\n", al_data->srcgeoip);
        } else {
            geoip_msg_src[0] = '\0';
        }
        if (al_data->dstgeoip) {
            snprintf(geoip_msg_dst, OS_SIZE_1024, "Dst Location: %s\r\n", al_data->dstgeoip);
        } else {
            geoip_msg_dst[0] = '\0';
        }
    } else {
        geoip_msg_src[0] = '\0';
        geoip_msg_dst[0] = '\0';
    }
#endif

    /* Body */
#ifdef LIBGEOIP_ENABLED
    snprintf(mail->body, BODY_SIZE - 1, MAIL_BODY,
             al_data->date,
             al_data->location,
             al_data->rule,
             al_data->level,
             al_data->comment,
             geoip_msg_src,
             geoip_msg_dst,
             extra_data,
             logs);
#else
    snprintf(mail->body, BODY_SIZE - 1, MAIL_BODY,
             al_data->date,
             al_data->location,
             al_data->rule,
             al_data->level,
             al_data->comment,
             extra_data,
             logs);
#endif
    debug2("OS_RecvMailQ: mail->body[%s]", mail->body);

    /* Check for granular email configs */
    if (Mail->gran_to) {
        i = 0;
        while (Mail->gran_to[i] != NULL) {
            int gr_set = 0;

            /* Look if location is set */
            if (Mail->gran_location[i]) {
                if (OSMatch_Execute(al_data->location,
                                    strlen(al_data->location),
                                    Mail->gran_location[i])) {
                    gr_set = 1;
                } else {
                    i++;
                    continue;
                }
            }

            /* Look for the level */
            if (Mail->gran_level[i]) {
                if (al_data->level >= Mail->gran_level[i]) {
                    gr_set = 1;
                } else {
                    i++;
                    continue;
                }
            }

            /* Look for rule id */
            if (Mail->gran_id[i]) {
                int id_i = 0;
                while (Mail->gran_id[i][id_i] != 0) {
                    if (Mail->gran_id[i][id_i] == al_data->rule) {
                        break;
                    }
                    id_i++;
                }

                /* If we found, id is going to be a valid rule */
                if (Mail->gran_id[i][id_i]) {
                    gr_set = 1;
                } else {
                    i++;
                    continue;
                }
            }

            /* Look for the group */
            if (Mail->gran_group[i]) {
                if (OSMatch_Execute(al_data->group,
                                    strlen(al_data->group),
                                    Mail->gran_group[i])) {
                    gr_set = 1;
                } else {
                    i++;
                    continue;
                }
            }

            /* If we got here, everything matched. Set this e-mail to be used. */
            if (gr_set) {
                if (Mail->gran_format[i] == SMS_FORMAT) {
                    Mail->gran_set[i] = SMS_FORMAT;

                    /* Set the SMS flag */
                    sms_set = 1;
                } else {
                    /* Options */
                    if (Mail->gran_format[i] == FORWARD_NOW) {
                        Mail->priority = 1;
                        Mail->gran_set[i] = FULL_FORMAT;
                    } else if (Mail->gran_format[i] == DONOTGROUP) {
                        Mail->priority = DONOTGROUP;
                        Mail->gran_set[i] = DONOTGROUP;
                        donotgroup = 1;
                    } else {
                        Mail->gran_set[i] = FULL_FORMAT;
                    }
                }
            }
            i++;
        }
    }


    /* If DONOTGROUP is set, we can't assign the new subject */
    if (!donotgroup) {
        /* Get highest level for alert */
        if (_g_subject[0] != '\0') {
            if (_g_subject_level < al_data->level) {
                strncpy(_g_subject, mail->subject, SUBJECT_SIZE);
                _g_subject_level = al_data->level;
            }
        } else {
            strncpy(_g_subject, mail->subject, SUBJECT_SIZE);
            _g_subject_level = al_data->level;
        }
    }

    /* If SMS is set, create the SMS output */
    if (sms_set) {
        MailMsg *msg_sms_tmp;

        /* Allocate memory for SMS */
        os_calloc(1, sizeof(MailMsg), msg_sms_tmp);
        os_calloc(BODY_SIZE, sizeof(char), msg_sms_tmp->body);
        os_calloc(SUBJECT_SIZE, sizeof(char), msg_sms_tmp->subject);

        snprintf(msg_sms_tmp->subject, SUBJECT_SIZE - 1, SMS_SUBJECT,
                 al_data->level,
                 al_data->rule,
                 al_data->comment);


        strncpy(msg_sms_tmp->body, logs, 128);
        msg_sms_tmp->body[127] = '\0';
        *msg_sms = msg_sms_tmp;
    }

    /* Clear the memory */
    FreeAlertData(al_data);

    return (mail);
}
예제 #3
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;
    }
}
예제 #4
0
파일: csyslogd.c 프로젝트: Ar0xA/ossec-hids
/* OS_SyslogD: Monitor the alerts and sends them via syslog.
 * Only return in case of error.
 */
void OS_CSyslogD(SyslogConfig **syslog_config)
{
    int s = 0;
    time_t tm;
    struct tm *p;
    int tries = 0;

    file_queue *fileq;
    alert_data *al_data;


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


    /* Initating file queue - to read the alerts */
    os_calloc(1, sizeof(file_queue), fileq);
    while( (Init_FileQueue(fileq, p, 0) ) < 0 ) {
        tries++;
        if( tries > OS_CSYSLOGD_MAX_TRIES ) {
            merror("%s: ERROR: Could not open queue after %d tries, exiting!",
                   ARGV0, tries
            );
            exit(1);
        }
        sleep(1);
    }
    debug1("%s: INFO: File queue connected.", ARGV0 );


    /* Connecting to syslog. */
    s = 0;
    while(syslog_config[s])
    {
        syslog_config[s]->socket = OS_ConnectUDP(syslog_config[s]->port,
                                                 syslog_config[s]->server, 0);
        if(syslog_config[s]->socket < 0)
        {
            merror(CONNS_ERROR, ARGV0, syslog_config[s]->server);
        }
        else
        {
            merror("%s: INFO: Forwarding alerts via syslog to: '%s:%d'.",
                   ARGV0, syslog_config[s]->server, syslog_config[s]->port);
        }

        s++;
    }



    /* Infinite loop reading the alerts and inserting them. */
    while(1)
    {
        tm = time(NULL);
        p = localtime(&tm);


        /* Get message if available (timeout of 5 seconds) */
        al_data = Read_FileMon(fileq, p, 5);
        if(!al_data)
        {
            continue;
        }



        /* Sending via syslog */
        s = 0;
        while(syslog_config[s])
        {
            OS_Alert_SendSyslog(al_data, syslog_config[s]);
            s++;
        }


        /* Clearing the memory */
        FreeAlertData(al_data);
    }
}