freebsd-ports/security/barnyard-sguil/files/patch-op-sguil.c
Pav Lucistnik 587c8499aa New slave port to security/barnyard - adds patches for sguil6
PR:		ports/92241
Submitted by:	Paul Schmehl <pauls@utdallas.edu>
2006-01-26 10:56:46 +00:00

1873 lines
60 KiB
C

--- src/output-plugins/op_sguil.c.orig Sat Apr 3 13:57:33 2004
+++ src/output-plugins/op_sguil.c Mon Jan 23 18:22:09 2006
@@ -1,8 +1,9 @@
-/* $Id: op_sguil.c,v 1.5 2004/04/03 19:57:33 andrewbaker Exp $ */
+/* $Id: op_sguil.c,v 1.16 2005/09/01 15:17:56 bamm Exp $ */
+
/*
-** Copyright (C) 2001-2002 Andrew R. Baker <andrewb@snort.org>
+** Copyright (C) 2002-2005 Robert (Bamm) Visscher <bamm@sguil.net>
**
-** This program is distributed under the terms of version 1.0 of the
+** 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,
@@ -11,21 +12,16 @@
**
*/
-/* 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
+/*
+** op_sguil is the sguil output plugin for barnyard (http://barnyard.sf.net).
+** For more information about sguil see http://www.sguil.net
*/
-/* I N C L U D E S *****************************************************/
-
-#ifdef ENABLE_MYSQL /* Wrap the whole thing in an ENABLE_MYSQL block */
+/*********************************************************************
+* I N C L U D E S *
+*********************************************************************/
+/* Std includes */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -48,52 +44,13 @@
#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 2
-
-static char *sgdb_flavours[] = {NULL, "mysql", "postgres"};
-
-/* Network socket defines */
-#define MAX_MSG_LEN 100
-
+/* Yeah TCL! */
+#include <tcl.h>
/* Output plug-in API functions */
static int OpSguil_Setup(OutputPlugin *, char *args);
@@ -103,56 +60,39 @@
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_MYSQL
-int 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
+typedef struct _OpSguil_Data
+{
+ char *sensor_name;
+ char *tag_path;
+ char *passwd;
+ u_int16_t sensor_id;
+ u_int32_t event_id;
+ u_int16_t agent_port;
+ int agent_sock;
+} OpSguil_Data;
-/* Global variables */
-static char sql_buffer[MAX_QUERY_SIZE];
+#define MAX_MSG_LEN 2048
+#define STD_BUFFER 128
-/*
- * 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);
+int OpSguil_AppendIPHdrData(Tcl_DString *list, Packet *p);
+int OpSguil_AppendICMPData(Tcl_DString *list, Packet *p);
+int OpSguil_AppendTCPData(Tcl_DString *list, Packet *p);
+int OpSguil_AppendUDPData(Tcl_DString *list, Packet *p);
+int OpSguil_AppendPayloadData(Tcl_DString *list, Packet *p);
+int OpSguil_SensorAgentConnect(OpSguil_Data *);
+//int OpSguil_SensorAgentAuth(OpSguil_Data *);
+int OpSguil_SensorAgentInit(OpSguil_Data *);
+int OpSguil_RTEventMsg(OpSguil_Data *data, char *msg);
+int OpSguil_SendAgentMsg(OpSguil_Data *data, char *msg);
+int OpSguil_RecvAgentMsg();
+OpSguil_Data *OpSguil_ParseArgs(char *);
- 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;
@@ -160,25 +100,9 @@
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
*/
@@ -186,11 +110,11 @@
{
/* 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
+
+/* 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)
@@ -198,478 +122,353 @@
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");
+
+ if(pv.verbose)
+ OpSguil_LogConfig(outputPlugin);
+
+ /* Figure out out sensor_name */
+ if(data->sensor_name == NULL)
+ {
+ /* See if the user used the ProgVar config hostname: */
+ if(pv.hostname != NULL)
+ {
+ data->sensor_name = pv.hostname;
+ }
+ else
+ {
+ FatalError("ERROR: Unable to determine hostname.");
+ }
+ }
+
+ /* Connect to sensor_agent */
+ OpSguil_SensorAgentConnect(data);
+
+ /* Initialize - get sid and next cid */
+ if(pv.verbose)
+ LogMessage("Waiting for sid and cid from sensor_agent.\n");
+ OpSguil_SensorAgentInit(data);
- /* 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");
- }
+
+ LogMessage("Sensor Name: %s\n", data->sensor_name);
+ LogMessage("Agent Port: %u\n", data->agent_port);
+
}
- 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);
+/*
+** if(SensorAgentAuth(data))
+** FatalError("OpSguil: Authentication failed.\n");
+**
+** if(pv.verbose)
+** LogMessage("OpSguil: Authentication successful.);
+*/
+
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");
+
+ return 0;
+}
+
+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 */
- /* close database connection */
- sgDbClose(data);
-
return 0;
}
-/* sguil only uses log */
-int OpSguil_Log(void *context, void *data)
+
+int OpSguil_Log(void *context, void *ul_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;
+ UnifiedLogRecord *record = (UnifiedLogRecord *)ul_data;
+ OpSguil_Data *data = (OpSguil_Data *)context;
Packet p;
+ char buffer[STD_BUFFER];
+ Tcl_DString list;
- 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
+ bzero(buffer, STD_BUFFER);
+ //LogMessage("Event id ==> %u\n", record->log.event.event_id);
+ //LogMessage("Ref time ==> %lu\n", record->log.event.ref_time.tv_sec);
- RenderTimestamp(record->log.pkth.ts.tv_sec, timestamp, TIMEBUF_SIZE);
- //fprintf(stdout, "Timestamp: %lu\n", GetMilliseconds());
- //fflush(stdout);
+ /* Sig info */
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);
+ sid->rev = record->log.event.sig_rev;
+
class_type = GetClassType(record->log.event.classification);
+
+ /* Here we build our RT event to send to sguild. The event is built with a
+ ** proper tcl list format.
+ ** RT FORMAT:
+ **
+ ** 0 1 2 3 4 5 6 7
+ ** {RTEVENT} {0} {sid} {cid} {sensor name} {snort event_id} {snort event_ref} {snort ref_time}
+ **
+ ** 8 9 10 11 12 13 14
+ ** {sig_gen} {sig id} {rev} {message} {timestamp} {priority} {class_type}
+ **
+ ** 15 16 17 18 19 20 21
+ ** {sip (dec)} {sip (string)} {dip (dec)} {dip (string)} {ip proto} {ip ver} {ip hlen}
+ **
+ ** 22 23 24 25 26 27 28
+ ** {ip tos} {ip len} {ip id} {ip flags} {ip off} {ip ttl} {ip csum}
+ **
+ ** 29 30 31 32 33
+ ** {icmp type} {icmp code} {icmp csum} {icmp id} {icmp seq}
+ **
+ ** 34 35
+ ** {src port} {dst port}
+ **
+ ** 36 37 38 39 40 41 42 43
+ ** {tcp seq} {tcp ack} {tcp off} {tcp res} {tcp flags} {tcp win} {tcp csum} {tcp urp}
+ **
+ ** 44 45
+ ** {udp len} {udp csum}
+ **
+ ** 46
+ ** {data payload}
+ */
+
+ Tcl_DStringInit(&list);
+
+ /* RTEVENT */
+ Tcl_DStringAppendElement(&list, "RTEVENT");
+
+ /* Status - 0 */
+ Tcl_DStringAppendElement(&list, "0");
+
+ /* Sensor ID (sid) */
+ sprintf(buffer, "%u", data->sensor_id);
+ Tcl_DStringAppendElement(&list, buffer);
+
+ /* Event ID (cid) */
+ sprintf(buffer, "%u", data->event_id);
+ Tcl_DStringAppendElement(&list, buffer);
+
+ /* Sensor Name */
+ Tcl_DStringAppendElement(&list, data->sensor_name);
+
+ /* Snort Event ID */
+ sprintf(buffer, "%u", record->log.event.event_id);
+ Tcl_DStringAppendElement(&list, buffer);
+
+ /* Snort Event Ref */
+ sprintf(buffer, "%u", record->log.event.event_reference);
+ Tcl_DStringAppendElement(&list, buffer);
+
+ /* Snort Event Ref Time */
+ if(record->log.event.ref_time.tv_sec == 0)
+ {
+ Tcl_DStringAppendElement(&list, "");
+ }
+ else
+ {
+ RenderTimestamp(record->log.event.ref_time.tv_sec, timestamp, TIMEBUF_SIZE);
+ Tcl_DStringAppendElement(&list, timestamp);
+ }
+
+ /* Generator ID */
+ sprintf(buffer, "%d", sid->gen);
+ Tcl_DStringAppendElement(&list, buffer);
+
+ /* Signature ID */
+ sprintf(buffer, "%d", sid->sid);
+ Tcl_DStringAppendElement(&list, buffer);
+
+ /* Signature Revision */
+ sprintf(buffer, "%d", sid->rev);
+ Tcl_DStringAppendElement(&list, buffer);
+
+ /* Signature Msg */
+ Tcl_DStringAppendElement(&list, sid->msg);
+
+ /* Packet Timestamp */
+ RenderTimestamp(record->log.pkth.ts.tv_sec, timestamp, TIMEBUF_SIZE);
+ Tcl_DStringAppendElement(&list, timestamp);
+
+ /* Alert Priority */
+ sprintf(buffer, "%u", record->log.event.priority);
+ Tcl_DStringAppendElement(&list, buffer);
- //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);
+ /* Alert Classification */
+ if (class_type == NULL)
+ {
+ Tcl_DStringAppendElement(&list, "unknown");
}
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 */
+ Tcl_DStringAppendElement(&list, class_type->type);
+ }
+
+ /* Pull decoded info from 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'",
- 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);
-
- strcat(insertValues, valuesTemp);
-
+ int i;
- /* SYSLOG - Changed to SguilSendEvent*/
- snprintf(ipInfo, 38, "|%u.%u.%u.%u|%u.%u.%u.%u|%u",
-#if defined(WORDS_BIGENDIAN)
- (p.iph->ip_src.s_addr & 0xff000000) >> 24,
- (p.iph->ip_src.s_addr & 0x00ff0000) >> 16,
- (p.iph->ip_src.s_addr & 0x0000ff00) >> 8,
- (p.iph->ip_src.s_addr & 0x000000ff),
- (p.iph->ip_dst.s_addr & 0xff000000) >> 24,
- (p.iph->ip_dst.s_addr & 0x00ff0000) >> 16,
- (p.iph->ip_dst.s_addr & 0x0000ff00) >> 8,
- (p.iph->ip_dst.s_addr & 0x000000ff),
-#else
- (p.iph->ip_src.s_addr & 0x000000ff),
- (p.iph->ip_src.s_addr & 0x0000ff00) >> 8,
- (p.iph->ip_src.s_addr & 0x00ff0000) >> 16,
- (p.iph->ip_src.s_addr & 0xff000000) >> 24,
- (p.iph->ip_dst.s_addr & 0x000000ff),
- (p.iph->ip_dst.s_addr & 0x0000ff00) >> 8,
- (p.iph->ip_dst.s_addr & 0x00ff0000) >> 16,
- (p.iph->ip_dst.s_addr & 0xff000000) >> 24,
-#endif
- p.iph->ip_proto);
- strcat(syslogMessage, ipInfo);
+ /* Add IP header */
+ OpSguil_AppendIPHdrData(&list, &p);
- /* store layer 4 data for non fragmented packets */
+ /* Add icmp || udp || tcp data */
if(!(p.pkt_flags & PKT_FRAG_FLAG))
{
+
switch(p.iph->ip_proto)
{
case IPPROTO_ICMP:
- snprintf(portInfo, 16, "|||");
- if(!p.icmph)
- break;
- strcat(insertColumns,
- ", icmp_type, icmp_code)");
- snprintf(valuesTemp, MAX_QUERY_SIZE,
- ", '%u', '%u')", p.icmph->icmp_type,
- p.icmph->icmp_code);
- strcat(insertValues, valuesTemp);
- strcat(insertColumns, insertValues);
- sgInsert(op_data, insertColumns, NULL);
- sgInsertICMPData(op_data, &p);
+ OpSguil_AppendICMPData(&list, &p);
break;
+
case IPPROTO_TCP:
- strcat(insertColumns,
- ", src_port, dst_port)");
- snprintf(valuesTemp, MAX_QUERY_SIZE,
- ", '%u', '%u')", p.sp, p.dp);
- strcat(insertValues, valuesTemp);
- strcat(insertColumns, insertValues);
- sgInsert(op_data, insertColumns, NULL);
- sgInsertTCPData(op_data, &p);
- snprintf(portInfo, 16, "|%u|%u|",
- p.sp, p.dp);
+ OpSguil_AppendTCPData(&list, &p);
break;
+
case IPPROTO_UDP:
- strcat(insertColumns,
- ", src_port, dst_port)");
- snprintf(valuesTemp, MAX_QUERY_SIZE,
- ", '%u', '%u')", p.sp, p.dp);
- strcat(insertValues, valuesTemp);
- strcat(insertColumns, insertValues);
- sgInsert(op_data, insertColumns, NULL);
- sgInsertUDPData(op_data, &p);
- snprintf(portInfo, 16, "|%u|%u|",
- p.sp, p.dp);
+ OpSguil_AppendUDPData(&list, &p);
+ break;
+
+ default:
+ for(i = 0; i < 17; ++i)
+ {
+ Tcl_DStringAppendElement(&list, "");
+ }
break;
}
- strcat(syslogMessage, portInfo);
+
}
else
{
- strcat(syslogMessage, "|||");
+ /* Null out TCP/UDP/ICMP fields */
+ for(i = 0; i < 17; ++i)
+ {
+ Tcl_DStringAppendElement(&list, "");
+ }
}
-
-
- /* Insert payload data */
- sgInsertPayloadData(op_data, &p);
}
else
{
- strcat(syslogMessage, "||||||");
+
+ /* No IP Header. */
+ int i;
+ for(i = 0; i < 31; ++i)
+ {
+ Tcl_DStringAppendElement(&list, "");
+ }
}
- }
- //sgEndTransaction(op_data); /* XXX: Error Checking */
- ++op_data->event_id;
- /* Append the sig id and rev to the RT event */
- snprintf(eventInfo, SYSLOG_BUF, "%u|%u|\n", sid->sid, sid->rev);
- strcat(syslogMessage, eventInfo);
- /* Write to the network socket */
- SguilSendEvent(op_data, syslogMessage);
- return 0;
-}
+ /* Add payload data */
+ OpSguil_AppendPayloadData(&list, &p);
-int sgInsertUDPData(OpSguil_Data *op_data, Packet *p)
-{
- if(!p->udph)
- return 0;
- if(snprintf(sql_buffer, MAX_QUERY_SIZE,
- "INSERT INTO udphdr(sid, cid, udp_len, udp_csum)"
- "VALUES ('%u', '%u', '%u', '%u')",
- op_data->sensor_id, op_data->event_id,
- ntohs(p->udph->uh_len),
- ntohs(p->udph->uh_chk)) < MAX_QUERY_SIZE)
+ }
+ else
+ {
+ /* ack! an event without a packet. Append 32 fillers */
+ int i;
+ for(i = 0; i < 32; ++i)
{
- sgInsert(op_data, sql_buffer, NULL); /* XXX: Error Checking */
+ Tcl_DStringAppendElement(&list, "");
}
- return 0;
-}
+ }
-int sgInsertTCPData(OpSguil_Data *op_data, Packet *p)
-{
- if(!p->tcph)
- return 0;
+ /* Send msg to sensor_agent */
+ if (OpSguil_RTEventMsg(data, Tcl_DStringValue(&list)))
+ FatalError("Unable to send RT Events to sensor agent.\n");
- /* insert data into the tcp header table */
- if(snprintf(sql_buffer, MAX_QUERY_SIZE,
- "INSERT INTO tcphdr(sid, cid, tcp_seq, "
- "tcp_ack, tcp_off, tcp_res, tcp_flags, tcp_win, tcp_csum, "
- "tcp_urp) VALUES('%u', '%u', '%u', '%u', '%u', "
- "'%u', '%u', '%u', '%u', '%u')",
- op_data->sensor_id, op_data->event_id,
- ntohl(p->tcph->th_seq), ntohl(p->tcph->th_ack),
- TCP_OFFSET(p->tcph), TCP_X2(p->tcph), p->tcph->th_flags,
- ntohs(p->tcph->th_win), ntohs(p->tcph->th_sum),
- ntohs(p->tcph->th_urp)) < MAX_QUERY_SIZE)
- {
- sgInsert(op_data, sql_buffer, NULL); /* XXX: Error checking */
- }
- /* XXX: TCP Options not handled */
- return 0;
-}
+ /* Free! */
+ Tcl_DStringFree(&list);
+
+ /* bump the event id */
+ ++data->event_id;
-int sgInsertICMPData(OpSguil_Data *op_data, Packet *p)
-{
- if(!p->icmph)
- return 0;
- if(p->icmph->icmp_type == 0 || p->icmph->icmp_type == 8 ||
- p->icmph->icmp_type == 13 || p->icmph->icmp_type == 14 ||
- p->icmph->icmp_type == 15 || p->icmph->icmp_type == 16)
- {
- if(snprintf(sql_buffer, MAX_QUERY_SIZE,
- "INSERT INTO icmphdr(sid, cid, "
- "icmp_csum, icmp_id, icmp_seq) "
- "VALUES('%u', '%u', '%u', '%u', '%u')",
- op_data->sensor_id, op_data->event_id,
- ntohs(p->icmph->icmp_csum),
- htons(p->icmph->icmp_hun.ih_idseq.icd_id),
- htons(p->icmph->icmp_hun.ih_idseq.icd_seq))
- < MAX_QUERY_SIZE)
- {
- sgInsert(op_data, sql_buffer, NULL); /* XXX: Error checking */
- }
- }
- else
- {
- if(snprintf(sql_buffer, MAX_QUERY_SIZE,
- "INSERT INTO icmphdr(sid, cid, "
- "icmp_csum) VALUES('%u', '%u', '%u')",
- op_data->sensor_id, op_data->event_id,
- ntohs(p->icmph->icmp_csum))
- < MAX_QUERY_SIZE)
- {
- sgInsert(op_data, sql_buffer, NULL); /* XXX: Error Checking */
- }
- }
return 0;
}
-int sgInsertPayloadData(OpSguil_Data *op_data, Packet *p)
+int OpSguil_RTEventMsg(OpSguil_Data *data, char *msg)
{
- char *hex_payload;
- if(p->dsize)
- {
- hex_payload = fasthex(p->data, p->dsize);
- if(snprintf(sql_buffer, MAX_QUERY_SIZE,
- "INSERT INTO data(sid, cid, data_payload) "
- "VALUES('%u', '%u', '%s')", op_data->sensor_id,
- op_data->event_id, hex_payload) < MAX_QUERY_SIZE)
- {
- sgInsert(op_data, sql_buffer, NULL); /* XXX: Error Checking */
- }
- free(hex_payload);
- }
- return 0;
-}
+ char tmpRecvMsg[MAX_MSG_LEN];
-/* Attempts to retrieve the sensor id
- */
-unsigned int SguilGetSensorId(OpSguil_Data *op_data)
-{
- unsigned int sensor_id = 0;
- /* XXX: This should be moved to global setup */
- if(pv.hostname == NULL)
- {
- /* query the hostname */
- /* the DB schema allows for a hostname of up to 2^16-1 characters, i am limiting
- * this to 255 (+1 for the NULL)
- */
- pv.hostname = (char *)malloc(256);
- if(gethostname(pv.hostname, 256))
- {
- FatalError("Error querying hostname: %s\n", strerror(errno));
- }
- }
+ /* Send Msg */
+ OpSguil_SendAgentMsg(data, msg);
- /* XXX: need to escape strings */
- if(snprintf(sql_buffer, MAX_QUERY_SIZE,
- "SELECT sid FROM sensor WHERE hostname='%s'"
- , pv.hostname) < MAX_QUERY_SIZE)
+ /* Get confirmation */
+ memset(tmpRecvMsg,0x0,MAX_MSG_LEN);
+ if(OpSguil_RecvAgentMsg(data, tmpRecvMsg) == 1 )
{
- if(sgSelectAsUInt(op_data, sql_buffer, &sensor_id) == -1)
- {
- FatalError("Database Error\n");
- }
- if(sensor_id == 0)
- {
- /* insert sensor information */
+ if(pv.verbose)
+ LogMessage("Retrying\n");
+
+ OpSguil_RTEventMsg(data, msg);
- if(snprintf(sql_buffer, MAX_QUERY_SIZE, "INSERT INTO sensor (hostname) "
- "VALUES ('%s')", pv.hostname) < MAX_QUERY_SIZE)
- {
- sgInsert(op_data, sql_buffer, &sensor_id);
- /* XXX: Error checking */
- }
- else
- {
- FatalError("Error building SQL Query\n");
- }
- }
- if(pv.verbose >= 2)
- LogMessage("sensor_id == %u\n", sensor_id);
}
else
{
- FatalError("Error building SQL Query\n");
- }
- return sensor_id;
-}
-/* Retrieves the next acid_cid to use for inserting into the database for this
- * sensor
- */
-unsigned int SguilGetNextCid(OpSguil_Data *data)
-{
- unsigned int cid = 0;
- if(snprintf(sql_buffer, MAX_QUERY_SIZE,
- "SELECT max(cid) FROM event WHERE sid='%u'", data->sensor_id)
- < MAX_QUERY_SIZE)
- {
- if(sgSelectAsUInt(data, sql_buffer, &cid) == -1)
+ char **toks;
+ int num_toks;
+
+ if(pv.verbose)
+ LogMessage("Received: %s", tmpRecvMsg);
+
+ /* Parse the response */
+ toks = mSplit(tmpRecvMsg, " ", 2, &num_toks, 0);
+ if(strcasecmp("Confirm", toks[0]) != 0 || atoi(toks[1]) != data->event_id )
{
- FatalError("Database Error\n");
+
+ FatalError("Expected Confirm %u and got: %s\n", data->event_id, tmpRecvMsg);
+
}
-#ifdef DEBUG
- LogMessage("cid == %u\n", cid); fflush(stdout);
-#endif
+
+ FreeToks(toks, num_toks);
+
}
- else
- {
- FatalError("Database Error\n");
- }
- return ++cid;
+
+ return 0;
+
}
OpSguil_Data *OpSguil_ParseArgs(char *args)
{
- OpSguil_Data *op_data;
+ OpSguil_Data *op_data;
+
op_data = (OpSguil_Data *)SafeAlloc(sizeof(OpSguil_Data));
-
- op_data->options = 0;
-
+
if(args != NULL)
{
char **toks;
@@ -685,77 +484,38 @@
while(isspace((int)*index))
++index;
stoks = mSplit(index, " ", 2, &num_stoks, 0);
- if(strcasecmp("database", stoks[0]) == 0)
- {
- if(num_stoks > 1 && op_data->database == NULL)
- op_data->database = strdup(stoks[1]);
- else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
- file_line, index);
- }
- else if(strcasecmp("server", stoks[0]) == 0)
- {
- if(num_stoks > 1 && op_data->server == NULL)
- op_data->server = strdup(stoks[1]);
- else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
- file_line, index);
- }
- else if(strcasecmp("user", stoks[0]) == 0)
+ if(strcasecmp("agent_port", stoks[0]) == 0)
{
- if(num_stoks > 1 && op_data->user == NULL)
- op_data->user = strdup(stoks[1]);
+ if(num_stoks > 1)
+ op_data->agent_port = atoi(stoks[1]);
else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
+ LogMessage("Argument Error in %s(%i): %s\n", file_name,
file_line, index);
}
- else if(strcasecmp("password", stoks[0]) == 0)
+ else if(strcasecmp("tag_path", stoks[0]) == 0)
{
- if(num_stoks > 1 && op_data->password == NULL)
- op_data->password = strdup(stoks[1]);
+ if(num_stoks > 1 && op_data->tag_path == NULL)
+ op_data->tag_path = strdup(stoks[1]);
else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
+ LogMessage("Argument Error in %s(%i): %s\n", file_name,
file_line, index);
}
- else if(strcasecmp("sensor_id", stoks[0]) == 0)
+ else if(strcasecmp("sensor_name", stoks[0]) == 0)
{
- if(num_stoks > 1 && op_data->sensor_id == 0)
- op_data->sensor_id = atoi(stoks[1]);
+ if(num_stoks > 1 && op_data->sensor_name == NULL)
+ op_data->sensor_name = strdup(stoks[1]);
else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
+ LogMessage("Argument Error in %s(%i): %s\n", file_name,
file_line, index);
}
- else if(strcasecmp("sguild_host", stoks[0]) == 0)
- {
- if(num_stoks > 1 && op_data->sguild_host == 0)
- op_data->sguild_host = strdup(stoks[1]);
- else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
- file_line, index);
- }
- else if(strcasecmp("nospin", stoks[0]) == 0)
- {
- op_data->nospin = 1;
- }
- else if(strcasecmp("sguild_port", stoks[0]) == 0)
+ else if(strcasecmp("passwd", stoks[0]) == 0)
{
- if(num_stoks > 1 && op_data->sguild_port == 0)
- op_data->sguild_port = atoi(stoks[1]);
- else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
- file_line, index);
- }
-
-#ifdef ENABLE_MYSQL
- else if(strcasecmp("mysql", stoks[0]) == 0)
- {
- if(op_data->flavor == 0)
- op_data->flavor = FLAVOR_MYSQL;
+ if(num_stoks > 1 && op_data->passwd == NULL)
+ op_data->passwd = strdup(stoks[1]);
else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
+ LogMessage("Argument Error in %s(%i): %s\n", file_name,
file_line, index);
}
-#endif /* ENABLE_MYSQL */
else
{
fprintf(stderr, "WARNING %s (%d) => Unrecognized argument for "
@@ -765,378 +525,544 @@
}
/* free your mSplit tokens */
FreeToks(toks, num_toks);
- }
- if(op_data->flavor == 0)
- FatalError("You must specify a database flavor\n");
- if (op_data->sguild_host == NULL)
- {
- FatalError("You must specify a sguild host.\n");
}
- if (!op_data->sguild_port)
+ if (op_data->agent_port == 0)
{
- FatalError("You must specify a sguild port.\n");
+ op_data->agent_port = 7735;
}
+
return op_data;
-}
+}
-int sgDbConnect(OpSguil_Data *op_data)
+int OpSguil_AppendIPHdrData(Tcl_DString *list, Packet *p)
{
- switch(op_data->flavor)
- {
-#ifdef ENABLE_MYSQL
- case FLAVOR_MYSQL:
- return sgMysqlConnect(op_data);
+ char buffer[STD_BUFFER];
+
+ bzero(buffer, STD_BUFFER);
+
+ sprintf(buffer, "%u", ntohl(p->iph->ip_src.s_addr));
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u.%u.%u.%u",
+#if defined(WORDS_BIGENDIAN)
+ (p->iph->ip_src.s_addr & 0xff000000) >> 24,
+ (p->iph->ip_src.s_addr & 0x00ff0000) >> 16,
+ (p->iph->ip_src.s_addr & 0x0000ff00) >> 8,
+ (p->iph->ip_src.s_addr & 0x000000ff));
+#else
+ (p->iph->ip_src.s_addr & 0x000000ff),
+ (p->iph->ip_src.s_addr & 0x0000ff00) >> 8,
+ (p->iph->ip_src.s_addr & 0x00ff0000) >> 16,
+ (p->iph->ip_src.s_addr & 0xff000000) >> 24);
#endif
- default:
- FatalError("Database flavor not supported\n");
- return 1;
- }
-// return 1;
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u", ntohl(p->iph->ip_dst.s_addr));
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u.%u.%u.%u",
+#if defined(WORDS_BIGENDIAN)
+ (p->iph->ip_dst.s_addr & 0xff000000) >> 24,
+ (p->iph->ip_dst.s_addr & 0x00ff0000) >> 16,
+ (p->iph->ip_dst.s_addr & 0x0000ff00) >> 8,
+ (p->iph->ip_dst.s_addr & 0x000000ff));
+#else
+ (p->iph->ip_dst.s_addr & 0x000000ff),
+ (p->iph->ip_dst.s_addr & 0x0000ff00) >> 8,
+ (p->iph->ip_dst.s_addr & 0x00ff0000) >> 16,
+ (p->iph->ip_dst.s_addr & 0xff000000) >> 24);
+#endif
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u", p->iph->ip_proto);
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u", IP_VER(p->iph));
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u", IP_HLEN(p->iph));
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u", p->iph->ip_tos);
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u", ntohs(p->iph->ip_len));
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u", ntohs(p->iph->ip_id));
+ Tcl_DStringAppendElement(list, buffer);
+
+#if defined(WORDS_BIGENDIAN)
+
+ sprintf(buffer, "%u", ((p->iph->ip_off & 0xE000) >> 13));
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u", htons(p->iph->ip_off & 0x1FFF));
+ Tcl_DStringAppendElement(list, buffer);
+
+#else
+
+ sprintf(buffer, "%u", ((p->iph->ip_off & 0x00E0) >> 5));
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u", htons(p->iph->ip_off & 0xFF1F));
+ Tcl_DStringAppendElement(list, buffer);
+
+#endif
+
+ sprintf(buffer, "%u", p->iph->ip_ttl);
+ Tcl_DStringAppendElement(list, buffer);
+ sprintf(buffer, "%u", htons(p->iph->ip_csum));
+ Tcl_DStringAppendElement(list, buffer);
+
+ return 0;
}
-int sgDbClose(OpSguil_Data *op_data)
+int OpSguil_AppendICMPData(Tcl_DString *list, Packet *p)
{
- switch(op_data->flavor)
+
+ int i;
+ char buffer[STD_BUFFER];
+
+ bzero(buffer, STD_BUFFER);
+
+ if(!p->icmph)
{
-#ifdef ENABLE_MYSQL
- case FLAVOR_MYSQL:
- return sgMysqlClose(op_data->mysql);
-#endif
- default:
- FatalError("Database flavor not supported\n");
- return 1;
- }
-}
+ /* Null out ICMP fields */
+ for(i=0; i < 5; i++)
+ Tcl_DStringAppendElement(list, "");
-int sgSelectAsUInt(OpSguil_Data *op_data, char *sql, unsigned int *result)
-{
- switch(op_data->flavor)
+ }
+ else
{
-#ifdef ENABLE_MYSQL
- case FLAVOR_MYSQL:
- return sgMysqlSelectAsUInt(op_data->mysql, sql, result);
-#endif
- default:
- FatalError("Database flavor not supported\n");
- return 1;
+
+ /* ICMP type */
+ sprintf(buffer, "%u", p->icmph->icmp_type);
+ Tcl_DStringAppendElement(list, buffer);
+
+ /* ICMP code */
+ sprintf(buffer, "%u", p->icmph->icmp_code);
+ Tcl_DStringAppendElement(list, buffer);
+
+ /* ICMP CSUM */
+ sprintf(buffer, "%u", ntohs(p->icmph->icmp_csum));
+ Tcl_DStringAppendElement(list, buffer);
+
+ /* Append other ICMP data if we have it */
+ if(p->icmph->icmp_type == ICMP_ECHOREPLY ||
+ p->icmph->icmp_type == ICMP_ECHO ||
+ p->icmph->icmp_type == ICMP_TIMESTAMP ||
+ p->icmph->icmp_type == ICMP_TIMESTAMPREPLY ||
+ p->icmph->icmp_type == ICMP_INFO_REQUEST ||
+ p->icmph->icmp_type == ICMP_INFO_REPLY)
+ {
+
+ /* ICMP ID */
+ sprintf(buffer, "%u", htons(p->icmph->icmp_hun.ih_idseq.icd_id));
+ Tcl_DStringAppendElement(list, buffer);
+
+ /* ICMP Seq */
+ sprintf(buffer, "%u", htons(p->icmph->icmp_hun.ih_idseq.icd_seq));
+ Tcl_DStringAppendElement(list, buffer);
+
+ }
+ else
+ {
+
+ /* Add two empty elements */
+ for(i=0; i < 2; i++)
+ Tcl_DStringAppendElement(list, "");
+
+ }
+
}
+
+ /* blank out 12 elements */
+ for(i = 0; i < 12; i++)
+ Tcl_DStringAppendElement(list, "");
+
+ return 0;
+
}
-int sgInsert(OpSguil_Data *op_data, char *sql, unsigned int *row_id)
+int OpSguil_AppendTCPData(Tcl_DString *list, Packet *p)
{
- switch(op_data->flavor)
+
+ /*
+ ** 33 34 35 36 37 38 39 40
+ ** {tcp seq} {tcp ack} {tcp off} {tcp res} {tcp flags} {tcp win} {tcp csum} {tcp urp}
+ **
+ */
+
+ int i;
+ char buffer[STD_BUFFER];
+
+ bzero(buffer, STD_BUFFER);
+
+ /* empty elements for icmp data */
+ for(i=0; i < 5; i++)
+ Tcl_DStringAppendElement(list, "");
+
+ if(!p->tcph)
{
-#ifdef ENABLE_MYSQL
- case FLAVOR_MYSQL:
- return sgMysqlInsert(op_data->mysql, sql, row_id);
-#endif
- default:
- FatalError("Database flavor not supported\n");
- return 1;
- }
-}
-int sgBeginTransaction(OpSguil_Data *op_data)
-{
- switch(op_data->flavor)
+ /* Null out TCP fields */
+ for(i=0; i < 10; i++)
+ Tcl_DStringAppendElement(list, "");
+
+ }
+ else
{
-#ifdef ENABLE_MYSQL
- case FLAVOR_MYSQL:
- return sgMysqlInsert(op_data->mysql, "BEGIN", NULL);
-#endif
- default:
- FatalError("Database flavor not supported\n");
- return 1;
+
+ sprintf(buffer, "%u", p->sp);
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", p->dp);
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", ntohl(p->tcph->th_seq));
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", ntohl(p->tcph->th_ack));
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", TCP_OFFSET(p->tcph));
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", TCP_X2(p->tcph));
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", p->tcph->th_flags);
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", ntohs(p->tcph->th_win));
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", ntohs(p->tcph->th_sum));
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", ntohs(p->tcph->th_urp));
+ Tcl_DStringAppendElement(list, buffer);
+
}
+
+ /* empty elements for UDP data */
+ for(i=0; i < 2; i++)
+ Tcl_DStringAppendElement(list, "");
+
+ return 0;
+
}
-int sgEndTransaction(OpSguil_Data *op_data)
+int OpSguil_AppendUDPData(Tcl_DString *list, Packet *p)
{
- switch(op_data->flavor)
+
+ int i;
+ char buffer[STD_BUFFER];
+
+ bzero(buffer, STD_BUFFER);
+
+ /* empty elements for icmp data */
+ for(i=0; i < 5; i++)
+ Tcl_DStringAppendElement(list, "");
+
+ if(!p->udph)
{
-#ifdef ENABLE_MYSQL
- case FLAVOR_MYSQL:
- return sgMysqlInsert(op_data->mysql, "COMMIT", NULL);
-#endif
- default:
- FatalError("Database flavor not supported\n");
- return 1;
+
+ /* Null out port info */
+ for(i=0; i < 2; i++)
+ Tcl_DStringAppendElement(list, "");
+
}
-}
-
-int sgAbortTransaction(OpSguil_Data *op_data)
-{
- switch(op_data->flavor)
+ else
{
-#ifdef ENABLE_MYSQL
- case FLAVOR_MYSQL:
- return sgMysqlInsert(op_data->mysql, "ROLLBACK", NULL);
-#endif
- default:
- FatalError("Database flavor not supported\n");
- return 1;
+
+ /* source and dst port */
+ sprintf(buffer, "%u", p->sp);
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", p->dp);
+ Tcl_DStringAppendElement(list, buffer);
+
}
-}
+ /* empty elements for tcp data */
+ for(i=0; i < 8; i++)
+ Tcl_DStringAppendElement(list, "");
+
+ if(!p->udph)
+ {
+
+ /* Null out UDP info */
+ for(i=0; i < 2; i++)
+ Tcl_DStringAppendElement(list, "");
+
+ }
+ else
+ {
+
+ sprintf(buffer, "%u", ntohs(p->udph->uh_len));
+ Tcl_DStringAppendElement(list, buffer);
+
+ sprintf(buffer, "%u", ntohs(p->udph->uh_chk));
+ Tcl_DStringAppendElement(list, buffer);
-#ifdef ENABLE_MYSQL
-int sgMysqlConnect(OpSguil_Data *op_data)
-{
- op_data->mysql = mysql_init(NULL);
- if(!mysql_real_connect(op_data->mysql, op_data->server, op_data->user,
- op_data->password, op_data->database, 0, NULL, 0))
- {
- FatalError("Failed to connect to database %s:%s@%s/%s: %s\n",
- op_data->user, op_data->password, op_data->server,
- op_data->database, mysql_error(op_data->mysql));
}
+
return 0;
+
}
-int sgMysqlClose(MYSQL *mysql)
+int OpSguil_AppendPayloadData(Tcl_DString *list, Packet *p)
{
- mysql_close(mysql);
+
+ char *hex_payload;
+
+ if(p->dsize)
+ {
+ hex_payload = fasthex(p->data, p->dsize);
+ Tcl_DStringAppendElement(list, hex_payload);
+ free(hex_payload);
+ } else {
+ Tcl_DStringAppendElement(list, "");
+ }
+
return 0;
+
}
-int sgMysqlExecuteQuery(MYSQL *mysql, char *sql)
+
+int OpSguil_SensorAgentConnect(OpSguil_Data *data)
{
- int mysqlErrno;
- int result;
- while((result = mysql_query(mysql, sql) != 0))
+
+ int sockfd;
+ struct sockaddr_in my_addr;
+
+ while(1)
{
- mysqlErrno = mysql_errno(mysql);
- if(mysqlErrno < CR_MIN_ERROR)
+
+ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
- if(pv.verbose)
- LogMessage("MySQL ERROR(%i): %s. Aborting Query\n",
- mysql_errno(mysql), mysql_error(mysql));
- return result;
+ FatalError("Cannot open a local socket.\n");
+ return 1;
}
- if((mysqlErrno == CR_SERVER_LOST)
- || (mysqlErrno == CR_SERVER_GONE_ERROR))
+
+ my_addr.sin_family = AF_INET;
+ my_addr.sin_port = htons(data->agent_port);
+ my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ memset(&(my_addr.sin_zero), '\0', 8);
+
+
+ if (connect(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) < 0)
{
- LogMessage("Lost connection to MySQL server. Reconnecting\n");
- while(mysql_ping(mysql) != 0)
+ LogMessage("Cannot connect to localhost on TCP port %u.\n",
+ data->agent_port);
+ close(sockfd);
+ LogMessage("Waiting 15 secs to try again.\n");
+ if (BarnyardSleep(15))
{
- if(BarnyardSleep(15))
- return result;
+ LogMessage("Received Kill Signal...");
+ CleanExit(0);
}
- LogMessage("Reconnected to MySQL server.\n");
+
}
else
{
- /* XXX we could spin here, but we do not */
- LogMessage("MySQL Error(%i): %s\n", mysqlErrno, mysql_error(mysql));
+
+ data->agent_sock = sockfd;
+ LogMessage("Connected to localhost on %u.\n",
+ data->agent_port);
+ return 0;
+
}
+
}
- return result;
-}
+}
-int sgMysqlSelectAsUInt(MYSQL *mysql, char *sql, unsigned int *result)
+/*
+int OpSguil_SensorAgentAuth(OpSguil_Data *data)
{
- int rval = 0;
- MYSQL_RES *mysql_res;
- MYSQL_ROW tuple;
-
- if(sgMysqlExecuteQuery(mysql, sql) != 0)
- {
- /* XXX: should really just return up the chain */
- FatalError("Error (%s) executing query: %s\n", mysql_error(mysql), sql);
- return -1;
- }
- mysql_res = mysql_store_result(mysql);
- if((tuple = mysql_fetch_row(mysql_res)))
- {
- if(tuple[0] == NULL)
- *result = 0;
- else
- *result = atoi(tuple[0]);
- rval = 1;
- }
- mysql_free_result(mysql_res);
- return rval;
+ Tcl_DString auth_cmd;
+
+ Tcl_DStringInit(&auth_cmd);
+ Tcl_DStringAppendElement(auth_cmd, "AUTH");
+ Tcl_DStringAppendElement(auth_cmd, data->passwd);
+
+
}
+*/
-int sgMysqlInsert(MYSQL *mysql, char *sql, unsigned int *row_id)
+/* Request sensor ID (sid) and next cid from sensor_agent */
+int OpSguil_SensorAgentInit(OpSguil_Data *data)
{
- if(sgMysqlExecuteQuery(mysql, sql) != 0)
+
+ char tmpSendMsg[MAX_MSG_LEN];
+ char tmpRecvMsg[MAX_MSG_LEN];
+
+ /* Send our Request */
+ snprintf(tmpSendMsg, MAX_MSG_LEN, "SidCidRequest %s", data->sensor_name);
+ OpSguil_SendAgentMsg(data, tmpSendMsg);
+
+ /* Get the Results */
+ memset(tmpRecvMsg,0x0,MAX_MSG_LEN);
+ if(OpSguil_RecvAgentMsg(data, tmpRecvMsg) == 1 )
{
- /* XXX: should really just return up the chain */
- FatalError("Error (%s) executing query: %s\n", mysql_error(mysql), sql);
- return -1;
+
+ OpSguil_SensorAgentInit(data);
+
}
+ else
+ {
- if(row_id != NULL)
- *row_id = mysql_insert_id(mysql);
- return 0;
-}
-#endif
+ char **toks;
+ int num_toks;
-/* SguildConnect() opens a network socket to sguild for sending
- * RT event messages. Bammkkkk
-*/
-int SguildConnect(OpSguil_Data *op_data)
-{
- int sockfd;
- struct hostent *he;
- struct sockaddr_in server_addr;
+ if(pv.verbose)
+ LogMessage("Received: %s", tmpRecvMsg);
- if ((he=gethostbyname(op_data->sguild_host)) == NULL)
+ /* Parse the response */
+ toks = mSplit(tmpRecvMsg, " ", 3, &num_toks, 0);
+ if(strcasecmp("SidCidResponse", toks[0]) == 0)
{
- FatalError("Cannot resolve hostname: %s\n", op_data->sguild_host);
- return 1;
+
+ data->sensor_id = atoi(toks[1]);
+ data->event_id = atoi(toks[2]);
+
}
-
- if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ else
{
-
- FatalError("Cannot open a local socket.\n");
- return 1;
-
+
+ FatalError("Expected SidCidResponse and got: %s\n", tmpRecvMsg);
+
}
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(op_data->sguild_port);
- server_addr.sin_addr = *((struct in_addr *)he->h_addr);
- memset(&(server_addr.sin_zero), '\0', 8);
+ FreeToks(toks, num_toks);
- if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
- {
-
- LogMessage("Cannot connect to %s on TCP port %u.\n",
- op_data->sguild_host, op_data->sguild_port);
- close(sockfd);
- return 1;
+ if(pv.verbose)
+ LogMessage("Sensor ID: %u\nLast cid: %u\n", data->sensor_id, data->event_id);
+
+ /* Use the next event_id */
+ ++data->event_id;
+
+ }
+
+ return 0;
+
+}
+
+int OpSguil_SendAgentMsg(OpSguil_Data *data, char *msg)
+{
+
+ int schars;
+ size_t len;
+ char *tmpMsg;
+
+ len = strlen(msg)+2;
- }
+ tmpMsg = SafeAlloc(len);
- op_data->sguild_sock = sockfd;
- return 0;
+ snprintf(tmpMsg, len, "%s\n", msg);
+
+ if((schars = send(data->agent_sock, tmpMsg, sizeof(char)*strlen(tmpMsg), 0)) < 0)
+ {
+
+ if(pv.verbose)
+ LogMessage("Lost connection to sensor_agent.\n");
+
+ /* Resend our msg */
+ OpSguil_SendAgentMsg(data, msg);
+
+ }
+
+ if(pv.verbose)
+ LogMessage("Sent: %s", tmpMsg);
+
+ free(tmpMsg);
+
+ return 0;
}
+
/* I love google. http://pont.net/socket/prog/tcpServer.c */
-int read_line(int newSd, char *line_to_return) {
-
+int OpSguil_RecvAgentMsg(OpSguil_Data *data, char *line_to_return) {
+
static int rcv_ptr=0;
static char rcv_msg[MAX_MSG_LEN];
static int n;
+ struct timeval tv;
+ fd_set read_fds;
int offset;
-
+
offset=0;
+ /* wait 15 secs for our response */
+ tv.tv_sec = 15;
+ tv.tv_usec = 0;
+
+ FD_ZERO(&read_fds);
+ FD_SET(data->agent_sock, &read_fds);
while(1) {
- if(rcv_ptr==0) {
- memset(rcv_msg,0x0,MAX_MSG_LEN);
- n = recv(newSd, rcv_msg, MAX_MSG_LEN, 0);
- if (n<0) {
- LogMessage("ERROR: Unable to read data.\n");
- return 1;
- } else if (n==0) {
- LogMessage("ERROR: Connecton closed by client\n");
- close(newSd);
- return 1;
- }
+ /* Wait for response from sguild */
+ select(data->agent_sock+1, &read_fds, NULL, NULL, &tv);
+
+ if (!(FD_ISSET(data->agent_sock, &read_fds)))
+ {
+ /* timed out */
+ if(pv.verbose)
+ LogMessage("Timed out waiting for response.\n");
+
+ return 1;
}
+ else
+ {
+ if(rcv_ptr==0) {
+
+ memset(rcv_msg,0x0,MAX_MSG_LEN);
+ n = recv(data->agent_sock, rcv_msg, MAX_MSG_LEN, 0);
+ if (n<0) {
+ LogMessage("ERROR: Unable to read data.\n");
+ /* Reconnect to sensor_agent */
+ OpSguil_SensorAgentConnect(data);
+ } else if (n==0) {
+ LogMessage("ERROR: Connecton closed by client\n");
+ close(data->agent_sock);
+ /* Reconnect to sensor_agent */
+ OpSguil_SensorAgentConnect(data);
+ }
+ }
+
+ /* if new data read on socket */
+ /* OR */
+ /* if another line is still in buffer */
+
+ /* copy line into 'line_to_return' */
+ while(*(rcv_msg+rcv_ptr)!=0x0A && rcv_ptr<n) {
+ memcpy(line_to_return+offset,rcv_msg+rcv_ptr,1);
+ offset++;
+ rcv_ptr++;
+ }
+
+ /* end of line + end of buffer => return line */
+ if(rcv_ptr==n-1) {
+ /* set last byte to END_LINE */
+ *(line_to_return+offset)=0x0A;
+ rcv_ptr=0;
+ return ++offset;
+ }
+
+ /* end of line but still some data in buffer => return line */
+ if(rcv_ptr <n-1) {
+ /* set last byte to END_LINE */
+ *(line_to_return+offset)=0x0A;
+ rcv_ptr++;
+ return ++offset;
+ }
- /* if new data read on socket */
- /* OR */
- /* if another line is still in buffer */
-
- /* copy line into 'line_to_return' */
- while(*(rcv_msg+rcv_ptr)!=0x0A && rcv_ptr<n) {
- memcpy(line_to_return+offset,rcv_msg+rcv_ptr,1);
- offset++;
- rcv_ptr++;
- }
-
- /* end of line + end of buffer => return line */
- if(rcv_ptr==n-1) {
- /* set last byte to END_LINE */
- *(line_to_return+offset)=0x0A;
- rcv_ptr=0;
- return ++offset;
- }
-
- /* end of line but still some data in buffer => return line */
- if(rcv_ptr <n-1) {
- /* set last byte to END_LINE */
- *(line_to_return+offset)=0x0A;
- rcv_ptr++;
- return ++offset;
+ /* end of buffer but line is not ended => */
+ /* wait for more data to arrive on socket */
+ if(rcv_ptr == n) {
+ rcv_ptr = 0;
+ }
+
}
- /* end of buffer but line is not ended => */
- /* wait for more data to arrive on socket */
- if(rcv_ptr == n) {
- rcv_ptr = 0;
- }
-
}
-}
-/* SguilSendEvent() sends the event via the open network socket.
- * Bammkkkk
-*/
-int SguilSendEvent(OpSguil_Data *op_data, char *eventMsg)
-{
-
- int schars;
- char line[100];
-
-
- if((schars = send(op_data->sguild_sock, eventMsg, strlen(eventMsg), 0)) < 0)
- {
- LogMessage("ERROR! Couldn't send msg.\n");
-
- /* ReConnect to sguild */
- while(SguildConnect(op_data) == 1)
- {
- if(op_data->nospin) return 0;
- LogMessage("ERROR: Couldn't reconnect. Will try again in 15 secs.\n");
- if (BarnyardSleep(15)) break;
- }
- LogMessage("Connected to %s.\n", op_data->sguild_host);
- SguilSendEvent(op_data, eventMsg);
-
- } else {
-
- //LogMessage("Msg sent: %s", eventMsg);
- //LogMessage("Chars sent: %i\n", schars);
-
- memset(line, 0x0, 100);
- if(read_line(op_data->sguild_sock, line) == 1)
- {
-
- if (op_data->nospin == 0)
- {
-
-
- LogMessage("ERROR! Didn't receive confirmation. Trying to reconnect.\n");
-
- /* ReConnect to sguild */
- while(SguildConnect(op_data) == 1)
- {
- LogMessage("ERROR: Couldn't reconnect. Will try again in 15 secs.\n");
- if (BarnyardSleep(15)) break;
- }
-
- LogMessage("Connected to %s.\n", op_data->sguild_host);
- SguilSendEvent(op_data, eventMsg);
-
- }
-
- }
- }
- return 0;
-
}
-#endif