⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 op_acid_db.c

📁 知名的开源IDS的日志工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: op_acid_db.c,v 1.16 2004/04/03 19:57:32 andrewbaker Exp $ *//*** Copyright (C) 2001-2002 Andrew R. Baker <andrewb@snort.org>**** This program is distributed under the terms of version 1.0 of the ** Q Public License.  See LICENSE.QPL for further details.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.***//*  I N C L U D E S  *****************************************************/#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <netinet/in.h>#include <time.h>#include <errno.h>#include <unistd.h>#include "ConfigFile.h"#include "mstring.h"#include "sid.h"#include "classification.h"#include "util.h"#include "input-plugins/dp_alert.h"#include "input-plugins/dp_log.h"#include "op_plugbase.h"#include "op_decode.h"#include "event.h"#include <ctype.h>#ifdef ENABLE_MYSQL#include <mysql.h>#include <errmsg.h>#endif /* ENABLE_MYSQL */#ifdef ENABLE_POSTGRES#include <libpq-fe.h>#endif /* ENABLE_POSTGRES *//*  D A T A   S T R U C T U R E S  **************************************/typedef struct _OpAcidDb_Data {    u_int8_t flavor;  /* what flavor of db?  MySQL, postgres, ... */    u_int8_t detail;    u_int16_t unused;    char *server;    char *database;    char *user;    char *password;    int sensor_id;    u_int32_t event_id;    int linktype;    /* db handles go here */#ifdef ENABLE_MYSQL    MYSQL *mysql;#endif /* ENABLE_MYSQL */#ifdef ENABLE_POSTGRES    PGconn *pq;#endif /* ENABLE_POSTGRES */} OpAcidDb_Data;#define MAX_QUERY_SIZE 8192/* database flavor defines */#define FLAVOR_MYSQL    1#define FLAVOR_POSTGRES 2char *db_flavours[] = {NULL, "mysql", "postgres"};/* Output plugin API functions */int OpAcidDb_Setup(OutputPlugin *, char *args);int OpAcidDb_Exit(OutputPlugin *);int OpAcidDb_Start(OutputPlugin *, void *);int OpAcidDb_Stop(OutputPlugin *);int OpAcidDb_Log(void *, void *);int OpAcidDb_Alert(void *, void *);int OpAcidDb_LogConfig(OutputPlugin *outputPlugin);/* Internal functions */OpAcidDb_Data *OpAcidDb_ParseArgs(char *);int DbClose(OpAcidDb_Data *data);int DbConnect(OpAcidDb_Data *data);u_int32_t AcidDbGetNextCid(OpAcidDb_Data *data);u_int32_t AcidDbGetSensorId(OpAcidDb_Data *data);int AcidDbCheckSchemaVersion(OpAcidDb_Data *data);u_int32_t AcidDbGetSigId(OpAcidDb_Data *, Sid *, ClassType *,         unsigned int priority);unsigned int GetAcidDbClassId(OpAcidDb_Data *data, ClassType *class_type);int InsertSigReferences(OpAcidDb_Data *, ReferenceData *, unsigned int sig_id);int InsertIPData(OpAcidDb_Data *data, Packet *p);int InsertICMPData(OpAcidDb_Data *data, Packet *p);int InsertUDPData(OpAcidDb_Data *data, Packet *p);int InsertTCPData(OpAcidDb_Data *data, Packet *p);int InsertPayloadData(OpAcidDb_Data *data, Packet *p);int SelectAsUInt(OpAcidDb_Data *data, char *sql, unsigned int *result);int Insert(OpAcidDb_Data *data, char *sql, unsigned int *row_id);char *EscapeString(OpAcidDb_Data *data, char *string);#ifdef ENABLE_MYSQLint MysqlConnect(OpAcidDb_Data *);int MysqlClose(MYSQL *mysql);int MysqlSelectAsUInt(MYSQL *mysql, char *sql, unsigned int *result);int MysqlInsert(MYSQL *mysql, char *sql, unsigned int *row_id);char *MysqlEscapeString(MYSQL *mysql, char *string);#endif#ifdef ENABLE_POSTGRESint PostgresConnect(OpAcidDb_Data *);int PostgresClose(PGconn *);int PostgresSelectAsUInt(PGconn *, char *sql, unsigned int *result);int PostgresInsert(PGconn *, char *sql);char *PostgresEscapeString(PGconn *, char *string);#endif /* ENABLE_POSTGRES *//* Global variables */static char sql_buffer[MAX_QUERY_SIZE];/* init routine makes this processor available for dataprocessor directives */void OpAcidDb_Init(){    OutputPlugin *outputPlugin;    outputPlugin = RegisterOutputPlugin("alert_acid_db", "alert");    outputPlugin->setupFunc = OpAcidDb_Setup;    outputPlugin->exitFunc = OpAcidDb_Exit;    outputPlugin->startFunc = OpAcidDb_Start;    outputPlugin->stopFunc = OpAcidDb_Stop;    outputPlugin->outputFunc = OpAcidDb_Alert;    outputPlugin->logConfigFunc = OpAcidDb_LogConfig;        outputPlugin = RegisterOutputPlugin("log_acid_db", "log");    outputPlugin->setupFunc = OpAcidDb_Setup;    outputPlugin->exitFunc = OpAcidDb_Exit;    outputPlugin->startFunc = OpAcidDb_Start;    outputPlugin->stopFunc = OpAcidDb_Stop;    outputPlugin->outputFunc = OpAcidDb_Log;    outputPlugin->logConfigFunc = OpAcidDb_LogConfig;    }/* Setup the output plugin, process any arguments, link the functions to * the output functional node */int OpAcidDb_Setup(OutputPlugin *outputPlugin, char *args){    /* setup the run time context for this output plugin */    outputPlugin->data = OpAcidDb_ParseArgs(args);    return 0;}/* Inverse of the setup function, free memory allocated in Setup  * can't free the outputPlugin since it is also the list node itself */int OpAcidDb_Exit(OutputPlugin *outputPlugin){    return 0;}int OpAcidDb_LogConfig(OutputPlugin *outputPlugin){    OpAcidDb_Data *data = NULL;    if(!outputPlugin || !outputPlugin->data)        return -1;    data = (OpAcidDb_Data *)outputPlugin->data;    LogMessage("OpAcidDB configured\n");    LogMessage("  Database Flavour: %s\n", db_flavours[data->flavor]);    LogMessage("  Detail Level: %s\n", data->detail == 1 ? "Full" : "Fast");    LogMessage("  Database Server: %s\n", data->server);    LogMessage("  Database User: %s\n", data->user);    return 0;}/*  * this function gets called at start time, you should open any output files * or establish DB connections, etc, here */int OpAcidDb_Start(OutputPlugin *outputPlugin, void *spool_header){    OpAcidDb_Data *data = (OpAcidDb_Data *)outputPlugin->data;    if(data == NULL)        FatalError("ERROR: Unable to find context for AcidDb startup!\n");        if(pv.verbose)    {        OpAcidDb_LogConfig(outputPlugin);    }        /* Connect to the database */    if(DbConnect(data))        FatalError("OpAcidDb_: Failed to connect to database: %s:%s@%s/%s\n",                data->user, data->password, data->server, data->database);    /* check the db schema */    if(AcidDbCheckSchemaVersion(data))        FatalError("OpAcidDb_: database schema mismatch\n");     /* if sensor id == 0, then we attempt attempt to determine it dynamically */    if(data->sensor_id == 0)    {        data->sensor_id = AcidDbGetSensorId(data);        /* XXX: Error checking */    }    /* Get the next cid from the database */    data->event_id = AcidDbGetNextCid(data);    if(pv.verbose)    {        LogMessage("SensorID: %i\n", data->sensor_id);        LogMessage("Next CID: %i\n", data->event_id);    }    return 0;}int OpAcidDb_Stop(OutputPlugin *outputPlugin){    OpAcidDb_Data *data = (OpAcidDb_Data *)outputPlugin->data;    if(data == NULL)        FatalError("ERROR: Unable to find context for AcidDb startup!\n");    /* close database connection */    DbClose(data);        return 0;}int OpAcidDb_Alert(void *context, void *data){    char timestamp[TIMEBUF_SIZE];    Sid *sid = NULL;    ClassType *class_type = NULL;    UnifiedAlertRecord *record = (UnifiedAlertRecord *)data;     OpAcidDb_Data *op_data = (OpAcidDb_Data *)context;    u_int32_t acid_sig_id;    RenderTimestamp(record->ts.tv_sec, timestamp, TIMEBUF_SIZE);    sid = GetSid(record->event.sig_generator, record->event.sig_id);    if(sid == NULL)        sid = FakeSid(record->event.sig_generator, record->event.sig_id);            if(!(class_type = GetClassType(record->event.classification))             && record->event.classification != 0)    {        LogMessage("WARNING: No ClassType found for classification '%i'\n",                record->event.classification);    }        if((acid_sig_id = AcidDbGetSigId(op_data, sid, class_type,             record->event.priority)) == 0)    {        FatalError("op_acid_db:  Failed to retrieve ACID DB sig id\n");    }        /* Insert data into the event table */    if(snprintf(sql_buffer, MAX_QUERY_SIZE,                "INSERT INTO event(sid, cid, signature, timestamp) "                "VALUES('%u', '%u', '%u', '%s')",                op_data->sensor_id, op_data->event_id, acid_sig_id,                timestamp) < MAX_QUERY_SIZE)    {        //LogMessage("SQL: %s\n", sql_buffer);        Insert(op_data, sql_buffer, NULL);     /* XXX: Error checking */    }    /* insert data into the ip header table */    if(snprintf(sql_buffer, MAX_QUERY_SIZE,            "INSERT INTO iphdr(sid, cid, ip_src, ip_dst, ip_proto) "            "VALUES('%u', '%u', '%u', '%u', '%u')",            op_data->sensor_id, op_data->event_id, record->sip,            record->dip, record->protocol) < MAX_QUERY_SIZE)    {        Insert(op_data, sql_buffer, NULL); /* XXX: Error checking */    }    /* build the protocol specific header information */    switch(record->protocol)    {        case IPPROTO_TCP:            if(snprintf(sql_buffer, MAX_QUERY_SIZE,                    "INSERT INTO tcphdr (sid, cid, tcp_sport, tcp_dport, "                    "tcp_flags) VALUES('%u', '%u', '%u', '%u', 0)",                     op_data->sensor_id, op_data->event_id, record->sp,                    record->dp) < MAX_QUERY_SIZE)            {                Insert(op_data, sql_buffer, NULL); /* XXX: Error checking */            }            break;        case IPPROTO_UDP:            if(snprintf(sql_buffer, MAX_QUERY_SIZE,                    "INSERT INTO udphdr (sid, cid, udp_sport, udp_dport) "                    "VALUES('%u', '%u', '%u', '%u')",                     op_data->sensor_id, op_data->event_id, record->sp,                    record->dp) < MAX_QUERY_SIZE)            {                Insert(op_data, sql_buffer, NULL);  /* XXX: Error checking */            }            break;        case IPPROTO_ICMP:            if(snprintf(sql_buffer, MAX_QUERY_SIZE,                    "INSERT INTO icmphdr (sid, cid, icmp_type, icmp_code) "                    "VALUES('%u', '%u', '%u', '%u')",                     op_data->sensor_id, op_data->event_id, record->sp,                    record->dp) < MAX_QUERY_SIZE)            {                Insert(op_data, sql_buffer, NULL); /* XXX: Error Checking */            }            break;    }    ++op_data->event_id;    return 0;}int OpAcidDb_Log(void *context, void *data){    char timestamp[TIMEBUF_SIZE];    Sid *sid = NULL;    ClassType *class_type;    UnifiedLogRecord *record = (UnifiedLogRecord *)data;     OpAcidDb_Data *op_data = (OpAcidDb_Data *)context;    u_int32_t acid_sig_id;    Packet p;#if 0 /* this is broken */    /* skip tagged packets, since the db does not have a mechanism to      * deal with them properly     */    if(record->log.event.event_reference)    {        LogMessage("Skipping tagged packet %i\n", record->log.event.event_reference);        return 0;    }#endif        RenderTimestamp(record->log.pkth.ts.tv_sec, timestamp, TIMEBUF_SIZE);    sid = GetSid(record->log.event.sig_generator, record->log.event.sig_id);    if(sid == NULL)        sid = FakeSid(record->log.event.sig_generator, record->log.event.sig_id);    class_type = GetClassType(record->log.event.classification);    if((acid_sig_id = AcidDbGetSigId(op_data, sid, class_type,             record->log.event.priority)) == 0)    {        FatalError("op_acid_db:  Failed to retrieve ACID DB sig id\n");    }    /* Insert data into the event table */    if(snprintf(sql_buffer, MAX_QUERY_SIZE,            "INSERT INTO event(sid, cid, signature, timestamp) "            "VALUES('%u', '%u', '%u', '%s')",             op_data->sensor_id, op_data->event_id, acid_sig_id,            timestamp) < MAX_QUERY_SIZE)    {        //LogMessage("SQL: %s\n", sql_buffer);        Insert(op_data, sql_buffer, NULL);  /* XXX: Error checking */    }    /* decode the packet */    if(DecodePacket(&p, &record->log.pkth, record->pkt + 2) == 0)    {        if(p.iph)        {            /* Insert ip header information */            InsertIPData(op_data, &p);            /* store layer 4 data for non fragmented packets */            if(!(p.pkt_flags & PKT_FRAG_FLAG))            {                switch(p.iph->ip_proto)                {                    case IPPROTO_ICMP:                        InsertICMPData(op_data, &p);                        break;                    case IPPROTO_TCP:                        InsertTCPData(op_data, &p);                        break;                    case IPPROTO_UDP:                        InsertUDPData(op_data, &p);                        break;                }            }            /* Insert payload data */            if(op_data->detail)                InsertPayloadData(op_data, &p);        }    }    ++op_data->event_id;    return 0;}int InsertIPData(OpAcidDb_Data *op_data, Packet *p){    if(op_data->detail)    {        if(snprintf(sql_buffer, MAX_QUERY_SIZE,                "INSERT INTO iphdr(sid, cid, ip_src, ip_dst, ip_proto, "                "ip_ver, ip_hlen, ip_tos, ip_len, ip_id, ip_flags, ip_off, "                "ip_ttl, ip_csum) VALUES('%u', '%u', '%u', '%u', '%u', "                "'%u', '%u', '%u', '%u', '%u', '%u', '%u', "                "'%u', '%u')",                op_data->sensor_id, op_data->event_id,                 ntohl(p->iph->ip_src.s_addr), ntohl(p->iph->ip_dst.s_addr),                 p->iph->ip_proto, IP_VER(p->iph), IP_HLEN(p->iph),                p->iph->ip_tos, ntohs(p->iph->ip_len), ntohs(p->iph->ip_id),#if defined(WORDS_BIGENDIAN)                ((p->iph->ip_off & 0xE000) >> 13),                htons(p->iph->ip_off & 0x1FFF),#else                ((p->iph->ip_off & 0x00E0) >> 5),                htons(p->iph->ip_off & 0xFF1F), #endif                p->iph->ip_ttl,                htons(p->iph->ip_csum)) < MAX_QUERY_SIZE)        {            Insert(op_data, sql_buffer, NULL);  /* XXX: Error Checking */        }        /* XXX: IP Options not handled */    }    else    {        if(snprintf(sql_buffer, MAX_QUERY_SIZE,                "INSERT INTO iphdr(sid, cid, ip_src, ip_dst, ip_proto) "                "VALUES('%u', '%u', '%u', '%u', '%u')",                op_data->sensor_id, op_data->event_id,                 ntohl(p->iph->ip_src.s_addr), ntohl(p->iph->ip_dst.s_addr),                 p->iph->ip_proto) < MAX_QUERY_SIZE)        {            Insert(op_data, sql_buffer, NULL);  /* XXX: Error Checking */        }    }    return 0;}int InsertUDPData(OpAcidDb_Data *op_data, Packet *p){    if(!p->udph)        return 0;    if(op_data->detail)    {        if(snprintf(sql_buffer, MAX_QUERY_SIZE,                "INSERT INTO udphdr(sid, cid, udp_sport, udp_dport, udp_len, "                "udp_csum) VALUES('%u', '%u', '%u', '%u', '%u', '%u')",                 op_data->sensor_id, op_data->event_id, p->sp,                p->dp, ntohs(p->udph->uh_len),                 ntohs(p->udph->uh_chk)) < MAX_QUERY_SIZE)        {            Insert(op_data, sql_buffer, NULL);  /* XXX: Error Checking */        }    }    else    {        /* insert data into the udp header table */        if(snprintf(sql_buffer, MAX_QUERY_SIZE,                "INSERT INTO udphdr (sid, cid, udp_sport, udp_dport) "                "VALUES('%u', '%u', '%u', '%u')",                 op_data->sensor_id, op_data->event_id, p->sp,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -