Permalink
Browse files

fixed: merge issue for db optimised pull request.

  • Loading branch information...
2 parents 840528b + 0974b1d commit 2ecfbb15439227ce03e823ea8d3f94529f8c652b @firnsy committed Jan 30, 2012
Showing with 9,053 additions and 2,353 deletions.
  1. +11 −0 src/barnyard2.c
  2. +51 −35 src/map.c
  3. +25 −20 src/map.h
  4. +2 −1 src/output-plugins/Makefile.am
  5. +3,296 −2,271 src/output-plugins/spo_database.c
  6. +645 −0 src/output-plugins/spo_database.h
  7. +4,506 −0 src/output-plugins/spo_database_cache.c
  8. +155 −0 src/output-plugins/spo_database_cache.h
  9. +17 −6 src/spooler.c
  10. +333 −20 src/util.c
  11. +12 −0 src/util.h
View
11 src/barnyard2.c
@@ -993,12 +993,17 @@ static void SigExitHandler(int signal)
if (exit_signal != 0)
return;
+
+
/* Don't want to have to wait to start processing packets before
* getting out of dodge */
if (barnyard2_initializing)
_exit(0);
exit_signal = signal;
+
+ Barnyard2Cleanup(signal);
+
}
static void SigUsrHandler(int signal)
@@ -1007,11 +1012,17 @@ static void SigUsrHandler(int signal)
return;
usr_signal = signal;
+
+ Barnyard2Cleanup(signal);
+
+
}
static void SigHupHandler(int signal)
{
hup_signal = 1;
+ Barnyard2Cleanup(signal);
+
}
/****************************************************************************
View
86 src/map.c
@@ -31,7 +31,11 @@
** Ideas stolen liberally from:
** 1. the orginal barnyard (A. Baker, M. Roesch)
**
+**
+**
+**
** TODO:
+** -ERROR CHECKING..........!@#$%@
** 1. Convert existing linked lists to adaptive splayed trees.
*/
@@ -272,7 +276,7 @@ int ReadReferenceFile(Barnyard2Config *bc, const char *file)
if(num_toks > 1)
{
ParseReferenceSystemConfig(bc, toks[1]);
- count++;
+ count++;
}
mSplitFree(&toks, num_toks);
@@ -291,6 +295,7 @@ int ReadReferenceFile(Barnyard2Config *bc, const char *file)
/************************ Class/Priority Implementation ***********************/
/* NOTE: This lookup can only be done during parse time */
+/* Wut ...*/
ClassType * ClassTypeLookupByType(Barnyard2Config *bc, char *type)
{
ClassType *node;
@@ -315,6 +320,7 @@ ClassType * ClassTypeLookupByType(Barnyard2Config *bc, char *type)
}
/* NOTE: This lookup can only be done during parse time */
+/* Wut ...*/
ClassType * ClassTypeLookupById(Barnyard2Config *bc, int id)
{
ClassType *node;
@@ -440,12 +446,12 @@ int ReadClassificationFile(Barnyard2Config *bc, const char *file)
char *index;
char **toks;
int num_toks;
- int count = 0;
-
-
+ int count = 0;
+
+
DEBUG_WRAP(DebugMessage(DEBUG_MAPS, "map: opening file %s\n", file););
- if((fd = fopen(file, "r")) == NULL)
+ if((fd = fopen(file, "r")) == NULL)
{
LogMessage("ERROR: Unable to open Classification file '%s' (%s)\n",
file, strerror(errno));
@@ -471,7 +477,7 @@ int ReadClassificationFile(Barnyard2Config *bc, const char *file)
if(num_toks > 1)
{
ParseClassificationConfig(bc, toks[1]);
- count++;
+ count++;
}
mSplitFree(&toks, num_toks);
@@ -524,7 +530,9 @@ int ReadSidFile(Barnyard2Config *bc, const char *file)
count++;
}
}
-
+
+ //LogMessage("Read [%u] signature \n",count);
+
if(fd != NULL)
fclose(fd);
@@ -620,6 +628,8 @@ void ParseSidMapLine(Barnyard2Config *bc, char *data)
}
mSplitFree(&toks, num_toks);
+
+ return;
}
SigNode *GetSigByGidSid(u_int32_t gid, u_int32_t sid)
@@ -644,13 +654,13 @@ SigNode *GetSigByGidSid(u_int32_t gid, u_int32_t sid)
}
/* create a default message since we didn't find any match */
- sn = CreateSigNode(&sigTypes);
+ sn = CreateSigNode(&sigTypes);
sn->generator = gid;
sn->id = sid;
sn->rev = 0;
sn->msg = (char *)SnortAlloc(42);
snprintf(sn->msg, 42, "Snort Alert [%u:%u:%u]", gid, sid, 0);
-
+
return sn;
}
@@ -668,12 +678,15 @@ SigNode *CreateSigNode(SigNode **head)
sn = *head;
while (sn->next != NULL)
- sn = sn->next;
-
+ sn = sn->next;
+
sn->next = (SigNode *) SnortAlloc(sizeof(SigNode));
-
+
return sn->next;
}
+
+ /* XXX */
+ return NULL;
}
int ReadGenFile(Barnyard2Config *bc, const char *file)
@@ -706,33 +719,36 @@ int ReadGenFile(Barnyard2Config *bc, const char *file)
if( (*index != '#') && (*index != 0x0a) && (index != NULL) )
{
ParseGenMapLine(index);
- count++;
+ count++;
}
}
+ //LogMessage("Read [%u] gen \n",count);
+
if(fd != NULL)
fclose(fd);
return 0;
}
+
void ParseGenMapLine(char *data)
{
char **toks;
int num_toks;
int i;
char *idx;
SigNode *sn;
-
+
toks = mSplitSpecial(data, "||", 32, &num_toks, '\0');
-
+
if(num_toks < 2)
{
LogMessage("WARNING: Ignoring bad line in SID file: \"%s\"\n", data);
- return;
+ return;
}
-
- sn = CreateSigNode(&sigTypes);
+
+ sn = CreateSigNode(&sigTypes);
for(i=0; i<num_toks; i++)
{
@@ -742,24 +758,24 @@ void ParseGenMapLine(char *data)
switch(i)
{
- case 0: /* gen */
- //TODO: error checking on conversion
- sn->generator = strtoul(idx, NULL, 10);
- break;
-
- case 1: /* sid */
- //TODO: error checking on conversion
- sn->id = strtoul(idx, NULL, 10);
- break;
-
- case 2: /* msg */
- sn->msg = SnortStrdup(idx);
- break;
-
- default:
- break;
+ case 0: /* gen */
+ //TODO: error checking on conversion
+ sn->generator = strtoul(idx, NULL, 10);
+ break;
+
+ case 1: /* sid */
+ //TODO: error checking on conversion
+ sn->id = strtoul(idx, NULL, 10);
+ break;
+
+ case 2: /* msg */
+ sn->msg = SnortStrdup(idx);
+ break;
+
+ default:
+ break;
}
}
-
+
mSplitFree(&toks, num_toks);
}
View
45 src/map.h
@@ -64,6 +64,7 @@ typedef struct _ReferenceSystemNode
char *name;
char *url;
struct _ReferenceSystemNode *next;
+
} ReferenceSystemNode;
ReferenceSystemNode * ReferenceSystemAdd(ReferenceSystemNode **, char *, char *);
@@ -77,9 +78,9 @@ void DeleteReferenceSystems(struct _Barnyard2Config *);
typedef struct _ReferenceNode
{
- char *id;
- ReferenceSystemNode *system;
- struct _ReferenceNode *next;
+ char *id;
+ ReferenceSystemNode *system;
+ struct _ReferenceNode *next;
} ReferenceNode;
ReferenceNode * AddReference(struct _Barnyard2Config *, ReferenceNode **, char *, char *);
@@ -88,36 +89,40 @@ void DeleteReferences(struct _Barnyard2Config *);
typedef struct _ClassType
{
- char *type;
- uint32_t id;
- char *name; /* "pretty" name */
- uint32_t priority;
- struct _ClassType *next;
-} ClassType;
+ char *type;
+ char *name; /* "pretty" name */
+ uint32_t id;
+ uint32_t priority;
+ struct _ClassType *next;
-ClassType * ClassTypeLookupByType(struct _Barnyard2Config *, char *);
-ClassType * ClassTypeLookupById(struct _Barnyard2Config *, int);
-int ReadClassificationFile(struct _Barnyard2Config *, const char *);
-void ParseClassificationConfig(struct _Barnyard2Config *, char *args);
-
-void DeleteClassTypes();
+} ClassType;
typedef struct _SigNode
{
uint32_t generator; /* generator ID */
uint32_t id; /* Snort ID */
uint32_t rev; /* revision (for future expansion) */
- uint32_t class_id;
- ClassType *classType;
- uint32_t priority;
- char *msg; /* messages */
+ uint32_t class_id;
+ uint32_t priority;
+ char *msg; /* messages */
+ ClassType *classType;
ReferenceNode *refs; /* references (eg bugtraq) */
-
struct _SigNode *next;
+
} SigNode;
+
+
+ClassType * ClassTypeLookupByType(struct _Barnyard2Config *, char *);
+ClassType * ClassTypeLookupById(struct _Barnyard2Config *, int);
+
+int ReadClassificationFile(struct _Barnyard2Config *, const char *);
+void ParseClassificationConfig(struct _Barnyard2Config *, char *args);
+
+void DeleteClassTypes();
+
SigNode *GetSigByGidSid(uint32_t, uint32_t);
int ReadSidFile(struct _Barnyard2Config *, const char *);
View
3 src/output-plugins/Makefile.am
@@ -21,7 +21,8 @@ spo_log_null.c spo_log_null.h \
spo_log_tcpdump.c spo_log_tcpdump.h \
spo_platypus.c spo_platypus.h \
spo_sguil.c spo_sguil.h \
-spo_database.c spo_database.h \
spo_syslog_full.c spo_syslog.full.h
+spo_database.c spo_database.h \
+spo_database_cache.c spo_database_cache.h
INCLUDES = -I.. -I ../sfutil
View
5,567 src/output-plugins/spo_database.c
3,296 additions, 2,271 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
645 src/output-plugins/spo_database.h
@@ -20,11 +20,656 @@
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+/* NOTE: -elz this file is a mess and need some cleanup */
/* $Id$ */
#ifndef __SPO_DATABASE_H__
#define __SPO_DATABASE_H__
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "barnyard2.h"
+#include "debug.h"
+#include "decode.h"
+#include "map.h"
+#include "plugbase.h"
+#include "parser.h"
+#include "rules.h"
+#include "unified2.h"
+#include "util.h"
+
+#include "output-plugins/spo_database_cache.h"
+
+
+/*
+ * If you want extra debugging information for solving database
+ * configuration problems, uncomment the following line.
+ */
+/* #define DEBUG */
+
+
+#ifdef ENABLE_POSTGRESQL
+# include <libpq-fe.h>
+#endif
+
+#ifdef ENABLE_MYSQL
+# if defined(_WIN32) || defined(_WIN64)
+# include <windows.h>
+# endif
+# include <mysql.h>
+# include <errmsg.h>
+#endif
+
+#ifdef ENABLE_ODBC
+# include <sql.h>
+# include <sqlext.h>
+# include <sqltypes.h>
+ /* The SQL Server libraries, for some reason I can't
+ * understand, define their own constants for SQLRETURN
+ * and SQLCHAR. But, in SQL Server, these are numeric
+ * values, not datatypes. So we define datatypes here
+ * with a non-conflicting name.
+ */
+typedef SQLRETURN ODBC_SQLRETURN;
+typedef SQLCHAR ODBC_SQLCHAR;
+#endif
+
+#ifdef ENABLE_ORACLE
+# include <oci.h>
+#endif
+
+#ifdef ENABLE_MSSQL
+# define DBNTWIN32
+# include <windows.h>
+# include <sqlfront.h>
+# include <sqldb.h>
+#endif
+
+#include "map.h"
+#include "plugbase.h"
+
+#ifndef DATABASE_MAX_ESCAPE_STATIC_BUFFER_LEN
+#define DATABASE_MAX_ESCAPE_STATIC_BUFFER_LEN 32768 /* Should theorically be enough to escape ....alot of queries */
+#endif /* DATABASE_MAX_ESCAPE_STATIC_BUFFER_LEN */
+
+#ifndef MAX_QUERY_LENGTH
+//#define MAX_QUERY_LENGTH 8192
+#define MAX_QUERY_LENGTH (65536 * 2) /* Lets add some space for payload decoding and query esaping..*/
+#endif /* MAX_QUERY_LENGTH */
+
+#ifndef MAX_SQL_QUERY_OPS
+#define MAX_SQL_QUERY_OPS 20
+#endif /* MAX_SQL_QUERY_OPS */
+
+
+/******** Data Types **************************************************/
+/* enumerate the supported databases */
+enum db_types_en
+{
+ DB_ENUM_MIN_VAL = 0,
+ DB_UNDEFINED = 0,
+ DB_MYSQL = 1,
+ DB_POSTGRESQL = 2,
+ DB_MSSQL = 3,
+ DB_ORACLE = 4,
+ DB_ODBC = 5,
+ DB_ENUM_MAX_VAL = DB_ODBC /* This value has to be updated if a new dbms is inserted in the enum
+ This is used for different function pointers used by the module depending on operation mode
+ */
+};
+typedef enum db_types_en dbtype_t;
+
+/* ------------------------------------------
+ DATABASE CACHE Structure and objects
+ ------------------------------------------ */
+
+/*
+ All those object could be referenced by one prototype and all
+ call to allocation and list manipulation could be generalized, but
+ for clarity and the purpose of this code (existance timeline), this was not done.
+
+ Here is a breif cache layout.
+ dbSystemObj
+ \
+ dbReferenceObj <------------------ \
+ \ |
+ dbSignatureCacheObj /
+ \---[dbReferenceObj * array] __/
+
+ dbSignatureReferenceObj
+
+*/
+
+#ifndef MAX_SIGLOOKUP
+#define MAX_SIGLOOKUP 255
+#endif /* MAX_SIGLOOKUP */
+
+/* ------------------------------------------
+ * REFERENCE OBJ
+ ------------------------------------------ */
+typedef struct _dbReferenceObj
+{
+ u_int32_t ref_id;
+ u_int32_t system_id; /* used by fetch for match else refer to parent.*/
+ char ref_tag[REF_TAG_LEN];
+ struct _cacheSystemObj *parent;
+
+} dbReferenceObj;
+
+typedef struct _cacheReferenceObj
+{
+ dbReferenceObj obj;
+ u_int32_t flag; /* Where its at */
+ struct _cacheReferenceObj *next;
+
+} cacheReferenceObj;
+/* ------------------------------------------
+ * REFERENCE OBJ
+ ------------------------------------------ */
+
+/* ------------------------------------------
+ * SYSTEM OBJ
+ ------------------------------------------ */
+typedef struct _dbSystemObj
+{
+ u_int32_t ref_system_id;
+ u_int32_t db_ref_system_id;
+ char ref_system_name[SYSTEM_NAME_LEN];
+ char ref_system_url[SYSTEM_URL_LEN];
+ cacheReferenceObj *refList;
+
+} dbSystemObj;
+
+typedef struct _cacheSystemObj
+{
+ dbSystemObj obj;
+ u_int32_t flag; /* Where its at */
+ struct _cacheSystemObj *next;
+
+} cacheSystemObj;
+/* ------------------------------------------
+ * SYSTEM OBJ
+ ------------------------------------------ */
+
+/* ------------------------------------------
+ * SIGNATUREREFERENCE OBJ
+ ------------------------------------------ */
+typedef struct _dbSignatureReferenceObj
+{
+ u_int32_t db_ref_id;
+ u_int32_t db_sig_id;
+ u_int32_t ref_seq;
+
+} dbSignatureReferenceObj;
+
+
+typedef struct _cacheSignatureReferenceObj
+{
+ dbSignatureReferenceObj obj;
+ u_int32_t flag; /* Where its at */
+ struct _cacheSignatureReferenceObj *next;
+
+} cacheSignatureReferenceObj;
+/* ------------------------------------------
+ * SIGNATUREREFERENCE OBJ
+ ------------------------------------------ */
+
+/* -----------------------------------------
+ * CLASSIFICATION OBJ
+ ------------------------------------------ */
+typedef struct _dbClassificationObj
+{
+ u_int32_t sig_class_id;
+ u_int32_t db_sig_class_id;
+ char sig_class_name[CLASS_NAME_LEN];
+
+} dbClassificationObj;
+
+typedef struct _cacheClassificationObj
+{
+ dbClassificationObj obj;
+ u_int32_t flag; /* Where its at */
+
+ struct _cacheClassificationObj *next;
+
+} cacheClassificationObj;
+/* ------------------------------------------
+ * CLASSIFICATION OBJ
+ ------------------------------------------ */
+
+/* ------------------------------------------
+ * SIGNATURE OBJ
+ ------------------------------------------ */
+typedef struct _dbSignatureObj
+{
+ u_int32_t db_id;
+ u_int32_t sid;
+ u_int32_t gid;
+ u_int32_t rev;
+ u_int32_t class_id;
+ u_int32_t priority_id;
+ char message[SIG_MSG_LEN];
+
+ /* Eliminate alot of useless lookup */
+ cacheReferenceObj *ref[MAX_REF_OBJ]; /* Used for backward lookup */
+ u_int32_t ref_count; /* Used for count on ref's */
+ /* Eliminate alot of useless lookup */
+
+} dbSignatureObj;
+
+
+typedef struct _cacheSignatureObj
+{
+ dbSignatureObj obj;
+ u_int32_t flag; /* Where its at */
+ struct _cacheSignatureObj *next;
+
+} cacheSignatureObj;
+/* ------------------------------------------
+ * SIGNATURE OBJ
+ ------------------------------------------ */
+
+
+/* ------------------------------------------
+ * Used for lookup in case multiple signature
+ * with same sid:gid couple exist but have different
+ * rev,class and priority
+ ------------------------------------------ */
+typedef struct _PluginSignatureObj
+{
+ cacheSignatureObj *cacheSigObj;
+
+} plgSignatureObj;
+/* ------------------------------------------
+ * Used for lookup in case multiple signature
+ * with same sid:gid couple exist but have different
+ * rev,class and priority
+ ------------------------------------------ */
+
+/* ------------------------------------------
+ Main cache entry point (used by DatabaseData->mc)
+ ------------------------------------------ */
+typedef struct _masterCache
+{
+ cacheClassificationObj *cacheClassificationHead;
+ cacheSignatureObj *cacheSignatureHead;
+ cacheSystemObj *cacheSystemHead;
+ cacheSignatureReferenceObj *cacheSigReferenceHead;
+ plgSignatureObj plgSigCompare[MAX_SIGLOOKUP]; /* Used by spo_database when querying the cache for signature match */
+
+} MasterCache;
+/* ------------------------------------------
+ Main cache entry point (used by DatabaseData->mc)
+ ------------------------------------------ */
+
+/* ------------------------------------------
+ DATABASE CACHE Structure and objects
+ ------------------------------------------ */
+
+/* Replace dynamic query node */
+typedef struct _SQLQueryList
+{
+ u_int32_t query_total;
+ u_int32_t query_count;
+ char **query_array;
+
+} SQLQueryList;
+/* Replace dynamic query node */
+
+
+/* Databse Reliability */
+typedef struct _dbReliabilityHandle
+{
+
+ u_int32_t dbConnectionCount; /* Count of effective reconnection */
+ u_int32_t dbConnectionLimit; /* Limit or reconnection try */
+ u_int32_t dbLimitReachFailsafe; /* Limit of time we wrap the reconnection try */
+ u_int32_t dbConnectionStat; /* Database Connection status (barnyard2) */
+ u_int32_t dbReconnectedInTransaction;
+
+ struct timespec dbReconnectSleepTime; /* Sleep time (milisec) before attempting a reconnect */
+
+ u_int8_t checkTransaction; /* If set , we are in transaction */
+ u_int8_t transactionCallFail; /* if(checkTransaction) && error set ! */
+ u_int8_t transactionErrorCount; /* Number of transaction fail for a single transaction (Reset by sucessfull commit)*/
+ u_int8_t transactionErrorThreshold; /* Consider the transaction threshold to be the same as reconnection maxiumum */
+
+
+ struct _DatabaseData *dbdata; /* Pointer to parent structure used for call clarity */
+
+#ifdef ENABLE_MYSQL
+ /* Herited from shared data globals */
+ char *ssl_key;
+ char *ssl_cert;
+ char *ssl_ca;
+ char *ssl_ca_path;
+ char *ssl_cipher;
+ /* Herited from shared data globals */
+
+ unsigned long pThreadID; /* Used to store thread information and know if we "reconnected automaticaly" */
+ my_bool mysql_reconnect; /* We will handle it via the api. */
+#endif /* ENABLE_MYSQL */
+
+#ifdef ENABLE_POSTGRESQL
+ /* Herited from shared data globals */
+ char *ssl_mode;
+ /* Herited from shared data globals */
+#endif
+
+#ifdef ENABLE_ODBC
+#endif
+
+#ifdef ENABLE_ORACLE
+#endif
+
+#ifdef ENABLE_MSSQL
+#endif
+
+ /* Set by dbms specific setup function */
+ u_int32_t (*dbConnectionStatus)(struct _dbReliabilityHandle *);
+} dbReliabilityHandle;
+/* Databse Reliability */
+
+typedef struct _DatabaseData
+{
+ u_short dbtype_id;
+ char *facility;
+ char *password;
+ char *user;
+ char *port;
+ char *sensor_name;
+ int encoding;
+ int detail;
+ int ignore_bpf;
+ int tz;
+ int DBschema_version;
+
+ char *dbname;
+ char *host;
+ int sid;
+ int cid;
+ int reference;
+ int use_ssl;
+
+ /* Some static allocated buffers, they might need some cleanup before release */
+ char timestampHolder[SMALLBUFFER]; /* For timestamp conversion .... */
+ char PacketDataNotEscaped[MAX_QUERY_LENGTH];
+ char PacketData[MAX_QUERY_LENGTH];
+ char sanitize_buffer[DATABASE_MAX_ESCAPE_STATIC_BUFFER_LEN];
+ /* Some static allocated buffers, they might need some cleanup before release */
+
+ /* Used for generic queries if you need consequtives queries uses SQLQueryList*/
+ char *SQL_SELECT;
+ char *SQL_INSERT;
+
+ u_int32_t SQL_SELECT_SIZE;
+ u_int32_t SQL_INSERT_SIZE;
+ /* Used for generic queries if you need consequtives queries uses SQLQueryList*/
+
+ SQLQueryList SQL;
+ MasterCache mc;
+
+#ifdef ENABLE_POSTGRESQL
+ PGconn * p_connection;
+ PGresult * p_result;
+#endif
+#ifdef ENABLE_MYSQL
+ MYSQL * m_sock;
+ MYSQL_RES * m_result;
+ MYSQL_ROW m_row;
+#endif
+#ifdef ENABLE_ODBC
+ SQLHENV u_handle;
+ SQLHDBC u_connection;
+ SQLHSTMT u_statement;
+ SQLINTEGER u_col;
+ SQLINTEGER u_rows;
+ dbtype_t u_underlying_dbtype_id;
+#endif
+#ifdef ENABLE_ORACLE
+ OCIEnv *o_environment;
+ OCISvcCtx *o_servicecontext;
+ OCIBind *o_bind;
+ OCIError *o_error;
+ OCIStmt *o_statement;
+ OCIDefine *o_define;
+ text o_errormsg[512];
+ sb4 o_errorcode;
+#endif
+#ifdef ENABLE_MSSQL
+ PDBPROCESS ms_dbproc;
+ PLOGINREC ms_login;
+ DBINT ms_col;
+#endif
+ char *args;
+
+/* Databse Reliability */
+/*
+ Defining an array of dbReliabilityHandle will enlarge the structure memory footprint
+ but it will enable support for compilation with multiple dbms. Be sure to update DB_ENUM_MAX_VAL
+ if you add a specific database support like some NoSQL *winks*.
+*/
+ struct _dbReliabilityHandle dbRH[DB_ENUM_MAX_VAL];
+/* Databse Reliability */
+
+} DatabaseData;
+
+
+/******** Constants ***************************************************/
+#define KEYWORD_POSTGRESQL "postgresql"
+#define KEYWORD_MYSQL "mysql"
+#define KEYWORD_ODBC "odbc"
+#define KEYWORD_ORACLE "oracle"
+#define KEYWORD_MSSQL "mssql"
+
+#define KEYWORD_HOST "host"
+#define KEYWORD_PORT "port"
+#define KEYWORD_USER "user"
+#define KEYWORD_PASSWORD "password"
+#define KEYWORD_DBNAME "dbname"
+#define KEYWORD_SENSORNAME "sensor_name"
+#define KEYWORD_ENCODING "encoding"
+ #define KEYWORD_ENCODING_HEX "hex"
+ #define KEYWORD_ENCODING_BASE64 "base64"
+ #define KEYWORD_ENCODING_ASCII "ascii"
+#define KEYWORD_DETAIL "detail"
+ #define KEYWORD_DETAIL_FULL "full"
+ #define KEYWORD_DETAIL_FAST "fast"
+#define KEYWORD_IGNOREBPF "ignore_bpf"
+#define KEYWORD_IGNOREBPF_NO "no"
+#define KEYWORD_IGNOREBPF_ZERO "0"
+#define KEYWORD_IGNOREBPF_YES "yes"
+#define KEYWORD_IGNOREBPF_ONE "1"
+
+
+#define KEYWORD_CONNECTION_LIMIT "connection_limit"
+#define KEYWORD_RECONNECT_SLEEP_TIME "reconnect_sleep_time"
+
+#define KEYWORD_MYSQL_RECONNECT "mysql_reconnect"
+
+#ifdef ENABLE_MYSQL
+# define KEYWORD_SSL_KEY "ssl_key"
+# define KEYWORD_SSL_CERT "ssl_cert"
+# define KEYWORD_SSL_CA "ssl_ca"
+# define KEYWORD_SSL_CA_PATH "ssl_ca_path"
+# define KEYWORD_SSL_CIPHER "ssl_cipher"
+#endif
+
+#ifdef ENABLE_POSTGRESQL
+# define KEYWORD_SSL_MODE "ssl_mode"
+# define KEYWORD_SSL_MODE_DISABLE "disable"
+# define KEYWORD_SSL_MODE_ALLOW "allow"
+# define KEYWORD_SSL_MODE_PREFER "prefer"
+# define KEYWORD_SSL_MODE_REQUIRE "require"
+#endif
+
+#define LATEST_DB_SCHEMA_VERSION 107
+
+
+/******** fatals *******************************************************/
+/*
+ NOTE: -elz
+ Some of those messages have been removed but they will be added and cleaned before release
+*/
+
+/* these strings deliberately break fatal error messages into
+ chunks with lengths < 509 to keep ISO C89 compilers happy
+ */
+
+static const char* FATAL_NO_SENSOR_1 =
+ " When this plugin starts, a SELECT query is run to find the sensor id for the\n"
+ " currently running sensor. If the sensor id is not found, the plugin will run\n"
+ " an INSERT query to insert the proper data and generate a new sensor id. Then a\n"
+ " SELECT query is run to get the newly allocated sensor id. If that fails then\n"
+ " this error message is generated.\n";
+
+static const char* FATAL_NO_SENSOR_2 =
+ " Some possible causes for this error are:\n"
+ " * the user does not have proper INSERT or SELECT privileges\n"
+ " * the sensor table does not exist\n"
+ "\n"
+ " If you are _absolutely_ certain that you have the proper privileges set and\n"
+ " that your database structure is built properly please let me know if you\n"
+ " continue to get this error. You can contact me at (roman@danyliw.com).\n";
+
+static const char* FATAL_BAD_SCHEMA_1 =
+ "database: The underlying database has not been initialized correctly. This\n"
+ " version of Snort requires version %d of the DB schema. Your DB\n"
+ " doesn't appear to have any records in the 'schema' table.\n%s";
+
+static const char* FATAL_BAD_SCHEMA_2 =
+ " Please re-run the appropriate DB creation script (e.g. create_mysql,\n"
+ " create_postgresql, create_oracle, create_mssql) located in the\n"
+ " contrib\\ directory.\n\n"
+ " See the database documentation for cursory details (doc/README.database).\n"
+ " and the URL to the most recent database plugin documentation.\n";
+
+static const char* FATAL_OLD_SCHEMA_1 =
+ "database: The underlying database seems to be running an older version of\n"
+ " the DB schema (current version=%d, required minimum version= %d).\n\n"
+ " If you have an existing database with events logged by a previous\n"
+ " version of snort, this database must first be upgraded to the latest\n"
+ " schema (see the snort-users mailing list archive or DB plugin\n"
+ " documention for details).\n%s\n";
+
+static const char* FATAL_OLD_SCHEMA_2 =
+ " If migrating old data is not desired, merely create a new instance\n"
+ " of the snort database using the appropriate DB creation script\n"
+ " (e.g. create_mysql, create_postgresql, create_oracle, create_mssql)\n"
+ " located in the contrib\\ directory.\n\n"
+ " See the database documentation for cursory details (doc/README.database).\n"
+ " and the URL to the most recent database plugin documentation.\n";
+
+static const char* FATAL_NO_SUPPORT_1 =
+ "If this build of snort was obtained as a binary distribution (e.g., rpm,\n"
+ "or Windows), then check for alternate builds that contains the necessary\n"
+ "'%s' support.\n\n"
+ "If this build of snort was compiled by you, then re-run the\n"
+ "the ./configure script using the '--with-%s' switch.\n"
+ "For non-standard installations of a database, the '--with-%s=DIR'\n%s";
+
+static const char* FATAL_NO_SUPPORT_2 =
+ "syntax may need to be used to specify the base directory of the DB install.\n\n"
+ "See the database documentation for cursory details (doc/README.database).\n"
+ "and the URL to the most recent database plugin documentation.\n";
+
void DatabaseSetup(void);
+
+
+
+/* The following is for supporting Microsoft SQL Server */
+#ifdef ENABLE_MSSQL
+
+/* If you want extra debugging information (specific to
+ Microsoft SQL Server), uncomment the following line. */
+#define ENABLE_MSSQL_DEBUG
+
+#if defined(DEBUG) || defined(ENABLE_MSSQL_DEBUG)
+ /* this is for debugging purposes only */
+ static char g_CurrentStatement[2048];
+ #define SAVESTATEMENT(str) strncpy(g_CurrentStatement, str, sizeof(g_CurrentStatement) - 1);
+ #define CLEARSTATEMENT() bzero((char *) g_CurrentStatement, sizeof(g_CurrentStatement));
+#else
+ #define SAVESTATEMENT(str) NULL;
+ #define CLEARSTATEMENT() NULL;
+#endif /* DEBUG || ENABLE_MSSQL_DEBUG*/
+
+ /* Prototype of SQL Server callback functions.
+ * See actual declaration elsewhere for details.
+ */
+ static int mssql_err_handler(PDBPROCESS dbproc, int severity, int dberr,
+ int oserr, LPCSTR dberrstr, LPCSTR oserrstr);
+ static int mssql_msg_handler(PDBPROCESS dbproc, DBINT msgno, int msgstate,
+ int severity, LPCSTR msgtext, LPCSTR srvname, LPCSTR procname,
+ DBUSMALLINT line);
+#endif /* ENABLE_MSSQL */
+
+
+/******** Prototypes **************************************************/
+/* NOTE: -elz prototypes will need some cleanup before release */
+DatabaseData *InitDatabaseData(char *args);
+char *snort_escape_string(char *, DatabaseData *);
+u_int32_t snort_escape_string_STATIC(char *from, u_int32_t buffer_max_len ,DatabaseData *data);
+
+void DatabaseInit(char *);
+void DatabaseInitFinalize(int unused, void *arg);
+void ParseDatabaseArgs(DatabaseData *data);
+void Database(Packet *, void *, uint32_t, void *);
+void SpoDatabaseCleanExitFunction(int, void *);
+void SpoDatabaseRestartFunction(int, void *);
+void InitDatabase();
+void Connect(DatabaseData *);
+void DatabasePrintUsage();
+
+int Insert(char *, DatabaseData *);
+int Select(char *, DatabaseData *,u_int32_t *);
+int UpdateLastCid(DatabaseData *, int, int);
+int GetLastCid(DatabaseData *, int,u_int32_t *);
+int CheckDBVersion(DatabaseData *);
+
+u_int32_t BeginTransaction(DatabaseData * data);
+u_int32_t CommitTransaction(DatabaseData * data);
+u_int32_t RollbackTransaction(DatabaseData * data);
+
+
+u_int32_t checkDatabaseType(DatabaseData *data);
+u_int32_t checkTransactionState(dbReliabilityHandle *pdbRH);
+u_int32_t checkTransactionCall(dbReliabilityHandle *pdbRH);
+u_int32_t dbReconnectSetCounters(dbReliabilityHandle *pdbRH);
+u_int32_t MYSQL_ManualConnect(DatabaseData *dbdata);
+u_int32_t dbConnectionStatusMYSQL(dbReliabilityHandle *pdbRH);
+
+void resetTransactionState(dbReliabilityHandle *pdbRH);
+void setTransactionState(dbReliabilityHandle *pdbRH);
+void setTransactionCallFail(dbReliabilityHandle *pdbRH);
+
+u_int32_t getReconnectState(dbReliabilityHandle *pdbRH);
+void setReconnectState(dbReliabilityHandle *pdbRH,u_int32_t reconnection_state);
+
+void DatabaseCleanSelect(DatabaseData *data);
+void DatabaseCleanInsert(DatabaseData *data);
+
+u_int32_t ConvertDefaultCache(Barnyard2Config *bc,DatabaseData *data);
+u_int32_t CacheSynchronize(DatabaseData *data);
+u_int32_t cacheEventClassificationLookup(cacheClassificationObj *iHead,u_int32_t iClass_id);
+u_int32_t cacheEventSignatureLookup(cacheSignatureObj *iHead,
+ plgSignatureObj *sigContainer,
+ u_int32_t gid,
+ u_int32_t sid);
+u_int32_t SignatureCacheInsertObj(dbSignatureObj *iSigObj,MasterCache *iMasterCache);
+u_int32_t SignaturePopulateDatabase(DatabaseData *data,cacheSignatureObj *cacheHead);
+void MasterCacheFlush(DatabaseData *data);
+
+u_int32_t dbConnectionStatusPOSTGRESQL(dbReliabilityHandle *pdbRH);
+
+
#endif /* __SPO_DATABASE_H__ */
View
4,506 src/output-plugins/spo_database_cache.c
4,506 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
155 src/output-plugins/spo_database_cache.h
@@ -0,0 +1,155 @@
+/*
+
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation. You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** 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. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ * Maintainers : The Barnyard2 Team <firnsy@gmail.com> <beenph@gmail.com> 2011-20xx
+ *
+ *
+ *
+ */
+
+
+
+#ifndef __SPO_DATABASE_CACHE_H__
+#define __SPO_DATABASE_CACHE_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "barnyard2.h"
+#include "debug.h"
+#include "map.h"
+#include "unified2.h"
+
+
+#ifndef CLASS_NAME_LEN
+#define CLASS_NAME_LEN 60
+#endif /* CLASS_NAME_LEN */
+
+#ifndef SYSTEM_NAME_LEN
+#define SYSTEM_NAME_LEN 20
+#endif /* SYSTEM_NAME_LEN */
+
+#ifndef SYSTEM_URL_LEN
+#define SYSTEM_URL_LEN 255 /* Use a shortener if your not happy ;) */
+#endif /* SYSTEM_URL_LEN */
+
+#ifndef REF_TAG_LEN
+#define REF_TAG_LEN 100 /* 100 is a limit that use to be in the classic original output plugin */
+#endif /* REF_TAG_LEN */
+
+#ifndef SIG_NAME_LEN
+#define SIG_NAME_LEN 42
+#endif /* SIG_NAME_LEN */
+
+#ifndef SIG_MSG_LEN
+#define SIG_MSG_LEN 255
+#endif /* SIG_MSG_LEN */
+
+#ifndef MAX_REF_OBJ
+#define MAX_REF_OBJ 255
+#endif /* MAX_REF_OBJ */
+
+#ifndef CACHE_SQL_QUERY
+#define CACHE_SQL_QUERY
+
+#define NUM_ROW_SIGREF 3
+#define NUM_ROW_REFERENCE_SYSTEM 2
+#define NUM_ROW_REF 3
+#define NUM_ROW_CLASSIFICATION 2
+#define NUM_ROW_SIGNATURE 7
+
+
+#if defined(ENABLE_MYSQL) || defined (ENABLE_ODBC) || defined (ENABLE_ORACLE) || defined (ENABLE_MSSQL)
+
+#define SQL_INSERT_SPECIFIC_REFERENCE_SYSTEM "INSERT INTO reference_system (ref_system_name) VALUES ('%s');"
+#define SQL_SELECT_SPECIFIC_REFERENCE_SYSTEM "SELECT ref_system_id FROM reference_system WHERE ref_system_name = '%s';"
+#define SQL_INSERT_SPECIFIC_REF "INSERT INTO reference (ref_system_id,ref_tag) VALUES ('%u','%s');"
+#define SQL_SELECT_SPECIFIC_REF "SELECT ref_id FROM reference WHERE ref_system_id = '%u' AND ref_tag = '%s';"
+#define SQL_INSERT_CLASSIFICATION "INSERT INTO sig_class (sig_class_name) VALUES ('%s');"
+#define SQL_SELECT_SPECIFIC_CLASSIFICATION "SELECT sig_class_id FROM sig_class WHERE sig_class_name = '%s';"
+#define SQL_INSERT_SIGNATURE "INSERT INTO signature (sig_sid, sig_gid, sig_rev, sig_class_id, sig_priority, sig_name) VALUES ('%u','%u','%u','%u','%u','%s');"
+#define SQL_SELECT_SPECIFIC_SIGNATURE "SELECT sig_id FROM signature WHERE " \
+ "(sig_sid = '%u') AND " \
+ "(sig_gid = '%u') AND " \
+ "(sig_rev = '%u') AND " \
+ "(sig_class_id = '%u') AND " \
+ "(sig_priority = '%u') AND " \
+ "(sig_name = '%s'); " \
+
+#elif defined(ENABLE_POSTGRESQL)
+
+#define SQL_INSERT_SPECIFIC_REFERENCE_SYSTEM "INSERT INTO reference_system (ref_system_name) VALUES (E'%s');"
+#define SQL_SELECT_SPECIFIC_REFERENCE_SYSTEM "SELECT ref_system_id FROM reference_system WHERE ref_system_name = E'%s';"
+#define SQL_INSERT_SPECIFIC_REF "INSERT INTO reference (ref_system_id,ref_tag) VALUES ('%u',E'%s');"
+#define SQL_SELECT_SPECIFIC_REF "SELECT ref_id FROM reference WHERE ref_system_id = '%u' AND ref_tag = E'%s';"
+#define SQL_INSERT_CLASSIFICATION "INSERT INTO sig_class (sig_class_name) VALUES (E'%s');"
+#define SQL_SELECT_SPECIFIC_CLASSIFICATION "SELECT sig_class_id FROM sig_class WHERE sig_class_name = E'%s';"
+#define SQL_INSERT_SIGNATURE "INSERT INTO signature (sig_sid, sig_gid, sig_rev, sig_class_id, sig_priority, sig_name) VALUES ('%u','%u','%u','%u','%u',E'%s');"
+#define SQL_SELECT_SPECIFIC_SIGNATURE "SELECT sig_id FROM signature WHERE " \
+ "(sig_sid = '%u') AND " \
+ "(sig_gid = '%u') AND " \
+ "(sig_rev = '%u') AND " \
+ "(sig_class_id = '%u') AND " \
+ "(sig_priority = '%u') AND " \
+ "(sig_name = E'%s'); " \
+
+#endif
+
+
+
+#define SQL_SELECT_ALL_SIGREF "SELECT ref_id, sig_id, ref_seq FROM sig_reference ORDER BY sig_id,ref_seq;"
+#define SQL_INSERT_SIGREF "INSERT INTO sig_reference (ref_id,sig_id,ref_seq) VALUES ('%u','%u','%u');"
+#define SQL_SELECT_SPECIFIC_SIGREF "SELECT ref_id FROM sig_reference WHERE (ref_id = '%u') AND (sig_id = '%u') AND (ref_seq='%u');"
+#define SQL_SELECT_ALL_REFERENCE_SYSTEM "SELECT ref_system_id, ref_system_name FROM reference_system;"
+#define SQL_SELECT_ALL_REF "SELECT ref_id, ref_system_id, ref_tag FROM reference; "
+#define SQL_SELECT_ALL_CLASSIFICATION "SELECT sig_class_id, sig_class_name FROM sig_class; "
+#define SQL_SELECT_ALL_SIGNATURE "SELECT sig_id, sig_sid, sig_gid, sig_rev, sig_class_id, sig_priority, sig_name FROM signature;"
+#define SQL_UPDATE_SPECIFIC_SIGNATURE "UPDATE signature SET " \
+ "sig_class_id = '%u'," \
+ "sig_priority = '%u'," \
+ "sig_rev = '%u' " \
+ "WHERE sig_id = '%u'; "
+
+#endif /* CACHE_SQL_QUERY */
+
+
+#ifndef CACHE_FLAGS
+#define CACHE_FLAGS
+#define CACHE_INTERNAL_ONLY 0x00000001
+#define CACHE_DATABASE_ONLY 0x00000010
+#define CACHE_BOTH 0x00000100 /* Digging a grave */
+
+
+#endif /* CACHE_FLAGS */
+
+
+
+
+
+
+#endif /*__SPO_DATABASE_CACHE_H__ */
+
View
23 src/spooler.c
@@ -603,7 +603,8 @@ int ProcessContinuous(const char *dirpath, const char *filebase,
}
/* close waldo if appropriate */
- spoolerCloseWaldo(&barnyard2_conf->waldo);
+ if(barnyard2_conf)
+ spoolerCloseWaldo(&barnyard2_conf->waldo);
return pc_ret;
}
@@ -964,10 +965,11 @@ int spoolerOpenWaldo(Waldo *waldo, uint8_t mode)
*/
int spoolerCloseWaldo(Waldo *waldo)
{
+
/* check we have a valid file descriptor */
if (waldo->state & WALDO_STATE_OPEN)
return WALDO_FILE_EOPEN;
-
+
/* close the file */
close(waldo->fd);
waldo->fd = -1;
@@ -995,7 +997,10 @@ int spoolerReadWaldo(Waldo *waldo)
/* check if we have a file in the correct mode (READ) */
if ( waldo->mode != WALDO_MODE_READ )
{
- spoolerCloseWaldo(waldo);
+ /* close waldo if appropriate */
+ if(barnyard2_conf)
+ spoolerCloseWaldo(waldo);
+
if ( (ret=spoolerOpenWaldo(waldo, WALDO_MODE_READ)) != WALDO_FILE_SUCCESS )
return ret;
}
@@ -1025,8 +1030,10 @@ int spoolerReadWaldo(Waldo *waldo)
waldo->data.spool_dir, waldo->data.spool_filebase,
waldo->data.timestamp, waldo->data.record_idx););
- /* close the file */
- spoolerCloseWaldo(waldo);
+
+ /* close waldo if appropriate */
+ if(barnyard2_conf)
+ spoolerCloseWaldo(waldo);
return WALDO_FILE_SUCCESS;
}
@@ -1057,7 +1064,11 @@ int spoolerWriteWaldo(Waldo *waldo, Spooler *spooler)
/* check if we have a file in the correct mode (READ) */
if ( waldo->mode != WALDO_MODE_WRITE )
{
- spoolerCloseWaldo(waldo);
+ /* close waldo if appropriate */
+ if(barnyard2_conf)
+ spoolerCloseWaldo(waldo);
+
+
spoolerOpenWaldo(waldo, WALDO_MODE_WRITE);
}
else if ( ! (waldo->state & WALDO_STATE_OPEN) )
View
353 src/util.c
@@ -95,6 +95,13 @@ static char _PATH_VARRUN[STD_BUF];
#define FILE_MAX_UTIL (PATH_MAX_UTIL + NAME_MAX_UTIL)
+
+#ifndef MAX_QUERY_LENGTH
+//#define MAX_QUERY_LENGTH 8192
+#define MAX_QUERY_LENGTH 65536 /* Lets add some space for payload decoding and query esaping..*/
+#endif /* MAX_QUERY_LENGTH */
+
+
/****************************************************************************
*
* Function: CalcPct(uint64_t, uint64_t)
@@ -1897,34 +1904,71 @@ char *GetTimestampByComponent(uint32_t sec, uint32_t usec, int tz)
{
struct tm *lt; /* localtime */
char *buf;
- time_t Time;
+ time_t Time;
int msec;
-
- buf = (char *)SnortAlloc(SMALLBUFFER * sizeof(char));
- Time = sec;
+ buf = (char *)SnortAlloc(SMALLBUFFER * sizeof(char));
+
+ Time = sec;
msec = usec / 1000;
- if (BcOutputUseUtc())
- {
- lt = gmtime(&Time);
+ if (BcOutputUseUtc())
+ {
+ lt = gmtime(&Time);
SnortSnprintf(buf, SMALLBUFFER,
- "%04i-%02i-%02i %02i:%02i:%02i.%03i",
- 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
- lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
- }
- else
- {
- lt = localtime(&Time);
+ "%04i-%02i-%02i %02i:%02i:%02i.%03i",
+ 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
+ lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
+ }
+ else
+ {
+ lt = localtime(&Time);
SnortSnprintf(buf, SMALLBUFFER,
- "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
- 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
- lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tz);
- }
-
+ "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
+ 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
+ lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tz);
+ }
+
return buf;
}
+/* Same a above using a static buffer */
+u_int32_t GetTimestampByComponent_STATIC(uint32_t sec, uint32_t usec, int tz,char *buf)
+{
+ struct tm *lt; /* localtime */
+ time_t Time;
+ int msec;
+
+ if(buf == NULL)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ Time = sec;
+ msec = usec / 1000;
+
+ if (BcOutputUseUtc())
+ {
+ lt = gmtime(&Time);
+ SnortSnprintf(buf, SMALLBUFFER,
+ "%04i-%02i-%02i %02i:%02i:%02i.%03i",
+ 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
+ lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
+ }
+ else
+ {
+ lt = localtime(&Time);
+ SnortSnprintf(buf, SMALLBUFFER,
+ "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
+ 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
+ lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tz);
+ }
+
+ return 0;
+}
+
+
/****************************************************************************
*
* Function: GetTimestampByStruct(register const struct timeval *tvp, int tz)
@@ -1966,6 +2010,41 @@ char *GetTimestampByStruct(register const struct timeval *tvp, int tz)
return buf;
}
+
+/* Same as above using static buffer */
+u_int32_t GetTimestampByStruct_STATIC(register const struct timeval *tvp, int tz,char *buf)
+{
+ struct tm *lt; /* localtime */
+ int msec;
+
+ if(buf == NULL)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ msec = tvp->tv_usec / 1000;
+
+ if (BcOutputUseUtc())
+ {
+ lt = gmtime((time_t *)&tvp->tv_sec);
+ SnortSnprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i",
+ 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
+ lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
+ }
+ else
+ {
+ lt = localtime((time_t *)&tvp->tv_sec);
+ SnortSnprintf(buf, SMALLBUFFER,
+ "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
+ 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
+ lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tz);
+ }
+
+ return 0;
+}
+
+
/****************************************************************************
*
* Function: GetLocalTimezone()
@@ -2009,7 +2088,7 @@ int GetLocalTimezone()
* Returns: char * -- You must free this char * when you are done with it.
*
***************************************************************************/
-char *GetCurrentTimestamp()
+char *GetCurrentTimestamp(void)
{
struct tm *lt;
struct timezone tz;
@@ -2049,6 +2128,54 @@ char *GetCurrentTimestamp()
return buf;
}
+/* Same as above using static */
+u_int32_t GetCurrentTimestamp_STATIC(char *buf)
+{
+ struct tm *lt;
+ struct timezone tz;
+ struct timeval tv;
+ struct timeval *tvp;
+ int tzone;
+ int msec;
+
+ if(buf == NULL)
+ {
+ /* XXX */
+ return 1;
+ }
+
+
+ bzero((char *)&tz,sizeof(tz));
+ gettimeofday(&tv,&tz);
+ tvp = &tv;
+
+ msec = tvp->tv_usec/1000;
+
+ if (BcOutputUseUtc())
+ {
+ lt = gmtime((time_t *)&tvp->tv_sec);
+ SnortSnprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i",
+ 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
+ lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
+ }
+ else
+ {
+ lt = localtime((time_t *)&tvp->tv_sec);
+
+ tzone = GetLocalTimezone();
+
+ SnortSnprintf(buf, SMALLBUFFER,
+ "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
+ 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
+ lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tzone);
+ }
+
+ return 0;
+}
+
+
+
+
/****************************************************************************
* Function: base64(char * xdata, int length)
*
@@ -2132,6 +2259,85 @@ char * base64(const u_char * xdata, int length)
return payloadptr;
}
+/* Same as above but uses a static buffer provided as a 3rd argument to function.. */
+u_int32_t base64_STATIC(const u_char * xdata, int length,char *output)
+{
+ int count, cols, bits, c, char_count;
+ unsigned char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* 64 bytes */
+ char * payloadptr;
+
+ char_count = 0;
+ bits = 0;
+ cols = 0;
+
+ if( ((length * 1.5) + 4 ) > MAX_QUERY_LENGTH)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ memset(output,'\0',MAX_QUERY_LENGTH);
+
+ payloadptr = output;
+
+ for(count = 0; count < length; count++)
+ {
+ c = xdata[count];
+
+ if(c > 255)
+ {
+ ErrorMessage("plugbase.c->base64(): encountered char > 255 (decimal %d)\n If you see this error message a char is more than one byte on your machine\n This means your base64 results can not be trusted", c);
+ }
+
+ bits += c;
+ char_count++;
+
+ if(char_count == 3)
+ {
+ *output = alpha[bits >> 18]; output++;
+ *output = alpha[(bits >> 12) & 0x3f]; output++;
+ *output = alpha[(bits >> 6) & 0x3f]; output++;
+ *output = alpha[bits & 0x3f]; output++;
+ cols += 4;
+ if(cols == 72)
+ {
+ *output = '\n'; output++;
+ cols = 0;
+ }
+ bits = 0;
+ char_count = 0;
+ }
+ else
+ {
+ bits <<= 8;
+ }
+ }
+
+ if(char_count != 0)
+ {
+ bits <<= 16 - (8 * char_count);
+ *output = alpha[bits >> 18]; output++;
+ *output = alpha[(bits >> 12) & 0x3f]; output++;
+ if(char_count == 1)
+ {
+ *output = '='; output++;
+ *output = '='; output++;
+ }
+ else
+ {
+ *output = alpha[(bits >> 6) & 0x3f];
+ output++; *output = '=';
+ output++;
+ }
+ }
+ *output = '\0';
+
+
+ return 0;
+}
+
+
+
/****************************************************************************
*
* Function: ascii(u_char *xdata, int length)
@@ -2212,6 +2418,77 @@ char *ascii(const u_char *xdata, int length)
return ret_val;
}
+/* Same as above but working with a static buffer .. */
+u_int32_t ascii_STATIC(const u_char *xdata, int length,char *ret_val)
+{
+ char *d_ptr;
+ int i,count = 0;
+ int size;
+
+ if( (xdata == NULL) ||
+ (ret_val == NULL))
+ {
+ return 1;
+ }
+
+ for(i=0;i<length;i++)
+ {
+ if(xdata[i] == '<')
+ count+=4; /* &lt; */
+ else if(xdata[i] == '&')
+ count+=5; /* &amp; */
+ else if(xdata[i] == '>') /* &gt; */
+ count += 4;
+ }
+
+ size = length + count + 1;
+
+ if(size > MAX_QUERY_LENGTH)
+ {
+ return 1;
+ }
+
+ memset(ret_val,'\0',MAX_QUERY_LENGTH);
+
+ d_ptr = ret_val;
+
+ for(i=0;i<length;i++)
+ {
+ if((xdata[i] > 0x1F) && (xdata[i] < 0x7F))
+ {
+ if(xdata[i] == '<')
+ {
+ SnortStrncpy(d_ptr, "&lt;", size - (d_ptr - ret_val));
+ d_ptr+=4;
+ }
+ else if(xdata[i] == '&')
+ {
+ SnortStrncpy(d_ptr, "&amp;", size - (d_ptr - ret_val));
+ d_ptr += 5;
+ }
+ else if(xdata[i] == '>')
+ {
+ SnortStrncpy(d_ptr, "&gt;", size - (d_ptr - ret_val));
+ d_ptr += 4;
+ }
+ else
+ {
+ *d_ptr++ = xdata[i];
+ }
+ }
+ else
+ {
+ *d_ptr++ = '.';
+ }
+ }
+
+ *d_ptr++ = '\0';
+
+ return 0;
+
+}
+
+
/****************************************************************************
*
* Function: hex(u_char *xdata, int length)
@@ -2254,6 +2531,8 @@ char *hex(const u_char *xdata, int length)
+
+
char *fasthex(const u_char *xdata, int length)
{
char conv[] = "0123456789ABCDEF";
@@ -2277,6 +2556,40 @@ char *fasthex(const u_char *xdata, int length)
return retbuf;
}
+/* same as above but working with a static buffer */
+u_int32_t fasthex_STATIC(const u_char *xdata, int length,char *retbuf)
+{
+ char conv[] = "0123456789ABCDEF";
+ const u_char *index;
+ const u_char *end;
+ char *ridx;
+
+ if( (xdata == NULL) ||
+ (retbuf == NULL) ||
+ (((length *2) + 1) > MAX_QUERY_LENGTH))
+ {
+ /* XXX */
+ return 1;
+ }
+
+ index = xdata;
+ end = xdata + length;
+
+ memset(retbuf,'\0',MAX_QUERY_LENGTH);
+
+ ridx = retbuf;
+
+ while(index < end)
+ {
+ *ridx++ = conv[((*index & 0xFF)>>4)];
+ *ridx++ = conv[((*index & 0xFF)&0x0F)];
+ index++;
+ }
+
+ return 0;
+}
+
+
/*
* Fatal Integer Parser
* Ascii to Integer conversion with fatal error support
View
12 src/util.h
@@ -211,6 +211,18 @@ char *GetIP(char *);
char *GetHostname();
int GetLocalTimezone();
+
+u_int32_t fasthex_STATIC(const u_char *xdata, int length,char *retbuf);
+u_int32_t base64_STATIC(const u_char * xdata, int length,char *output);
+u_int32_t ascii_STATIC(const u_char *xdata, int length,char *ret_val);
+
+u_int32_t GetTimestampByComponent_STATIC(uint32_t sec, uint32_t usec, int tz,char *buf);
+u_int32_t GetTimestampByStruct_STATIC(register const struct timeval *tvp, int tz,char *buf);
+u_int32_t GetCurrentTimestamp_STATIC(char *buf);
+
+
+
+
/***********************************************************
If you use any of the functions in this section, you need
to call free() on the char * that is returned after you are

0 comments on commit 2ecfbb1

Please sign in to comment.