?? op_sguil.c
字號:
/* $Id: op_sguil.c,v 1.5 2004/04/03 19:57:33 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.***//* op_sguil is a modified op_acid_db plugin configured to work with * sguil (Snort GUI for Lamerz). Sguil and ACIDs DB schemas differ. * Sguil combines the event and iphdr tables along with moving the * src and dst port columns into event. I've also added SguilSendEvent * which opens a network socket and sends RT events to sguild. * * Andrew, sorry about mangling your code but it works so well :) * * Bammkkkk*//* I N C L U D E S *****************************************************/#ifdef ENABLE_MYSQL /* Wrap the whole thing in an ENABLE_MYSQL block */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <netinet/in.h>#include <time.h>#include <errno.h>#include <unistd.h>#include <ctype.h>#include "strlcpyu.h"#include "ConfigFile.h"#include "plugbase.h"#include "mstring.h"#include "sid.h"#include "classification.h"#include "util.h"#include "input-plugins/dp_log.h"#include "op_plugbase.h"#include "op_decode.h"#include "event.h"/* Needed for network socket */#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#ifdef ENABLE_MYSQL#include <mysql.h>#include <errmsg.h>#endif /* ENABLE_MYSQL *//* D A T A S T R U C T U R E S **************************************/typedef struct _OpSguil_Data { u_int8_t flavor; /* what flavor of db? MySQL, postgres, ... */ u_int16_t unused; char *server; char *database; char *user; char *password; int sensor_id; int options; char *sguild_host; int sguild_sock; int sguild_port; int nospin; u_int32_t event_id; /* db handles go here */#ifdef ENABLE_MYSQL MYSQL *mysql;#endif /* ENABLE_MYSQL */} OpSguil_Data;#define MAX_QUERY_SIZE 8192#define SYSLOG_BUF 1024/* database flavor defines */#define FLAVOR_MYSQL 1#define FLAVOR_POSTGRES 2static char *sgdb_flavours[] = {NULL, "mysql", "postgres"};/* Network socket defines */#define MAX_MSG_LEN 100/* Output plug-in API functions */static int OpSguil_Setup(OutputPlugin *, char *args);static int OpSguil_Exit(OutputPlugin *);static int OpSguil_Start(OutputPlugin *, void *);static int OpSguil_Stop(OutputPlugin *);static int OpSguil_Log(void *, void *);static int OpSguil_LogConfig(OutputPlugin *outputPlugin);/* Internal functions */int SguildConnect(OpSguil_Data *);int SguilSendEvent(OpSguil_Data *data, char *eventMsg);int read_line();OpSguil_Data *OpSguil_ParseArgs(char *);int sgDbClose(OpSguil_Data *data);int sgDbConnect(OpSguil_Data *data);u_int32_t SguilGetNextCid(OpSguil_Data *data);u_int32_t SguilGetSensorId(OpSguil_Data *data);int SguilCheckSchemaVersion(OpSguil_Data *data);int InsertIPData(OpSguil_Data *data, Packet *p);int sgInsertICMPData(OpSguil_Data *data, Packet *p);int sgInsertUDPData(OpSguil_Data *data, Packet *p);int sgInsertTCPData(OpSguil_Data *data, Packet *p);int sgInsertPayloadData(OpSguil_Data *data, Packet *p);int sgSelectAsUInt(OpSguil_Data *data, char *sql, unsigned int *result);int sgInsert(OpSguil_Data *data, char *sql, unsigned int *row_id);int sgBeginTransaction(OpSguil_Data *);int sgEndTransaction(OpSguil_Data *);int sgAbortTransaction(OpSguil_Data *);#ifdef ENABLE_MYSQLint sgMysqlConnect(OpSguil_Data *);int sgMysqlClose(MYSQL *mysql);int sgMysqlSelectAsUInt(MYSQL *mysql, char *sql, unsigned int *result);int sgMysqlInsert(MYSQL *mysql, char *sql, unsigned int *row_id);#endif/* Global variables */static char sql_buffer[MAX_QUERY_SIZE];/* * Rather than using an incremental connection id (cid), this uses the * current time in milliseconds. BY is fast, but will we get dups in the * same millisecond? * Okay, lets wait on doing this.long GetMilliseconds() { struct timeval tv; gettimeofday(&tv, NULL); return (long)(tv.tv_sec * 1000 + tv.tv_usec / 1000);}*//* init routine makes this processor available for dataprocessor directives */void OpSguil_Init(){ OutputPlugin *outputPlugin; outputPlugin = RegisterOutputPlugin("sguil", "log"); outputPlugin->setupFunc = OpSguil_Setup; outputPlugin->exitFunc = OpSguil_Exit; outputPlugin->startFunc = OpSguil_Start; outputPlugin->stopFunc = OpSguil_Stop; outputPlugin->outputFunc = OpSguil_Log; outputPlugin->logConfigFunc = OpSguil_LogConfig; }int OpSguil_LogConfig(OutputPlugin *outputPlugin){ OpSguil_Data *data = NULL; if(!outputPlugin || !outputPlugin->data) return -1; data = (OpSguil_Data *)outputPlugin->data; LogMessage("OpSguil configured\n"); /* XXX We need to print the configuration details here */ return 0;} /* Setup the output plugin, process any arguments, link the functions to * the output functional node */int OpSguil_Setup(OutputPlugin *outputPlugin, char *args){ /* setup the run time context for this output plugin */ outputPlugin->data = OpSguil_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 OpSguil_Exit(OutputPlugin *outputPlugin){ return 0;}/* * this function gets called at start time, you should open any output files * or establish DB connections, etc, here */int OpSguil_Start(OutputPlugin *outputPlugin, void *spool_header){ char tmpMsg [256]; OpSguil_Data *data = (OpSguil_Data *)outputPlugin->data; LogMessage("OpSguil_Start\n"); if(data == NULL) FatalError("ERROR: Unable to find context for Sguil startup!\n"); /* Connect to sguild */ if(SguildConnect(data)) FatalError("OpSguil_: Failed to connect to sguild: %s:%i\n", data->sguild_host, data->sguild_port); /* Write a system-info message*/ sprintf(tmpMsg, "RTEvent |||system-info|%s||Barnyard started.||||||||\n", pv.hostname); SguilSendEvent(data, tmpMsg); /* Connect to the database */ if(sgDbConnect(data)) FatalError("OpSguil_: Failed to connect to database: %s:%s@%s/%s\n", data->user, data->password, data->server, data->database); /* check the db schema */ /*if(SguilCheckSchemaVersion(data)) FatalError("OpSguil_: database schema mismatch\n");*/ /* if sensor id == 0, then we attempt attempt to determine it dynamically */ if(data->sensor_id == 0) { data->sensor_id = SguilGetSensorId(data); /* XXX: Error checking */ } /* Get the next cid from the database */ data->event_id = SguilGetNextCid(data); if(pv.verbose) { LogMessage("OpAcidDB configuration details\n"); LogMessage("Database Flavour: %s\n", sgdb_flavours[data->flavor]); LogMessage("Database Server: %s\n", data->server); LogMessage("Database User: %s\n", data->user); LogMessage("SensorID: %i\n", data->sensor_id); LogMessage("Sguild Host: %s\n", data->sguild_host); LogMessage("Sguild Port: %i\n", data->sguild_port); } if((data->nospin) == NULL) { if(pv.verbose) { LogMessage("Barnyard will sleep(15) if unable to connect to sguild.\n"); } data->nospin = 0; } else { if(pv.verbose) { LogMessage("Spinning disabled.\n"); } } sprintf(tmpMsg, "RTEvent |||system-info|%s||Database Server: %s.||||||||\n", pv.hostname, data->server); SguilSendEvent(data, tmpMsg); sprintf(tmpMsg, "RTEvent |||system-info|%s||Database Next CID: %i.||||||||\n", pv.hostname, data->event_id); SguilSendEvent(data, tmpMsg); return 0;}int OpSguil_Stop(OutputPlugin *outputPlugin){ OpSguil_Data *data = (OpSguil_Data *)outputPlugin->data; if(data == NULL) FatalError("ERROR: Unable to find context for Sguil startup!\n"); /* close database connection */ sgDbClose(data); return 0;}/* sguil only uses log */int OpSguil_Log(void *context, void *data){ char timestamp[TIMEBUF_SIZE]; char syslogMessage[SYSLOG_BUF]; char eventInfo[SYSLOG_BUF]; //int MAX_INSERT_LEN = 1024; char insertColumns[MAX_QUERY_SIZE]; char insertValues[MAX_QUERY_SIZE]; char valuesTemp[MAX_QUERY_SIZE]; char ipInfo[38]; char portInfo[16]; char *esc_message; Sid *sid = NULL; ClassType *class_type; UnifiedLogRecord *record = (UnifiedLogRecord *)data; OpSguil_Data *op_data = (OpSguil_Data *)context; Packet p; bzero(syslogMessage, SYSLOG_BUF); bzero(insertColumns, MAX_QUERY_SIZE); bzero(insertValues, MAX_QUERY_SIZE);#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); //fprintf(stdout, "Timestamp: %lu\n", GetMilliseconds()); //fflush(stdout); 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); //sgBeginTransaction(op_data); /* XXX: Error checking */ /* Build the event insert. */ snprintf(insertColumns, MAX_QUERY_SIZE, "INSERT INTO event (status, sid, cid, signature_id, signature_rev, signature, timestamp, priority, class"); esc_message = malloc(strlen(sid->msg)*2+1); mysql_real_escape_string(op_data->mysql, esc_message, sid->msg, strlen(sid->msg)); if(class_type == NULL) { snprintf(valuesTemp, MAX_QUERY_SIZE, "VALUES ('0', '%u', '%u', '%d', '%d', '%s', '%s', '%u', 'unknown'", op_data->sensor_id, op_data->event_id, sid->sid, sid->rev, esc_message, timestamp, record->log.event.priority); snprintf(eventInfo, SYSLOG_BUF, "RTEvent |0|%u|unknown|%s|%s|%u|%u|%s", record->log.event.priority, pv.hostname, timestamp, op_data->sensor_id, op_data->event_id, sid->msg); } else { snprintf(valuesTemp, MAX_QUERY_SIZE, "VALUES ('0', '%u', '%u', '%d', '%d', '%s', '%s', '%u', '%s'", op_data->sensor_id, op_data->event_id, sid->sid, sid->rev, esc_message, timestamp, record->log.event.priority, class_type->type); snprintf(eventInfo, SYSLOG_BUF, "RTEvent |0|%u|%s|%s|%s|%u|%u|%s", record->log.event.priority, class_type->type, pv.hostname, timestamp, op_data->sensor_id, op_data->event_id, sid->msg); } free(esc_message); insertValues[0] = '\0'; strcat(insertValues, valuesTemp); syslogMessage[0] = '\0'; strcat(syslogMessage, eventInfo); /* decode the packet */ if(DecodePacket(&p, &record->log.pkth, record->pkt + 2) == 0) { if(p.iph) { /* Insert ip header information */ //InsertIPData(op_data, &p); strcat(insertColumns, ",src_ip, dst_ip, ip_proto, ip_ver, ip_hlen, ip_tos, ip_len, ip_id, ip_flags, ip_off, ip_ttl, ip_csum"); snprintf(valuesTemp, MAX_QUERY_SIZE, ",'%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u'",
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -