Project

General

Profile

Developing an Application Using Prelude Fetching Events Feature

The goal of this page is to help you to develop and understand the libprelude fetching events feature. First, raw code is shown, compilable and usable. Each function is explained latter.

Code

#include <libprelude/prelude.h>
#include <libprelude/prelude-message-id.h>
#include <libprelude/idmef-message-print.h>

#define CLIENT_PROFILE "PoolingTest" 
#define MANAGER_ADDRESS "127.0.0.1" 
#define POOL_TIMEOUT 2        /* set the alert pooling check at two seconds */

static prelude_client_t *client;

static int
initialize_prelude(void)
{
        int ret;
        char *buffer;

        ret = prelude_init(NULL, NULL);
        if ( ret < 0 ) {
                prelude_perror(ret, "error initializing the prelude library");
                return ret;
        }

        ret = prelude_client_new(&client, CLIENT_PROFILE);
        if ( ret < 0 ) {
                prelude_perror(ret, "error creating the prelude client");
                return ret;
        }

        prelude_client_set_required_permission(client, PRELUDE_CONNECTION_PERMISSION_IDMEF_READ);

    ret = prelude_client_init(client);
        if ( ret < 0 ) {
                prelude_perror(ret, "error initializing the prelude client");
                return ret;
        }

        return 0;
}

static const char *
pooling_get_classification(idmef_alert_t *alert)
{
        int ret;

        idmef_classification_t *classification;
        prelude_string_t *pstr;
        const char *buffer;

        classification = idmef_alert_get_classification(alert);
        if ( ! classification ) {
                printf("Cannot get classification from alert\n");
                return NULL;
        }
        pstr = idmef_classification_get_text(classification);
        if ( ! pstr ) {
                printf("Cannot get text from classification\n");
                return NULL;
        }

        buffer = prelude_string_get_string(pstr);

        return buffer;

}

static idmef_impact_t *
pooling_get_impact(idmef_alert_t *alert)
{

        int ret;

        idmef_assessment_t *assessment;
        idmef_impact_t *impact;

        assessment = idmef_alert_get_assessment(alert);
        if ( ! assessment ) {
                printf("Cannot get assessment from alert\n");
                return NULL;
        }
        impact = idmef_assessment_get_impact (assessment);
        if ( ! impact ) {
                printf("Cannot get impact from assessment\n");
                return NULL;
        }

        return impact;

}

static const char *
pooling_get_impact_description(idmef_impact_t *impact)
{

        prelude_string_t *pstr;
        const char *buffer;

        pstr = idmef_impact_get_description(impact);
        if ( ! impact ) {
                printf("Cannot get description from impact\n");
                return NULL;
        }

        buffer = prelude_string_get_string(pstr);

        return buffer;

}

static void
pooling_get_target_infos(idmef_alert_t *alert, const char **node_name, const char **node_addr)
{
        idmef_target_t *target = NULL;
        idmef_address_t *address = NULL;
        idmef_node_t   *node;

        prelude_string_t *pstr;
        const char *buffer;

        while ( (target = idmef_alert_get_next_target(alert, target)) ) {
                node = idmef_target_get_node(target);

                pstr = idmef_node_get_name(node);
                buffer = prelude_string_get_string(pstr);
                *node_name = buffer;

                while ( (address = idmef_node_get_next_address(node, address)) ) {

                        pstr = idmef_address_get_address(address);
                        buffer = prelude_string_get_string(pstr);
                        *node_addr = buffer;
                }
        }
}

static int
process_idmef_message(prelude_msg_t *msg)
{

        int ret;

        idmef_message_t         *idmef;
        idmef_message_type_t     msg_type;
        idmef_alert_t           *alert;
        idmef_impact_t          *impact;
        idmef_impact_severity_t *severity;
        idmef_target_t          *target;

        const char *classbuf;
        const char *descrbuf;
        const char *target_name;
        const char *target_addr;

        ret = idmef_message_new(&idmef);
        if ( ret < 0 )
                return ret;

        ret = idmef_message_read(idmef, msg);
        if ( ret < 0 ) {
                prelude_perror(ret, "error reading IDMEF message");
                return ret;
        }

        /* We only process the Alert class */
        msg_type = idmef_message_get_type(idmef);
        if ( msg_type != IDMEF_MESSAGE_TYPE_ALERT )
        return 0;

        if ( idmef ) {
                alert = idmef_message_get_alert(idmef);
                if ( ! alert ) {
                        printf("Cannot get alert from message\n");
                        return -1;
                }
        } else {
                return -1;
        }

        pooling_get_target_infos(alert, &target_name, &target_addr);

        classbuf = pooling_get_classification(alert);
        if ( ! classbuf ) classbuf="";

        impact   = pooling_get_impact(alert);
        if ( impact ) {
                descrbuf = pooling_get_impact_description(impact);
                if ( ! descrbuf ) descrbuf="";
                severity = idmef_impact_get_severity(impact);
                if ( ! severity ) return -1;

        printf("Classbuf=[%s],descrbuf=[%s], target_name=[%s], targer_addr=[%s]\n", 
               classbuf, descrbuf, target_name, target_addr);
        } else {
                printf("Cannot get impact!\n");
        }

        idmef_message_destroy(idmef);

        return 0;

}

extern int event_cb(prelude_connection_pool_t *pool, prelude_connection_pool_event_t event,
                    prelude_connection_t *conn, void *extra)
{
        int ret;
        prelude_msg_t *msg = NULL;

        ret = prelude_connection_recv(conn, &msg);
        if ( ret < 0 ) {
                prelude_perror(ret, "couldn't read message");
                return ret;
        }

        if ( prelude_msg_get_tag(msg) != PRELUDE_MSG_IDMEF )
                return 0;

        return process_idmef_message(msg);
}

extern int
check_for_event(prelude_connection_pool_t *pool)
{
        int ret;

        if ( ! pool ) {
                printf("Cannot get data from the pool");
                return -1;
        }

        ret = prelude_connection_pool_check_event(pool, 0, event_cb, NULL);
        if ( ret < 0 ) {
                prelude_perror(ret, "error setting callback");
                return -1;
        }

}

extern int
connect_prelude(const char *manager_addr)
{
        int ret;
        prelude_connection_pool_t *pool = NULL;

        prelude_connection_pool_new(&pool,
                                    prelude_client_get_profile(client),
                                    prelude_client_get_required_permission(client));

    ret = prelude_connection_pool_set_connection_string(pool, manager_addr);
    if ( ret < 0 ) {
                prelude_perror(ret, "error setting new prelude connection string");
                return -1;
        }

    prelude_client_set_connection_pool(client, pool);

        ret = prelude_connection_pool_init(pool);
        if ( ret < 0 ) {
                prelude_perror(ret, "error initializing connection pool");
                return -1;
        }

        while (1) {
                sleep(POOL_TIMEOUT);
                check_for_event(pool);
        }

        prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS);

        return 0;
}

int main(void)
{
    int ret;

    ret = initialize_prelude();
        if ( ret < 0 ) {
                printf("Cannot initialize prelude\n");
        }

    ret = connect_prelude(MANAGER_ADDRESS);
        if ( ret < 0 ) {
                printf("Cannot connecting prelude\n");
        }

    return 0;
}

Compile

gcc pooling.c -o pooling `libprelude-config --pthread-cflags --libs`

Register

If the pooling user as UID 1000 and GID 1000:

sudo prelude-admin register [[PoolingTest]] "idmef:r" localhost --uid 1000 --gid 1000

Use

On one side we run prelude-lml, on the other, the manager. Everything is localhost.

Now we can connect the pooling to the manager:

$ ./pooling
Classbuf=[SUDO Command Executed],descrbuf=[User toady successfully executed the command '/bin/ls /' as root.], target_name=[myhost], targer_addr=[127.0.1.1]