diff -Nru securityonion-barnyard2-20121109/autogen.sh securityonion-barnyard2-20140531/autogen.sh --- securityonion-barnyard2-20121109/autogen.sh 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/autogen.sh 2014-02-10 16:34:05.000000000 +0000 @@ -10,5 +10,6 @@ echo "Failed to find libtoolize or glibtoolize, please ensure it is installed and accessible via your PATH env variable" exit 1 fi; -autoreconf -fv --install +#autoreconf -fv --install +autoreconf -fvi echo "You can now run \"./configure\" and then \"make\"." diff -Nru securityonion-barnyard2-20121109/configure.in securityonion-barnyard2-20140531/configure.in --- securityonion-barnyard2-20121109/configure.in 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/configure.in 2014-02-10 16:34:05.000000000 +0000 @@ -4,7 +4,7 @@ AC_PREREQ(2.50) AC_INIT(src/barnyard2.c) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(barnyard2,1.10) +AM_INIT_AUTOMAKE(barnyard2,1.13) AC_CONFIG_MACRO_DIR([m4]) LT_INIT @@ -815,7 +815,8 @@ postgresql_fail="no" fi - AC_MSG_CHECKING(for postgresql) + + AC_MSG_CHECKING([for postgresql]) if test "x$with_pgsql_includes" != "xno"; then for i in $with_pgsql_includes $postgresql_directory; do @@ -861,6 +862,7 @@ fi fi + if test -z "$POSTGRESQL_DIR"; then for dir in $postgresql_directory; do for i in "lib" "lib/pgsql"; do @@ -898,6 +900,10 @@ exit 1 fi fi + +AC_CHECK_FUNC([PQping], [AC_DEFINE([HAVE_PQPING], [1], + [Define if PQping exists.])]) + fi AC_ARG_WITH(oracle, @@ -1042,33 +1048,13 @@ [ --enable-plugin-echidna Enable echidna plugin (experimental)], enable_plugin_echidna="$enableval", enable_plugin_echidna="no") if test "x$enable_plugin_echidna" = "xyes"; then - CPPFLAGS="$CPPFLAGS -DENABLE_PLUGIN_ECHIDNA" - LIBS="$LIBS -lwebsockets -ljson -lcurl" - - AC_CHECK_LIB(curl, curl_easy_setopt,, LCURL="no") - if test "x$LCURL" = "xno"; then - echo - echo " ERROR! libcurl not found!" - echo - exit 1 - fi - - AC_CHECK_LIB(websockets, libwebsocket_create_context,, LWEBSOCKETS="no") - if test "x$LWEBSOCKETS" = "xno"; then - echo - echo " ERROR! libwebsockets not found." - echo - exit 1 - fi - - AC_CHECK_LIB(json, json_tokener_parse,, LJSON="no") - if test "x$LJSON" = "xno"; then - echo - echo " ERROR! libjson not found." - echo - exit 1 - fi + AC_CHECK_LIB([crypto], [SHA256_Init], [], [AC_MSG_ERROR([SHA256_Init was not found in libcrypto])]) + AC_CHECK_LIB([curl], [curl_easy_setopt], [], [AC_MSG_ERROR([curl_easy_setopt was not found in libcurl])]) + AC_CHECK_LIB([websockets], [libwebsocket_create_context], [], [AC_MSG_ERROR([libwebsocket_create_context was not found in libwebsockets])]) + AC_CHECK_LIB([json], [json_tokener_parse], [], [AC_MSG_ERROR([json_tokener_parse was not found in libjson])]) + CPPFLAGS="$CPPFLAGS -DENABLE_PLUGIN_ECHIDNA" + LIBS="$LIBS -lwebsockets -ljson -lcurl -lcrypto" fi @@ -1154,15 +1140,15 @@ The MySQL client version you are using does not by default reconnect to the server if the connection is lost and does not have the option to configure - this for the client. Snort, for security reasons, erases the connection + this for the client. Barnyard2, for security reasons, erases the connection password from memory, so it cannot explicity reconnect at runtime. Please update your version of MySQL to 5.0.13 or greater or you risk connections - timing out because of inactivity resulting in the inablilty of Snort to write + timing out because of inactivity resulting in the inablilty of Barnyard2 to write alerts to the database. If you can't upgrade, try setting the 'wait-timeout' configuration parameter to the maximum value possible in the @<:@mysqld@:>@ section of my.cnf, e.g. wait-timeout=31536000. This should give you a good year of inactivity before the server terminates the connection ... if your - network is this clean, you probably don't need to use Snort. + network is this clean, you probably don't need to use Barnyard2. ******************************************************************************** diff -Nru securityonion-barnyard2-20121109/debian/changelog securityonion-barnyard2-20140531/debian/changelog --- securityonion-barnyard2-20121109/debian/changelog 2012-11-09 13:28:36.000000000 +0000 +++ securityonion-barnyard2-20140531/debian/changelog 2014-06-01 01:43:13.000000000 +0000 @@ -1,5 +1,5 @@ -securityonion-barnyard2 (20121109-0ubuntu0securityonion1) precise; urgency=low +securityonion-barnyard2 (20140531-0ubuntu0securityonion1) precise; urgency=low - * Initial release + * Initial release - -- Doug Burks Fri, 09 Nov 2012 08:27:20 -0500 + -- Doug Burks Sat, 31 May 2014 21:42:46 -0400 diff -Nru securityonion-barnyard2-20121109/debian/copyright securityonion-barnyard2-20140531/debian/copyright --- securityonion-barnyard2-20121109/debian/copyright 2012-11-09 13:27:22.000000000 +0000 +++ securityonion-barnyard2-20140531/debian/copyright 2014-06-01 01:42:24.000000000 +0000 @@ -14,7 +14,7 @@ # If you want to use GPL v2 or later for the /debian/* files use # the following clauses, or change it to suit. Delete these two lines Files: debian/* -Copyright: 2012 Doug Burks +Copyright: 2014 Doug Burks License: GPL-2+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -Nru securityonion-barnyard2-20121109/debian/patches/don't-process-Makefile-in-etc securityonion-barnyard2-20140531/debian/patches/don't-process-Makefile-in-etc --- securityonion-barnyard2-20121109/debian/patches/don't-process-Makefile-in-etc 2012-11-09 13:37:48.000000000 +0000 +++ securityonion-barnyard2-20140531/debian/patches/don't-process-Makefile-in-etc 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -Description: - TODO: Put a short summary on the line above and replace this paragraph - with a longer explanation of this change. Complete the meta-information - with other relevant fields (see below for details). To make it easier, the - information below has been extracted from the changelog. Adjust it or drop - it. - . - securityonion-barnyard2 (20121109-0ubuntu0securityonion1) precise; urgency=low - . - * Initial release -Author: Doug Burks - ---- -The information above should follow the Patch Tagging Guidelines, please -checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here -are templates for supplementary fields that you might want to add: - -Origin: , -Bug: -Bug-Debian: http://bugs.debian.org/ -Bug-Ubuntu: https://launchpad.net/bugs/ -Forwarded: -Reviewed-By: -Last-Update: - ---- securityonion-barnyard2-20121109.orig/Makefile.am -+++ securityonion-barnyard2-20121109/Makefile.am -@@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS = foreign no-dependenci - - ACLOCAL_AMFLAGS = -I m4 - --SUBDIRS = src etc doc rpm schemas m4 -+SUBDIRS = src doc rpm schemas m4 - - INCLUDES = @INCLUDES@ - diff -Nru securityonion-barnyard2-20121109/debian/patches/series securityonion-barnyard2-20140531/debian/patches/series --- securityonion-barnyard2-20121109/debian/patches/series 2012-11-09 13:37:41.000000000 +0000 +++ securityonion-barnyard2-20140531/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -don't-process-Makefile-in-etc diff -Nru securityonion-barnyard2-20121109/doc/README.database securityonion-barnyard2-20140531/doc/README.database --- securityonion-barnyard2-20121109/doc/README.database 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/doc/README.database 2014-02-10 16:34:05.000000000 +0000 @@ -4,9 +4,11 @@ - Postgresql, - MySQL, - - any unixODBC database, - - MS SQL Server and - - Oracle. + +# Currently unsupported. +# - any unixODBC database, +# - MS SQL Server and +# - Oracle. This README contains some quick information about how to set up and configure database logging with in snort. More complete and @@ -34,9 +36,11 @@ (unixODBC + some other RDBMS) MySQL => http://www.mysql.org Postgresql => http://www.postgesql.org - unixODBC => http://www.unixodbc.org - Oracle => http://www.oracle.com - SQL Server => http://www.microsoft.com + +# Currently Unsupported +# unixODBC => http://www.unixodbc.org +# Oracle => http://www.oracle.com +# SQL Server => http://www.microsoft.com 2) Follow directions from your database vendor to be sure your RDBMS is properly configured and secured. @@ -207,7 +211,16 @@ [yes|1]: Ignore the BPF part when looking for the server definition - + connection_limit : default 10 - The maximum number of time that barnyard2 will tolerate a transaction faillure and or + database connection failure. + + reconnect_sleep_time : default 5 - The number of seconds to sleep betwen connection retry. + + disable_signature_reference_table - Tell the output plugin not to synchronize the sig_reference table in the schema. + This option will speedup the process, especialy if you use sid-msg.mapv2 file or + have alot of signature already in databases. + (Make sure that you do not need that information before enablign this) + MYSQL ONLY diff -Nru securityonion-barnyard2-20121109/doc/README.sig_suppress securityonion-barnyard2-20140531/doc/README.sig_suppress --- securityonion-barnyard2-20121109/doc/README.sig_suppress 1970-01-01 00:00:00.000000000 +0000 +++ securityonion-barnyard2-20140531/doc/README.sig_suppress 2014-02-10 16:34:05.000000000 +0000 @@ -0,0 +1,64 @@ +-=Barnyard2 Team=- + +================================================== + +Barnyard2 support event suppression at the +spooler level using the configuration directive sig_suppress. + +Syntax: +======= +config sig_suppress: (GID):(SID) + +Note: +GID is optional and SID can be a single SID or a range (START)-(END) (see below). + +EX: +======= +config sig_suppress: 1:10 +AND +config sig_suppress: 10 + +The above expressions ARE equivalent. + +config sig_suppress: 1:10 +AND +config sig_suppress: 112:10 + +The above expressions ARE NOT equivalent because one speficy gid 1 (alert) while the other speficy gid 112 (spp_arpspoof) + +config sig_suppress: 10-40 <= RANGE +IS equivalent to + config sig_suppress: 1:10-40 <= RANGE +AND ALSO equivalent to + config sig_suppress: 10,11,12,13,14,15,16....,38,39,40 + +NOTE: single entries are less effective,especially if you have large lists. + +As the time of this writing, if you change the list you will need to restart the process (STOP/START) and not SIGHUP +if you want the changes to be applied to event processing. + +If we define the following list (overlaping entries are ignored or replaced when a range covering them is encountered): +config sig_suppress: 1:10,20,1:30,2:90-102 +config sig_suppress: 1:10,1:30-40,15,10-40,25 +config sig_suppress: 1:10,50-55,15,10-20,80,51-52,31-35 +config sig_suppress: 2:93,2:95,2:100-101,2:91-122,22-27,2008175,2657,2011766,9900009,2001972,2101623 + +So with the example above the final list is the following: + + +[ Signature Suppress list ]+ + ---------------------------- + -- Element type:[RANGE ] gid:[2] sid min:[90] sid max:[122] + -- Element type:[RANGE ] gid:[1] sid min:[30] sid max:[40] + -- Element type:[RANGE ] gid:[1] sid min:[50] sid max:[55] + -- Element type:[RANGE ] gid:[1] sid min:[10] sid max:[20] + -- Element type:[SINGLE] gid:[1] sid min:[80] sid max:[80] + -- Element type:[RANGE ] gid:[1] sid min:[22] sid max:[27] + -- Element type:[SINGLE] gid:[1] sid min:[2008175] sid max:[2008175] + -- Element type:[SINGLE] gid:[1] sid min:[2657] sid max:[2657] + -- Element type:[SINGLE] gid:[1] sid min:[2011766] sid max:[2011766] + -- Element type:[SINGLE] gid:[1] sid min:[9900009] sid max:[9900009] + -- Element type:[SINGLE] gid:[1] sid min:[2001972] sid max:[2001972] + -- Element type:[SINGLE] gid:[1] sid min:[2101623] sid max:[2101623] + ---------------------------- + +[ Signature Suppress list ]+ + diff -Nru securityonion-barnyard2-20121109/etc/barnyard2.conf securityonion-barnyard2-20140531/etc/barnyard2.conf --- securityonion-barnyard2-20121109/etc/barnyard2.conf 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/etc/barnyard2.conf 2014-02-10 16:34:05.000000000 +0000 @@ -29,6 +29,13 @@ config gen_file: /etc/snort/gen-msg.map config sid_file: /etc/snort/sid-msg.map + +# Configure signature suppression at the spooler level see doc/README.sig_suppress +# +# +#config sig_suppress: 1:10 + + # Set the event cache size to defined max value before recycling of event occur. # # @@ -272,6 +279,7 @@ # operation_mode $operaion_mode - default | complete : default mode is compatible with default snort syslog message, complete prints more information such as the raw packet (hexed) # log_priority $log_priority - used by local option for syslog priority call. (man syslog(3) for supported options) (default: LOG_INFO) # log_facility $log_facility - used by local option for syslog facility call. (man syslog(3) for supported options) (default: LOG_USER) +# payload_encoding - (default: hex) support hex/ascii/base64 for log_syslog_full using operation_mode complete only. # Usage Examples: # output alert_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514, operation_mode default diff -Nru securityonion-barnyard2-20121109/README securityonion-barnyard2-20140531/README --- securityonion-barnyard2-20121109/README 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/README 2014-02-10 16:34:05.000000000 +0000 @@ -3,20 +3,21 @@ 0. SUMMARY ------------------------------------------------------------------------------ -Barnyard2 - version 2-1.10 +Barnyard2 - version 2-1.13 This README contains some quick information about how to set up and configure barnyard2 to ensure it works as it should. Distribution Site: -http://www.securixlive.com/barnyard2 +http://www.securixlive.com +http://www.github.com/firnsy/barnyard2 ------------------------------------------------------------------------------ 1. COPYRIGHT ------------------------------------------------------------------------------ -Copyright (C)2008-2012 Ian Firns +Copyright (C)2008-2013 Ian Firns Copyright (C)2008-2010 SecurixLive This program is free software; you can redistribute it and/or modify @@ -157,3 +158,14 @@ # ./barnyard2 -c /etc/barnyard2.conf -o file1.u2 file2.u2 file3.u2 + +------------------------------------------------------------------------------ +4. CONTACT +------------------------------------------------------------------------------ + +You can contact the barnyard2 team and user base for question/help debugging issue concerning barnyard2 by using our mailing lists. + +barnyard2-users@googlegroups.com +AND +barnyard2-devel@googlegroups.com + diff -Nru securityonion-barnyard2-20121109/RELEASE.NOTES securityonion-barnyard2-20140531/RELEASE.NOTES --- securityonion-barnyard2-20121109/RELEASE.NOTES 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/RELEASE.NOTES 2014-02-10 16:34:05.000000000 +0000 @@ -1,3 +1,25 @@ +2013-02-15 - Barnyard 2.1.12 + [*] Improvements + * spo_syslog_full. Added both ascii and base64 support. + + * spo_database. Many tweaks and fixes. + + * Fixed PQping detection on build. + +2012-11-29 - Barnyard 2.1.11 + [*] Improvements + * spo_database. Keep-alive (via ping) for postgresql databases. + + * Updated RPM spec file to support alternative pcap libraries and cleaned + some existing cruft. Thanks to Brent Woodruff. + + * spo_alert_unixsock. Supports synchronisation, multiple connections and + improved error reporting. Thanks to Martijn van Oosterhaut. + + * Many other general bug fixes and clean ups. Thanks to Jason Ish, + Thorsten Fischer, Brad Voth and Bill Parker. + + 2012-10-24 - Barnyard 2.1.10 [*] Additions * spo_database. Support of encrypted connections to postgresql is now diff -Nru securityonion-barnyard2-20121109/rpm/barnyard2.spec securityonion-barnyard2-20140531/rpm/barnyard2.spec --- securityonion-barnyard2-20121109/rpm/barnyard2.spec 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/rpm/barnyard2.spec 2014-02-10 16:34:05.000000000 +0000 @@ -43,12 +43,13 @@ Summary: Snort Log Backend Name: barnyard2 -Version: 1.9 +Version: 1.13 +Source0: https://github.com/firnsy/barnyard2/archive/v2-%{version}.tar.gz Release: 1%{?dist} License: GPL Group: Applications/Internet -Source0: http://www.securixlive.com/download/barnyard2/%{name}-%{version}.tar.gz -Url: http://www.securixlive.com/barnyard2/ +Url: http://www.github.com/firnsy/barnyard2 + BuildRoot: %{_tmppath}/%{name}-%{version}-root %if %{libpcap1} BuildRequires: libpcap1-devel diff -Nru securityonion-barnyard2-20121109/schemas/SCHEMA_ACCESS securityonion-barnyard2-20140531/schemas/SCHEMA_ACCESS --- securityonion-barnyard2-20121109/schemas/SCHEMA_ACCESS 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/schemas/SCHEMA_ACCESS 2014-02-10 16:34:05.000000000 +0000 @@ -73,6 +73,12 @@ ============= ============= +TABLE : schema +============= +SELECT +============= + +============= TABLE : sig_class ============= INSERT diff -Nru securityonion-barnyard2-20121109/src/barnyard2.c securityonion-barnyard2-20140531/src/barnyard2.c --- securityonion-barnyard2-20121109/src/barnyard2.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/barnyard2.c 2014-02-10 16:34:05.000000000 +0000 @@ -21,17 +21,8 @@ /* * - * Program: Snort - * - * Purpose: Check out the README file for info on what you can do - * with Snort. - * - * Author: Martin Roesch (roesch@clark.net) - * - * Comments: Ideas and code stolen liberally from Mike Borella's IP Grab - * program. Check out his stuff at http://www.borella.net. I - * also have ripped some util functions from TCPdump, plus Mike's - * prog is derived from it as well. All hail TCPdump.... + * Program: barnyard2 + * Alot of code borrowed from snort. (all credit due) * */ @@ -120,11 +111,13 @@ } GetOptArgType; - /* Globals ********************************************************************/ PacketCount pc; /* packet count information */ + +unsigned short stat_dropped = 0; uint32_t *netmasks = NULL; /* precalculated netmask array */ char **protocol_names = NULL; + char *barnyard2_conf_file = NULL; /* -c */ char *barnyard2_conf_dir = NULL; @@ -137,12 +130,10 @@ VarNode *cmd_line_var_list = NULL; int exit_signal = 0; -static int usr_signal = 0; +static int usr_signal = 0; static volatile int hup_signal = 0; - volatile int barnyard2_initializing = 1; -static volatile int barnyard2_exiting = 0; InputConfigFuncNode *input_config_funcs = NULL; OutputConfigFuncNode *output_config_funcs = NULL; @@ -210,6 +201,8 @@ extern int opterr; extern int optopt; + + /* Private function prototypes ************************************************/ static void InitNetmasks(void); static void InitProtoNames(void); @@ -226,22 +219,25 @@ #if defined(NOCOREFILE) && !defined(WIN32) static void SetNoCores(void); #endif -static void Barnyard2Cleanup(int); + +static void Barnyard2Cleanup(int,int); static void FreeInputConfigs(InputConfig *); static void FreeOutputConfigs(OutputConfig *); -static void FreeClassifications(ClassType *); -static void FreeReferences(ReferenceSystemNode *); static void FreePlugins(Barnyard2Config *); static void Barnyard2PostInit(void); static char * ConfigFileSearch(void); +int SignalCheck(void); + /* Signal handler declarations ************************************************/ + static void SigExitHandler(int); static void SigUsrHandler(int); static void SigHupHandler(int); + /* F U N C T I O N D E F I N I T I O N S **********************************/ /* @@ -259,6 +255,12 @@ */ int main(int argc, char *argv[]) { + barnyard2_argc = argc; + barnyard2_argv = argv; + + argc = 0; + argv = NULL; + #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) /* Do some sanity checking, because some people seem to forget to * put spaces between their parameters @@ -275,14 +277,11 @@ /* If the first parameter is "/SERVICE", then start Snort as a Win32 service */ if((argc > 1) && (_stricmp(argv[1],SERVICE_CMDLINE_PARAM) == 0)) { - return Barnyard2ServiceMain(argc, argv); + return Barnyard2ServiceMain(barnyard2_argc, barnyard2_argv); } #endif /* WIN32 && ENABLE_WIN32_SERVICE */ - - barnyard2_argc = argc; - barnyard2_argv = argv; - - return Barnyard2Main(argc, argv); + + return Barnyard2Main(barnyard2_argc, barnyard2_argv); } /* @@ -310,6 +309,8 @@ FatalError("Could not Initialize Winsock!\n"); #endif +restart: + Barnyard2Init(argc, argv); if (BcDaemonMode()) @@ -364,16 +365,31 @@ LogMessage("Processing %d files...\n", barnyard2_conf->batch_total_files); for(idx = 0; idx < barnyard2_conf->batch_total_files; idx++) { - ProcessBatch("", barnyard2_conf->batch_filelist[idx]); - } + ProcessBatch("", barnyard2_conf->batch_filelist[idx]); + if( SignalCheck()) + { + /* Clean Things up */ + Barnyard2Cleanup(0,0); + /* Relaunch status */ + goto restart; + } + } } } - /* Continual processing mode */ - else if (BcContinuousMode()) - { - ProcessContinuousWithWaldo(&barnyard2_conf->waldo); + /* Continual processing mode */ + else if (BcContinuousMode()) + { + ProcessContinuousWithWaldo(&barnyard2_conf->waldo); + + if( SignalCheck()) + { + /* Clean Things up */ + Barnyard2Cleanup(0,0); + /* Relaunch status */ + goto restart; } - + } + #ifndef WIN32 closelog(); #endif @@ -562,7 +578,7 @@ FatalError("%s(%d) Trying to parse the command line again.\n", __FILE__, __LINE__); } - + barnyard2_cmd_line_conf = Barnyard2ConfNew(); barnyard2_conf = barnyard2_cmd_line_conf; /* Set the global for log messages */ bc = barnyard2_cmd_line_conf; @@ -620,6 +636,7 @@ ** Instead, we check optopt and it will tell us. */ optopt = 0; + optind = 0; /* in case we are being re-invoked , think HUP */ /* loop through each command line var and process it */ while ((ch = getopt_long(argc, argv, valid_options, long_options, &option_index)) != -1) @@ -719,9 +736,7 @@ ConfigSetGid(bc, optarg); break; - case 'G': /* snort loG identifier */ - ConfigGenFile(bc, optarg); - break; + case 'h': ConfigHostname(bc, optarg); @@ -790,9 +805,13 @@ #endif break; - case 'S': /* set a rules file variable */ - ConfigSidFile(bc, optarg); - break; + case 'S': /* set a rules file variable */ + bc->sid_msg_file = strndup(optarg,PATH_MAX); + break; + + case 'G': /* snort preprocessor identifier */ + bc->gen_msg_file = strndup(optarg,PATH_MAX); + break; case 't': /* chroot to the user specified directory */ ConfigChrootDir(bc, optarg); @@ -853,27 +872,27 @@ } } - /* when batch processing check for any remaining arguments which should */ - /* be a parsed as a list of files to process. */ - if ((bc->run_mode_flags & RUN_MODE_FLAG__BATCH) && (optind < argc)) + /* when batch processing check for any remaining arguments which should */ + /* be a parsed as a list of files to process. */ + if ((bc->run_mode_flags & RUN_MODE_FLAG__BATCH) && (optind < argc)) + { + int idx = 0; + + bc->batch_total_files = argc - optind; + bc->batch_filelist = SnortAlloc(bc->batch_total_files * sizeof(char *)); + + while (optind < argc) { - int idx = 0; - - bc->batch_total_files = argc - optind; - bc->batch_filelist = SnortAlloc(bc->batch_total_files * sizeof(char *)); - - while (optind < argc) - { - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Extra args: %s\n", argv[optind]);); - bc->batch_filelist[idx] = SnortStrdup(argv[optind]); - - idx++; - optind++; - } - - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Total files: %i\n", bc->batch_total_files);); + DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Extra args: %s\n", argv[optind]);); + bc->batch_filelist[idx] = SnortStrdup(argv[optind]); + + idx++; + optind++; } - + + DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Total files: %i\n", bc->batch_total_files);); + } + if ((bc->run_mode_flags & RUN_MODE_FLAG__TEST) && (bc->run_flags & RUN_FLAG__DAEMON)) { @@ -882,12 +901,12 @@ "mode and then restart in daemon mode.\n"); } else if ((bc->run_mode_flags & RUN_MODE_FLAG__BATCH) && - (bc->run_flags & RUN_MODE_FLAG__CONTINUOUS)) + (bc->run_flags & RUN_MODE_FLAG__CONTINUOUS)) { FatalError("Cannot use batch mode and continuous mode together.\n"); } - - + + if ((bc->run_mode_flags & RUN_MODE_FLAG__TEST) && (barnyard2_conf_file == NULL)) { @@ -895,10 +914,10 @@ "file. Use the '-c' option on the command line to " "specify a configuration file.\n"); } - + if (pcap_filter != NULL) free(pcap_filter); - + /* Set the run mode based on what we've got from command line */ /* Version overrides all */ @@ -1007,36 +1026,32 @@ 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); - + return; } static void SigUsrHandler(int signal) { - if (usr_signal != 0) + if ( (usr_signal != 0) || + (exit_signal != 0)) return; - + usr_signal = signal; - - Barnyard2Cleanup(signal); - - + return; } static void SigHupHandler(int signal) { + if(exit_signal != 0) + return; + + exit_signal = 1; hup_signal = 1; - Barnyard2Cleanup(signal); - + + return; } /**************************************************************************** @@ -1052,56 +1067,84 @@ ****************************************************************************/ void CleanExit(int exit_val) { - LogMessage("Snort exiting\n"); - Barnyard2Cleanup(exit_val); + LogMessage("Barnyard2 exiting\n"); + #ifndef WIN32 closelog(); #endif - exit(exit_val); + + Barnyard2Cleanup(exit_val,1); } -static void Barnyard2Cleanup(int exit_val) + +static void Barnyard2Cleanup(int exit_val,int exit_needed) { PluginSignalFuncNode *idxPlugin = NULL; + PluginSignalFuncNode *idxPluginNext = NULL; - /* This function can be called more than once. For example, - * once from the SIGINT signal handler, and once recursively - * as a result of calling pcap_close() below. We only need - * to perform the cleanup once, however. So the static - * variable already_exiting will act as a flag to prevent - * double-freeing any memory. Not guaranteed to be - * thread-safe, but it will prevent the simple cases. - */ + /* This function can be called more than once. */ static int already_exiting = 0; + if( already_exiting != 0 ) { return; } + already_exiting = 1; - barnyard2_exiting = 1; + barnyard2_initializing = 0; /* just in case we cut out early */ - + if (BcContinuousMode() || BcBatchMode()) { /* Do some post processing on any incomplete Plugin Data */ - idxPlugin = plugin_shutdown_funcs; + idxPlugin = plugin_clean_exit_funcs; while(idxPlugin) { + idxPluginNext = idxPlugin->next; idxPlugin->func(SIGQUIT, idxPlugin->arg); - idxPlugin = idxPlugin->next; + free(idxPlugin); + idxPlugin = idxPluginNext; } + plugin_clean_exit_funcs = NULL; } + + + + /* + Right now we will just free them if they are initialized since + in the context we operate if we receive HUP we mainly just "restart" + */ + idxPlugin = plugin_restart_funcs; + while(idxPlugin) + { + idxPluginNext = idxPlugin->next; + free(idxPlugin); + idxPlugin = idxPluginNext; + } + plugin_restart_funcs = NULL; + + + idxPlugin = plugin_shutdown_funcs; + while(idxPlugin) + { + idxPluginNext = idxPlugin->next; + free(idxPlugin); + idxPlugin = idxPluginNext; + } + plugin_shutdown_funcs = NULL; + + if (!exit_val) { struct timeval difftime; struct timezone tz; - + memset((char *) &tz, 0, sizeof(tz)); /* bzero() deprecated, replaced by memset() */ gettimeofday(&endtime, &tz); - + TIMERSUB(&endtime, &starttime, &difftime); - + if (exit_signal) { LogMessage("Run time prior to being shutdown was %lu.%lu seconds\n", @@ -1116,34 +1159,75 @@ idxPlugin = plugin_clean_exit_funcs; while(idxPlugin) { + idxPluginNext = idxPlugin->next; idxPlugin->func(SIGQUIT, idxPlugin->arg); - idxPlugin = idxPlugin->next; + free(idxPlugin); + idxPlugin = idxPluginNext; } + plugin_clean_exit_funcs = NULL; } /* Print Statistics */ - if (!BcTestMode() && !BcVersionMode() - ) + if (!BcTestMode() && !BcVersionMode()) { - DropStats(2); + if(!stat_dropped) + { + DropStats(2); + } + else + { + stat_dropped = 0; + } } - CleanupProtoNames(); + /* Cleanup some spooler stuff */ + if(barnyard2_conf->spooler) + { + spoolerEventCacheFlush(barnyard2_conf->spooler); + + if(barnyard2_conf->spooler->header) + { + free(barnyard2_conf->spooler->header); + barnyard2_conf->spooler->header = NULL; + } - ClosePidFile(); + if(barnyard2_conf->spooler->record.header) + { + free(barnyard2_conf->spooler->record.header); + barnyard2_conf->spooler->record.header = NULL; + } + if(barnyard2_conf->spooler->record.data) + { + free(barnyard2_conf->spooler->record.data); + barnyard2_conf->spooler->record.data = NULL; + } + } + + CleanupProtoNames(); + ClosePidFile(); + /* remove pid file */ if (SnortStrnlen(barnyard2_conf->pid_filename, sizeof(barnyard2_conf->pid_filename)) > 0) { int ret; ret = unlink(barnyard2_conf->pid_filename); - + if (ret != 0) { ErrorMessage("Could not remove pid file %s: %s\n", barnyard2_conf->pid_filename, strerror(errno)); } } + + spoolerCloseWaldo(&barnyard2_conf->waldo); + + if(barnyard2_conf->spooler) + { + spoolerClose(barnyard2_conf->spooler); + barnyard2_conf->spooler = NULL; + } + /* free allocated memory */ if (barnyard2_conf == barnyard2_cmd_line_conf) @@ -1160,49 +1244,44 @@ barnyard2_conf = NULL; } - FreeOutputConfigFuncs(); FreeOutputList(AlertList); + FreeOutputList(LogList); AlertList = NULL; - - FreeOutputList(LogList); LogList = NULL; + FreeOutputConfigFuncs(); + + FreeInputPlugins(); + /* Global lists */ ParserCleanup(); - + /* Stuff from plugbase */ - ClearDumpBuf(); - + if (netmasks != NULL) { free(netmasks); netmasks = NULL; } - - if (protocol_names != NULL) - { - int i; - - for (i = 0; i < NUM_IP_PROTOS; i++) - { - if (protocol_names[i] != NULL) - free(protocol_names[i]); - } - - free(protocol_names); - protocol_names = NULL; - } - + if (barnyard2_conf_file != NULL) + { free(barnyard2_conf_file); - + barnyard2_conf_file = NULL; + } + if (barnyard2_conf_dir != NULL) + { free(barnyard2_conf_dir); - + barnyard2_conf_dir = NULL; + } - _exit(exit_val); + if(exit_needed) + _exit(exit_val); + already_exiting = 0; + return; } void Restart(void) @@ -1221,7 +1300,7 @@ LogMessage("\n"); LogMessage("***** Restarting Barnyard2 *****\n"); LogMessage("\n"); - Barnyard2Cleanup(0); + Barnyard2Cleanup(0,0); if (daemon_mode) { @@ -1259,6 +1338,7 @@ exit(-1); } + /* * Check for signal activity */ @@ -1266,67 +1346,85 @@ { switch (exit_signal) { - case SIGTERM: - if (!exit_logged) - { - ErrorMessage("*** Caught Term-Signal\n"); - exit_logged = 1; - } - CleanExit(0); - break; - - case SIGINT: - if (!exit_logged) - { - ErrorMessage("*** Caught Int-Signal\n"); - exit_logged = 1; - } - CleanExit(0); - break; - case SIGQUIT: - if (!exit_logged) - { - ErrorMessage("*** Caught Quit-Signal\n"); - exit_logged = 1; - } - CleanExit(0); - break; + case SIGTERM: + if (!exit_logged) + { + ErrorMessage("*** Caught Term-Signal\n"); + exit_logged = 1; + } + + CleanExit(exit_signal); + break; + + case SIGINT: + if (!exit_logged) + { + ErrorMessage("*** Caught Int-Signal\n"); + exit_logged = 1; + } + + CleanExit(exit_signal); + break; + + case SIGQUIT: + if (!exit_logged) + { + ErrorMessage("*** Caught Quit-Signal\n"); + exit_logged = 1; + } + + CleanExit(exit_signal); + break; + + case SIGKILL: + if (!exit_logged) + { + ErrorMessage("*** Caught Kill-Signal\n"); + exit_logged = 1; + } + + CleanExit(exit_signal); + break; - default: - break; + default: + break; } - + exit_signal = 0; - + switch (usr_signal) { - case SIGUSR1: - ErrorMessage("*** Caught Usr-Signal\n"); - DropStats(0); - break; - - case SIGNAL_SNORT_ROTATE_STATS: - ErrorMessage("*** Caught Usr-Signal: 'Rotate Stats'\n"); - break; + case SIGUSR1: + ErrorMessage("*** Caught Usr-Signal\n"); + DropStats(0); + break; + + case SIGNAL_SNORT_ROTATE_STATS: + ErrorMessage("*** Caught Usr-Signal: 'Rotate Stats'\n"); + break; } - + usr_signal = 0; - + if (hup_signal) { ErrorMessage("*** Caught Hup-Signal\n"); + DropStats(0); + stat_dropped = 1; + ErrorMessage("*** Resetting Stats\n"); + memset(&pc,'\0',sizeof(PacketCount)); hup_signal = 0; return 1; } - + return 0; } + static void InitGlobals(void) { memset(&pc, 0, sizeof(PacketCount)); - InitNetmasks(); InitProtoNames(); } @@ -1355,41 +1453,110 @@ { if (bc == NULL) return; - + if (bc->log_dir != NULL) + { free(bc->log_dir); - + bc->log_dir = NULL; + } + if (bc->orig_log_dir != NULL) + { free(bc->orig_log_dir); - + bc->orig_log_dir = NULL; + } + if (bc->interface != NULL) + { free(bc->interface); - + bc->interface = NULL; + } + if (bc->chroot_dir != NULL) + { free(bc->chroot_dir); - + bc->chroot_dir = NULL; + } + if (bc->archive_dir != NULL) + { free(bc->archive_dir); + bc->archive_dir = NULL; + } + + if(bc->config_file != NULL) + { + free(bc->config_file); + bc->config_file = NULL; + } + + if(bc->config_dir != NULL) + { + free(bc->config_dir); + bc->config_dir = NULL; + } + + if(bc->hostname != NULL) + { + free(bc->hostname); + bc->hostname = NULL; + } + + if(bc->class_file != NULL) + { + free(bc->class_file); + bc->class_file = NULL; + } + + if( bc->sid_msg_file != NULL) + { + free(bc->sid_msg_file); + bc->sid_msg_file = NULL; + } + + if( bc->gen_msg_file != NULL) + { + free(bc->gen_msg_file); + bc->gen_msg_file = NULL; + } - if (bc->batch_total_files > 0) + if( bc->reference_file != NULL) + { + free(bc->reference_file); + bc->reference_file = NULL; + } + + if( bc->bpf_filter != NULL) + { + free(bc->bpf_filter); + bc->bpf_filter = NULL; + } + + if (bc->batch_total_files > 0) + { + int idx; + for(idx = 0; idx< bc->batch_total_files; idx++) { - int idx; - for(idx = 0; idx< bc->batch_total_files; idx++) - { - free(bc->batch_filelist[idx]); - } - free(bc->batch_filelist); + free(bc->batch_filelist[idx]); + bc->batch_filelist[idx] = NULL; } + free(bc->batch_filelist); + } + FreeSigSuppression(&bc->ssHead); + FreeSigNodes(&bc->sigHead); + FreeClassifications(&bc->classifications); + FreeReferences(&bc->references); + FreeInputConfigs(bc->input_configs); + bc->input_configs = NULL; + FreeOutputConfigs(bc->output_configs); - - FreeClassifications(bc->classifications); - FreeReferences(bc->references); - + bc->output_configs = NULL; + VarTablesFree(bc); FreePlugins(bc); - + free(bc); } @@ -1518,7 +1685,7 @@ { if (bc == NULL) return; - + FreePluginSigFuncs(bc->plugin_post_config_funcs); bc->plugin_post_config_funcs = NULL; } @@ -1533,7 +1700,7 @@ FatalError("%s(%d) Merging barnyard2 configs: barnyard2 conf is NULL.\n", __FILE__, __LINE__); } - + ResolveOutputPlugins(cmd_line, config_file); if (config_file == NULL) @@ -1555,13 +1722,56 @@ if (config_file == NULL) return cmd_line; + + if(cmd_line->ssHead) + { + config_file->ssHead = cmd_line->ssHead; + cmd_line->ssHead = NULL; + } + if( (cmd_line->sid_msg_file) && + (config_file->sid_msg_file)) + { + FatalError("The sid map file was included two times command line (-S) [%s] and in the configuration file (config sid_map) [%s].\n" + "It only need to be defined once.\n", + cmd_line->sid_msg_file, + config_file->sid_msg_file); + } + + if( (cmd_line->gen_msg_file) && + (config_file->gen_msg_file)) + { + FatalError("The gen map file was included two times command line (-G) [%s] and in the configuration file (config gen_map) [%s].\n" + "It only need to be defined once.\n", + cmd_line->gen_msg_file, + config_file->gen_msg_file); + } + + if( (cmd_line->sid_msg_file != NULL) && + (config_file->sid_msg_file == NULL)) + { + config_file->sid_msg_file = cmd_line->sid_msg_file; + cmd_line->sid_msg_file = NULL; + } + + if( (cmd_line->gen_msg_file != NULL) && + (config_file->gen_msg_file == NULL)) + { + config_file->gen_msg_file = cmd_line->gen_msg_file; + cmd_line->gen_msg_file = NULL; + } + if( cmd_line->event_cache_size > config_file->event_cache_size) { config_file->event_cache_size = cmd_line->event_cache_size; } + /* In case */ + if(cmd_line->sidmap_version > config_file->sidmap_version) + { + config_file->sidmap_version = cmd_line->sidmap_version; + } /* Used because of a potential chroot */ @@ -1585,8 +1795,22 @@ if (cmd_line->pid_path[0] != '\0') ConfigPidPath(config_file, cmd_line->pid_path); + + if( config_file->alert_on_each_packet_in_stream_flag == 0) + { + LogMessage("[INFO]: Alerting on each packet in stream has been disabled by configuration file,\n" + "\tevents will only be outputed for the first matching event/packet,\n" + "\tfurther packets matching previous processed events will be ignored"); + } + else if( cmd_line->alert_on_each_packet_in_stream_flag == 0 ) + { + LogMessage("[INFO]: Alerting on each packet in stream has been disabled by command line option,\n" + "\tevents will only be outputed for the first matching event/packet,\n" + "\tfurther packets matching previous processed events will be ignored"); - config_file->alert_on_each_packet_in_stream_flag = cmd_line->alert_on_each_packet_in_stream_flag; + config_file->alert_on_each_packet_in_stream_flag = cmd_line->alert_on_each_packet_in_stream_flag; + } + config_file->process_new_records_only_flag = cmd_line->process_new_records_only_flag; #ifdef SUP_IP6 @@ -1768,6 +1992,22 @@ * Set the global barnyard2_conf that will be used during run time */ barnyard2_conf = MergeBarnyard2Confs(barnyard2_cmd_line_conf, bc); + DisplaySigSuppress(BCGetSigSuppressHead()); + + if(ReadSidFile(barnyard2_conf)) + { + FatalError("[%s()], failed while processing [%s] \n", + __FUNCTION__, + bc->sid_msg_file); + } + + if(ReadGenFile(barnyard2_conf)) + { + FatalError("[%s()], failed while processing [%s] \n", + __FUNCTION__, + bc->gen_msg_file); + } + if(barnyard2_conf->event_cache_size == 0) { barnyard2_conf->event_cache_size = 2048; @@ -1778,9 +2018,22 @@ } + /* Resolve classification integer for signature and free some memory */ + if(barnyard2_conf->sidmap_version == SIDMAPV2) + { + if(SignatureResolveClassification(barnyard2_conf->classifications, + (SigNode *)*BcGetSigNodeHead(), + barnyard2_conf->sid_msg_file, + barnyard2_conf->class_file)) + { + FatalError("[%s()], Call to SignatureResolveClassification failed \n", + __FUNCTION__); + } + } + /* pcap_snaplen is already initialized to SNAPLEN */ -// if (barnyard2_conf->pkt_snaplen != -1) -// pcap_snaplen = (uint32_t)snort_conf->pkt_snaplen; + // if (barnyard2_conf->pkt_snaplen != -1) + // pcap_snaplen = (uint32_t)snort_conf->pkt_snaplen; /* Display barnyard2 version information here so that we can also show dynamic * plugin versions, if loaded. */ @@ -1949,41 +2202,5 @@ free(tmp); } -} - -static void FreeClassifications(ClassType *head) -{ - while (head != NULL) - { - ClassType *tmp = head; - - head = head->next; - - if (tmp->name != NULL) - free(tmp->name); - - if (tmp->type != NULL) - free(tmp->type); - - free(tmp); - } -} - -static void FreeReferences(ReferenceSystemNode *head) -{ - while (head != NULL) - { - ReferenceSystemNode *tmp = head; - - head = head->next; - - if (tmp->name != NULL) - free(tmp->name); - - if (tmp->url != NULL) - free(tmp->url); - - free(tmp); - } } diff -Nru securityonion-barnyard2-20121109/src/barnyard2.h securityonion-barnyard2-20140531/src/barnyard2.h --- securityonion-barnyard2-20121109/src/barnyard2.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/barnyard2.h 2014-02-10 16:34:05.000000000 +0000 @@ -1,5 +1,5 @@ /* -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** ** Copyright (C) 2005-2009 Sourcefire, Inc. ** Copyright (C) 1998-2005 Martin Roesch @@ -62,8 +62,8 @@ #define PROGRAM_NAME "Barnyard" #define VER_MAJOR "2" #define VER_MINOR "1" -#define VER_REVISION "11" -#define VER_BUILD "317" +#define VER_REVISION "13" +#define VER_BUILD "333" #define STD_BUF 1024 @@ -89,6 +89,15 @@ #define TIMEBUF_SIZE 26 + +#ifndef ULONG_MAX +# if __WORDSIZE == 64 +# define ULONG_MAX 18446744073709551615UL +# else +# define ULONG_MAX 4294967295UL +# endif +#endif + #define DO_IP_CHECKSUMS 0x00000001 #define DO_TCP_CHECKSUMS 0x00000002 #define DO_UDP_CHECKSUMS 0x00000004 @@ -121,6 +130,15 @@ # define DEFAULT_LABELCHAIN_LENGTH -1 #endif + +/* SIDMAP V2 */ +#define SIDMAPV1STRING "v1" +#define SIDMAPV2STRING "v2" +#define SIDMAPV1 0x01 +#define SIDMAPV2 0x02 +/* SIDMAP V2 */ + + /* This macro helps to simplify the differences between Win32 and non-Win32 code when printing out the name of the interface */ #ifndef WIN32 @@ -288,80 +306,49 @@ } VarNode; + /* struct to contain the program variables and command line args */ typedef struct _Barnyard2Config { +/* Does not need cleanup */ RunMode run_mode; + int checksums_mode; + char ignore_ports[0x10000]; int run_mode_flags; int run_flags; int output_flags; int logging_flags; -// int log_tcpdump; -// int no_log; - - unsigned int event_cache_size; - - VarEntry *var_table; -#ifdef SUP_IP6 - vartable_t *ip_vartable; -#endif - - /* staging - snort specific variables */ - int checksums_mode; - char ignore_ports[0x10000]; - - /* general variables */ - char *config_file; /* -c */ - char *config_dir; + int thiszone; + int quiet_flag; + int verbose_flag; + int verbose_bytedump_flag; + int show2hdr_flag; + int char_data_flag; + int data_flag; + int obfuscation_flag; + int alert_on_each_packet_in_stream_flag; - char *hostname; /* -h or config hostname */ - char *interface; /* -i or config interface */ - - char *class_file; /* -C or config class_map */ - char *sid_msg_file; /* -S or config sid_map */ - char *gen_msg_file; /* -G or config gen_map */ - char *reference_file; /* -R or config reference_map */ - char *log_dir; /* -l or config log_dir */ - char *orig_log_dir; /* set in case of chroot */ - char *chroot_dir; /* -t or config chroot */ - uint8_t verbose; /* -v */ - uint8_t localtime; - char *bpf_filter; /* config bpf_filter */ - - int thiszone; - - int quiet_flag; - int verbose_flag; - int verbose_bytedump_flag; - int show2hdr_flag; - int char_data_flag; - int data_flag; - int obfuscation_flag; - int alert_on_each_packet_in_stream_flag; + int logtosyslog_flag; + int test_mode_flag; - int logtosyslog_flag; - int test_mode_flag; + int use_utc; + int include_year; - int use_utc; - int include_year; - - int line_buffer_flag; - char nostamp; - - - int user_id; - int group_id; - mode_t file_mask; + int line_buffer_flag; + char nostamp; + int user_id; + int group_id; + mode_t file_mask; /* -h and -B */ #ifdef SUP_IP6 - sfip_t homenet; - sfip_t obfuscation_net; + sfip_t homenet; + sfip_t obfuscation_net; #else - u_long homenet; - u_long netmask; - uint32_t obfuscation_net; - uint32_t obfuscation_mask; + u_long homenet; + u_long netmask; + uint32_t obfuscation_net; + uint32_t obfuscation_mask; #endif #ifdef MPLS @@ -369,40 +356,70 @@ long int mpls_stack_depth; /* --max_mpls_labelchain_len */ #endif - /* batch mode options */ - int batch_mode_flag; - int batch_total_files; - char **batch_filelist; + /* batch mode options */ + int batch_mode_flag; + int batch_total_files; + /* continual mode options */ - int process_new_records_only_flag; - Waldo waldo; - char *archive_dir; - int daemon_flag; - int daemon_restart_flag; + int process_new_records_only_flag; + Waldo waldo; + + int daemon_flag; + int daemon_restart_flag; /* runtime parameters */ char pid_filename[STD_BUF]; char pid_path[STD_BUF]; /* --pid-path or config pidpath */ - - char pidfile_suffix[MAX_PIDFILE_SUFFIX+1]; /* room for a null */ char create_pid_file; char nolock_pid_file; - int done_processing; + int done_processing; int restart_flag; int print_version; int usr_signal; int cant_hup_signal; + unsigned int event_cache_size; + uint8_t verbose; /* -v */ + uint8_t localtime; + +/* Need to be handled by Barnyard2ConfFree() */ + VarEntry *var_table; +#ifdef SUP_IP6 + vartable_t *ip_vartable; +#endif + SigSuppress_list *ssHead; + ClassType *classifications; ReferenceSystemNode *references; - + SigNode *sigHead; /* Signature list Head */ + /* plugin active flags*/ - InputConfig *input_configs; - OutputConfig *output_configs; - + InputConfig *input_configs; + OutputConfig *output_configs; PluginSignalFuncNode *plugin_post_config_funcs; + + char *config_file; /* -c */ + char *config_dir; + char *hostname; /* -h or config hostname */ + char *interface; /* -i or config interface */ + + char *class_file; /* -C or config class_map */ + char *sid_msg_file; /* -S or config sid_map */ + short sidmap_version; /* Set by ReadSidFile () */ + char *gen_msg_file; /* -G or config gen_map */ + + char *reference_file; /* -R or config reference_map */ + char *log_dir; /* -l or config log_dir */ + char *orig_log_dir; /* set in case of chroot */ + char *chroot_dir; /* -t or config chroot */ + + char *bpf_filter; /* config bpf_filter */ + char **batch_filelist; + char *archive_dir; + + Spooler *spooler; /* Used to know if we need to call spoolerClose */ } Barnyard2Config; @@ -414,6 +431,7 @@ uint64_t total_packets; uint64_t total_processed; uint64_t total_unknown; + uint64_t total_suppressed; uint64_t s5tcp1; uint64_t s5tcp2; @@ -553,16 +571,20 @@ extern Barnyard2Config *barnyard2_conf_for_parsing; /* P R O T O T Y P E S ******************************************************/ +Barnyard2Config * Barnyard2ConfNew(void); + int Barnyard2Main(int argc, char *argv[]); int Barnyard2Sleep(unsigned int); +int SignalCheck(void); + void CleanExit(int); void SigCantHupHandler(int signal); void FreeVarList(VarNode *); -Barnyard2Config * Barnyard2ConfNew(void); void Barnyard2ConfFree(Barnyard2Config *); void CleanupPreprocessors(Barnyard2Config *); void CleanupPlugins(Barnyard2Config *); + static INLINE int BcTestMode(void) { return barnyard2_conf->run_mode == RUN_MODE__TEST; @@ -727,5 +749,54 @@ { return barnyard2_conf->mpls_payload_type; } + #endif + +static INLINE short BcSidMapVersion(void) +{ + return barnyard2_conf->sidmap_version; +} + +static INLINE SigNode ** BcGetSigNodeHead(void) +{ + return &barnyard2_conf->sigHead; +} + +static INLINE Barnyard2Config * BcGetConfig(void) +{ + return barnyard2_conf; +} + +static INLINE char * BcGetSourceFile(u_int8_t source_file) +{ + switch(source_file) + { + + case SOURCE_SID_MSG: + return barnyard2_conf->sid_msg_file; + break; + + + case SOURCE_GEN_MSG: + return barnyard2_conf->gen_msg_file; + break; + + default: + return "UKNOWN FILE\n"; + break; + } +} + +static INLINE SigSuppress_list ** BCGetSigSuppressHead(void) +{ + return &barnyard2_conf->ssHead; +} + +static INLINE void SigSuppressCount(void) +{ + pc.total_suppressed++; + return; +} + + #endif /* __BARNYARD2_H__ */ diff -Nru securityonion-barnyard2-20121109/src/debug.h securityonion-barnyard2-20140531/src/debug.h --- securityonion-barnyard2-20121109/src/debug.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/debug.h 2014-02-10 16:34:05.000000000 +0000 @@ -44,20 +44,23 @@ #define DEBUG_VARIABLE "BARNYARD2_DEBUG" -#define DEBUG_ALL 0xffffffff /* 4294967295 */ -#define DEBUG_INIT 0x00000001 /* 1 */ -#define DEBUG_CONFIGRULES 0x00000002 /* 2 */ -#define DEBUG_PLUGIN 0x00000004 /* 4 */ -#define DEBUG_VARS 0x00000010 /* 16 */ -#define DEBUG_LOG 0x00000020 /* 32 */ -#define DEBUG_FLOW 0x00000040 -#define DEBUG_DECODE 0x00000080 -#define DEBUG_DATALINK 0x00000100 -#define DEBUG_INPUT_PLUGIN 0x00000200 -#define DEBUG_OUTPUT_PLUGIN 0x00000400 -#define DEBUG_SPOOLER 0x00000800 -#define DEBUG_MAPS 0x00001000 -#define DEBUG_PATTERN_MATCH 0x00080000 +#define DEBUG_ALL 0xffffffff /* 4294967295 */ +#define DEBUG_INIT 0x00000001 /* 1 */ +#define DEBUG_CONFIGRULES 0x00000002 /* 2 */ +#define DEBUG_PLUGIN 0x00000004 /* 4 */ +#define DEBUG_VARS 0x00000010 /* 16 */ +#define DEBUG_LOG 0x00000020 /* 32 */ +#define DEBUG_FLOW 0x00000040 +#define DEBUG_DECODE 0x00000080 +#define DEBUG_DATALINK 0x00000100 +#define DEBUG_INPUT_PLUGIN 0x00000200 +#define DEBUG_OUTPUT_PLUGIN 0x00000400 +#define DEBUG_SPOOLER 0x00000800 +#define DEBUG_MAPS 0x00001000 +#define DEBUG_MAPS_DEEP 0x00002000 +#define DEBUG_PATTERN_MATCH 0x00080000 +#define DEBUG_SID_SUPPRESS 0x00100000 +#define DEBUG_SID_SUPPRESS_PARSE 0x00200000 void DebugMessageFunc(int dbg,char *fmt, ...); #ifdef HAVE_WCHAR_H diff -Nru securityonion-barnyard2-20121109/src/input-plugins/spi_unified2.c securityonion-barnyard2-20140531/src/input-plugins/spi_unified2.c --- securityonion-barnyard2-20121109/src/input-plugins/spi_unified2.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/input-plugins/spi_unified2.c 2014-02-10 16:34:05.000000000 +0000 @@ -1,6 +1,6 @@ /* ** -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** ** 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 @@ -236,13 +236,16 @@ void Unified2CleanExitFunc(int signal, void *arg) { DEBUG_WRAP(DebugMessage(DEBUG_LOG,"Unified2CleanExitFunc\n");); + return; } void Unified2RestartFunc(int signal, void *arg) { DEBUG_WRAP(DebugMessage(DEBUG_LOG,"Unified2RestartFunc\n");); + return; } + #ifdef DEBUG void Unified2PrintEventCommonRecord(Unified2EventCommon *evt) { diff -Nru securityonion-barnyard2-20121109/src/input-plugins/spi_unified2.h securityonion-barnyard2-20140531/src/input-plugins/spi_unified2.h --- securityonion-barnyard2-20121109/src/input-plugins/spi_unified2.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/input-plugins/spi_unified2.h 2014-02-10 16:34:05.000000000 +0000 @@ -1,6 +1,6 @@ /* ** -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** ** 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 diff -Nru securityonion-barnyard2-20121109/src/log_text.c securityonion-barnyard2-20140531/src/log_text.c --- securityonion-barnyard2-20121109/src/log_text.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/log_text.c 2014-02-10 16:34:05.000000000 +0000 @@ -92,7 +92,7 @@ else { TextLog_Print( - log, "[Classification ID: %s] [Priority ID: %d] ", + log, "[Classification ID: %d] [Priority ID: %d] ", classification_id, priority_id ); } diff -Nru securityonion-barnyard2-20121109/src/map.c securityonion-barnyard2-20140531/src/map.c --- securityonion-barnyard2-20121109/src/map.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/map.c 2014-02-10 16:34:05.000000000 +0000 @@ -1,6 +1,6 @@ /* ** -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** ** 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 @@ -122,7 +122,7 @@ char **toks, *system, *id; int num_toks; - DEBUG_WRAP(DebugMessage(DEBUG_MAPS, "map: parsing reference %s\n", args);); + DEBUG_WRAP(DebugMessage(DEBUG_MAPS_DEEP, "map: parsing reference %s\n", args);); /* 2 tokens: system, id */ toks = mSplit(args, ",", 2, &num_toks, 0); @@ -319,6 +319,28 @@ return node; } +ClassType * ClassTypeLookupByTypePure(ClassType *node, char *type) +{ + + if( (node == NULL) || + (type == NULL)) + { + return NULL; + } + + + while (node != NULL) + { + if (strcasecmp(type, node->type) == 0) + return node; + + node = node->next; + } + + return NULL; +} + + /* NOTE: This lookup can only be done during parse time */ /* Wut ...*/ ClassType * ClassTypeLookupById(Barnyard2Config *bc, int id) @@ -439,7 +461,7 @@ bc->classifications = NULL; } -int ReadClassificationFile(Barnyard2Config *bc, const char *file) +int ReadClassificationFile(Barnyard2Config *bc) { FILE *fd; char buf[BUFFER_SIZE]; @@ -448,27 +470,33 @@ int num_toks; int count = 0; + if( (bc == NULL) || + (bc->class_file == NULL)) + { + /* XXX */ + return 1; + } - DEBUG_WRAP(DebugMessage(DEBUG_MAPS, "map: opening file %s\n", file);); + DEBUG_WRAP(DebugMessage(DEBUG_MAPS, "map: opening file %s\n", bc->class_file);); - if((fd = fopen(file, "r")) == NULL) + if((fd = fopen(bc->class_file, "r")) == NULL) { LogMessage("ERROR: Unable to open Classification file '%s' (%s)\n", - file, strerror(errno)); + bc->class_file, strerror(errno)); return -1; } - + memset(buf, 0, BUFFER_SIZE); /* bzero() deprecated, replaced with memset() */ while ( fgets(buf, BUFFER_SIZE, fd) != NULL ) { index = buf; - + /* advance through any whitespace at the beginning of the line */ while (*index == ' ' || *index == '\t') index++; - + /* if it's not a comment or a , send it to the parser */ if ( (*index != '#') && (*index != 0x0a) && (index != NULL) ) { @@ -487,6 +515,7 @@ if(fd != NULL) fclose(fd); + return 0; } @@ -494,41 +523,227 @@ /************************* Sid/Gid Map Implementation *************************/ -SigNode *sigTypes = NULL; -int ReadSidFile(Barnyard2Config *bc, const char *file) + +/* + Classification parsing should happen before signature parsing, + so classification resolution should be done at signature initialization. + + But at the moment this function was written classification could be parsed before + signature or signature before classification, thus leading to possible unresolvability. + + hence. +*/ +int SignatureResolveClassification(ClassType *class,SigNode *sig,char *sid_msg_file,char *classification_file) +{ + + ClassType *found = NULL; + + if( (class == NULL) || + (sig == NULL) || + (sid_msg_file == NULL) || + (classification_file == NULL)) + { + DEBUG_WRAP(DebugMessage(DEBUG_MAPS,"ERROR [%s()]: Failed class ptr [0x%x], sig ptr [0x%x], " + "sig_literal ptr [0x%x], sig_map_file ptr [0x%x], classification_file ptr [0x%x] \n", + __FUNCTION__, + class, + sig, + sig->classLiteral, + sid_msg_file, + classification_file);); + return 1; + } + + while(sig != NULL) + { + found = NULL; + + if(sig->classLiteral) + { + if(strncasecmp(sig->classLiteral,"NOCLASS",strlen("NOCLASS")) == 0) + { + DEBUG_WRAP(DebugMessage(DEBUG_MAPS, + "\nINFO: [%s()],In File [%s] \n" + "Signature [gid: %d] [sid : %d] [revision: %d] message [%s] has no classification [%s] defined, signature priority is [%d]\n\n", + __FUNCTION__, + BcGetSourceFile(sig->source_file), + sig->generator, + sig->id, + sig->rev, + sig->msg, + sig->classLiteral, + sig->priority);); + + } + else if( (found = ClassTypeLookupByTypePure(class,sig->classLiteral)) == NULL) + { + sig->class_id = 0; + } + else + { + sig->class_id = found->id; + } + } + else + { + if(sig->class_id == 0) + { + + DEBUG_WRAP(DebugMessage(DEBUG_MAPS, + "\nINFO: [%s()],In file [%s]\n" + "Signature [gid: %d] [sid : %d] [revision: %d] message [%s] has no classification literal defined, signature priority is [%d]\n\n", + __FUNCTION__, + BcGetSourceFile(sig->source_file), + sig->generator, + sig->id, + sig->rev, + sig->msg, + sig->priority);); + } + } + + if(sig->priority == 0) + { + if(found) + sig->priority = found->priority; + } + else + { + if( (found) && + (found->priority != sig->priority)) + { + DEBUG_WRAP(DebugMessage(DEBUG_MAPS, + "\nINFO: [%s()],In file [%s]\n" + "Signature [gid: %d] [sid : %d] [revision: %d] message [%s] has classification [%s] priority [%d]\n" + "The priority define by the rule will overwride classification [%s] priority [%d] defined in [%s] using [%d] as priority \n\n", + __FUNCTION__, + BcGetSourceFile(sig->source_file), + sig->generator, + sig->id, + sig->rev, + sig->msg, + sig->classLiteral, + sig->priority, + found->type, + found->priority, + classification_file, + sig->priority);); + } + } + + if(sig->classLiteral) + { + free(sig->classLiteral); + sig->classLiteral = NULL; + } + + sig = sig->next; + } + + return 0; +} + +u_int32_t SigLookup(SigNode *head,u_int32_t gid,u_int32_t sid,u_int8_t source_file,SigNode **r_node) +{ + if( (head == NULL) || + (r_node == NULL)) + { + return 0; + } + + while(head != NULL) + { + + if(head->source_file == source_file) + { + if( (head->generator == gid) && + (head->id == sid)) + { + *r_node = head; + return 1; + } + } + + head = head->next; + } + + + *r_node = NULL; + return 0; + +} + + + +int ReadSidFile(Barnyard2Config *bc) { FILE *fd; char buf[BUFFER_SIZE]; char *index; int count = 0; - DEBUG_WRAP(DebugMessage(DEBUG_MAPS, "map: opening file %s\n", file);); + if(bc == NULL) + { + return 1; + } - if( (fd = fopen(file, "r")) == NULL ) + if(bc->sid_msg_file == NULL) { - LogMessage("ERROR: Unable to open SID file '%s' (%s)\n", file, - strerror(errno)); - - return -1; + return 0; } + DEBUG_WRAP(DebugMessage(DEBUG_MAPS, "[%s()] map: opening file %s\n", + __FUNCTION__, + bc->sid_msg_file);); + + if( (fd = fopen(bc->sid_msg_file, "r")) == NULL ) + { + LogMessage("ERROR: Unable to open SID file '%s' (%s)\n", + bc->sid_msg_file, + strerror(errno)); + return 1; + } + memset(buf, 0, BUFFER_SIZE); /* bzero() deprecated, replaced by memset() */ while(fgets(buf, BUFFER_SIZE, fd) != NULL) { index = buf; - + /* advance through any whitespace at the beginning of the line */ while(*index == ' ' || *index == '\t') index++; - - /* if it's not a comment or a , send it to the parser */ - if((*index != '#') && (*index != 0x0a) && (index != NULL)) - { - ParseSidMapLine(bc, index); - count++; - } + + /* Check if we are dealing with a sidv2 file */ + if( (count == 0) && + (bc->sidmap_version == 0)) + { + if(*index == '#') + { + index++; + if(strncasecmp(index,SIDMAPV1STRING,strlen(SIDMAPV1STRING)) == 0) + { + bc->sidmap_version=SIDMAPV1; + } + else if( strncasecmp(index,SIDMAPV2STRING,strlen(SIDMAPV2STRING)) == 0) + { + bc->sidmap_version=SIDMAPV2; + continue; + } + } + else + { + bc->sidmap_version=SIDMAPV1; + } + } + + /* if it's not a comment or a , send it to the parser */ + if((*index != '#') && (*index != 0x0a) && (index != NULL)) + { + ParseSidMapLine(bc, index); + count++; + } } //LogMessage("Read [%u] signature \n",count); @@ -536,125 +751,261 @@ if(fd != NULL) fclose(fd); - return count; + return 0; } -void DeleteSigNodes() -{ - SigNode *sn = NULL, *snn = NULL; - ReferenceNode *rn = NULL, *rnn = NULL; - sn = sigTypes; - - while(sn != NULL) - { - snn = sn->next; - - /* free the message */ - if(sn->msg) - free(sn->msg); - - /* free the references (NOT the reference systems) */ - if(sn->refs) - { - rn = sn->refs; - while(rn != NULL) - { - rnn = rn->next; - - /* free the id */ - if(rn->id) - free(rn->id); - - /* free the reference node */ - free(rn); - - rn = rnn; - } - } - - /* free the signature node */ - free(sigTypes); - - sigTypes = snn; - } - - sigTypes = NULL; -} void ParseSidMapLine(Barnyard2Config *bc, char *data) { - char **toks; - char *idx; - int num_toks; - int i; - SigNode *sn; - toks = mSplitSpecial(data, "||", 32, &num_toks, '\0'); + SigNode *sn = NULL; + SigNode t_sn = {0}; - if(num_toks < 2) + char **toks = NULL; + char *idx = NULL; + + int num_toks = 0; + int min_toks = 0; + int i = 0; + + toks = mSplitSpecial(data, "||", 32, &num_toks, '\0'); + + switch(bc->sidmap_version) + { + case SIDMAPV1: + min_toks = 2; + break; + + case SIDMAPV2: + min_toks = 6; + break; + + default: + FatalError("[%s()]: Unknown sidmap file version [%d] \n", + __FUNCTION__, + bc->sidmap_version); + } + + if(num_toks < min_toks) { LogMessage("WARNING: Ignoring bad line in SID file: '%s'\n", data); } else { - DEBUG_WRAP(DebugMessage(DEBUG_MAPS, "map: creating new node\n");); + DEBUG_WRAP(DebugMessage(DEBUG_MAPS_DEEP, "map: creating new node\n");); - sn = CreateSigNode(&sigTypes); - + for(i = 0; igenerator = 1; - sn->id = strtoul(idx, NULL, 10); - break; + if( (idx == NULL) || + (strlen(idx) == 0)) + { + LogMessage("\n"); + FatalError("[%s()], File [%s],\nError in map definition [%s] for value [%s] \n\n", + __FUNCTION__, + bc->sid_msg_file, + data, + idx); + } + + switch(bc->sidmap_version) + { + case SIDMAPV1: + switch(i) + { + case 0: /* sid */ + t_sn.generator = 1; + if( (t_sn.id = strtoul(idx, NULL, 10)) == ULONG_MAX) + { + FatalError("[%s()], error converting integer [%s] for line [%s] \n", + __FUNCTION__, + strerror(errno), + data); + } + break; + case 1: /* msg */ - sn->msg = SnortStrdup(idx); + if( (t_sn.msg = SnortStrdup(idx)) == NULL) + { + FatalError("[%s()], error converting string for line [%s] \n", + __FUNCTION__, + data); + } break; - + default: /* reference data */ - ParseReference(bc, idx, sn); + ParseReference(bc, idx, &t_sn); break; - } + } + break; + + case SIDMAPV2: + + switch(i) + { + + case 0: /*gid */ + if( (t_sn.generator = strtoul(idx,NULL,10)) == ULONG_MAX) + { + FatalError("[%s()], error converting integer [%s] for line [%s] \n", + __FUNCTION__, + strerror(errno), + data); + } + + break; + + case 1: /* sid */ + if( (t_sn.id = strtoul(idx, NULL, 10)) == ULONG_MAX) + { + FatalError("[%s()], error converting integer [%s] for line [%s] \n", + __FUNCTION__, + strerror(errno), + data); + } + break; + + case 2: /* revision */ + if( (t_sn.rev = strtoul(idx, NULL, 10)) == ULONG_MAX) + { + FatalError("[%s()], error converting integer [%s] for line [%s] \n", + __FUNCTION__, + strerror(errno), + data); + } + break; + + case 3: /* classification */ + if( (t_sn.classLiteral = SnortStrdup(idx)) == NULL) + { + FatalError("[%s()], error converting string for line [%s] \n", + __FUNCTION__, + data); + } + break; + + case 4: /* priority */ + + if( (t_sn.priority = strtoul(idx, NULL, 10)) == ULONG_MAX) + { + FatalError("[%s()], error converting integer [%s] for line [%s] \n", + __FUNCTION__, + strerror(errno), + data); + } + break; + + case 5: /* msg */ + if( (t_sn.msg = SnortStrdup(idx)) == NULL) + { + FatalError("[%s()], error converting string for line [%s] \n", + __FUNCTION__, + data); + } + break; + + default: /* reference data */ + ParseReference(bc, idx, &t_sn); + break; + } + break; + } + } + } + + sn = (SigNode *)*BcGetSigNodeHead(); + + /* Look if we have a brother inserted from sid map file */ + sig_lookup_continue: + if(SigLookup(sn,t_sn.generator,t_sn.id,SOURCE_SID_MSG,&sn)) + { + if(t_sn.rev == sn->rev) + { + DEBUG_WRAP(DebugMessage(DEBUG_MAPS, + "[%s()],Item not inserted [ gid:[%d] sid:[%d] rev:[%d] msg:[%s] class:[%d] prio:[%d] ] in signature list \n" + "\t Item already present [ gid:[%d] sid:[%d] rev:[%d] msg:[%s] class:[%d] prio:[%d] ] \n", + __FUNCTION__, + t_sn.generator,t_sn.id,t_sn.rev,t_sn.msg,t_sn.class_id,t_sn.priority, /* revision,class_id and priority are hardcoded for generator */ + sn->generator,sn->id,sn->rev,sn->msg,sn->class_id,sn->priority);); + } + else + { + /* Continue to traverse the list to be sure */ + sn = sn->next; + goto sig_lookup_continue; + } + } + else + { + if( (sn = CreateSigNode(BcGetSigNodeHead(),SOURCE_SID_MSG)) == NULL) + { + FatalError("[%s()], CreateSigNode() returned a NULL node, bailing \n", + __FUNCTION__); } + + memcpy(sn,&t_sn,sizeof(SigNode)); + + sn->source_file = SOURCE_SID_MSG; } mSplitFree(&toks, num_toks); - + return; } SigNode *GetSigByGidSid(u_int32_t gid, u_int32_t sid,u_int32_t revision) { /* set temp node pointer to the Sid map list head */ - SigNode *sn = sigTypes; - - /* a snort general rule (gid=1) and a snort dynamic rule (gid=3) use the */ - /* the same sids and thus can be considered one in the same. */ - if (gid == 3) - gid = 1; + SigNode **sh = BcGetSigNodeHead(); + SigNode *sn = *sh; - /* find any existing Snort ID's that match */ - while (sn != NULL) + switch(BcSidMapVersion()) { - if (sn->generator == gid && sn->id == sid) + case SIDMAPV1: + /* The comment below is not true anymore with sidmapv2 files generated by pulled pork */ + + /* a snort general rule (gid=1) and a snort dynamic rule (gid=3) use the */ + /* the same sids and thus can be considered one in the same. */ + if (gid == 3) + { + gid = 1; + } + + /* find any existing Snort ID's that match */ + while (sn != NULL) + { + if (sn->generator == gid && sn->id == sid) + { + return sn; + } + + sn = sn->next; + } + break; + + case SIDMAPV2: + while (sn != NULL) { - return sn; + if ( (sn->generator == gid) && + (sn->id == sid) && + (sn->rev == revision)) + { + return sn; + } + + sn = sn->next; } - - sn = sn->next; + break; } - - /* create a default message since we didn't find any match */ - sn = CreateSigNode(&sigTypes); + + /* create a default message since we didn't find any match */ + sn = CreateSigNode(BcGetSigNodeHead(),SOURCE_GEN_RUNTIME); sn->generator = gid; sn->id = sid; sn->rev = revision; @@ -664,24 +1015,28 @@ return sn; } -SigNode *CreateSigNode(SigNode **head) -{ - SigNode *sn; + +SigNode *CreateSigNode(SigNode **head,const u_int8_t source_file) +{ + SigNode *sn = NULL; + if (*head == NULL) { *head = (SigNode *) SnortAlloc(sizeof(SigNode)); + sn = *head; + sn->source_file = source_file; return *head; } else { sn = *head; - + while (sn->next != NULL) sn = sn->next; sn->next = (SigNode *) SnortAlloc(sizeof(SigNode)); - + sn->next->source_file = source_file; return sn->next; } @@ -689,22 +1044,31 @@ return NULL; } -int ReadGenFile(Barnyard2Config *bc, const char *file) +int ReadGenFile(Barnyard2Config *bc) { FILE *fd; char buf[BUFFER_SIZE]; char *index; - int count = 0; + int count = 0; - - if ( (fd = fopen(file, "r")) == NULL ) + if(bc->gen_msg_file == NULL) { - LogMessage("ERROR: Unable to open Generator file \"%s\": %s\n", file, - strerror(errno)); - - return -1; + return 0; } + + DEBUG_WRAP(DebugMessage(DEBUG_MAPS, "[%s()] map: opening file %s\n", + __FUNCTION__, + bc->gen_msg_file);); + if ( (fd = fopen(bc->gen_msg_file, "r")) == NULL ) + { + LogMessage("ERROR: Unable to open Generator file \"%s\": %s\n", + bc->gen_msg_file, + strerror(errno)); + + return 1; + } + memset(buf, 0, BUFFER_SIZE); /* bzero() deprecated, replaced by memset() */ while( fgets(buf, BUFFER_SIZE, fd) != NULL ) @@ -722,24 +1086,27 @@ count++; } } - + //LogMessage("Read [%u] gen \n",count); - - if(fd != NULL) - fclose(fd); - - return 0; + + if(fd != NULL) + fclose(fd); + + return 0; } void ParseGenMapLine(char *data) { - char **toks; - int num_toks; - int i; - char *idx; - SigNode *sn; + char **toks = NULL; + char *idx = NULL; + + SigNode *sn = NULL; + SigNode t_sn = {0}; /* used for temp storage before lookup */ + int num_toks = 0; + int i = 0; + toks = mSplitSpecial(data, "||", 32, &num_toks, '\0'); if(num_toks < 2) @@ -748,28 +1115,41 @@ return; } - sn = CreateSigNode(&sigTypes); - for(i=0; igenerator = strtoul(idx, NULL, 10); + if( (t_sn.generator = strtoul(idx, NULL, 10)) == ULONG_MAX) + { + FatalError("[%s()], error converting integer [%s] for line [%s] \n", + __FUNCTION__, + strerror(errno), + data); + } break; case 1: /* sid */ - //TODO: error checking on conversion - sn->id = strtoul(idx, NULL, 10); + if( (t_sn.id = strtoul(idx, NULL, 10)) == ULONG_MAX) + { + FatalError("[%s()], error converting integer [%s] for line [%s] \n", + __FUNCTION__, + strerror(errno), + data); + } break; case 2: /* msg */ - sn->msg = SnortStrdup(idx); + if( (t_sn.msg = SnortStrdup(idx)) == NULL) + { + FatalError("[%s()], error converting string for line [%s] \n", + __FUNCTION__, + data); + } break; default: @@ -777,5 +1157,220 @@ } } + switch(BcSidMapVersion()) + { + case SIDMAPV1: + t_sn.rev = 1; + t_sn.priority = 0; + t_sn.classLiteral = strdup("NOCLASS"); /* default */ + t_sn.class_id = 0; + break; + + case SIDMAPV2: + /* + Generators have pre-defined revision,classification and priority + */ + t_sn.rev = 1; + t_sn.classLiteral = strdup("NOCLASS"); /* default */ + t_sn.class_id = 0; + t_sn.priority = 3; + break; + } + + /* Look if we have a brother inserted from sid map file */ + if(SigLookup((SigNode *)*BcGetSigNodeHead(),t_sn.generator,t_sn.id,SOURCE_SID_MSG,&sn)) + { + + DEBUG_WRAP(DebugMessage(DEBUG_MAPS, + "[%s()],Item not inserted [ gid:[%d] sid:[%d] rev:[%d] msg:[%s] class:[%d] prio:[%d] ] in signature list \n" + "\t Item already present [ gid:[%d] sid:[%d] rev:[%d] msg:[%s] class:[%d] prio:[%d] ] \n", + __FUNCTION__, + t_sn.generator,t_sn.id,t_sn.rev,t_sn.msg,t_sn.class_id,t_sn.priority, /* revision,class_id and priority are hardcoded for generator */ + sn->generator,sn->id,sn->rev,sn->msg,sn->class_id,sn->priority);); + + /* + This is a quick hack for now to put sweet gid-msg.map messages up there + */ + if(t_sn.msg) + { + DEBUG_WRAP(DebugMessage(DEBUG_MAPS,"[%s()], swapping message [%s] for [%s] \n", + __FUNCTION__, + sn->msg, + t_sn.msg);); + free(sn->msg); + sn->msg = NULL; + sn->msg = t_sn.msg; + t_sn.msg = NULL; + } + + if(t_sn.classLiteral) + { + free(t_sn.classLiteral); + t_sn.classLiteral = NULL; + } + + DEBUG_WRAP(DebugMessage(DEBUG_MAPS,"\n");); + + } + else + { + if(SigLookup((SigNode *)*BcGetSigNodeHead(),t_sn.generator,t_sn.id,SOURCE_GEN_MSG,&sn) == 0) + { + if( (sn = CreateSigNode(BcGetSigNodeHead(),SOURCE_GEN_MSG)) == NULL) + { + FatalError("[%s()], CreateSigNode() returned a NULL node, bailing \n", + __FUNCTION__); + } + + memcpy(sn,&t_sn,sizeof(SigNode)); + + sn->source_file = SOURCE_GEN_MSG; + } + else + { + + DEBUG_WRAP(DebugMessage(DEBUG_MAPS, + "[%s()],Item not inserted [ gid:[%d] sid:[%d] rev:[%d] msg:[%s] class:[%d] prio:[%d] ] in signature list \n" + "\t Item already present [ gid:[%d] sid:[%d] rev:[%d] msg:[%s] class:[%d] prio:[%d] ] \n\n", + __FUNCTION__, + t_sn.generator,t_sn.id,t_sn.rev,t_sn.msg,t_sn.class_id,t_sn.priority, /* revision,class_id and priority are hardcoded for generator */ + sn->generator,sn->id,sn->rev,sn->msg,sn->class_id,sn->priority);); + + if(t_sn.msg) + { + free(t_sn.msg); + t_sn.msg = NULL; + } + + if(t_sn.classLiteral) + { + free(t_sn.classLiteral); + t_sn.classLiteral = NULL; + } + + } + } + mSplitFree(&toks, num_toks); + + return; +} + +/* + * Some destructors + * + * + */ + +void FreeSigNodes(SigNode **sigHead) +{ + SigNode *sn = NULL, *snn = NULL; + ReferenceNode *rn = NULL, *rnn = NULL; + sn = *sigHead; + + while(sn != NULL) + { + snn = sn->next; + + /* free the message */ + if(sn->msg) + { + free(sn->msg); + sn->msg = NULL; + } + + if(sn->classLiteral) + { + free(sn->classLiteral); + sn->classLiteral = NULL; + } + + /* free the references (NOT the reference systems) */ + if(sn->refs) + { + rn = sn->refs; + while(rn != NULL) + { + rnn = rn->next; + + /* free the id */ + if(rn->id) + free(rn->id); + + /* free the reference node */ + free(rn); + + rn = rnn; + } + } + + /* free the signature node */ + free(sn); + sn = NULL; + sn = snn; + } + + *sigHead = NULL; + + return; +} + +void FreeClassifications(ClassType **i_head) +{ + ClassType *head = *i_head; + + while (head != NULL) + { + ClassType *tmp = head; + + head = head->next; + + if (tmp->name != NULL) + free(tmp->name); + + if (tmp->type != NULL) + free(tmp->type); + + free(tmp); + } + + *i_head = NULL; +} + + +void FreeReferences(ReferenceSystemNode **i_head) +{ + ReferenceSystemNode *head = *i_head; + + while (head != NULL) + { + ReferenceSystemNode *tmp = head; + + head = head->next; + + if (tmp->name != NULL) + free(tmp->name); + + if (tmp->url != NULL) + free(tmp->url); + + free(tmp); + } + + *i_head = NULL; +} + +void FreeSigSuppression(SigSuppress_list **i_head) +{ + SigSuppress_list *head = *i_head; + + while(head != NULL) + { + SigSuppress_list *next = head->next; + + free(head); + head = next; + } + + *i_head = NULL; } diff -Nru securityonion-barnyard2-20121109/src/map.h securityonion-barnyard2-20140531/src/map.h --- securityonion-barnyard2-20121109/src/map.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/map.h 2014-02-10 16:34:05.000000000 +0000 @@ -1,6 +1,6 @@ /* ** -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** ** 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 @@ -44,7 +44,6 @@ #include #include - #include "sf_types.h" #define BUGTRAQ_URL_HEAD "http://www.securityfocus.com/bid/" @@ -56,6 +55,11 @@ #define BUFFER_SIZE 1024 + +#define SOURCE_SID_MSG 0x0001 +#define SOURCE_GEN_MSG 0x0002 +#define SOURCE_GEN_RUNTIME 0x0004 + struct _Barnyard2Config; /* this contains a list of the URLs for various reference systems */ @@ -67,15 +71,6 @@ } ReferenceSystemNode; -ReferenceSystemNode * ReferenceSystemAdd(ReferenceSystemNode **, char *, char *); -ReferenceSystemNode * ReferenceSystemLookup(ReferenceSystemNode *, char *); - -int ReadReferenceFile(struct _Barnyard2Config *, const char *); -void ParseReferenceSystemConfig(struct _Barnyard2Config *, char *args); - -void DeleteReferenceSystems(struct _Barnyard2Config *); - - typedef struct _ReferenceNode { char *id; @@ -83,9 +78,6 @@ struct _ReferenceNode *next; } ReferenceNode; -ReferenceNode * AddReference(struct _Barnyard2Config *, ReferenceNode **, char *, char *); -void DeleteReferences(struct _Barnyard2Config *); - typedef struct _ClassType { @@ -98,42 +90,66 @@ } ClassType; - typedef struct _SigNode { + struct _SigNode *next; uint32_t generator; /* generator ID */ - uint32_t id; /* Snort ID */ + uint32_t id; /* Snort ID */ uint32_t rev; /* revision (for future expansion) */ uint32_t class_id; - uint32_t priority; + uint32_t priority; + u_int8_t source_file; /* where was it parsed from */ + char *classLiteral; /* sid-msg.map v2 type only */ char *msg; /* messages */ - ClassType *classType; ReferenceNode *refs; /* references (eg bugtraq) */ - struct _SigNode *next; } SigNode; +#define SS_SINGLE 0x0001 +#define SS_RANGE 0x0002 -ClassType * ClassTypeLookupByType(struct _Barnyard2Config *, char *); -ClassType * ClassTypeLookupById(struct _Barnyard2Config *, int); +typedef struct _SigSuppress_list +{ + u_int8_t ss_type; /* Single or Range */ + u_int8_t flag; /* Flagged for deletion */ + unsigned long gid; /* Generator id */ + unsigned long ss_min; /* VAL for SS_SINGLE, MIN VAL for RANGE */ + unsigned long ss_max; /* VAL for SS_SINGLE, MAX VAL for RANGE */ + struct _SigSuppress_list *next; +} SigSuppress_list; -int ReadClassificationFile(struct _Barnyard2Config *, const char *); -void ParseClassificationConfig(struct _Barnyard2Config *, char *args); -void DeleteClassTypes(); + +ReferenceSystemNode * ReferenceSystemAdd(ReferenceSystemNode **, char *, char *); +ReferenceSystemNode * ReferenceSystemLookup(ReferenceSystemNode *, char *); +ReferenceNode * AddReference(struct _Barnyard2Config *, ReferenceNode **, char *, char *); SigNode *GetSigByGidSid(uint32_t, uint32_t, uint32_t); +SigNode *CreateSigNode(SigNode **,u_int8_t); -int ReadSidFile(struct _Barnyard2Config *, const char *); -void ParseSidMapLine(struct _Barnyard2Config *, char *); +ClassType * ClassTypeLookupByType(struct _Barnyard2Config *, char *); +ClassType * ClassTypeLookupById(struct _Barnyard2Config *, int); -int ReadGenFile(struct _Barnyard2Config *, const char *); -void ParseGenMapLine(char *); +int ReadReferenceFile(struct _Barnyard2Config *, const char *); +int ReadClassificationFile(struct _Barnyard2Config *); +int ReadSidFile(struct _Barnyard2Config *); +int ReadGenFile(struct _Barnyard2Config *); +int SignatureResolveClassification(ClassType *class,SigNode *sig,char *sid_map_file,char *classification_file); + +void DeleteReferenceSystems(struct _Barnyard2Config *); +void DeleteReferences(struct _Barnyard2Config *); -void DeleteSigNodes(); +void ParseReferenceSystemConfig(struct _Barnyard2Config *, char *args); +void ParseClassificationConfig(struct _Barnyard2Config *, char *args); +void ParseSidMapLine(struct _Barnyard2Config *, char *); +void ParseGenMapLine(char *); -SigNode *CreateSigNode(SigNode **); +/* Destructors */ +void FreeSigNodes(SigNode **); +void FreeClassifications(ClassType **); +void FreeReferences(ReferenceSystemNode **); +void FreeSigSuppression(SigSuppress_list **); #endif /* __MAP_H__ */ diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_alert_cef.c securityonion-barnyard2-20140531/src/output-plugins/spo_alert_cef.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_alert_cef.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_alert_cef.c 2014-02-10 16:34:05.000000000 +0000 @@ -572,6 +572,8 @@ /* free memory from SyslogData */ if(data) free(data); + + closelog(); } void AlertCEFRestart(int signal, void *arg) @@ -581,5 +583,7 @@ /* free memory from SyslogData */ if(data) free(data); + + closelog(); } diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_alert_csv.c securityonion-barnyard2-20140531/src/output-plugins/spo_alert_csv.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_alert_csv.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_alert_csv.c 2014-02-10 16:34:05.000000000 +0000 @@ -533,6 +533,29 @@ TextLog_Print(log, "%s", tcpFlags); } } + else if(!strncasecmp("interface",type,strlen("interface"))) + { + if( barnyard2_conf->interface ) + { + TextLog_Print(log, "%s", barnyard2_conf->interface); + } + else + { + TextLog_Print(log, "%s", "by2_no_interface_configured"); + } + } + else if(!strncasecmp("hostname",type,strlen("hostname"))) + { + if( barnyard2_conf->hostname) + { + TextLog_Print(log, "%s", barnyard2_conf->hostname); + } + else + { + TextLog_Print(log, "%s", "by2_no_hostname_configured"); + } + } + DEBUG_WRAP(DebugMessage(DEBUG_LOG, "WOOT!\n");); diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_alert_fast.c securityonion-barnyard2-20140531/src/output-plugins/spo_alert_fast.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_alert_fast.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_alert_fast.c 2014-02-10 16:34:05.000000000 +0000 @@ -408,10 +408,17 @@ { SpoAlertFastData *data = (SpoAlertFastData *)arg; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "%s\n", msg);); - + /*free memory from SpoAlertFastData */ - if ( data->log ) TextLog_Term(data->log); - free(data); + if ( data->log ) + { + TextLog_Term(data->log); + } + + if(data) + free(data); + + return; } static void AlertFastCleanExitFunc(int signal, void *arg) diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_alert_full.c securityonion-barnyard2-20140531/src/output-plugins/spo_alert_full.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_alert_full.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_alert_full.c 2014-02-10 16:34:05.000000000 +0000 @@ -329,8 +329,15 @@ DEBUG_WRAP(DebugMessage(DEBUG_LOG, "%s\n", msg);); /* free memory from SpoAlertFullData */ - if ( data->log ) TextLog_Term(data->log); - free(data); + if ( data->log ) + { + TextLog_Term(data->log); + } + + if(data) + free(data); + + return; } static void AlertFullCleanExit(int signal, void *arg) diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_alert_fwsam.c securityonion-barnyard2-20140531/src/output-plugins/spo_alert_fwsam.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_alert_fwsam.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_alert_fwsam.c 2014-02-10 16:34:05.000000000 +0000 @@ -895,6 +895,7 @@ * unlike inet_ntoa which keeps only one. This is used for (s)printf's were two IP * addresses are printed. */ +/* char *inettoa(unsigned long ip) { struct in_addr ips; @@ -906,6 +907,7 @@ strncpy(addr[toggle],inet_ntoa(ips),18); return addr[toggle]; } +*/ #endif diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_alert_prelude.c securityonion-barnyard2-20140531/src/output-plugins/spo_alert_prelude.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_alert_prelude.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_alert_prelude.c 2014-02-10 16:34:05.000000000 +0000 @@ -687,16 +687,16 @@ static void snort_alert_prelude_clean_exit(int signal, void *data) { - /* - * A Snort sensor reporting to Prelude shall never go offline, - * which is why we use PRELUDE_CLIENT_EXIT_STATUS_FAILURE. - */ - prelude_client_destroy(data, PRELUDE_CLIENT_EXIT_STATUS_FAILURE); - - /* - * Free libprelude relevant data and synchronize asynchronous thread. - */ - prelude_deinit(); + /* + * A Snort sensor reporting to Prelude shall never go offline, + * which is why we use PRELUDE_CLIENT_EXIT_STATUS_FAILURE. + */ + prelude_client_destroy(data, PRELUDE_CLIENT_EXIT_STATUS_FAILURE); + + /* + * Free libprelude relevant data and synchronize asynchronous thread. + */ + prelude_deinit(); } diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_alert_syslog.c securityonion-barnyard2-20140531/src/output-plugins/spo_alert_syslog.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_alert_syslog.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_alert_syslog.c 2014-02-10 16:34:05.000000000 +0000 @@ -659,6 +659,8 @@ /* free memory from SyslogData */ if(data) free(data); + + closelog(); } void AlertSyslogRestart(int signal, void *arg) @@ -668,4 +670,7 @@ /* free memory from SyslogData */ if(data) free(data); + + + closelog(); } diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_alert_unixsock.c securityonion-barnyard2-20140531/src/output-plugins/spo_alert_unixsock.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_alert_unixsock.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_alert_unixsock.c 2014-02-10 16:34:05.000000000 +0000 @@ -193,10 +193,14 @@ break; } } - if ( !filename ) filename = UNSOCK_FILE; + + if ( !filename ) + { + filename = strdup(UNSOCK_FILE); + } data->filename = ProcessFileOption(barnyard2_conf_for_parsing, filename); - + mSplitFree(&toks, num_toks); DEBUG_WRAP(DebugMessage( @@ -375,6 +379,17 @@ SpoAlertUnixSockData *data = (SpoAlertUnixSockData *)arg; DEBUG_WRAP(DebugMessage(DEBUG_LOG,"AlertUnixSockCleanExitFunc\n");); CloseAlertSock(data); + + if(data->filename) + { + free(data->filename); + } + + if(data) + { + free(data); + } + } void AlertUnixSockRestart(int signal, void *arg) @@ -382,6 +397,17 @@ SpoAlertUnixSockData *data = (SpoAlertUnixSockData *)arg; DEBUG_WRAP(DebugMessage(DEBUG_LOG,"AlertUnixSockRestartFunc\n");); CloseAlertSock(data); + + if(data->filename) + { + free(data->filename); + } + + if(data) + { + free(data); + } + } void CloseAlertSock(SpoAlertUnixSockData *data) diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_database.c securityonion-barnyard2-20140531/src/output-plugins/spo_database.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_database.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_database.c 2014-02-10 16:34:05.000000000 +0000 @@ -60,7 +60,7 @@ 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" + " version of barnyard2 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 = @@ -74,8 +74,8 @@ "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" + " version of barnyard2, this database must first be upgraded to the latest\n" + " schema (see the barnyard2-users mailing list archive or DB plugin\n" " documention for details).\n%s\n"; static const char* FATAL_OLD_SCHEMA_2 = @@ -87,10 +87,10 @@ " 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" + "If this build of barnyard2 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" + "If this build of barnyard2 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"; @@ -344,20 +344,19 @@ if(Select(data->SQL_SELECT,data,(u_int32_t *)&c_cid)) { - LogMessage("database: [%s()]: Problems executing [%s] \n", - __FUNCTION__, - data->SQL_SELECT); + DEBUG_WRAP(DebugMessage(DB_DEBUG,"database: [%s()]: Problems executing [%s], (there is probably no row in the table for sensor id [%d] \n", + __FUNCTION__, + data->SQL_SELECT, + data->sid);); } if(c_cid > data->cid) { - LogMessage("INFO database: Table [%s] had a more rescent cid [%u] using it. \n", - table_array[itr], - c_cid); - - LogMessage("\t Using cid [%u] instead of [%u]\n", - c_cid, - data->cid); + DEBUG_WRAP(DebugMessage(DB_DEBUG,"INFO database: Table [%s] had a more recent cid [%u], using cid [%u] instead of [%u] \n", + table_array[itr], + c_cid, + c_cid, + data->cid);); data->cid = c_cid; } @@ -1044,7 +1043,7 @@ !strncasecmp(type, KEYWORD_MSSQL, strlen(KEYWORD_MSSQL)) || !strncasecmp(type, KEYWORD_ORACLE, strlen(KEYWORD_ORACLE)) ) { - ErrorMessage("ERROR database: '%s' support is not compiled into this build of snort\n\n", type); + ErrorMessage("ERROR database: '%s' support is not compiled into this build of barnyard2\n\n", type); FatalError(FATAL_NO_SUPPORT_1, type, type, type, FATAL_NO_SUPPORT_2); } else @@ -1150,6 +1149,10 @@ { data->dbRH[data->dbtype_id].dbReconnectSleepTime.tv_sec = strtoul(a1,NULL,10); } + if(!strncasecmp(dbarg,KEYWORD_DISABLE_SIGREFTABLE,strlen(KEYWORD_DISABLE_SIGREFTABLE))) + { + data->dbRH[data->dbtype_id].disablesigref = 1; + } #ifdef ENABLE_MYSQL /* Option declared here should be forced to dbRH[DB_MYSQL] */ @@ -1285,7 +1288,6 @@ */ u_int32_t dbSignatureInformationUpdate(DatabaseData *data,cacheSignatureObj *iUpdateSig) { - u_int32_t db_sig_id = 0; if( (data == NULL) || @@ -1441,17 +1443,20 @@ revision = ntohl(((Unified2EventCommon *)event)->signature_revision); priority = ntohl(((Unified2EventCommon *)event)->priority_id); classification = ntohl(((Unified2EventCommon *)event)->classification_id); - - /* Originaly forgot about this, since - those signature messages will be put in sid-msg.map by programs like pulledpork */ - /* map.c - a snort general rule (gid=1) and a snort dynamic rule (gid=3) use the - the same sids and thus can be considered one in the same. */ - if (gid == 3) + + /* + This is now only needed for backward compatible with old sid-msg.map file. + new version has gid || sid || revision || msg || etc.. + */ + if( BcSidMapVersion() == SIDMAPV1) { - gid = 1; + if (gid == 3) + { + gid = 1; + } } + /* NOTE: elz For sanity purpose the sig_class table SHOULD have internal classification id to prevent possible miss classification tagging ... but this is not happening with the old schema. @@ -1483,7 +1488,6 @@ if( (sigMatchCount = cacheEventSignatureLookup(data->mc.cacheSignatureHead, data->mc.plgSigCompare, gid,sid)) > 0 ) - { for(x = 0 ; x < sigMatchCount ; x++) { if( (data->mc.plgSigCompare[x].cacheSigObj->obj.rev == revision) && @@ -1497,8 +1501,14 @@ } /* If we have an "uninitialized signature save it */ - if( data->mc.plgSigCompare[x].cacheSigObj->obj.rev == 0 || - data->mc.plgSigCompare[x].cacheSigObj->obj.rev < revision) + if( ( (data->mc.plgSigCompare[x].cacheSigObj->obj.rev == 0) || + (data->mc.plgSigCompare[x].cacheSigObj->obj.rev < revision)) || + + /* So we have a signature that was inserted, probably a preprocessor signature, + but it has probably never been logged before lets set it as a temporary unassigned signature */ + ((data->mc.plgSigCompare[x].cacheSigObj->obj.rev == revision) && + ( data->mc.plgSigCompare[x].cacheSigObj->obj.class_id == 0 || + data->mc.plgSigCompare[x].cacheSigObj->obj.priority_id == 0))) { memcpy(&unInitSig,data->mc.plgSigCompare[x].cacheSigObj,sizeof(cacheSignatureObj)); @@ -1514,50 +1524,51 @@ } } } - } + + if(BcSidMapVersion() == SIDMAPV1) + { + if(unInitSig.obj.db_id != 0) + { +#if DEBUG + DEBUG_WRAP(DebugMessage(DB_DEBUG, + "[%s()], [%u] signatures where found in cache for [gid: %u] [sid: %u] but non matched event criteria.\n" + "Updating database [db_sig_id: %u] FROM [rev: %u] classification [ %u ] priority [%u] " + " TO [rev: %u] classification [ %u ] priority [%u]\n", + __FUNCTION__, + sigMatchCount, + gid, + sid, + unInitSig.obj.db_id, + unInitSig.obj.rev,unInitSig.obj.class_id,unInitSig.obj.priority_id, + revision,db_classification_id,priority)); +#endif + + unInitSig.obj.rev = revision; + unInitSig.obj.class_id = db_classification_id; + unInitSig.obj.priority_id = priority; + + if( (dbSignatureInformationUpdate(data,&unInitSig))) + { + + LogMessage("[%s()] Line[%u], call to dbSignatureInformationUpdate failed for : \n" + "[gid :%u] [sid: %u] [upd_rev: %u] [upd class: %u] [upd pri %u]\n", + __FUNCTION__, + __LINE__, + gid, \ + sid, + revision, + db_classification_id, + priority); + return 1; + } + + assert( unInitSig.obj.db_id != 0); -/* - This shouldn't be needed since unitialized signature are not inserted anymore, thus preventing the need for update - if(unInitSig.obj.db_id != 0) - { - #if DEBUG - DEBUG_WRAP(DebugMessage(DB_DEBUG,"[%s()], [%u] signatures where found in cache for [gid: %u] [sid: %u] but non matched\n" - "updating database [db_sig_id: %u] with [rev: 0] to [rev: %u] \n", - __FUNCTION__, - sigMatchCount, - gid, - sid, - unInitSig.obj.db_id, - revision)); - #endif - - unInitSig.obj.rev = revision; - unInitSig.obj.class_id = db_classification_id; - unInitSig.obj.priority_id = priority; - - - if( (dbSignatureInformationUpdate(data,&unInitSig))) - { - - LogMessage("[%s()] Line[%u], call to dbSignatureInformationUpdate failed for : \n" - "[gid :%u] [sid: %u] [upd_rev: %u] [upd class: %u] [upd pri %u]\n", - __FUNCTION__, - __LINE__, - gid, \ - sid, - revision, - db_classification_id, - priority); - return 1; - } - - - assert( unInitSig.obj.db_id != 0); - - *psig_id = unInitSig.obj.db_id; - return 0; - } -*/ + *psig_id = unInitSig.obj.db_id; + return 0; + } + } + /* To avoid possible collision with an older barnyard process or avoid signature insertion race condition we will look in the @@ -1917,14 +1928,14 @@ case IPPROTO_ICMP: - if( (SQLQueryPtr=SQL_GetNextQuery(data)) == NULL) - { - goto bad_query; - } - /* IPPROTO_ICMP */ if(p->icmph) { + if( (SQLQueryPtr=SQL_GetNextQuery(data)) == NULL) + { + goto bad_query; + } + /*** Build a query for the ICMP Header ***/ if(data->detail) { @@ -1961,10 +1972,11 @@ } else { - LogMessage("[%s()], unable to build query, IP header tell's us its an ICMP packet but " - "there is not icmp header in the decoded packet ... \n", - __FUNCTION__); - goto bad_query; + + DEBUG_WRAP(DebugMessage(DB_DEBUG, + "[%s()], unable to build query, IP header tell's us its an ICMP packet but " + "there is not ICMP header in the decoded packet ... \n", + __FUNCTION__)); } break; /* IPPROTO_ICMP */ @@ -1973,176 +1985,196 @@ /* IPPROTO_TCP */ case IPPROTO_TCP: - if( (SQLQueryPtr=SQL_GetNextQuery(data)) == NULL) + if(p->tcph) { - goto bad_query; - } - - /*** Build a query for the TCP Header ***/ - if(data->detail) - { - if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, - "INSERT INTO " - "tcphdr (sid, cid, tcp_sport, tcp_dport, " - "tcp_seq, tcp_ack, tcp_off, tcp_res, " - "tcp_flags, tcp_win, tcp_csum, tcp_urp) " - "VALUES (%u,%u,%u,%u,%lu,%lu,%u,%u,%u,%u,%u,%u);", - data->sid, - data->cid, - ntohs(p->tcph->th_sport), - ntohs(p->tcph->th_dport), - (u_long)ntohl(p->tcph->th_seq), - (u_long)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))) != SNORT_SNPRINTF_SUCCESS) + if( (SQLQueryPtr=SQL_GetNextQuery(data)) == NULL) { goto bad_query; } - } - else - { - if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, - "INSERT INTO " - "tcphdr (sid,cid,tcp_sport,tcp_dport,tcp_flags) " - "VALUES (%u,%u,%u,%u,%u);", - data->sid, - data->cid, - ntohs(p->tcph->th_sport), - ntohs(p->tcph->th_dport), - p->tcph->th_flags)) != SNORT_SNPRINTF_SUCCESS) + + /*** Build a query for the TCP Header ***/ + if(data->detail) + { + if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, + "INSERT INTO " + "tcphdr (sid, cid, tcp_sport, tcp_dport, " + "tcp_seq, tcp_ack, tcp_off, tcp_res, " + "tcp_flags, tcp_win, tcp_csum, tcp_urp) " + "VALUES (%u,%u,%u,%u,%lu,%lu,%u,%u,%u,%u,%u,%u);", + data->sid, + data->cid, + ntohs(p->tcph->th_sport), + ntohs(p->tcph->th_dport), + (u_long)ntohl(p->tcph->th_seq), + (u_long)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))) != SNORT_SNPRINTF_SUCCESS) + { + goto bad_query; + } + } + else { - goto bad_query; + if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, + "INSERT INTO " + "tcphdr (sid,cid,tcp_sport,tcp_dport,tcp_flags) " + "VALUES (%u,%u,%u,%u,%u);", + data->sid, + data->cid, + ntohs(p->tcph->th_sport), + ntohs(p->tcph->th_dport), + p->tcph->th_flags)) != SNORT_SNPRINTF_SUCCESS) + { + goto bad_query; + } } - } - - if(data->detail) - { + + if(data->detail) + { /*** Build the query for TCP Options ***/ - for(i=0; i < (int)(p->tcp_option_count); i++) - { - - if( p->tcp_options[i].len > 0) + for(i=0; i < (int)(p->tcp_option_count); i++) { - if( (SQLQueryPtr=SQL_GetNextQuery(data)) == NULL) - { - goto bad_query; - } - - if((data->encoding == ENCODING_HEX) || (data->encoding == ENCODING_ASCII)) + + if( (&p->tcp_options[i]) && + (p->tcp_options[i].len > 0)) { - //packet_data = fasthex(p->tcp_options[i].data, p->tcp_options[i].len); - if( fasthex_STATIC(p->tcp_options[i].data, p->tcp_options[i].len,data->PacketData)) + if( (SQLQueryPtr=SQL_GetNextQuery(data)) == NULL) { - /* XXX */ goto bad_query; } - } - else - { - //packet_data = base64(p->tcp_options[i].data, p->tcp_options[i].len); - if( base64_STATIC(p->tcp_options[i].data, p->tcp_options[i].len,data->PacketData)) + + if((data->encoding == ENCODING_HEX) || (data->encoding == ENCODING_ASCII)) { + //packet_data = fasthex(p->tcp_options[i].data, p->tcp_options[i].len); + if( fasthex_STATIC(p->tcp_options[i].data, p->tcp_options[i].len,data->PacketData)) + { /* XXX */ - goto bad_query; + goto bad_query; + } } - } - - - if(data->dbtype_id == DB_ORACLE) - { - /* Oracle field BLOB type case. We append unescaped - * opt_data data after query, which later in Insert() - * will be cut off and uploaded with OCIBindByPos(). - */ - if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, - "INSERT INTO " - "opt (sid,cid,optid,opt_proto,opt_code,opt_len,opt_data) " - "VALUES (%u,%u,%u,%u,%u,%u,:1);|%s", - data->sid, - data->cid, - i, - 6, - p->tcp_options[i].code, - p->tcp_options[i].len, - //packet_data)) != SNORT_SNPRINTF_SUCCESS) - data->PacketData)) != SNORT_SNPRINTF_SUCCESS) + else { - goto bad_query; - } + //packet_data = base64(p->tcp_options[i].data, p->tcp_options[i].len); + if( base64_STATIC(p->tcp_options[i].data, p->tcp_options[i].len,data->PacketData)) + { + /* XXX */ + goto bad_query; + } + } - } - else - { - if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, - "INSERT INTO " - "opt (sid,cid,optid,opt_proto,opt_code,opt_len,opt_data) " - "VALUES (%u,%u,%u,%u,%u,%u,'%s');", - data->sid, - data->cid, - i, - 6, - p->tcp_options[i].code, - p->tcp_options[i].len, - //packet_data)) != SNORT_SNPRINTF_SUCCESS) - data->PacketData)) != SNORT_SNPRINTF_SUCCESS) + if(data->dbtype_id == DB_ORACLE) { - goto bad_query; + /* Oracle field BLOB type case. We append unescaped + * opt_data data after query, which later in Insert() + * will be cut off and uploaded with OCIBindByPos(). + */ + if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, + "INSERT INTO " + "opt (sid,cid,optid,opt_proto,opt_code,opt_len,opt_data) " + "VALUES (%u,%u,%u,%u,%u,%u,:1);|%s", + data->sid, + data->cid, + i, + 6, + p->tcp_options[i].code, + p->tcp_options[i].len, + //packet_data)) != SNORT_SNPRINTF_SUCCESS) + data->PacketData)) != SNORT_SNPRINTF_SUCCESS) + { + goto bad_query; + } + } + else + { + if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, + "INSERT INTO " + "opt (sid,cid,optid,opt_proto,opt_code,opt_len,opt_data) " + "VALUES (%u,%u,%u,%u,%u,%u,'%s');", + data->sid, + data->cid, + i, + 6, + p->tcp_options[i].code, + p->tcp_options[i].len, + //packet_data)) != SNORT_SNPRINTF_SUCCESS) + data->PacketData)) != SNORT_SNPRINTF_SUCCESS) + { + goto bad_query; + } } } } } - } + } + else + { + DEBUG_WRAP(DebugMessage(DB_DEBUG, + "[%s()], unable to build query, IP header tell's us its an TCP packet but " + "there is not TCP header in the decoded packet ... \n", + __FUNCTION__)); + } + break; /* IPPROTO_TCP */ /* IPPROTO_UDP */ case IPPROTO_UDP: - - /*** Build the query for the UDP Header ***/ - if( (SQLQueryPtr=SQL_GetNextQuery(data)) == NULL) - { - goto bad_query; - } - - if(data->detail) + + if(p->udph) { - if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, - "INSERT INTO " - "udphdr (sid, cid, udp_sport, udp_dport, udp_len, udp_csum) " - "VALUES (%u, %u, %u, %u, %u, %u);", - data->sid, - data->cid, - ntohs(p->udph->uh_sport), - ntohs(p->udph->uh_dport), - ntohs(p->udph->uh_len), - ntohs(p->udph->uh_chk))) != SNORT_SNPRINTF_SUCCESS) + /*** Build the query for the UDP Header ***/ + if( (SQLQueryPtr=SQL_GetNextQuery(data)) == NULL) { goto bad_query; } + + if(data->detail) + { + if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, + "INSERT INTO " + "udphdr (sid, cid, udp_sport, udp_dport, udp_len, udp_csum) " + "VALUES (%u, %u, %u, %u, %u, %u);", + data->sid, + data->cid, + ntohs(p->udph->uh_sport), + ntohs(p->udph->uh_dport), + ntohs(p->udph->uh_len), + ntohs(p->udph->uh_chk))) != SNORT_SNPRINTF_SUCCESS) + { + goto bad_query; + } + } + else + { + if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, + "INSERT INTO " + "udphdr (sid, cid, udp_sport, udp_dport) " + "VALUES (%u, %u, %u, %u);", + data->sid, + data->cid, + ntohs(p->udph->uh_sport), + ntohs(p->udph->uh_dport))) != SNORT_SNPRINTF_SUCCESS) + { + goto bad_query; + } + } } else { - if( (SnortSnprintf(SQLQueryPtr, MAX_QUERY_LENGTH, - "INSERT INTO " - "udphdr (sid, cid, udp_sport, udp_dport) " - "VALUES (%u, %u, %u, %u);", - data->sid, - data->cid, - ntohs(p->udph->uh_sport), - ntohs(p->udph->uh_dport))) != SNORT_SNPRINTF_SUCCESS) - { - goto bad_query; - } + DEBUG_WRAP(DebugMessage(DB_DEBUG, + "[%s()], unable to build query, IP header tell's us its an UDP packet but " + "there is not UDP header in the decoded packet ... \n", + __FUNCTION__)); } break; /* IPPROTO_UDP */ - + /* DEFAULT */ default: @@ -2208,7 +2240,8 @@ { for(i=0 ; i < (int)(p->ip_option_count); i++) { - if(&p->ip_options[i]) + if( (&p->ip_options[i]) && + (p->ip_options[i].len > 0)) { if( (SQLQueryPtr=SQL_GetNextQuery(data)) == NULL) { @@ -3097,7 +3130,7 @@ if( (SnortSnprintf(data->SQL_SELECT, MAX_QUERY_LENGTH, "SELECT vseq FROM [schema]")) != SNORT_SNPRINTF_SUCCESS) { - return -1; + return 1; } } else @@ -3113,7 +3146,7 @@ if( (SnortSnprintf(data->SQL_SELECT, MAX_QUERY_LENGTH, "SELECT vseq FROM `schema`")) != SNORT_SNPRINTF_SUCCESS) { - return -1; + return 1; } } else @@ -3122,7 +3155,7 @@ if( (SnortSnprintf(data->SQL_SELECT, MAX_QUERY_LENGTH, "SELECT vseq FROM schema")) != SNORT_SNPRINTF_SUCCESS) { - return -1; + return 1; } } } @@ -3683,6 +3716,8 @@ ErrorMessage("ERROR database: Query [%s] returned more than one result\n", query); result = 0; + PQclear(data->p_result); + data->p_result = NULL; return 1; } else @@ -3690,6 +3725,12 @@ *rval = atoi(PQgetvalue(data->p_result,0,0)); } } + else + { + PQclear(data->p_result); + data->p_result = NULL; + return 1; + } } if(!result) @@ -3950,6 +3991,21 @@ #ifdef ENABLE_POSTGRESQL case DB_POSTGRESQL: + +#ifdef HAVE_PQPING + /* Set PQPing String */ + memset(data->p_pingString,'\0',1024); + if(SnortSnprintf(data->p_pingString,1024,"host='%s' port='%s' user='%s' dbname='%s'", + data->host, + data->port == NULL ? "5432" : data->port, + data->user, + data->dbname)) + { + /* XXX */ + FatalError("[%s()],unable to create PQPing connection string.. bailing \n", + __FUNCTION__); + } +#endif if (data->use_ssl == 1) { @@ -3978,6 +4034,7 @@ if(PQstatus(data->p_connection) == CONNECTION_BAD) { PQfinish(data->p_connection); + data->p_connection = NULL; FatalError("database Connection to database '%s' failed\n", data->dbname); } break; @@ -4011,16 +4068,26 @@ data->port == NULL ? 0 : atoi(data->port), NULL, 0) == NULL) { if(mysql_errno(data->m_sock)) - FatalError("database mysql_error: %s\n", mysql_error(data->m_sock)); - - FatalError("database Failed to logon to database '%s'\n", data->dbname); + { + LogMessage("database mysql_error: %s\n", mysql_error(data->m_sock)); + mysql_close(data->m_sock); + data->m_sock = NULL; + CleanExit(1); + } + + LogMessage("database Failed to logon to database '%s'\n", data->dbname); + mysql_close(data->m_sock); + data->m_sock = NULL; + CleanExit(1); } if(mysql_autocommit(data->m_sock,0)) { /* XXX */ + mysql_close(data->m_sock); + data->m_sock = NULL; LogMessage("WARNING database: unable to unset autocommit\n"); - return ; + return; } data->dbRH[data->dbtype_id].pThreadID = mysql_thread_id(data->m_sock); @@ -4269,8 +4336,9 @@ } if(data->p_connection) - { + { PQfinish(data->p_connection); + data->p_connection = NULL; } break; @@ -4289,7 +4357,7 @@ if(data->m_sock) { mysql_close(data->m_sock); - + data->m_sock = NULL; } @@ -4396,7 +4464,7 @@ puts(" The configuration I am currently using is MySQL with the database"); puts(" name of \"snort\". The user \"snortusr@localhost\" has INSERT and SELECT"); puts(" privileges on the \"snort\" database and does not require a password."); - puts(" The following line enables snort to log to this database.\n"); + puts(" The following line enables barnyard2 to log to this database.\n"); puts(" output database: log, mysql, dbname=snort user=snortusr host=localhost\n"); } @@ -4420,34 +4488,36 @@ } } - + resetTransactionState(&data->dbRH[data->dbtype_id]); MasterCacheFlush(data,CACHE_FLUSH_ALL); SQL_Finalize(data); - UpdateLastCid(data, data->sid, ((data->cid)-1)); + if( !(data->dbRH[data->dbtype_id].dbConnectionStatus(&data->dbRH[data->dbtype_id]))) + { + UpdateLastCid(data, data->sid, ((data->cid)-1)); + } Disconnect(data); - } - - if(data->SQL_INSERT != NULL) - { - free(data->SQL_INSERT); + + if(data->SQL_INSERT != NULL) + { + free(data->SQL_INSERT); data->SQL_INSERT = NULL; - } - - if(data->SQL_SELECT != NULL) - { - free(data->SQL_SELECT); - data->SQL_SELECT = NULL; - } - - free(data->args); - free(data); + } + + if(data->SQL_SELECT != NULL) + { + free(data->SQL_SELECT); + data->SQL_SELECT = NULL; + } + + free(data->args); + free(data); data = NULL; - + } return; } @@ -4728,6 +4798,9 @@ LogMessage("database: mysql_error: %s\n", mysql_error(dbdata->m_sock)); LogMessage("database: Failed to logon to database '%s'\n", dbdata->dbname); + + mysql_close(dbdata->m_sock); + dbdata->m_sock = NULL; return 1; } @@ -4736,6 +4809,8 @@ { /* XXX */ LogMessage("database Can't set autocommit off \n"); + mysql_close(dbdata->m_sock); + dbdata->m_sock = NULL; return 1; } @@ -4743,6 +4818,8 @@ if (mysql_options(dbdata->m_sock, MYSQL_OPT_RECONNECT, &dbdata->dbRH[dbdata->dbtype_id].mysql_reconnect) != 0) { LogMessage("database: Failed to set reconnect option: %s\n", mysql_error(dbdata->m_sock)); + mysql_close(dbdata->m_sock); + dbdata->m_sock = NULL; return 1; } @@ -4768,6 +4845,9 @@ dbdata = pdbRH->dbdata; + if(dbdata->m_sock == NULL) + return 1; + MYSQL_RetryConnection: /* mysql_ping() could reconnect and we wouldn't know */ @@ -5039,6 +5119,8 @@ { DatabaseData *data = NULL; + int PQpingRet = 0; + if( (pdbRH == NULL) || (pdbRH->dbdata == NULL)) { @@ -5051,6 +5133,44 @@ conn_test: if(data->p_connection != NULL) { + +#ifdef HAVE_PQPING + switch( (PQpingRet = PQping(data->p_pingString))) + { + case PQPING_OK: + break; + + case PQPING_NO_ATTEMPT: + LogMessage("[%s()], PQPing call assumed [PQPING_NO_ATTEMPT] using connection string [%s], continuing \n", + __FUNCTION__, + data->p_pingString); + break; + + case PQPING_REJECT: + case PQPING_NO_RESPONSE: + default: + + LogMessage("[%s()], PQPing call retval[%d] seem's to indicate unreacheable server, assuming connection is dead \n", + __FUNCTION__, + PQpingRet); + + if(checkTransactionState(pdbRH)) + { + /* ResetState for the caller */ + setReconnectState(pdbRH,1); + setTransactionCallFail(pdbRH); + setTransactionState(pdbRH); + } + + if(data->p_connection) + { + PQfinish(data->p_connection); + data->p_connection = NULL; + } + break; + } +#endif + switch(PQstatus(data->p_connection)) { case CONNECTION_OK: @@ -5076,7 +5196,11 @@ } /* Changed PQreset by call to PQfinish and PQdbLogin */ - PQfinish(data->p_connection); + if(data->p_connection) + { + PQfinish(data->p_connection); + data->p_connection = NULL; + } if (data->use_ssl == 1) { diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_database_cache.c securityonion-barnyard2-20140531/src/output-plugins/spo_database_cache.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_database_cache.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_database_cache.c 2014-02-10 16:34:05.000000000 +0000 @@ -106,9 +106,31 @@ void MasterCacheFlush(DatabaseData *data,u_int32_t flushFlag); /* Destructor */ +/* Return largest string lenght */ +inline u_int32_t glsl(char *a,char *b) +{ + u_int32_t alen = 0; + u_int32_t blen = 0; + + alen = strlen(a); + blen = strlen(b); + + if(alen > blen) + { + return alen; + } + else if(alen < blen) + { + return blen; + } + if(alen == blen) + { + return alen; + } -extern SigNode *sigTypes; - + abort(); + return 0; +} #if DEBUG u_int32_t file_reference_object_count = 0; @@ -236,7 +258,9 @@ while(iHead != NULL) { - if( (strncasecmp(iLookup->message,iHead->obj.message,strlen(iHead->obj.message)) == 0) && + + if( (strncasecmp(iLookup->message,iHead->obj.message, + glsl(iLookup->message,iHead->obj.message)) == 0) && (iLookup->sid == iHead->obj.sid) && (iLookup->gid == iHead->obj.gid) && (iLookup->rev == iHead->obj.rev)) @@ -278,7 +302,8 @@ while(iHead != NULL) { - if( (strncasecmp(iLookup->message,iHead->obj.message,strlen(iHead->obj.message)) == 0) && + if( (strncasecmp(iLookup->message,iHead->obj.message, + glsl(iLookup->message,iHead->obj.message)) == 0) && (iLookup->sid == iHead->obj.sid) && (iLookup->gid == iHead->obj.gid) && (iLookup->rev == iHead->obj.rev)) @@ -421,7 +446,8 @@ while(iHead != NULL) { - if( (strncasecmp(iLookup->ref_tag,iHead->obj.ref_tag,strlen(iLookup->ref_tag)) == 0)) + if( (strncasecmp(iLookup->ref_tag,iHead->obj.ref_tag, + glsl(iLookup->ref_tag,iHead->obj.ref_tag)) == 0)) { /* Match */ *retRefLookupNode = iHead; @@ -527,10 +553,11 @@ while(iHead != NULL) { - if( (strncasecmp(iLookup->ref_tag,iHead->obj.ref_tag,strlen(iHead->obj.ref_tag)) == 0)) + if( (strncasecmp(iLookup->ref_tag,iHead->obj.ref_tag, + glsl(iLookup->ref_tag,iHead->obj.ref_tag))) == 0) { /* Found */ - if( iHead->flag & CACHE_INTERNAL_ONLY) + if(iHead->flag & CACHE_INTERNAL_ONLY) { iHead->flag ^= (CACHE_INTERNAL_ONLY | CACHE_BOTH); } @@ -538,6 +565,7 @@ { iHead->flag ^= CACHE_BOTH; } + iHead->obj.ref_id = iLookup->ref_id; iHead->obj.system_id = iHead->obj.parent->obj.db_ref_system_id; return 1; @@ -577,7 +605,8 @@ while(iHead != NULL) { - if((strncasecmp(iLookup->ref_system_name,iHead->obj.ref_system_name,strlen(iHead->obj.ref_system_name)) == 0)) + if((strncasecmp(iLookup->ref_system_name,iHead->obj.ref_system_name, + glsl(iLookup->ref_system_name,iHead->obj.ref_system_name))) == 0) { /* Found */ if( iHead->flag & CACHE_INTERNAL_ONLY) @@ -588,6 +617,7 @@ { iHead->flag ^= CACHE_BOTH; } + iHead->obj.db_ref_system_id = iLookup->db_ref_system_id; return 1; } @@ -630,7 +660,8 @@ while(iHead != NULL) { - if( (strncasecmp(iLookup->message,iHead->obj.message,strlen(iHead->obj.message)) == 0) && + if( (strncasecmp(iLookup->message,iHead->obj.message, + glsl(iLookup->message,iHead->obj.message)) == 0) && (iLookup->sid == iHead->obj.sid) && (iLookup->gid == iHead->obj.gid)) { @@ -717,7 +748,8 @@ while(iHead != NULL) { - if( (strncasecmp(iLookup->sig_class_name,iHead->obj.sig_class_name,strlen(iHead->obj.sig_class_name)) == 0)) + if( (strncasecmp(iLookup->sig_class_name,iHead->obj.sig_class_name, + glsl(iLookup->sig_class_name,iHead->obj.sig_class_name)) == 0)) { /* Found */ if( iHead->flag & CACHE_INTERNAL_ONLY) @@ -897,7 +929,7 @@ refFound = 0; for(tItr=0; tItr < cSobj->obj.ref_count; tItr++) { - if( (memcmp(&cSobj->obj.ref[tItr]->obj,&retRefLookupNode->obj,sizeof(dbReferenceObj))) ) + if( (memcmp(&cSobj->obj.ref[tItr]->obj,&retRefLookupNode->obj,sizeof(dbReferenceObj))) == 0) { refFound = 1; break; @@ -1809,7 +1841,7 @@ { if(cacheHead->flag & CACHE_INTERNAL_ONLY) { - + #if DEBUG inserted_classification_object_count++; #endif @@ -2013,7 +2045,7 @@ #if DEBUG DEBUG_WRAP(DebugMessage(DB_DEBUG,"[%s()] Signature was not found in cache, looking for existance in the database:\n" - "\t if this message occur to offent, make sure your sid-msg.map and gen-msg.map file are up to date.\n" + "\t if this message occur to often, make sure your sid-msg.map and gen-msg.map file are up to date.\n" "\t Executing [%s]\n", __FUNCTION__, data->SQL_SELECT)); @@ -5186,10 +5218,13 @@ cacheSignatureReferenceObj *tempCache = NULL; cacheSignatureReferenceObj *tNode = NULL; cacheSignatureReferenceObj *rNode = NULL; - dbSignatureReferenceObj *cObj = NULL; - - u_int32_t maxSeq = 0; + + u_int32_t databasemaxSeq = 0; + u_int32_t sigRefFound = 0; + u_int32_t sigSeq = 0; + u_int32_t sigRefArr[MAX_REF_OBJ] = {0}; + int x = 0; if( (iDBList == NULL) || @@ -5257,57 +5292,116 @@ while(cacheLookup != NULL) { - maxSeq = 0; - - /* Look if we have colision with the databases entry*/ - /* sig_id,ref_id */ - /* if we have such collision, get Largest ref_id, bump it */ + sigRefFound = 0; + + if(sigSeq != cacheLookup->obj.db_sig_id) + { + sigSeq = cacheLookup->obj.db_sig_id; + databasemaxSeq = 0; + memset(sigRefArr,'\0',MAX_REF_OBJ); + } + if(dbSignatureReferenceLookup(&cacheLookup->obj,tempCache,&rNode,1)) { - if(cacheLookup->obj.ref_seq > rNode->obj.ref_seq) + if( (cacheLookup->obj.ref_seq != rNode->obj.ref_seq)) { - cacheLookup->obj.ref_seq = rNode->obj.ref_seq; + cacheLookup->obj.ref_seq = rNode->obj.ref_seq; + + if(cacheLookup->obj.ref_seq > MAX_REF_OBJ) + { + FatalError("[%s()], can't process reference_sequence of [%d] for signature [%d] reference [%d] \n", + __FUNCTION__, + cacheLookup->obj.ref_seq, + cacheLookup->obj.db_sig_id, + cacheLookup->obj.db_ref_id); + } + + + sigRefArr[cacheLookup->obj.ref_seq] = 1; + + if(databasemaxSeq < cacheLookup->obj.ref_seq) + { + databasemaxSeq = cacheLookup->obj.ref_seq; + } } cacheLookup->flag ^=(CACHE_BOTH | CACHE_INTERNAL_ONLY); } else { - /* Validate in internal cache */ - cCheck = *cacheHead; + /* Validate against value in database */ + cCheck = tempCache; while(cCheck != NULL) - { - if(cCheck->obj.db_sig_id == cacheLookup->obj.db_sig_id) - { - if(cCheck->obj.ref_seq > maxSeq) + { + if( (cCheck->obj.db_sig_id == cacheLookup->obj.db_sig_id) && + (cCheck->obj.db_ref_id == cacheLookup->obj.db_ref_id)) + { + + cacheLookup->obj.ref_seq = cCheck->obj.ref_seq; + + if(cacheLookup->obj.ref_seq > MAX_REF_OBJ) { - maxSeq = cCheck->obj.ref_seq; + FatalError("[%s()], can't process reference_sequence of [%d] for signature [%d] reference [%d] \n", + __FUNCTION__, + cacheLookup->obj.ref_seq, + cacheLookup->obj.db_sig_id, + cacheLookup->obj.db_ref_id); } - } - - cCheck = cCheck->next; - } - - /* Validate in temp cache */ - cCheck = tempCache; + - while(cCheck != NULL) - { - if(cCheck->obj.db_sig_id == cacheLookup->obj.db_sig_id) - { - if(cCheck->obj.ref_seq > maxSeq) - { - maxSeq = cCheck->obj.ref_seq; - } - } + sigRefArr[cacheLookup->obj.ref_seq] = 1; + sigRefFound = 1; + if(databasemaxSeq < cacheLookup->obj.ref_seq) + { + databasemaxSeq = cacheLookup->obj.ref_seq; + break; + } + } + cCheck = cCheck->next; } - cacheLookup->obj.ref_seq = maxSeq+1; - + if(!sigRefFound) + { + if(sigRefArr[cacheLookup->obj.ref_seq]) + { + cacheLookup->obj.ref_seq = (databasemaxSeq + 1); + + if(cacheLookup->obj.ref_seq > MAX_REF_OBJ) + { + FatalError("[%s()], can't process reference_sequence of [%d] for signature [%d] reference [%d] \n", + __FUNCTION__, + cacheLookup->obj.ref_seq, + cacheLookup->obj.db_sig_id, + cacheLookup->obj.db_ref_id); + } + + + databasemaxSeq = cacheLookup->obj.ref_seq; + sigRefArr[cacheLookup->obj.ref_seq] = 1; + } + else + { + if(cacheLookup->obj.ref_seq > MAX_REF_OBJ) + { + FatalError("[%s()], can't process reference_sequence of [%d] for signature [%d] reference [%d] \n", + __FUNCTION__, + cacheLookup->obj.ref_seq, + cacheLookup->obj.db_sig_id, + cacheLookup->obj.db_ref_id); + } + + sigRefArr[cacheLookup->obj.ref_seq] = 1; + + if(databasemaxSeq < cacheLookup->obj.ref_seq) + { + databasemaxSeq = cacheLookup->obj.ref_seq; + } + } + } } - + cacheLookup = cacheLookup->next; } @@ -5345,7 +5439,7 @@ */ u_int32_t SignatureReferencePopulateDatabase(DatabaseData *data,cacheSignatureReferenceObj *cacheHead) { - u_int32_t row_validate; + u_int32_t row_validate = 0; if( (data == NULL)) { @@ -5374,13 +5468,13 @@ data->SQL_SELECT); } - + while(cacheHead != NULL) { if(cacheHead->flag & CACHE_INTERNAL_ONLY) { - + row_validate = 0; #if DEBUG inserted_sigref_object_count++; #endif @@ -5584,7 +5678,7 @@ return 1; } - if( (ConvertSignatureCache(&sigTypes,&data->mc,data))) + if( (ConvertSignatureCache(BcGetSigNodeHead(),&data->mc,data))) { /* XXX */ return 1; @@ -5767,13 +5861,16 @@ return 1; } - //SigRef Synchronize - if( (SigRefSynchronize(data,&data->mc.cacheSigReferenceHead,data->mc.cacheSignatureHead))) + if(!data->dbRH[data->dbtype_id].disablesigref) { - /* XXX */ - LogMessage("[%s()]: SigRefSynchronize() call failed \n", - __FUNCTION__); - return 1; + //SigRef Synchronize + if( (SigRefSynchronize(data,&data->mc.cacheSigReferenceHead,data->mc.cacheSignatureHead))) + { + /* XXX */ + LogMessage("[%s()]: SigRefSynchronize() call failed \n", + __FUNCTION__); + return 1; + } } } else diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_database.h securityonion-barnyard2-20140531/src/output-plugins/spo_database.h --- securityonion-barnyard2-20121109/src/output-plugins/spo_database.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_database.h 2014-02-10 16:34:05.000000000 +0000 @@ -342,7 +342,8 @@ 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 */ - + + u_int8_t disablesigref; /* Allow user to prevent generation and creation of signature reference table */ struct _DatabaseData *dbdata; /* Pointer to parent structure used for call clarity */ @@ -422,6 +423,10 @@ #ifdef ENABLE_POSTGRESQL PGconn * p_connection; PGresult * p_result; + +#ifdef HAVE_PQPING + char p_pingString[1024]; +#endif #endif #ifdef ENABLE_MYSQL MYSQL * m_sock; @@ -491,9 +496,9 @@ #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_DISABLE_SIGREFTABLE "disable_signature_reference_table" #define KEYWORD_MYSQL_RECONNECT "mysql_reconnect" diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_echidna.c securityonion-barnyard2-20140531/src/output-plugins/spo_echidna.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_echidna.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_echidna.c 2014-02-10 16:34:05.000000000 +0000 @@ -1,5 +1,5 @@ /* -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** ** 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 @@ -45,7 +45,7 @@ #include #include #include - +#include #include "barnyard2.h" #include "debug.h" @@ -72,6 +72,10 @@ u_int16_t node_port; int use_ssl; + + + + CURL *curl; } SpoEchidnaData; static int session_state = 0; @@ -141,7 +145,7 @@ switch (reason) { case LWS_CALLBACK_CLOSED: - fprintf(stderr, "echidna: LWS_CALLBACK_CLOSED\n"); + //fprintf(stderr, "echidna: LWS_CALLBACK_CLOSED\n"); wsi_echidna = NULL; /* session key is invalidated */ @@ -157,13 +161,13 @@ * start the ball rolling, * LWS_CALLBACK_CLIENT_WRITEABLE will come next service */ - fprintf(stderr, "Connection established ...\n"); + //fprintf(stderr, "Connection established ...\n"); libwebsocket_callback_on_writable(this, wsi); break; case LWS_CALLBACK_CLIENT_RECEIVE: - fprintf(stderr, "rx %d '%s'\n", (int)len, (char *)in); + //fprintf(stderr, "rx %d '%s'\n", (int)len, (char *)in); json = json_tokener_parse( in ); @@ -183,7 +187,7 @@ node_id = SnortStrdup( json_object_get_string(val) ); - fprintf(stderr, "NODE ID: %s\n", node_id); + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "NODE ID: %s\n", node_id);); } else if( strncmp( key, "session_key", 11 ) == 0 && ( type == json_type_string ) ) { @@ -192,7 +196,7 @@ free(session_key); session_key = SnortStrdup( json_object_get_string(val) ); - fprintf(stderr, "SESSION KEY: %s\n", session_key); + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "SESSION KEY: %s\n", session_key);); } else if( strncmp( key, "session_uri", 11 ) == 0 && ( type == json_type_string ) ) { @@ -201,7 +205,7 @@ free(session_uri); session_uri = SnortStrdup( json_object_get_string(val) ); - fprintf(stderr, "SESSION URI: %s\n", session_uri); + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "SESSION URI: %s\n", session_uri);); } } @@ -233,49 +237,46 @@ break; case LWS_CALLBACK_ESTABLISHED: - fprintf(stderr, " LWS_CALLBACK_ESTABLISHED\n"); + //fprintf(stderr, " LWS_CALLBACK_ESTABLISHED\n"); break; case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - fprintf(stderr, " LWS_CALLBACK_CLIENT_CONNECTION_ERROR\n"); + //fprintf(stderr, " LWS_CALLBACK_CLIENT_CONNECTION_ERROR\n"); break; case LWS_CALLBACK_RECEIVE: - fprintf(stderr, " LWS_CALLBACK_RECEIVE\n"); + //fprintf(stderr, " LWS_CALLBACK_RECEIVE\n"); break; case LWS_CALLBACK_CLIENT_RECEIVE_PONG: - fprintf(stderr, " LWS_CALLBACK_CLIENT_RECEIVE_PONG\n"); + //fprintf(stderr, " LWS_CALLBACK_CLIENT_RECEIVE_PONG\n"); break; case LWS_CALLBACK_SERVER_WRITEABLE: - fprintf(stderr, " LWS_CALLBACK_SERVER_WRITEABLE\n"); + //fprintf(stderr, " LWS_CALLBACK_SERVER_WRITEABLE\n"); break; case LWS_CALLBACK_HTTP: - fprintf(stderr, " LWS_CALLBACK_HTTP\n"); - break; - case LWS_CALLBACK_BROADCAST: - fprintf(stderr, " LWS_CALLBACK_BROADCAST\n"); + //fprintf(stderr, " LWS_CALLBACK_HTTP\n"); break; case LWS_CALLBACK_FILTER_NETWORK_CONNECTION: - fprintf(stderr, " LWS_CALLBACK_FILTER_NETWORK_CONNECTION\n"); + //fprintf(stderr, " LWS_CALLBACK_FILTER_NETWORK_CONNECTION\n"); break; case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: - fprintf(stderr, " LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION\n"); + //fprintf(stderr, " LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION\n"); break; case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: - fprintf(stderr, " LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS\n"); + //fprintf(stderr, " LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS\n"); break; case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: - fprintf(stderr, " LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS\n"); + //fprintf(stderr, " LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS\n"); break; case LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: - fprintf(stderr, " LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION\n"); + //fprintf(stderr, " LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION\n"); break; case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: - fprintf(stderr, " LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER\n"); + //fprintf(stderr, " LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER\n"); break; case LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: - fprintf(stderr, " LWS_CALLBACK_CONFIRM_EXTENSION_OKAY\n"); + //fprintf(stderr, " LWS_CALLBACK_CONFIRM_EXTENSION_OKAY\n"); break; case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: - fprintf(stderr, " LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED\n"); + //fprintf(stderr, " LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED\n"); break; case LWS_CALLBACK_ADD_POLL_FD: @@ -325,6 +326,11 @@ spd_data = InitEchidnaData(args); AddFuncToPostConfigList(EchidnaInitFinalize, spd_data); + + // TODO: +// AddFuncToIdleList(EchidnaIdle, spd_data); + + lws_set_log_level(0, NULL); } SpoEchidnaData *InitEchidnaData(char *args) @@ -387,12 +393,32 @@ { json_object *json; + char *timestamp; + char *data_msg; + char id_hash_text[512] = {0}; + char evt_corr_id_hash_text[512] = {0}; + char ssn_corr_id_hash_text[512] = {0}; + + uint8_t id_hash[SHA256_DIGEST_LENGTH]; + uint8_t evt_corr_id_hash[SHA256_DIGEST_LENGTH]; + uint8_t ssn_corr_id_hash[SHA256_DIGEST_LENGTH]; + + char id_hash_hex[64]; + char evt_corr_id_hash_hex[64]; + char ssn_corr_id_hash_hex[64]; + + SHA256_CTX ctx; + char sip4[INET_ADDRSTRLEN]; char dip4[INET_ADDRSTRLEN]; char sip6[INET6_ADDRSTRLEN]; char dip6[INET6_ADDRSTRLEN]; + uint16_t sport; + uint16_t dport; + + int i; SpoEchidnaData *data; SigNode *sn = NULL; @@ -403,6 +429,11 @@ data = (SpoEchidnaData *)arg; + timestamp = EchidnaTimestamp( + ntohl(((Unified2EventCommon *)event)->event_second), + ntohl(((Unified2EventCommon *)event)->event_microsecond) + ); + /* grab the appropriate signature and classification information */ sn = GetSigByGidSid( ntohl(((Unified2EventCommon *)event)->generator_id), @@ -414,25 +445,73 @@ /* initialise our json object */ json = json_object_new_object(); + json_object_object_add(json, "node_id", json_object_new_string(node_id)); + + /* not yet classified */ + json_object_object_add(json, "classification", json_object_new_int(0)); + json_object_object_add(json, "meta_u2_event_id", json_object_new_int( ntohl(((Unified2EventCommon *)event)->event_id) )); + /* IP version, addresses, ports and protocol */ + switch( event_type ) + { + case UNIFIED2_IDS_EVENT: + case UNIFIED2_IDS_EVENT_MPLS: + case UNIFIED2_IDS_EVENT_VLAN: + inet_ntop(AF_INET, &((Unified2IDSEvent*)event)->ip_source, sip4, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &((Unified2IDSEvent*)event)->ip_destination, dip4, INET_ADDRSTRLEN); + sport = ntohs(((Unified2IDSEvent *)event)->sport_itype); + dport = ntohs(((Unified2IDSEvent *)event)->dport_icode); + + json_object_object_add(json, "net_version", json_object_new_int( 4 )); + json_object_object_add(json, "net_src_ip", json_object_new_string( sip4 )); + json_object_object_add(json, "net_src_port", json_object_new_int( sport )); + json_object_object_add(json, "net_dst_ip", json_object_new_string( dip4 )); + json_object_object_add(json, "net_dst_port", json_object_new_int( dport )); + json_object_object_add(json, "net_protocol", json_object_new_int( ((Unified2IDSEvent *)event)->protocol)); + + SnortSnprintfAppend(ssn_corr_id_hash_text, 512, "%s%d%s%d%d", sip4, sport, dip4, dport, ((Unified2IDSEvent *)event)->protocol); + break; + case UNIFIED2_IDS_EVENT_IPV6: + case UNIFIED2_IDS_EVENT_IPV6_MPLS: + case UNIFIED2_IDS_EVENT_IPV6_VLAN: + inet_ntop(AF_INET6, &((Unified2IDSEventIPv6 *)event)->ip_source, sip6, INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, &((Unified2IDSEventIPv6 *)event)->ip_destination, dip6, INET6_ADDRSTRLEN); + sport = ntohs(((Unified2IDSEventIPv6 *)event)->sport_itype); + dport = ntohs(((Unified2IDSEventIPv6 *)event)->dport_icode); + + json_object_object_add(json, "net_version", json_object_new_int( 6 )); + json_object_object_add(json, "net_src_ip", json_object_new_string( sip6 )); + json_object_object_add(json, "net_src_port", json_object_new_int( sport )); + json_object_object_add(json, "net_dst_ip", json_object_new_string( dip6 )); + json_object_object_add(json, "net_dst_port", json_object_new_int( dport )); + json_object_object_add(json, "net_protocol", json_object_new_int( ((Unified2IDSEventIPv6 *)event)->protocol )); + + SnortSnprintfAppend(ssn_corr_id_hash_text, 512, "%s%d%s%d%d", sip6, sport, dip6, dport, ((Unified2IDSEventIPv6 *)event)->protocol); + break; + } + /* snort event reference time */ - json_object_object_add(json, "timestamp", json_object_new_string( - EchidnaTimestamp( - ntohl(((Unified2EventCommon *)event)->event_second), - ntohl(((Unified2EventCommon *)event)->event_microsecond) - ) - )); + json_object_object_add(json, "timestamp", json_object_new_string( timestamp )); + + SnortSnprintfAppend(id_hash_text, 512, "%s%s", ssn_corr_id_hash_text, timestamp); /* generator ID */ json_object_object_add(json, "sig_type", json_object_new_int( ntohl(((Unified2EventCommon *)event)->generator_id) )); /* signature ID */ - json_object_object_add(json, "sig_id,", json_object_new_int( ntohl(((Unified2EventCommon *)event)->signature_id) )); + json_object_object_add(json, "sig_id", json_object_new_int( ntohl(((Unified2EventCommon *)event)->signature_id) )); /* signature revision */ - json_object_object_add(json, "sig_rev", json_object_new_int( ntohl(((Unified2EventCommon *)event)->signature_revision) )); + json_object_object_add(json, "sig_revision", json_object_new_int( ntohl(((Unified2EventCommon *)event)->signature_revision) )); + + SnortSnprintfAppend(evt_corr_id_hash_text, 512, "%s%d%d%d", + ssn_corr_id_hash_text, + ntohl(((Unified2EventCommon *)event)->generator_id), + ntohl(((Unified2EventCommon *)event)->signature_id), + ntohl(((Unified2EventCommon *)event)->signature_revision) + ); /* signature message */ json_object_object_add(json, "sig_message", json_object_new_string( sn->msg )); @@ -457,7 +536,7 @@ json_object_object_add(json, "net_src_port", json_object_new_int( ntohs(((Unified2IDSEvent *)event)->sport_itype) )); json_object_object_add(json, "net_dst_ip", json_object_new_string( sip4 )); json_object_object_add(json, "net_dst_port", json_object_new_int( ntohs(((Unified2IDSEvent *)event)->dport_icode) )); - json_object_object_add(json, "net_version", json_object_new_int( ((Unified2IDSEvent *)event)->protocol )); + json_object_object_add(json, "net_protocol", json_object_new_int( ((Unified2IDSEvent *)event)->protocol )); break; case UNIFIED2_IDS_EVENT_IPV6: case UNIFIED2_IDS_EVENT_IPV6_MPLS: @@ -470,7 +549,7 @@ json_object_object_add(json, "net_src_port", json_object_new_int( ntohs(((Unified2IDSEventIPv6 *)event)->sport_itype) )); json_object_object_add(json, "net_dst_ip", json_object_new_string( sip6 )); json_object_object_add(json, "net_dst_port", json_object_new_int( ntohs(((Unified2IDSEventIPv6 *)event)->dport_icode) )); - json_object_object_add(json, "net_version", json_object_new_int( ((Unified2IDSEventIPv6 *)event)->protocol )); + json_object_object_add(json, "net_protocol", json_object_new_int( ((Unified2IDSEventIPv6 *)event)->protocol )); break; } @@ -517,9 +596,42 @@ } } + /* construct id hash */ + SHA256_Init(&ctx); + SHA256_Update(&ctx, id_hash_text, strlen(id_hash_text)); + SHA256_Final(id_hash, &ctx); + for( i=0; icurl == NULL ) { - fprintf(stderr, "submitting %s => %s failed\n", session_uri, json_object_to_json_string( json )); + spd_data->curl = curl_easy_init(); + + if( spd_data->curl ) + { + snprintf(uri, 2048, "%s?session=%s", session_uri, session_key); + + curl_easy_setopt(spd_data->curl, CURLOPT_URL, uri); + curl_easy_setopt(spd_data->curl, CURLOPT_WRITEFUNCTION, &_curl_dummy_write); + } + else + { + FatalError("echidna: unable to allocate a CURL structure.\n"); + } + } + + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "submitting: %s\n", json_object_to_json_string( json ));); - curl_easy_setopt(curl, CURLOPT_URL, session_uri); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_object_to_json_string( json ) ); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &_curl_dummy_write); + curl_easy_setopt(spd_data->curl, CURLOPT_POSTFIELDS, json_object_to_json_string( json ) ); - while( rc != 200 ) + while( rc != 200 ) + { + if( ( res = curl_easy_perform(spd_data->curl) ) == CURLE_OK ) { - if( ( res = curl_easy_perform(curl) ) == CURLE_OK ) + curl_easy_getinfo(spd_data->curl, CURLINFO_RESPONSE_CODE, &rc); + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "RC: %lu\n", rc);); + + if( rc == 403 ) { - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rc); - fprintf(stderr, "RC: %lu\n", rc); + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "forbidden. TODO: request new session key\n");); + sleep(15); } - else if( rc == 403 ) + else if( rc != 200 ) { - fprintf(stderr, "forbidden. TODO: reconnect\n"); - } - else - { - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(res)); + DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));); + sleep(15); } - - sleep(15); } - - fprintf(stderr, "cleaning up curl\n"); - - /* always cleanup */ - curl_easy_cleanup(curl); } } @@ -822,22 +943,19 @@ /* free allocated memory from SpoEchidnaData */ if( spd_data != NULL ) { - - fprintf(stderr, "Exiting\n"); - - - if( spd_data->agent_name ) free(spd_data->agent_name); if( spd_data->args ) free(spd_data->args); + if( spd_data->curl ) + curl_easy_cleanup(spd_data->curl); + free(spd_data); } /* cleanup the websocket contexts */ - libwebsocket_close_and_free_session(context, wsi_echidna, LWS_CLOSE_STATUS_GOINGAWAY); libwebsocket_context_destroy(context); /* clean up curl */ diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_echidna.h securityonion-barnyard2-20140531/src/output-plugins/spo_echidna.h --- securityonion-barnyard2-20121109/src/output-plugins/spo_echidna.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_echidna.h 2014-02-10 16:34:05.000000000 +0000 @@ -1,5 +1,5 @@ /* -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** ** 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 diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_log_tcpdump.c securityonion-barnyard2-20140531/src/output-plugins/spo_log_tcpdump.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_log_tcpdump.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_log_tcpdump.c 2014-02-10 16:34:05.000000000 +0000 @@ -566,7 +566,7 @@ free (data->filename); } - bzero(data, sizeof(LogTcpdumpData)); + memset(data,'\0',sizeof(LogTcpdumpData)); free(data); } @@ -598,4 +598,4 @@ log_tcpdump_ptr->size += dumpSize; } -#endif /* HAVE_LIBPCAP */ \ No newline at end of file +#endif /* HAVE_LIBPCAP */ diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_sguil.c securityonion-barnyard2-20140531/src/output-plugins/spo_sguil.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_sguil.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_sguil.c 2014-02-10 16:34:05.000000000 +0000 @@ -1,5 +1,5 @@ /* -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** Copyright (C) 2002-2005 Robert (Bamm) Visscher ** ** This program is free software; you can redistribute it and/or modify @@ -213,7 +213,12 @@ if(BcLogVerbose()) LogMessage("sguil: Waiting for sid and cid from sensor_agent.\n"); - SguilSensorAgentInit(ssd_data); + /* try to connect, if we are not getting retval 0 it timed out + * so we try again, and again, and again... */ + do { + if (SguilSensorAgentInit(ssd_data) == 0) + break; + } while (1); /* set the preprocessor function into the function list */ AddFuncToOutputList(Sguil, OUTPUT_TYPE__ALERT, ssd_data); @@ -984,7 +989,10 @@ return 1; } -/* Request sensor ID (sid) and next cid from sensor_agent */ +/* Request sensor ID (sid) and next cid from sensor_agent + * return 0 on success + * return 1 on timeout + */ int SguilSensorAgentInit(SpoSguilData *ssd_data) { char tmpSendMsg[MAX_MSG_LEN]; @@ -1005,7 +1013,7 @@ sguil_agent_setup_timeouts++; /* timeout, resend */ - SguilSensorAgentInit(ssd_data); + return 1; } else { @@ -1201,20 +1209,29 @@ /* free allocated memory from SpoSguilData */ if (ssd_data) { - if (ssd_data->sensor_name) - free(ssd_data->sensor_name); - - if (ssd_data->tag_path) - free(ssd_data->tag_path); - - if (ssd_data->passwd) - free(ssd_data->passwd); - - if (ssd_data->args) - free(ssd_data->args); - free(ssd_data); + if(ssd_data->agent_sock > 0) + { + close(ssd_data->agent_sock); + ssd_data->agent_sock = -1; + } + + + if (ssd_data->sensor_name) + free(ssd_data->sensor_name); + + if (ssd_data->tag_path) + free(ssd_data->tag_path); + + if (ssd_data->passwd) + free(ssd_data->passwd); + + if (ssd_data->args) + free(ssd_data->args); + + free(ssd_data); } + } void SguilRestartFunc(int signal, void *arg) @@ -1226,19 +1243,26 @@ /* free allocated memory from SpoSguilData */ if (ssd_data) { - if (ssd_data->sensor_name) - free(ssd_data->sensor_name); - - if (ssd_data->tag_path) - free(ssd_data->tag_path); - - if (ssd_data->passwd) - free(ssd_data->passwd); - - if (ssd_data->args) - free(ssd_data->args); - free(ssd_data); + if(ssd_data->agent_sock > 0) + { + close(ssd_data->agent_sock); + ssd_data->agent_sock = -1; + } + + if (ssd_data->sensor_name) + free(ssd_data->sensor_name); + + if (ssd_data->tag_path) + free(ssd_data->tag_path); + + if (ssd_data->passwd) + free(ssd_data->passwd); + + if (ssd_data->args) + free(ssd_data->args); + + free(ssd_data); } } diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_sguil.h securityonion-barnyard2-20140531/src/output-plugins/spo_sguil.h --- securityonion-barnyard2-20121109/src/output-plugins/spo_sguil.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_sguil.h 2014-02-10 16:34:05.000000000 +0000 @@ -1,5 +1,5 @@ /* -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** Copyright (C) 2002-2005 Robert (Bamm) Visscher ** ** This program is free software; you can redistribute it and/or modify diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_syslog_full.c securityonion-barnyard2-20140531/src/output-plugins/spo_syslog_full.c --- securityonion-barnyard2-20121109/src/output-plugins/spo_syslog_full.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_syslog_full.c 2014-02-10 16:34:05.000000000 +0000 @@ -35,6 +35,7 @@ # operation_mode $operaion_mode - default | complete : default mode is compatible with default snort syslog message, complete prints more information such as the raw packet (hexed) # log_priority $log_priority - used by local option for syslog priority call. (man syslog(3) for supported options) (default: LOG_INFO) # log_facility $log_facility - used by local option for syslog facility call. (man syslog(3) for supported options) (default: LOG_USER) +# payload_encoding - (default: hex) support hex/ascii/base64 for log_syslog_full using operation_mode complete only. # Usage Examples: # output alert_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514, operation_mode default @@ -223,6 +224,8 @@ } NetClose(iSyslogContext); + + free(iSyslogContext); return; } @@ -521,25 +524,29 @@ static int Syslog_FormatIPHeaderLog(OpSyslog_Data *data, Packet *p) { - unsigned int s, d, proto, ver, hlen, tos, len, id, off, ttl, csum; - s=d=proto=ver=hlen=tos=len=id=off=ttl=csum=0; + //unsigned int s, d, + unsigned int proto, ver, hlen, tos, len, id, off, ttl, csum; + //s=d=...; + proto=ver=hlen=tos=len=id=off=ttl=csum=0; char sip[16] = {0}; char dip[16] = {0}; - if(p->iph) { - if(p->iph->ip_src.s_addr) - s = ntohl( p->iph->ip_src.s_addr); - if(p->iph->ip_dst.s_addr) - d = ntohl( p->iph->ip_dst.s_addr); + /* + if(p->iph->ip_src.s_addr) + s = ntohl( p->iph->ip_src.s_addr); + if(p->iph->ip_dst.s_addr) + d = ntohl( p->iph->ip_dst.s_addr); + */ + if(p->iph->ip_proto) proto = p->iph->ip_proto; if(IP_VER(p->iph)) ver = IP_VER(p->iph); if(IP_HLEN(p->iph)) - ver = IP_HLEN(p->iph); + hlen = IP_HLEN(p->iph) << 2; if(p->iph->ip_tos) tos = p->iph->ip_tos; if(p->iph->ip_len) @@ -804,8 +811,6 @@ int Syslog_FormatPayload(OpSyslog_Data *data, Packet *p) { - char *hex_payload = NULL; - if( (data == NULL) || (p == NULL) || (p->pkt == NULL)) @@ -817,22 +822,54 @@ if(p->pkth->len > 0) { - if( (hex_payload = fasthex(p->pkt, p->pkth->len)) == NULL) + memset(data->payload_escape_buffer,'\0',MAX_QUERY_LENGTH); + + switch(data->payload_encoding) { - /* XXX */ - return 1; + + case ENCODE_HEX: + if( (fasthex_STATIC(p->pkt, p->pkth->len, + data->payload_escape_buffer))) + { + /* XXX */ + return 1; + } + break; + + case ENCODE_ASCII: + if( (ascii_STATIC(p->pkt,p->pkth->len, + data->payload_escape_buffer))) + { + /* XXX */ + return 1; + } + break; + + case ENCODE_BASE64: + if( (base64_STATIC(p->pkt,p->pkth->len, + data->payload_escape_buffer))) + { + /* XXX */ + return 1; + } + break; + + default: + FatalError("[%s()]: Unknown encoding payload scheme [%d] \n", + __FUNCTION__, + data->payload_encoding); + break; } + if( (data->format_current_pos += snprintf(data->formatBuffer, SYSLOG_MAX_QUERY_SIZE, "%u%c%s", p->pkth->len,data->field_separators, - hex_payload)) >= SYSLOG_MAX_QUERY_SIZE) + data->payload_escape_buffer)) >= SYSLOG_MAX_QUERY_SIZE) { /* XXX */ - free(hex_payload); return 1; } - free(hex_payload); } return OpSyslog_Concat(data); @@ -1247,14 +1284,18 @@ int i; /* parse out your args */ toks = mSplit(args, ",", 31, &num_toks, '\\'); + for(i = 0; i < num_toks; ++i) { char **stoks; int num_stoks; char *index = toks[i]; - while(isspace((int)*index)) + + while(isspace((int)*index)) ++index; - stoks = mSplit(index, " ", 2, &num_stoks, 0); + + stoks = mSplit(index, " ", 2, &num_stoks, 0); + if(strcasecmp("port", stoks[0]) == 0) { if(num_stoks > 1 ) @@ -1374,6 +1415,34 @@ } } + else if(strcasecmp("payload_encoding", stoks[0]) == 0) + { + if(num_stoks >=1) + { + if(strcasecmp("hex",stoks[1]) == 0) + { + op_data->payload_encoding = ENCODE_HEX; + } + else if(strcasecmp("ascii",stoks[1]) == 0) + { + op_data->payload_encoding = ENCODE_ASCII; + } + else if(strcasecmp("base64",stoks[1]) == 0) + { + op_data->payload_encoding = ENCODE_BASE64; + } + else + { + LogMessage("Invalid payload_encoding defined [%s], will use HEX encoding by default \n",stoks[1]); + op_data->payload_encoding = ENCODE_HEX; + } + } + else + { + LogMessage("Invalid payload_encoding defined, will use HEX encoding by default \n"); + op_data->payload_encoding = ENCODE_HEX; + } + } else if(strcasecmp("local", stoks[0]) == 0) { op_data->local_logging = 1; @@ -1560,7 +1629,7 @@ "SyslogFull plugin: %s\n", file_name, file_line, index); } - + mSplitFree(&stoks,num_stoks); } /* free your mSplit tokens */ mSplitFree(&toks, num_toks); @@ -1844,6 +1913,7 @@ if(op_data->local_logging == 1) { syslog(op_data->syslog_priority, + "%s", op_data->payload); return 0; } @@ -1854,7 +1924,7 @@ case LOG_UDP: /* UDP */ - if(sendto(op_data->socket,op_data->payload, strlen(op_data->payload), 0 , (struct sockaddr *)&op_data->sockaddr, sizeof(struct sockaddr)) <= 0) + if(sendto(op_data->socket,op_data->payload, strlen(op_data->payload)+1, 0 , (struct sockaddr *)&op_data->sockaddr, sizeof(struct sockaddr)) <= 0) { /* XXX */ close(op_data->socket); @@ -1866,7 +1936,7 @@ case LOG_TCP: /* TCP */ - sendRetVal = send(op_data->socket, op_data->payload, strlen(op_data->payload),0); + sendRetVal = send(op_data->socket, op_data->payload, strlen(op_data->payload)+1,0); if((sendRetVal < sendSize) || (sendRetVal < 0) ) diff -Nru securityonion-barnyard2-20121109/src/output-plugins/spo_syslog_full.h securityonion-barnyard2-20140531/src/output-plugins/spo_syslog_full.h --- securityonion-barnyard2-20121109/src/output-plugins/spo_syslog_full.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/output-plugins/spo_syslog_full.h 2014-02-10 16:34:05.000000000 +0000 @@ -49,6 +49,11 @@ #define LOG_UDP 0 #define LOG_TCP 1 +#define ENCODE_HEX 0x0000 +#define ENCODE_ASCII 0x0001 +#define ENCODE_BASE64 0x0002 + +#define SYSLOG_MAX_QUERY_SIZE MAX_QUERY_LENGTH typedef struct _OpSyslog_Data { @@ -56,10 +61,12 @@ char *sensor_name; u_int8_t log_context; - + u_int8_t payload_encoding; u_int8_t operation_mode; u_int8_t local_logging; u_int32_t syslog_priority; + + char payload_escape_buffer[MAX_QUERY_LENGTH]; char syslog_tx_facility[16]; char syslog_tx_priority[16]; @@ -87,11 +94,6 @@ void OpSyslog_Setup(void); void OpSyslog_Init(char *args,u_int8_t context); -#define SYSLOG_MAX_QUERY_SIZE 65535 /* This could be easely filled in log mode with the full packet payload, - we issue a warning if payload is truncated in log mode - We could make the query size max payload *2 + 1024 or so bytes and we should be fine, but that would make large - syslog messages if reached and i wonder if SIEM would be able to handle that. - */ #endif /* __OP_SYSLOG_FULL_H_ */ diff -Nru securityonion-barnyard2-20121109/src/parser.c securityonion-barnyard2-20140531/src/parser.c --- securityonion-barnyard2-20121109/src/parser.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/parser.c 2014-02-10 16:34:05.000000000 +0000 @@ -179,11 +179,11 @@ static const KeywordFunc barnyard2_conf_keywords[] = { /* Non-rule keywords */ + { BARNYARD2_CONF_KEYWORD__VAR, KEYWORD_TYPE__MAIN, 0, ParseVar }, { BARNYARD2_CONF_KEYWORD__CONFIG, KEYWORD_TYPE__MAIN, 1, ParseConfig }, { BARNYARD2_CONF_KEYWORD__IPVAR, KEYWORD_TYPE__MAIN, 0, ParseIpVar }, { BARNYARD2_CONF_KEYWORD__INPUT, KEYWORD_TYPE__MAIN, 1, ParseInput }, { BARNYARD2_CONF_KEYWORD__OUTPUT, KEYWORD_TYPE__MAIN, 1, ParseOutput }, - { BARNYARD2_CONF_KEYWORD__VAR, KEYWORD_TYPE__MAIN, 0, ParseVar }, { NULL, 0, 0, NULL } /* Marks end of array */ }; @@ -207,6 +207,7 @@ { CONFIG_OPT__INTERFACE, 1, 1, ConfigInterface }, { CONFIG_OPT__LOG_DIR, 1, 1, ConfigLogDir }, { CONFIG_OPT__OBFUSCATE, 0, 1, ConfigObfuscate }, + { CONFIG_OPT__SIGSUPPRESS,0,0,ConfigSigSuppress}, /* XXX We can configure this on the command line - why not in config file ??? */ #ifdef NOT_UNTIL_WE_DAEMONIZE_AFTER_READING_CONFFILE { CONFIG_OPT__PID_PATH, 1, 1, ConfigPidPath }, @@ -283,9 +284,13 @@ /* Need to set this for plugin configurations since they're using * lists of callbacks */ barnyard2_conf_for_parsing = bc; + InitParser(); + /* By default */ + bc->alert_on_each_packet_in_stream_flag=1; + /* We're not going to parse rules on the first pass */ parse_rules = 0; @@ -1297,35 +1302,11 @@ if (num_toks > 1) { - /* Dup the opts because we're putting into hash table */ + opts = SnortStrdup(toks[1]); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Args: %s\n", opts);); } -/* - switch (sfghash_add(bc->config_table, toks[0], opts)) - { - case SFGHASH_NOMEM: - FatalError("%s(%d) No memory to add entry to config table.\n", - __FILE__, __LINE__); - break; - case SFGHASH_INTABLE: - */ - /* Only reference and classifications are likely dup candidates - * right now and we're not too worried about keeping track of - * all of them */ -/* if (opts != NULL) - { - free(opts); - opts = toks[1]; - } - - break; - - default: - break; - } -*/ for (i = 0; config_opts[i].name != NULL; i++) { if (strcasecmp(toks[0], config_opts[i].name) == 0) @@ -1358,6 +1339,12 @@ } mSplitFree(&toks, num_toks); + + if(opts) + { + free(opts); + } + } /* @@ -1719,7 +1706,9 @@ if ((args == NULL) || (bc == NULL) ) return; - ReadClassificationFile(bc, args); + bc->class_file = strndup(args,strlen(args)); + + ReadClassificationFile(bc); } void ConfigCreatePidFile(Barnyard2Config *bc, char *args) @@ -1787,8 +1776,9 @@ { if ((args == NULL) || (bc == NULL) ) return; - - ReadGenFile(bc, args); + + bc->gen_msg_file = strndup(args,PATH_MAX); + return; } void ConfigHostname(Barnyard2Config *bc, char *args) @@ -1941,6 +1931,7 @@ /* 2 tokens: name */ toks = mSplit(args, " \t", 0, &num_toks, 0); + if (num_toks > 2) { ParseError("Reference config requires at most two arguments: " @@ -1949,7 +1940,7 @@ if (num_toks == 2) url = toks[1]; - + ReferenceSystemAdd(&bc->references, toks[0], url); mSplitFree(&toks, num_toks); @@ -2152,7 +2143,7 @@ if ((args == NULL) || (bc == NULL) ) return; - ReadSidFile(bc, args); + bc->sid_msg_file = strndup(args,PATH_MAX); } void ConfigUmask(Barnyard2Config *bc, char *args) @@ -2232,6 +2223,456 @@ bc->waldo.state |= WALDO_STATE_ENABLED; } + +void DisplaySigSuppress(SigSuppress_list **sHead) +{ + if(sHead == NULL) + { + return; + } + SigSuppress_list *cNode = *sHead; + + LogMessage("\n\n+[ Signature Suppress list ]+\n" + "----------------------------\n"); + + if(cNode) + { + while(cNode) + { + LogMessage("-- Element type:[%s] gid:[%d] sid min:[%d] sid max:[%d] \n", + (cNode->ss_type & SS_SINGLE) ? "SINGLE" : "RANGE ", + cNode->gid, + cNode->ss_min, + cNode->ss_max); + + cNode = cNode->next; + } + } + else + { + LogMessage("+[No entry in Signature Suppress List]+\n"); + } + LogMessage("----------------------------\n" + "+[ Signature Suppress list ]+\n\n"); + return; +} + +int SigSuppressUnlinkNode(SigSuppress_list **sHead,SigSuppress_list **cNode,SigSuppress_list **pNode) +{ + SigSuppress_list *nNode = NULL; + + if( ((sHead == NULL) || (*sHead == NULL)) || + ((cNode == NULL) || (*cNode == NULL)) || + ((pNode == NULL) || (*pNode == NULL))) + { + return 1; + } + + nNode =(SigSuppress_list *)(*cNode)->next; + + if( *cNode == *sHead) + { + *sHead = nNode; + free(*cNode); + *cNode = nNode; + *pNode = *cNode; + } + else + { + (*(SigSuppress_list **)(pNode))->next = nNode; + free(*cNode); + *cNode = nNode; + } + + return 0; +} + +int SigSuppressAddElement(SigSuppress_list **sHead,SigSuppress_list *sElement) +{ + SigSuppress_list *cNode = NULL; + SigSuppress_list *pNode = NULL; + SigSuppress_list *newNode = NULL; + + u_int8_t comp_set[4] = {0}; + + int has_flag = 0; + int no_add = 0; + + if( (sHead == NULL) || + (sElement == NULL)) + { + return 1; + } + + if(*sHead == NULL) + { + if( (newNode = calloc(1,sizeof(SigSuppress_list))) == NULL) + { + return 1; + } + + memcpy(newNode,sElement,sizeof(SigSuppress_list)); + *sHead = newNode; + } + else + { + cNode = *sHead; + pNode = cNode; + + has_flag = 0; + no_add = 0; + + while(cNode != NULL) + { + memset(&comp_set,'\0',(sizeof(u_int8_t)*4)); + + if( (cNode->gid == sElement->gid)) + { + switch(sElement->ss_type) + { + case SS_SINGLE: + switch(cNode->ss_type) + { + case SS_SINGLE: + if( ((cNode->ss_min == sElement->ss_min) && + (cNode->ss_max == sElement->ss_max))) + { + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS,"[%s()], Signature Suppress configuration entry type:[SINGLE] gid:[%d] sid:[%d] was not added because it is already in present.\n", + __FUNCTION__, + sElement->gid, + sElement->ss_min);); + return 0; + } + break; + + case SS_RANGE: + if( ((cNode->ss_min <= sElement->ss_min) && + (cNode->ss_max >= sElement->ss_max))) + { + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS, + "[%s()], Signature Suppress configuration entry gid:[%d] sid[%d] already covered by\n" + "Signature Suppress configuration list element type:[RANGE] gid:[%d] sid min:[%d] sid max:[%d].\n", + __FUNCTION__, + sElement->gid, + sElement->ss_min, + cNode->gid, + cNode->ss_min, + cNode->ss_max);); + return 0; + } + break; + + default: + /* XXX */ + return 1; + break; + } + break; + + case SS_RANGE: + switch(cNode->ss_type) + { + case SS_SINGLE: + if( ((sElement->ss_min <= cNode->ss_min) && + (sElement->ss_max >= cNode->ss_max))) + { + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS, + "[%s()], Signature Suppress configuration gid:[%d] sid:[%d] flagged for deletion from list,\n" + "Element is intersecting with Signature Suppress list range gid[%d] sid min:[%d] sid max:[%d]\n\n", + __FUNCTION__, + cNode->gid, + cNode->ss_min, + sElement->gid, + sElement->ss_min, + sElement->ss_max);); + cNode->flag = 1; + has_flag = 1; + } + break; + + case SS_RANGE: + if(sElement->ss_min <= cNode->ss_min) + comp_set[0] = 1; + + if(sElement->ss_min >= cNode->ss_max) + comp_set[1] = 1; + + if(sElement->ss_max >= cNode->ss_min) + comp_set[2] = 1; + + if(sElement->ss_max <= cNode->ss_max) + comp_set[3] = 1; + + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS, + "[%s()]: Comparing Signature intersection comp0:[%d] comp1:[%d] comp2:[%d] comp3:[%d]\n" + "Signature Suppress configuration entry: gid:[%d] sid min:[%d] sid max:[%d]\n" + "Signature Suppress list entry: gid:[%d] sid min:[%d] sid max:[%d]\n\n", + __FUNCTION__, + comp_set[0],comp_set[1],comp_set[2],comp_set[3], + sElement->gid,sElement->ss_min,sElement->ss_max, + cNode->gid,cNode->ss_min,cNode->ss_max);); + + if( (comp_set[0] && !comp_set[1] && comp_set[2] && comp_set[3]) || + (!comp_set[0] && !comp_set[1] && comp_set[2] && comp_set[3])) + { + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS, + "[%s()]: Signature Suppress configuration entry gid:[%d] sid min:[%d] sid max:[%d] is INCLUDED in \n" + "Signature Suppress list entry gid:[%d] sid min:[%d] sid max:[%d]\n\n", + __FUNCTION__, + sElement->gid,sElement->ss_min,sElement->ss_max, + cNode->gid,cNode->ss_min,cNode->ss_max);); + + no_add = 1; + } + else if( (comp_set[0] && comp_set[1] && !comp_set[2] && comp_set[3]) || + (!comp_set[0] && !comp_set[1] && comp_set[2] && !comp_set[3])) + { + + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS, + "[%s()]: Signature Suppress list entry gid:[%d] sid min:[%d] sid max:[%d] and\n" + "Signature Suppress configuration entry gid:[%d] sid min:[%d] sid max:[%d] share some intesection, altering list entry. \n\n", + __FUNCTION__, + cNode->gid,cNode->ss_min,cNode->ss_max, + sElement->gid,sElement->ss_min,sElement->ss_max);); + + if(sElement->ss_min <= cNode->ss_min) + { + cNode->ss_min = sElement->ss_min; + } + + if(sElement->ss_max >= cNode->ss_max) + { + cNode->ss_max = sElement->ss_max; + } + + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS, + "[%s()]: Modified Signature Suppress list entry gid:[%d] sid min:[%d] sid max:[%d] \n", + __FUNCTION__, + cNode->gid,cNode->ss_min,cNode->ss_max);); + + no_add = 1; + } + break; + + default: + FatalError("[%s()]: Unknown type[%d] for Signature Suppress configuration entry gid:[%d] sid min:[%d] max sid:[%d] \n", + __FUNCTION__, + cNode->ss_type, + cNode->gid, + cNode->ss_min, + cNode->ss_max); + return 1; + break; + + } + break; + + default: + FatalError("[%s()]: Unknown type[%d] for Signature Suppress configuration entry gid:[%d] sid min:[%d] max sid:[%d] \n", + __FUNCTION__, + sElement->ss_type, + sElement->gid, + sElement->ss_min, + sElement->ss_max); + return 1; + break; + } + } + + pNode = cNode; + cNode = cNode->next; + } + + /* We could keep an index, but rolling is way faster isin't ;) */ + if(has_flag) + { + cNode = *sHead; + pNode = cNode; + + while(cNode) + { + if(cNode->flag) + { + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS, + "[%s(), unlinking Signature Suppress list entry type:[%d] gid:[%d] sid_min:[%d] sid_max:[%d] \n", + __FUNCTION__, + cNode->ss_type, + cNode->gid, + cNode->ss_min, + cNode->ss_max);); + + if( SigSuppressUnlinkNode(sHead,&cNode,&pNode)) + { + return 1; + } + } + + if(cNode) + { + pNode = cNode; + cNode = cNode->next; + } + } + } + + if(!no_add) + { + if( (newNode = calloc(1,sizeof(SigSuppress_list))) == NULL) + { + return 1; + } + + memcpy(newNode,sElement,sizeof(SigSuppress_list)); + + pNode->next = newNode; + + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS, + "[%s()], Signature Suppress configuration entry type:[%s] gid:[%d] sid min:[%d] sid max:[%d] added to Signature Suppress list.\n", + __FUNCTION__, + (newNode->ss_type & SS_SINGLE) ? "SINGLE" : "RANGE", + newNode->gid, + newNode->ss_min, + newNode->ss_max);); + } + } + + + return 0; +} + +void ConfigSigSuppress(Barnyard2Config *bc, char *args) +{ + char **toks = NULL; + int num_toks = 0; + int ptoks = 0; + + char gid_string[256] = {0}; + + char **range_toks = NULL; + int range_num_toks = 0; + + char **gid_toks = NULL; + char *gid_sup_toks = NULL; + int gid_num_toks = 0; + + SigSuppress_list t_supp_elem = {0}; + + if( (bc == NULL) || (args == NULL)) + { + return; + } + + toks = mSplit(args, ",", 0, &num_toks, 0); + + while(ptoks < num_toks) + { + memset(gid_string,'\0',256); + + gid_toks = mSplit(toks[ptoks], ":", 2, &gid_num_toks, 0); + + if(gid_num_toks == 1) + { + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS_PARSE,"Defaulting gid 1 for toks [%s]\n", + toks[ptoks]);); + t_supp_elem.gid = 1; + gid_sup_toks = toks[ptoks]; + } + else if(gid_num_toks == 2) + { + memcpy(gid_string,gid_toks[0],strlen(gid_toks[0])); + + if( BY2Strtoul(gid_string,&t_supp_elem.gid)) + { + FatalError("[%s] \n",__FUNCTION__); + } + + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS_PARSE,"Using gid [%d] for toks [%s]\n", + t_supp_elem.gid, + toks[ptoks]);); + + gid_sup_toks = gid_toks[1]; + } + else + { + FatalError("[%s()]: Invalid gid split value for [%s]\n", + __FUNCTION__, + toks[ptoks]); + } + + range_toks = mSplit(gid_sup_toks, "-", 0, &range_num_toks, 0); + + if(range_num_toks == 1) + { + t_supp_elem.ss_type = SS_SINGLE; + + if( BY2Strtoul(gid_sup_toks,&t_supp_elem.ss_min)) + { + FatalError("[%s] \n",__FUNCTION__); + } + + t_supp_elem.ss_max = t_supp_elem.ss_min; + + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS_PARSE,"Single element gid[%d] sid[%d] \n", + t_supp_elem.gid, + t_supp_elem.ss_min);); + } + else if(range_num_toks == 2) + { + DEBUG_WRAP(DebugMessage(DEBUG_SID_SUPPRESS_PARSE,"Got range [%s] : [%s] [%s] \n", + gid_sup_toks, + range_toks[0], + range_toks[1]);); + + t_supp_elem.ss_type = SS_RANGE; + + if( BY2Strtoul(range_toks[0],&t_supp_elem.ss_min)) + { + FatalError("[%s] \n",__FUNCTION__); + } + + if( BY2Strtoul(range_toks[1],&t_supp_elem.ss_max)) + { + FatalError("[%s] \n",__FUNCTION__); + } + + if(t_supp_elem.ss_min > t_supp_elem.ss_max) + { + FatalError("[%s()], Min greater than max, invalid range [%s] \n", + __FUNCTION__, + gid_sup_toks); + } + + if(t_supp_elem.ss_min == t_supp_elem.ss_max) + { + FatalError("[%s()], Min equal than max, invalid range [%s] \n", + __FUNCTION__, + gid_sup_toks); + } + } + else + { + FatalError("element[%s] is an invalid range \n",gid_sup_toks); + } + + mSplitFree(&range_toks, range_num_toks); + mSplitFree(&gid_toks, gid_num_toks); + + if(SigSuppressAddElement(BCGetSigSuppressHead(),&t_supp_elem)) + { + FatalError("[%s()], unrecoverable call to SigSuppressAddElement() \n", + __FUNCTION__); + } + + ptoks++; + } + + mSplitFree(&toks, num_toks); + return; +} + + + + #ifdef MPLS void ConfigMaxMplsLabelChain(Barnyard2Config *bc, char *args) { diff -Nru securityonion-barnyard2-20121109/src/parser.h securityonion-barnyard2-20140531/src/parser.h --- securityonion-barnyard2-20121109/src/parser.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/parser.h 2014-02-10 16:34:05.000000000 +0000 @@ -76,6 +76,7 @@ #define CONFIG_OPT__UTC "utc" #define CONFIG_OPT__VERBOSE "verbose" #define CONFIG_OPT__WALDO_FILE "waldo_file" +#define CONFIG_OPT__SIGSUPPRESS "sig_suppress" #ifdef MPLS # define CONFIG_OPT__MAX_MPLS_LABELCHAIN_LEN "max_mpls_labelchain_len" # define CONFIG_OPT__MPLS_PAYLOAD_TYPE "mpls_payload_type" @@ -151,6 +152,9 @@ void ConfigMaxMplsLabelChain(Barnyard2Config *, char *); void ConfigMplsPayloadType(Barnyard2Config *, char *); #endif +void ConfigSigSuppress(Barnyard2Config *, char *); +void DisplaySigSuppress(SigSuppress_list **); + // use this so mSplit doesn't split IP lists (try c = ';') char* FixSeparators (char* rule, char c, const char* err); diff -Nru securityonion-barnyard2-20121109/src/plugbase.c securityonion-barnyard2-20140531/src/plugbase.c --- securityonion-barnyard2-20121109/src/plugbase.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/plugbase.c 2014-02-10 16:34:05.000000000 +0000 @@ -51,6 +51,8 @@ #include "debug.h" #include "util.h" +#include "unified2.h" + /* built-in input plugins */ #include "input-plugins/spi_unified2.h" @@ -79,6 +81,7 @@ extern PluginSignalFuncNode *plugin_shutdown_funcs; extern PluginSignalFuncNode *plugin_clean_exit_funcs; extern PluginSignalFuncNode *plugin_restart_funcs; + extern InputFuncNode *InputList; extern OutputFuncNode *AlertList; extern OutputFuncNode *LogList; @@ -95,7 +98,6 @@ void RegisterInputPlugins() { LogMessage("Initializing Input Plugins!\n"); - Unified2Setup(); } @@ -198,6 +200,7 @@ node2->keyword = SnortStrdup(keyword); } + InputConfigFunc GetInputConfigFunc(char *keyword) { InputConfigFuncNode *head = input_config_funcs; @@ -321,7 +324,7 @@ void RegisterOutputPlugins(void) { LogMessage("Initializing Output Plugins!\n"); - + AlertCEFSetup(); AlertSyslogSetup(); @@ -465,8 +468,61 @@ free(head); head = tmp; } + + output_config_funcs = NULL; } + +void FreeInputPlugins(void) +{ + + InputConfigFuncNode *tmp = input_config_funcs; + InputConfigFuncNode *next = NULL; + + InputFuncNode *tmp2 = InputList; + InputFuncNode *next2 = NULL; + + while(tmp != NULL) + { + next = tmp->next; + + if(tmp->keyword != NULL) + { + free(tmp->keyword); + tmp->keyword = NULL; + } + + free(tmp); + tmp = next; + } + + + while(tmp2 != NULL) + { + next2 =tmp2->next; + + if( tmp2->keyword != NULL) + { + free(tmp2->keyword); + tmp2->keyword = NULL; + } + + if( tmp2->arg != NULL) + { + free(tmp2->arg); + tmp2->arg = NULL; + } + + free(tmp2); + tmp2 = next2; + } + + input_config_funcs = NULL; + InputList = NULL; + return; +} + + void FreeOutputList(OutputFuncNode *list) { while (list != NULL) @@ -480,6 +536,7 @@ free(tmp); } } + } /**************************************************************************** @@ -554,10 +611,75 @@ node->arg = arg; } +int pbCheckSignatureSuppression(void *event) +{ + Unified2EventCommon *uCommon = (Unified2EventCommon *)event; + SigSuppress_list **sHead = BCGetSigSuppressHead(); + SigSuppress_list *cNode = NULL; + u_int32_t gid = 0; + u_int32_t sid = 0; + + if( (uCommon == NULL) || + (sHead == NULL)) + { + return 0; + } + + cNode = *sHead; + + gid = ntohl(uCommon->generator_id); + sid = ntohl(uCommon->signature_id); + + while(cNode) + { + if(cNode->gid == gid) + { + switch(cNode->ss_type) + { + case SS_SINGLE: + if(cNode->ss_min == sid) + { + SigSuppressCount(); + return 1; + } + break; + + case SS_RANGE: + if( (sid >= cNode->ss_min) && + (sid <= cNode->ss_max)) + { + SigSuppressCount(); + return 1; + } + break; + + default: + FatalError("[%s()], Unknown Signature suppress type \n", + __FUNCTION__); + break; + } + + } + cNode = cNode->next; + } + + return 0; +} + + + void CallOutputPlugins(OutputType out_type, Packet *packet, void *event, uint32_t event_type) { OutputFuncNode *idx = NULL; + /* Plug for sid suppression */ + if(event) + { + if(pbCheckSignatureSuppression(event)) + return; + } + + if (out_type == OUTPUT_TYPE__SPECIAL) { idx = AlertList; @@ -666,6 +788,7 @@ node->arg = arg; } + void FreePluginSigFuncs(PluginSignalFuncNode *head) { while (head != NULL) diff -Nru securityonion-barnyard2-20121109/src/plugbase.h securityonion-barnyard2-20140531/src/plugbase.h --- securityonion-barnyard2-20121109/src/plugbase.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/plugbase.h 2014-02-10 16:34:05.000000000 +0000 @@ -190,6 +190,6 @@ void AddFuncToSignalList(PluginSignalFunc, void *, PluginSignalFuncNode **); void PostConfigInitPlugins(PluginSignalFuncNode *); void FreePluginSigFuncs(PluginSignalFuncNode *); - +void FreeInputPlugins(void); #endif /* __PLUGBASE_H__ */ diff -Nru securityonion-barnyard2-20121109/src/spooler.c securityonion-barnyard2-20140531/src/spooler.c --- securityonion-barnyard2-20121109/src/spooler.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/spooler.c 2014-02-10 16:34:05.000000000 +0000 @@ -1,6 +1,6 @@ /* ** -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** ** 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 @@ -162,6 +162,8 @@ /* create the spooler structure and allocate all memory */ spooler = (Spooler *)SnortAlloc(sizeof(Spooler)); + RegisterSpooler(spooler); + /* allocate some extra structures required (ie. Packet) */ spooler->fd = -1; @@ -180,6 +182,7 @@ /* sanity check the filepath */ if (ret != SNORT_SNPRINTF_SUCCESS) { + UnRegisterSpooler(spooler); spoolerClose(spooler); FatalError("spooler: filepath too long!\n"); } @@ -193,6 +196,7 @@ { LogMessage("ERROR: Unable to open log spool file '%s' (%s)\n", spooler->filepath, strerror(errno)); + UnRegisterSpooler(spooler); spoolerClose(spooler); spooler = NULL; return NULL; @@ -205,6 +209,7 @@ if (spooler->ifn == NULL) { + UnRegisterSpooler(spooler); spoolerClose(spooler); spooler = NULL; FatalError("ERROR: No suitable input plugin found!\n"); @@ -234,6 +239,51 @@ return 0; } +void RegisterSpooler(Spooler *spooler) +{ + Barnyard2Config *bc = BcGetConfig(); + + if(!bc) + return; + + + if(bc->spooler) + { + /* XXX */ + FatalError("[%s()], can't register spooler. \n", + __FUNCTION__); + } + else + { + bc->spooler = spooler; + } + + return; +} + +void UnRegisterSpooler(Spooler *spooler) +{ + Barnyard2Config *bc = BcGetConfig(); + + if(!bc) + return; + + if(bc->spooler != spooler) + { + /* XXX */ + FatalError("[%s()], can't un-register spooler. \n", + __FUNCTION__); + } + else + { + bc->spooler = NULL; + } + + return; +} + + + int spoolerReadRecordHeader(Spooler *spooler) { int ret; @@ -315,6 +365,9 @@ while (exit_signal == 0 && pb_ret == 0) { + /* for SIGUSR1 / dropstats */ + SignalCheck(); + switch (spooler->state) { case SPOOLER_STATE_OPENED: @@ -404,6 +457,9 @@ /* Start the main process loop */ while (exit_signal == 0) { + /* for SIGUSR1 / dropstats */ + SignalCheck(); + /* no spooler exists so let's create one */ if (spooler == NULL) { @@ -492,6 +548,7 @@ #endif /* we've finished with the spooler so destroy and cleanup */ + UnRegisterSpooler(spooler); spoolerClose(spooler); spooler = NULL; @@ -568,6 +625,7 @@ ArchiveFile(spooler->filepath, BcArchiveDir()); /* close (ie. destroy and cleanup) the spooler so we can rotate */ + UnRegisterSpooler(spooler); spoolerClose(spooler); spooler = NULL; @@ -608,8 +666,8 @@ /* close waldo if appropriate */ if(barnyard2_conf) - spoolerCloseWaldo(&barnyard2_conf->waldo); - + spoolerCloseWaldo(&barnyard2_conf->waldo); + return pc_ret; } @@ -918,6 +976,36 @@ return 0; } +void spoolerEventCacheFlush(Spooler *spooler) +{ + EventRecordNode *next_ptr = NULL; + EventRecordNode *evt_ptr = NULL; + + if (spooler == NULL || spooler->event_cache == NULL ) + return; + + evt_ptr = spooler->event_cache; + + while(evt_ptr != NULL) + { + next_ptr = evt_ptr->next; + + if(evt_ptr->data) + { + free(evt_ptr->data); + evt_ptr->data = NULL; + } + + free(evt_ptr); + + evt_ptr = next_ptr; + } + + spooler->event_cache = NULL; + + return; +} + void spoolerFreeRecord(Record *record) { @@ -926,6 +1014,7 @@ free(record->data); } + record->data = NULL; } @@ -996,13 +1085,17 @@ */ int spoolerCloseWaldo(Waldo *waldo) { - + if(waldo == NULL) + return WALDO_STRUCT_EMPTY; + /* check we have a valid file descriptor */ if (waldo->state & WALDO_STATE_OPEN) return WALDO_FILE_EOPEN; /* close the file */ - close(waldo->fd); + if(waldo->fd > 0) + close(waldo->fd); + waldo->fd = -1; /* reset open state and mode */ diff -Nru securityonion-barnyard2-20121109/src/spooler.h securityonion-barnyard2-20140531/src/spooler.h --- securityonion-barnyard2-20121109/src/spooler.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/spooler.h 2014-02-10 16:34:05.000000000 +0000 @@ -1,6 +1,6 @@ /* ** -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** ** 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 @@ -98,7 +98,7 @@ void *header; // header of input file Record record; // data of current Record - + EventRecordNode *event_cache; // linked list of cached events uint32_t events_cached; @@ -130,6 +130,12 @@ int ProcessWaldoFile(const char *); int spoolerReadWaldo(Waldo *); +void spoolerEventCacheFlush(Spooler *); +void RegisterSpooler(Spooler *); +void UnRegisterSpooler(Spooler *); + +int spoolerCloseWaldo(Waldo *); +int spoolerClose(Spooler *); #endif /* __SPOOLER_H__ */ diff -Nru securityonion-barnyard2-20121109/src/unified2.h securityonion-barnyard2-20140531/src/unified2.h --- securityonion-barnyard2-20121109/src/unified2.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/unified2.h 2014-02-10 16:34:05.000000000 +0000 @@ -1,6 +1,6 @@ /* ** -** Copyright (C) 2008-2012 Ian Firns (SecurixLive) +** Copyright (C) 2008-2013 Ian Firns (SecurixLive) ** ** Copyright (C) 2002-2009 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch diff -Nru securityonion-barnyard2-20121109/src/util.c securityonion-barnyard2-20140531/src/util.c --- securityonion-barnyard2-20121109/src/util.c 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/util.c 2014-02-10 16:34:05.000000000 +0000 @@ -145,7 +145,7 @@ " ______ -*> Barnyard2 <*-\n" " / ,,_ \\ Version %s.%s.%s (Build %s)%s%s\n" " |o\" )~| By Ian Firns (SecurixLive): http://www.securixlive.com/\n" - " + '''' + (C) Copyright 2008-2012 Ian Firns \n" + " + '''' + (C) Copyright 2008-2013 Ian Firns \n" "\n" , VER_MAJOR, VER_MINOR, VER_REVISION, VER_BUILD, #ifdef DEBUG @@ -593,7 +593,8 @@ #endif } - exit(1); + CleanExit(1); + } @@ -836,13 +837,15 @@ "===============================\n"); LogMessage("Record Totals:\n"); - LogMessage(" Records: " FMTu64("12") "\n", pc.total_records); - LogMessage(" Events: " FMTu64("12") " (%.3f%%)\n", pc.total_events, + LogMessage(" Records:" FMTu64("12") "\n", pc.total_records); + LogMessage(" Events:" FMTu64("12") " (%.3f%%)\n", pc.total_events, CalcPct(pc.total_events, pc.total_records)); - LogMessage(" Packets: " FMTu64("12") " (%.3f%%)\n", pc.total_packets, + LogMessage(" Packets:" FMTu64("12") " (%.3f%%)\n", pc.total_packets, CalcPct(pc.total_packets, pc.total_records)); - LogMessage(" Unknown: " FMTu64("12") " (%.3f%%)\n", pc.total_unknown, + LogMessage(" Unknown:" FMTu64("12") " (%.3f%%)\n", pc.total_unknown, CalcPct(pc.total_unknown, pc.total_records)); + LogMessage(" Suppressed:" FMTu64("12") " (%.3f%%)\n", pc.total_suppressed, + CalcPct(pc.total_suppressed, pc.total_records)); total = pc.total_packets; @@ -1018,6 +1021,13 @@ protocol_names[i] = NULL; } } + + if(protocol_names) + { + free(protocol_names); + protocol_names = NULL; + } + } /**************************************************************************** @@ -1078,9 +1088,9 @@ { #ifndef WIN32 int exit_val = 0; - int ret = 0; + int ret = 0; pid_t fs; - + LogMessage("Initializing daemon mode\n"); if (BcDaemonRestart()) @@ -1179,7 +1189,6 @@ ret = dup(0); /* stderr, fd 0 => fd 2 */ SignalWaitingParent(); - #endif /* ! WIN32 */ } @@ -2262,8 +2271,8 @@ { int count, cols, bits, c, char_count; unsigned char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* 64 bytes */ - char * payloadptr; + char_count = 0; bits = 0; cols = 0; @@ -2276,7 +2285,6 @@ memset(output,'\0',MAX_QUERY_LENGTH); - payloadptr = output; for(count = 0; count < length; count++) { @@ -2715,3 +2723,35 @@ return 0; } + +int BY2Strtoul(char *inStr,unsigned long *ul_ptr) +{ + char *endptr = NULL; + + if( (inStr == NULL) || + (ul_ptr == NULL)) + { + return 1; + } + + *ul_ptr = strtoul(inStr,&endptr,10); + + if ((errno == ERANGE && ( *ul_ptr == LONG_MAX || *ul_ptr == LONG_MIN)) || + (errno != 0 && *ul_ptr == 0)) + { + FatalError("[%s()], strtoul error : [%s] for [%s]\n", + __FUNCTION__, + strerror(errno), + inStr); + } + + if( *endptr != '\0' || (endptr == inStr)) + { + LogMessage("[%s()], is not a digit [%s] \n", + __FUNCTION__, + inStr); + return 1; + } + + return 0; +} diff -Nru securityonion-barnyard2-20121109/src/util.h securityonion-barnyard2-20140531/src/util.h --- securityonion-barnyard2-20121109/src/util.h 2012-11-07 11:08:08.000000000 +0000 +++ securityonion-barnyard2-20140531/src/util.h 2014-02-10 16:34:05.000000000 +0000 @@ -248,4 +248,5 @@ unsigned long int xatou(const char *, const char *); unsigned long int xatoup(const char *, const char *); // return > 0 +int BY2Strtoul(char *,unsigned long *); #endif /*__UTIL_H__*/