From 54be743c48d0a9f64be75bd3de15384024e7fa0e Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Tue, 7 Sep 2021 14:37:46 -0600 Subject: [PATCH] prelude: remove the prelude output It was broken in 6 and that didn't cause much issue. Just remove it for 7. --- configure.ac | 25 - doxygen.cfg | 2 +- m4/libprelude.m4 | 189 ------ qa/docker/buildbot.cfg | 4 +- src/Makefile.am | 2 - src/alert-prelude.c | 1313 --------------------------------------- src/alert-prelude.h | 31 - src/output.c | 3 - src/runmode-af-packet.c | 1 - src/runmode-netmap.c | 1 - src/runmodes.c | 9 - src/suricata-common.h | 1 - src/util-profiling.c | 1 - src/util-runmodes.c | 1 - suricata.yaml.in | 8 - 15 files changed, 3 insertions(+), 1588 deletions(-) delete mode 100644 m4/libprelude.m4 delete mode 100644 src/alert-prelude.c delete mode 100644 src/alert-prelude.h diff --git a/configure.ac b/configure.ac index 5d9411a46d..5c5781feec 100644 --- a/configure.ac +++ b/configure.ac @@ -1184,30 +1184,6 @@ fi # /WinDivert - # prelude - AC_ARG_ENABLE(prelude, - AS_HELP_STRING([--enable-prelude], [Enable Prelude support for alerts]),[enable_prelude=$enableval],[enable_prelude=no]) - # Prelude doesn't work with -Werror - STORECFLAGS="${CFLAGS}" - CFLAGS="${CFLAGS} -Wno-error=unused-result" - - AS_IF([test "x$enable_prelude" = "xyes"], [ - AM_PATH_LIBPRELUDE(0.9.9, , AC_MSG_ERROR(Cannot find libprelude: Is libprelude-config in the path?), no) - if test "x${LIBPRELUDE_CFLAGS}" != "x"; then - CPPFLAGS="${CPPFLAGS} ${LIBPRELUDE_CFLAGS}" - fi - - if test "x${LIBPRELUDE_LDFLAGS}" != "x"; then - LDFLAGS="${LDFLAGS} ${LIBPRELUDE_LDFLAGS}" - fi - - if test "x${LIBPRELUDE_LIBS}" != "x"; then - LDFLAGS="${LDFLAGS} ${LIBPRELUDE_LIBS}" - fi - AC_DEFINE([PRELUDE], [1], [Libprelude support enabled]) - ]) - CFLAGS="${STORECFLAGS}" - # libnet AC_ARG_WITH(libnet_includes, @@ -2724,7 +2700,6 @@ SURICATA_BUILD_CONF="Suricata Configuration: libjansson support: ${enable_jansson} hiredis support: ${enable_hiredis} hiredis async with libevent: ${enable_hiredis_async} - Prelude support: ${enable_prelude} PCRE jit: ${pcre_jit_available} LUA support: ${enable_lua} libluajit: ${enable_luajit} diff --git a/doxygen.cfg b/doxygen.cfg index 273e402551..7dee5c2a2e 100644 --- a/doxygen.cfg +++ b/doxygen.cfg @@ -2170,7 +2170,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = NFQ IPFW HAVE_PFRING HAVE_AF_PACKET PRELUDE HAVE_NAPATECH HAVE_DAG PROFILING UNITTESTS +PREDEFINED = NFQ IPFW HAVE_PFRING HAVE_AF_PACKET HAVE_NAPATECH HAVE_DAG PROFILING UNITTESTS # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/m4/libprelude.m4 b/m4/libprelude.m4 deleted file mode 100644 index 64b6478e39..0000000000 --- a/m4/libprelude.m4 +++ /dev/null @@ -1,189 +0,0 @@ -dnl Autoconf macros for libprelude -dnl $id$ - -# Modified for LIBPRELUDE -- Yoann Vandoorselaere -# Modified for LIBGNUTLS -- nmav -# Configure paths for LIBGCRYPT -# Shamelessly stolen from the one of XDELTA by Owen Taylor -# Werner Koch 99-12-09 - -dnl AM_PATH_LIBPRELUDE([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]], THREAD_SUPPORT) -dnl Test for libprelude, and define LIBPRELUDE_PREFIX, LIBPRELUDE_CFLAGS, LIBPRELUDE_PTHREAD_CFLAGS, -dnl LIBPRELUDE_LDFLAGS, and LIBPRELUDE_LIBS -dnl -AC_DEFUN([AM_PATH_LIBPRELUDE], -[dnl -dnl Get the cflags and libraries from the libprelude-config script -dnl -AC_ARG_WITH(libprelude-prefix, AC_HELP_STRING(--with-libprelude-prefix=PFX, - Prefix where libprelude is installed (optional)), - libprelude_config_prefix="$withval", libprelude_config_prefix="") - - if test x$libprelude_config_prefix != x ; then - if test x${LIBPRELUDE_CONFIG+set} != xset ; then - LIBPRELUDE_CONFIG=$libprelude_config_prefix/bin/libprelude-config - fi - fi - - AC_PATH_PROG(LIBPRELUDE_CONFIG, libprelude-config, no) - if test "$LIBPRELUDE_CONFIG" != "no"; then - if $($LIBPRELUDE_CONFIG --thread > /dev/null 2>&1); then - LIBPRELUDE_PTHREAD_CFLAGS=`$LIBPRELUDE_CONFIG --thread --cflags` - - if test x$4 = xtrue || test x$4 = xyes; then - libprelude_config_args="--thread" - else - libprelude_config_args="--no-thread" - fi - else - LIBPRELUDE_PTHREAD_CFLAGS=`$LIBPRELUDE_CONFIG --pthread-cflags` - fi - fi - - min_libprelude_version=ifelse([$1], ,0.1.0,$1) - AC_MSG_CHECKING(for libprelude - version >= $min_libprelude_version) - no_libprelude="" - if test "$LIBPRELUDE_CONFIG" = "no" ; then - no_libprelude=yes - else - LIBPRELUDE_CFLAGS=`$LIBPRELUDE_CONFIG $libprelude_config_args --cflags` - LIBPRELUDE_LDFLAGS=`$LIBPRELUDE_CONFIG $libprelude_config_args --ldflags` - LIBPRELUDE_LIBS=`$LIBPRELUDE_CONFIG $libprelude_config_args --libs` - LIBPRELUDE_PREFIX=`$LIBPRELUDE_CONFIG $libprelude_config_args --prefix` - LIBPRELUDE_CONFIG_PREFIX=`$LIBPRELUDE_CONFIG $libprelude_config_args --config-prefix` - libprelude_config_version=`$LIBPRELUDE_CONFIG $libprelude_config_args --version` - - - ac_save_CFLAGS="$CFLAGS" - ac_save_LDFLAGS="$LDFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $LIBPRELUDE_CFLAGS" - LDFLAGS="$LDFLAGS $LIBPRELUDE_LDFLAGS" - LIBS="$LIBS $LIBPRELUDE_LIBS" -dnl -dnl Now check if the installed libprelude is sufficiently new. Also sanity -dnl checks the results of libprelude-config to some extent -dnl - rm -f conf.libpreludetest - AC_TRY_RUN([ -#include -#include -#include -#include - -int -main () -{ - system ("touch conf.libpreludetest"); - - if( strcmp( prelude_check_version(NULL), "$libprelude_config_version" ) ) - { - printf("\n*** 'libprelude-config --version' returned %s, but LIBPRELUDE (%s)\n", - "$libprelude_config_version", prelude_check_version(NULL) ); - printf("*** was found! If libprelude-config was correct, then it is best\n"); - printf("*** to remove the old version of LIBPRELUDE. You may also be able to fix the error\n"); - printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); - printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); - printf("*** required on your system.\n"); - printf("*** If libprelude-config was wrong, set the environment variable LIBPRELUDE_CONFIG\n"); - printf("*** to point to the correct copy of libprelude-config, and remove the file config.cache\n"); - printf("*** before re-running configure\n"); - } - else if ( strcmp(prelude_check_version(NULL), LIBPRELUDE_VERSION ) ) { - printf("\n*** LIBPRELUDE header file (version %s) does not match\n", LIBPRELUDE_VERSION); - printf("*** library (version %s)\n", prelude_check_version(NULL) ); - } - else { - if ( prelude_check_version( "$min_libprelude_version" ) ) - return 0; - else { - printf("no\n*** An old version of LIBPRELUDE (%s) was found.\n", - prelude_check_version(NULL) ); - printf("*** You need a version of LIBPRELUDE newer than %s. The latest version of\n", - "$min_libprelude_version" ); - printf("*** LIBPRELUDE is always available from http://www.prelude-siem.com/index.php/en/community/download\n"); - printf("*** \n"); - printf("*** If you have already installed a sufficiently new version, this error\n"); - printf("*** probably means that the wrong copy of the libprelude-config shell script is\n"); - printf("*** being found. The easiest way to fix this is to remove the old version\n"); - printf("*** of LIBPRELUDE, but you can also set the LIBPRELUDE_CONFIG environment to point to the\n"); - printf("*** correct copy of libprelude-config. (In this case, you will have to\n"); - printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); - printf("*** so that the correct libraries are found at run-time))\n"); - } - } - return 1; -} -],, no_libprelude=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - LDFLAGS="$ac_save_LDFLAGS" - fi - - if test "x$no_libprelude" = x ; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - if test -f conf.libpreludetest ; then - : - else - AC_MSG_RESULT(no) - fi - if test "$LIBPRELUDE_CONFIG" = "no" ; then - echo "*** The libprelude-config script installed by LIBPRELUDE could not be found" - echo "*** If LIBPRELUDE was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the LIBPRELUDE_CONFIG environment variable to the" - echo "*** full path to libprelude-config." - else - if test -f conf.libpreludetest ; then - : - else - echo "*** Could not run libprelude test program, checking why..." - CFLAGS="$CFLAGS $LIBPRELUDE_CFLAGS" - LDFLAGS="$LDFLAGS $LIBPRELUDE_LDFLAGS" - LIBS="$LIBS $LIBPRELUDE_LIBS" - AC_TRY_LINK([ -#include -#include -#include -#include -], [ return !!prelude_check_version(NULL); ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding LIBPRELUDE or finding the wrong" - echo "*** version of LIBPRELUDE. If it is not finding LIBPRELUDE, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" - echo "***" ], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means LIBPRELUDE was incorrectly installed" - echo "*** or that you have moved LIBPRELUDE since it was installed. In the latter case, you" - echo "*** may want to edit the libprelude-config script: $LIBPRELUDE_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - LDFLAGS="$ac_save_LDFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - LIBPRELUDE_CFLAGS="" - LIBPRELUDE_LDFLAGS="" - LIBPRELUDE_LIBS="" - ifelse([$3], , :, [$3]) - fi - rm -f conf.libpreludetest - AC_SUBST(LIBPRELUDE_CFLAGS) - AC_SUBST(LIBPRELUDE_PTHREAD_CFLAGS) - AC_SUBST(LIBPRELUDE_LDFLAGS) - AC_SUBST(LIBPRELUDE_LIBS) - AC_SUBST(LIBPRELUDE_PREFIX) - AC_SUBST(LIBPRELUDE_CONFIG_PREFIX) - - m4_ifdef([LT_INIT], - [AC_DEFINE([PRELUDE_APPLICATION_USE_LIBTOOL2], [], [Define whether application use libtool >= 2.0])], - []) - -]) - -dnl *-*wedit:notab*-* Please keep this as the last line. diff --git a/qa/docker/buildbot.cfg b/qa/docker/buildbot.cfg index dec1d126b9..aae492b82e 100644 --- a/qa/docker/buildbot.cfg +++ b/qa/docker/buildbot.cfg @@ -112,11 +112,11 @@ factory_clang_32.addStep(ShellCommand(command=["make", "clean"])) factory_features = SuriBuildFactory() # run the tests (note that this will require that 'trial' is installed) factory_features.addStep(ShellCommand(command=["./autogen.sh"])) -factory_features.addStep(ShellCommand(command=["./configure","--enable-debug","--enable-unittests","--enable-nfqueue","--enable-nflog", "--enable-lua", "--enable-prelude"])) +factory_features.addStep(ShellCommand(command=["./configure","--enable-debug","--enable-unittests","--enable-nfqueue","--enable-nflog", "--enable-lua"])) factory_features.addStep(ShellCommand(command=["make"])) factory_features.addStep(ShellCommand(command=["make", "clean"])) import psutil -factory_features.addStep(ShellCommand(command=["make", "distcheck"],env={'DISTCHECK_CONFIGURE_FLAGS': "--enable-debug --enable-unittests --enable-nfqueue --enable-nflog --enable-lua --enable-prelude", "CONCURRENCY_LEVEL": str(psutil.cpu_count())})) +factory_features.addStep(ShellCommand(command=["make", "distcheck"],env={'DISTCHECK_CONFIGURE_FLAGS': "--enable-debug --enable-unittests --enable-nfqueue --enable-nflog --enable-lua", "CONCURRENCY_LEVEL": str(psutil.cpu_count())})) import os PCAP_PATH='/data/oisf/qa/docker/pcaps/' diff --git a/src/Makefile.am b/src/Makefile.am index 4965809dd5..a5c1a8714e 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,7 +13,6 @@ noinst_HEADERS = \ action-globals.h \ alert-debuglog.h \ alert-fastlog.h \ - alert-prelude.h \ alert-syslog.h \ app-layer-dcerpc-common.h \ app-layer-detect-proto.h \ @@ -595,7 +594,6 @@ noinst_HEADERS = \ libsuricata_c_a_SOURCES = \ alert-debuglog.c \ alert-fastlog.c \ - alert-prelude.c \ alert-syslog.c \ app-layer.c \ app-layer-detect-proto.c \ diff --git a/src/alert-prelude.c b/src/alert-prelude.c deleted file mode 100644 index 1e74bf69cd..0000000000 --- a/src/alert-prelude.c +++ /dev/null @@ -1,1313 +0,0 @@ -/* Copyright (C) 2007-2017 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pierre Chifflier - * \author Yoann Vandoorselaere - * - * Logs alerts to the Prelude system, using IDMEF (RFC 4765) messages. - * - * Each message contains the alert description and reference (using - * the SID/GID), and a normalized description (assessment, impact, - * sources etc.) - * - * libprelude handles the connection with the manager (collecting component), - * spooling and sending the event asynchronously. It also offers transport - * security (using TLS and trusted certificates) and reliability (events - * are retransmitted if not sent successfully). - * - * This modules requires a Prelude profile to work (see man prelude-admin - * and the Prelude Handbook for help). - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-time.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-print.h" - -#include "output.h" -#include "output-json.h" -#include "output-json-http.h" -#include "output-json-tls.h" -#include "output-json-ssh.h" -#include "output-json-smtp.h" -#include "output-json-email-common.h" - -#include "util-privs.h" -#include "util-optimize.h" - -#include "stream.h" - -#include "alert-prelude.h" - -#ifndef PRELUDE - -/* Handle the case where no PRELUDE support is compiled in. */ - -void AlertPreludeRegister(void) -{ - SCLogDebug("Can't register Prelude output thread - Prelude support was disabled during build."); -} - -#else /* implied we do have PRELUDE support */ - -#include - -#define ANALYZER_CLASS "NIDS" -#define ANALYZER_MODEL "Suricata" -#define ANALYZER_MANUFACTURER "http://www.openinfosecfoundation.org/" -#define ANALYZER_SID_URL "http://www.snort.org/search/sid/" - -#define SNORT_MAX_OWNED_SID 1000000 -#define DEFAULT_ANALYZER_NAME "suricata" - -#define DEFAULT_PRELUDE_PROFILE "suricata" - -static unsigned int info_priority = 4; -static unsigned int low_priority = 3; -static unsigned int mid_priority = 2; - -/** - * This holds global structures and variables. Since libprelude is thread-safe, - * there is no need to store a mutex. - */ -typedef struct AlertPreludeCtx_ { - /** The client (which has the send function) */ - prelude_client_t *client; - int log_packet_content; - int log_packet_header; -} AlertPreludeCtx; - -/** - * This holds per-thread specific structures and variables. - */ -typedef struct AlertPreludeThread_ { - /** Pointer to the global context */ - AlertPreludeCtx *ctx; - idmef_analyzer_t *analyzer; -} AlertPreludeThread; - - -/** - * \brief Initialize analyzer description - * - * \return 0 if ok - */ -static int SetupAnalyzer(idmef_analyzer_t *analyzer) -{ - int ret; - prelude_string_t *string; - - SCEnter(); - - ret = idmef_analyzer_new_model(analyzer, &string); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating analyzer model: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(ret); - } - ret = prelude_string_set_constant(string, ANALYZER_MODEL); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting analyzer model: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(ret); - } - - ret = idmef_analyzer_new_class(analyzer, &string); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating analyzer class: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(ret); - } - ret = prelude_string_set_constant(string, ANALYZER_CLASS); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting analyzer class: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(ret); - } - - ret = idmef_analyzer_new_manufacturer(analyzer, &string); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating analyzer manufacturer: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(ret); - } - ret = prelude_string_set_constant(string, ANALYZER_MANUFACTURER); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting analyzer manufacturer: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(ret); - } - - ret = idmef_analyzer_new_version(analyzer, &string); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating analyzer version: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(ret); - } - ret = prelude_string_set_constant(string, VERSION); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting analyzer version: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(ret); - } - - SCReturnInt(0); -} - -/** - * \brief Create event impact description (see section - * 4.2.6.1 of RFC 4765). - * The impact contains the severity, completion (succeeded or failed) - * and basic classification of the attack type. - * Here, we don't set the completion since we don't know it (default - * is unknown). - * - * \return 0 if ok - */ -static int EventToImpact(const PacketAlert *pa, const Packet *p, idmef_alert_t *alert) -{ - int ret; - prelude_string_t *str; - idmef_impact_t *impact; - idmef_assessment_t *assessment; - idmef_impact_severity_t severity; - - SCEnter(); - - ret = idmef_alert_new_assessment(alert, &assessment); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating assessment: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(ret); - } - - ret = idmef_assessment_new_impact(assessment, &impact); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating assessment impact: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(ret); - } - - if ( (unsigned int)pa->s->prio < mid_priority ) - severity = IDMEF_IMPACT_SEVERITY_HIGH; - - else if ( (unsigned int)pa->s->prio < low_priority ) - severity = IDMEF_IMPACT_SEVERITY_MEDIUM; - - else if ( (unsigned int)pa->s->prio < info_priority ) - severity = IDMEF_IMPACT_SEVERITY_LOW; - - else - severity = IDMEF_IMPACT_SEVERITY_INFO; - - idmef_impact_set_severity(impact, severity); - - if (PacketTestAction(p, ACTION_DROP) || PacketTestAction(p, ACTION_REJECT) || - PacketTestAction(p, ACTION_REJECT_DST) || PacketTestAction(p, ACTION_REJECT_BOTH)) { - idmef_action_t *action; - - ret = idmef_action_new(&action); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - idmef_action_set_category(action, IDMEF_ACTION_CATEGORY_BLOCK_INSTALLED); - idmef_assessment_set_action(assessment, action, 0); - } - - if (pa->s->msg) { - ret = idmef_impact_new_description(impact, &str); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - prelude_string_set_ref(str, pa->s->msg); - } - - SCReturnInt(0); -} - -/** - * \brief Add Source and Target fields to the IDMEF alert. - * These objects contains IP addresses, source and destination - * ports (see sections 4.2.4.3 and 4.2.4.4 of RFC 4765). - * - * \return 0 if ok - */ -static int EventToSourceTarget(const PacketAlert *pa, const Packet *p, - idmef_alert_t *alert) -{ - int ret; - idmef_node_t *node; - idmef_source_t *source; - idmef_target_t *target; - idmef_address_t *address; - idmef_service_t *service; - prelude_string_t *string; - static char saddr[128], daddr[128]; - uint8_t ip_vers; - uint8_t ip_proto; - uint16_t sp, dp; - uint8_t invert = 0; - - SCEnter(); - - if ( !p ) - SCReturnInt(0); - - if ( ! IPH_IS_VALID(p) ) - SCReturnInt(0); - - if (pa->s->flags & SIG_FLAG_HAS_TARGET) { - if (pa->s->flags & SIG_FLAG_SRC_IS_TARGET) { - invert = 1; - } else { - invert = 0; - } - } else { - invert = 0; - } - - if (PKT_IS_IPV4(p)) { - ip_vers = 4; - ip_proto = IPV4_GET_RAW_IPPROTO(p->ip4h); - if (invert) { - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), saddr, sizeof(saddr)); - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), daddr, sizeof(daddr)); - sp = p->dp; - dp = p->sp; - } else { - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), saddr, sizeof(saddr)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), daddr, sizeof(daddr)); - sp = p->sp; - dp = p->dp; - - } - } else if (PKT_IS_IPV6(p)) { - ip_vers = 6; - ip_proto = IPV6_GET_L4PROTO(p); - if (invert) { - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), saddr, sizeof(saddr)); - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), daddr, sizeof(daddr)); - sp = p->dp; - dp = p->sp; - } else { - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), saddr, sizeof(saddr)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), daddr, sizeof(daddr)); - sp = p->sp; - dp = p->dp; - } - } else - SCReturnInt(0); - - ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_source_new_service(source, &service); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - if ( p->tcph || p->udph ) - idmef_service_set_port(service, sp); - - idmef_service_set_ip_version(service, ip_vers); - idmef_service_set_iana_protocol_number(service, ip_proto); - - ret = idmef_source_new_node(source, &node); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_address_new_address(address, &string); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - prelude_string_set_ref(string, saddr); - - ret = idmef_alert_new_target(alert, &target, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_target_new_service(target, &service); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - if ( p->tcph || p->udph ) - idmef_service_set_port(service, dp); - - idmef_service_set_ip_version(service, ip_vers); - idmef_service_set_iana_protocol_number(service, ip_proto); - - ret = idmef_target_new_node(target, &node); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_address_new_address(address, &string); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - prelude_string_set_ref(string, daddr); - - SCReturnInt(0); -} - -/** - * \brief Add binary data, to be stored in the Additional Data - * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765). - * - * \return 0 if ok - */ -static int AddByteData(idmef_alert_t *alert, const char *meaning, const unsigned char *data, size_t size) -{ - int ret; - prelude_string_t *str; - idmef_additional_data_t *ad; - - SCEnter(); - - if ( ! data || ! size ) - SCReturnInt(0); - - ret = idmef_alert_new_additional_data(alert, &ad, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(0); - - ret = idmef_additional_data_set_byte_string_ref(ad, data, size); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting byte string data: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - ret = idmef_additional_data_new_meaning(ad, &str); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating additional-data meaning: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - ret = prelude_string_set_ref(str, meaning); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting byte string data meaning: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - SCReturnInt(0); -} - -/** - * \brief Add integer data, to be stored in the Additional Data - * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765). - * - * \return 0 if ok - */ -static int AddIntData(idmef_alert_t *alert, const char *meaning, uint32_t data) -{ - int ret; - prelude_string_t *str; - idmef_additional_data_t *ad; - - SCEnter(); - - ret = idmef_alert_new_additional_data(alert, &ad, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - idmef_additional_data_set_integer(ad, data); - - ret = idmef_additional_data_new_meaning(ad, &str); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating additional-data meaning: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - ret = prelude_string_set_ref(str, meaning); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting integer data meaning: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - SCReturnInt(0); -} - -/** - * \brief Add string data, to be stored in the Additional Data - * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765). - * \param alert IDMEF alert where to add additional data - * \param meaning Name of the value to add to IDMEF alert - * \param data String to add to IDMEF alert - * \return 0 if ok, else < 0 - */ -static int AddStringData(idmef_alert_t *alert, const char *meaning, const char *data) -{ - int ret; - idmef_additional_data_t *ad; - prelude_string_t * p_str; - - SCEnter(); - - ret = idmef_alert_new_additional_data(alert, &ad, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_additional_data_new_meaning(ad, &p_str); - if (ret < 0) { - idmef_additional_data_destroy(ad); - SCReturnInt(ret); - } - - ret = prelude_string_ncat(p_str, meaning, strlen(meaning)); - if (ret < 0) { - idmef_additional_data_destroy(ad); - SCReturnInt(ret); - } - - ret = prelude_string_new(&p_str); - if (ret < 0) { - idmef_additional_data_destroy(ad); - SCReturnInt(ret); - } - - ret = prelude_string_ncat(p_str, data, strlen(data)); - if (ret < 0) { - prelude_string_destroy(p_str); - idmef_additional_data_destroy(ad); - SCReturnInt(ret); - } - - ret = idmef_additional_data_set_string_dup_fast(ad, prelude_string_get_string(p_str), prelude_string_get_len(p_str)); - - prelude_string_destroy(p_str); - - if (ret < 0) { - idmef_additional_data_destroy(ad); - SCReturnInt(ret); - } - SCReturnInt(0); -} - -/** - * \brief Add real data, to be stored in the Additional Data - * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765). - * \param alert IDMEF alert where to add additional data - * \param meaning Name of the value to add to IDMEF alert - * \param data Real to add to IDMEF alert - * \return 0 if ok - */ -static int AddRealData(idmef_alert_t *alert, const char *meaning, uint32_t data) -{ - int ret; - prelude_string_t *str; - idmef_additional_data_t *ad; - - SCEnter(); - - ret = idmef_alert_new_additional_data(alert, &ad, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - idmef_additional_data_set_real(ad, data); - - ret = idmef_additional_data_new_meaning(ad, &str); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating additional-data meaning: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - ret = prelude_string_set_ref(str, meaning); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting integer data meaning: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - SCReturnInt(0); -} - -/** - * \brief Add IPv4 header data, to be stored in the Additional Data - * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765). - * - * \return 0 if ok - */ -static int PacketToDataV4(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert) -{ - SCEnter(); - - AddIntData(alert, "ip_ver", IPV4_GET_RAW_VER(p->ip4h)); - AddIntData(alert, "ip_hlen", IPV4_GET_RAW_HLEN(p->ip4h)); - AddIntData(alert, "ip_tos", IPV4_GET_RAW_IPTOS(p->ip4h)); - AddIntData(alert, "ip_len", SCNtohs(IPV4_GET_RAW_IPLEN(p->ip4h))); - - AddIntData(alert, "ip_id", SCNtohs(IPV4_GET_RAW_IPID(p->ip4h))); - - AddIntData(alert, "ip_off", SCNtohs(IPV4_GET_RAW_IPOFFSET(p->ip4h))); - - AddIntData(alert, "ip_ttl", IPV4_GET_RAW_IPTTL(p->ip4h)); - AddIntData(alert, "ip_proto", IPV4_GET_RAW_IPPROTO(p->ip4h)); - - AddIntData(alert, "ip_sum", SCNtohs(p->ip4h->ip_csum)); - - SCReturnInt(0); -} - -/** - * \brief Add IPv6 header data, to be stored in the Additional Data - * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765). - * - * \return 0 if ok - */ -static int PacketToDataV6(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert) -{ - SCEnter(); - - AddIntData(alert, "ip_ver", IPV6_GET_VER(p)); - AddIntData(alert, "ip_class", IPV6_GET_CLASS(p)); - AddIntData(alert, "ip_flow", IPV6_GET_FLOW(p)); - AddIntData(alert, "ip_nh", IPV6_GET_NH(p)); - AddIntData(alert, "ip_plen", IPV6_GET_PLEN(p)); - AddIntData(alert, "ip_hlim", IPV6_GET_HLIM(p)); - AddIntData(alert, "ip_proto", IPV6_GET_L4PROTO(p)); - - SCReturnInt(0); -} - -/** - * \brief Convert JSON object to Prelude additional data with - * the right type of data. Browse the JSON object to get - * the key=value information. - * \param key Name of the JSON value - * \param value JSON object to add to the IDMEF alert - * \param alert IDMEF alert - * \return 0 if ok - */ -static int JsonToAdditionalData(const char * key, json_t * value, idmef_alert_t *alert) -{ - SCEnter(); - - int ret = 0; - const char *key_js; - char local_key[128]; - json_t *value_js; - size_t index; - - if (!json_is_object(value) && key == NULL) - SCReturnInt(-1); - - if (json_is_object(value)) { - json_object_foreach(value, key_js, value_js) { - if (key != NULL) { - snprintf(local_key, sizeof(local_key), "%s_%s", key, key_js); - } else { - snprintf(local_key, sizeof(local_key), "%s", key_js); - } - ret = JsonToAdditionalData(local_key, value_js, alert); - } - } else if (json_is_array(value)) { - json_array_foreach(value, index, value_js) { - ret = snprintf(local_key, sizeof(local_key), "%s_%ju", key, (uintmax_t)index); - if (ret < 0 || (size_t)ret >= sizeof(local_key)) { - SCLogError(SC_ERR_SPRINTF,"failed to construct key"); - continue; - } - ret = JsonToAdditionalData(local_key, value_js, alert); - } - } else if (json_is_integer(value)) { - ret = AddIntData(alert, key, json_integer_value(value)); - } else if (json_is_real(value)) { - ret = AddRealData(alert, key, json_real_value(value)); - } else if (json_is_boolean(value)) { - ret = AddIntData(alert, key, json_is_true(value)); - } else if (json_is_string(value)) { - ret = AddStringData(alert, key, json_string_value(value)); - } else { - ret = AddStringData(alert, key, json_dumps(value, 0)); - } - SCReturnInt(ret); -} - -/** - * \brief Handle ALPROTO_HTTP1 JSON information - * \param p Packet where to extract data - * \param pa Packet alert information - * \param alert IDMEF alert - * \return void - */ -static void PacketToDataProtoHTTP(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert) -{ - json_t *js; - - js = JsonHttpAddMetadata(p->flow, pa->tx_id); - if (js == NULL) - return; - - JsonToAdditionalData(NULL, js, alert); - - json_decref(js); - -} - -/** - * \brief Handle ALPROTO_HTTP2 JSON information - * \param p Packet where to extract data - * \param pa Packet alert information - * \param alert IDMEF alert - * \return void - */ -static void PacketToDataProtoHTTP2(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert) -{ - void *http2_state = FlowGetAppState(f); - if (http2_state) { - void *tx_ptr = rs_http2_state_get_tx(http2_state, pa->tx_id); - json_t *js = rs_http2_log_json(tx_ptr); - if (unlikely(js == NULL)) - return; - JsonToAdditionalData(NULL, js, alert); - json_decref(js); - } -} - -/** - * \brief Handle ALPROTO_TLS JSON information - * \param p Packet where to extract data - * \param pa Packet alert information - * \param alert IDMEF alert - * \return void - */ -static void PacketToDataProtoTLS(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert) -{ - json_t *js; - SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow); - - if (ssl_state == NULL) - return; - - js = json_object(); - if (js == NULL) - return; - - JsonTlsLogJSONBasic(js, ssl_state); - JsonTlsLogJSONExtended(js, ssl_state); - JsonToAdditionalData(NULL, js, alert); - - json_decref(js); - -} - -/** - * \brief Handle ALPROTO_SSH JSON information - * \param p Packet where to extract data - * \param pa Packet alert information - * \param alert IDMEF alert - * \return void - */ -static void PacketToDataProtoSSH(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert) -{ - json_t *js, *s_js; - void *ssh_state = FlowGetAppState(p->flow); - - if (ssh_state == NULL) - return; - - void *tx_ptr = rs_ssh_state_get_tx(ssh_state, 0); - BUG_ON(tx_ptr == NULL); - js = rs_ssh_log_json(tx_ptr); - if (unlikely(js == NULL)) - return; - - s_js = json_object_get(js, "server"); - if (s_js != NULL) { - JsonToAdditionalData(NULL, s_js, alert); - } - - s_js = json_object_get(js, "client"); - if (s_js != NULL) { - JsonToAdditionalData(NULL, s_js, alert); - } - - json_decref(js); - -} - -/** - * \brief Handle ALPROTO_SMTP JSON information - * \param p Packet where to extract data - * \param pa Packet alert information - * \param alert IDMEF alert - * \return void - */ -static void PacketToDataProtoSMTP(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert) -{ - json_t *js; - - js = JsonSMTPAddMetadata(p->flow, pa->tx_id); - if (js == NULL) - return; - - JsonToAdditionalData(NULL, js, alert); - - json_decref(js); - -} - -/** - * \brief Handle ALPROTO_(SMTP|IMAP) Email JSON information - * \param p Packet where to extract data - * \param pa Packet alert information - * \param alert IDMEF alert - * \return void - */ -static void PacketToDataProtoEmail(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert) -{ - json_t *js; - - js = JsonEmailAddMetadata(p->flow, pa->tx_id); - if (js == NULL) - return; - - JsonToAdditionalData(NULL, js, alert); - - json_decref(js); - -} - -/** - * \brief Convert IP packet to an IDMEF alert (RFC 4765). - * This function stores the alert SID (description and reference), - * the payload of the packet, and pre-processed data. - * - * \return 0 if ok - */ -static int PacketToData(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert, AlertPreludeCtx *ctx) -{ - SCEnter(); - - if (unlikely(p == NULL)) - SCReturnInt(0); - - if (p->flow != NULL) { - uint16_t proto = FlowGetAppProtocol(p->flow); - switch (proto) { - case ALPROTO_HTTP1: - PacketToDataProtoHTTP(p, pa, alert); - break; - case ALPROTO_HTTP2: - PacketToDataProtoHTTP(p, pa, alert); - break; - case ALPROTO_TLS: - PacketToDataProtoTLS(p, pa, alert); - break; - case ALPROTO_SSH: - PacketToDataProtoSSH(p, pa, alert); - break; - case ALPROTO_SMTP: - case ALPROTO_IMAP: - PacketToDataProtoSMTP(p, pa, alert); - PacketToDataProtoEmail(p, pa, alert); - break; - } - } - - AddIntData(alert, "snort_rule_sid", pa->s->id); - AddIntData(alert, "snort_rule_rev", pa->s->rev); - - if (ctx->log_packet_header) { - if ( PKT_IS_IPV4(p) ) - PacketToDataV4(p, pa, alert); - - else if ( PKT_IS_IPV6(p) ) - PacketToDataV6(p, pa, alert); - - if ( PKT_IS_TCP(p) ) { - AddIntData(alert, "tcp_seq", TCP_GET_SEQ(p)); - AddIntData(alert, "tcp_ack", TCP_GET_ACK(p)); - - AddIntData(alert, "tcp_off", TCP_GET_OFFSET(p)); - AddIntData(alert, "tcp_res", TCP_GET_X2(p)); - AddIntData(alert, "tcp_flags", TCP_GET_FLAGS(p)); - - AddIntData(alert, "tcp_win", TCP_GET_WINDOW(p)); - AddIntData(alert, "tcp_sum", TCP_GET_SUM(p)); - AddIntData(alert, "tcp_urp", TCP_GET_URG_POINTER(p)); - if (p->tcpvars.ts_val != 0) { - AddIntData(alert, "tcp_tsval", TCP_GET_TSVAL(p)); - } - if (p->tcpvars.ts_ecr != 0) { - AddIntData(alert, "tcp_tsecr", TCP_GET_TSECR(p)); - } - if (p->tcph != NULL) { - AddIntData(alert, "tcp_wscale", TCP_GET_WSCALE(p)); - } - if (TCP_HAS_SACKOK(p)) { - AddIntData(alert, "tcp_sackok", TCP_GET_SACKOK(p)); - } - if (TCP_HAS_SACK(p)) { - AddIntData(alert, "tcp_sack_cnt", TCP_GET_SACK_CNT(p)); - } - AddIntData(alert, "tcp_hlen", TCP_GET_HLEN(p)); - } - - else if ( PKT_IS_UDP(p) ) { - AddIntData(alert, "udp_len", UDP_GET_LEN(p)); - AddIntData(alert, "udp_sum", UDP_GET_SUM(p)); - } - - else if ( PKT_IS_ICMPV4(p) ) { - AddIntData(alert, "icmp_type", ICMPV4_GET_TYPE(p)); - AddIntData(alert, "icmp_code", ICMPV4_GET_CODE(p)); - AddIntData(alert, "icmp_sum", ICMPV4_GET_RAW_CSUM(p)); - - } - - else if ( PKT_IS_ICMPV6(p) ) { - AddIntData(alert, "icmp_type", ICMPV6_GET_TYPE(p)); - AddIntData(alert, "icmp_code", ICMPV6_GET_CODE(p)); - AddIntData(alert, "icmp_csum", ICMPV6_GET_RAW_CSUM(p)); - } - } - - if (ctx->log_packet_content) - AddByteData(alert, "payload", p->payload, p->payload_len); - - SCReturnInt(0); -} - -/** - * \brief Store reference on rule (SID and GID) in the IDMEF alert, - * and embed an URL pointing to the rule description. - * - * \return 0 if ok - */ -static int AddSnortReference(idmef_classification_t *class, int gen_id, int sig_id) -{ - int ret; - prelude_string_t *str; - idmef_reference_t *ref; - - SCEnter(); - - if ( sig_id >= SNORT_MAX_OWNED_SID ) - SCReturnInt(0); - - ret = idmef_classification_new_reference(class, &ref, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_reference_new_name(ref, &str); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - idmef_reference_set_origin(ref, IDMEF_REFERENCE_ORIGIN_VENDOR_SPECIFIC); - - if ( gen_id == 0 ) - ret = prelude_string_sprintf(str, "%u", sig_id); - else - ret = prelude_string_sprintf(str, "%u:%u", gen_id, sig_id); - - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_reference_new_meaning(ref, &str); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = prelude_string_sprintf(str, "Snort Signature ID"); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_reference_new_url(ref, &str); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - if ( gen_id == 0 ) - ret = prelude_string_sprintf(str, ANALYZER_SID_URL "%u", sig_id); - else - ret = prelude_string_sprintf(str, ANALYZER_SID_URL "%u-%u", gen_id, sig_id); - - SCReturnInt(ret); -} - -/** - * \brief Create event classification description (see section - * 4.2.4.2 of RFC 4765). - * The classification is the "name" of the alert, identification of the - * rule signature, and additional information on the rule. - * - * \return 0 if ok - */ -static int EventToReference(const PacketAlert *pa, const Packet *p, idmef_classification_t *class) -{ - int ret; - prelude_string_t *str; - - SCEnter(); - - ret = idmef_classification_new_ident(class, &str); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - if ( pa->s->gid == 0 ) - ret = prelude_string_sprintf(str, "%u", pa->s->id); - else - ret = prelude_string_sprintf(str, "%u:%u", pa->s->gid, pa->s->id); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = AddSnortReference(class, pa->s->gid, pa->s->id); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - SCReturnInt(0); -} - -static int PreludePrintStreamSegmentCallback(const Packet *p, void *data, const uint8_t *buf, uint32_t buflen) -{ - int ret; - - ret = AddByteData((idmef_alert_t *)data, "stream-segment", buf, buflen); - if (ret == 0) - return 1; - else - return -1; -} - -/** - * \brief Initialize thread-specific data. Each thread structure contains - * a pointer to the \a AlertPreludeCtx context. - * - * \return TM_ECODE_OK if ok, else TM_ECODE_FAILED - */ -static TmEcode AlertPreludeThreadInit(ThreadVars *t, const void *initdata, void **data) -{ - int ret; - AlertPreludeThread *aun; - - SCEnter(); - - if (unlikely(initdata == NULL)) { - SCLogError(SC_ERR_INITIALIZATION, - "Error getting context for Prelude. \"initdata\" argument NULL"); - SCReturnInt(TM_ECODE_FAILED); - } - - aun = SCMalloc(sizeof(AlertPreludeThread)); - if (unlikely(aun == NULL)) - SCReturnInt(TM_ECODE_FAILED); - memset(aun, 0, sizeof(AlertPreludeThread)); - - /* Use the Ouput Context */ - aun->ctx = ((OutputCtx *)initdata)->data; - - /* Create a per-thread idmef analyzer */ - ret = idmef_analyzer_clone(prelude_client_get_analyzer(aun->ctx->client), &aun->analyzer); - if (unlikely(ret < 0)) { - SCLogError(SC_ERR_INITIALIZATION, - "Error creating idmef analyzer for Prelude."); - - SCFree(aun); - SCReturnInt(TM_ECODE_FAILED); - } - - *data = (void *)aun; - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Free thread-specific data. - * - * \return TM_ECODE_OK if ok, else TM_ECODE_FAILED - */ -static TmEcode AlertPreludeThreadDeinit(ThreadVars *t, void *data) -{ - AlertPreludeThread *aun = (AlertPreludeThread *)data; - - SCEnter(); - - if (unlikely(aun == NULL)) { - SCLogDebug("AlertPreludeThreadDeinit done (error)"); - SCReturnInt(TM_ECODE_FAILED); - } - - /* clear memory */ - idmef_analyzer_destroy(aun->analyzer); - memset(aun, 0, sizeof(AlertPreludeThread)); - SCFree(aun); - - SCReturnInt(TM_ECODE_OK); -} - -static void AlertPreludeDeinitCtx(OutputCtx *output_ctx) -{ - AlertPreludeCtx *ctx = (AlertPreludeCtx *)output_ctx->data; - - prelude_client_destroy(ctx->client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCFree(output_ctx); -} - -/** \brief Initialize the Prelude logging module: initialize - * library, create the client and try to establish the connection - * to the Prelude Manager. - * Client flags are set to force asynchronous (non-blocking) mode for - * both alerts and heartbeats. - * This function requires an existing Prelude profile to work. - * - * \return A newly allocated AlertPreludeCtx structure, or NULL - */ -static OutputInitResult AlertPreludeInitCtx(ConfNode *conf) -{ - int ret; - prelude_client_t *client; - AlertPreludeCtx *ctx; - const char *prelude_profile_name; - const char *log_packet_content; - const char *log_packet_header; - OutputInitResult result = { NULL, false }; - OutputCtx *output_ctx; - - SCEnter(); - - ret = prelude_init(0, NULL); - if (unlikely(ret < 0)) { - prelude_perror(ret, "unable to initialize the prelude library"); - SCReturnCT(result, "OutputInitResult"); - } - - prelude_profile_name = ConfNodeLookupChildValue(conf, "profile"); - if (prelude_profile_name == NULL) - prelude_profile_name = DEFAULT_PRELUDE_PROFILE; - - log_packet_content = ConfNodeLookupChildValue(conf, "log-packet-content"); - log_packet_header = ConfNodeLookupChildValue(conf, "log-packet-header"); - - ret = prelude_client_new(&client, prelude_profile_name); - if ( unlikely(ret < 0 || client == NULL )) { - prelude_perror(ret, "Unable to create a prelude client object"); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnCT(result, "OutputInitResult"); - } - - ret = prelude_client_set_flags(client, prelude_client_get_flags(client) | PRELUDE_CLIENT_FLAGS_ASYNC_TIMER|PRELUDE_CLIENT_FLAGS_ASYNC_SEND); - if (unlikely(ret < 0)) { - SCLogDebug("Unable to set asynchronous send and timer."); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnCT(result, "OutputInitResult"); - } - - ret = SetupAnalyzer(prelude_client_get_analyzer(client)); - if (ret < 0) { - SCLogDebug("Unable to setup prelude client analyzer."); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnCT(result, "OutputInitResult"); - } - - ret = prelude_client_start(client); - if (unlikely(ret < 0)) { - prelude_perror(ret, "Unable to start prelude client"); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnCT(result, "OutputInitResult"); - } - - ctx = SCMalloc(sizeof(AlertPreludeCtx)); - if (unlikely(ctx == NULL)) { - prelude_perror(ret, "Unable to allocate memory"); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnCT(result, "OutputInitResult"); - } - - ctx->client = client; - ctx->log_packet_content = 0; - ctx->log_packet_header = 1; - if (log_packet_content && ConfValIsTrue(log_packet_content)) - ctx->log_packet_content = 1; - if (log_packet_header && ConfValIsFalse(log_packet_header)) - ctx->log_packet_header = 0; - - output_ctx = SCMalloc(sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(ctx); - prelude_perror(ret, "Unable to allocate memory"); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnCT(result, "OutputInitResult"); - } - - output_ctx->data = ctx; - output_ctx->DeInit = AlertPreludeDeinitCtx; - - result.ctx = output_ctx; - result.ok = true; - SCReturnCT(result, "OutputInitResult"); -} - -static int AlertPreludeCondition(ThreadVars *tv, const Packet *p) -{ - if (p->alerts.cnt == 0) - return FALSE; - if (!IPH_IS_VALID(p)) - return FALSE; - return TRUE; -} - -/** - * \brief Handle Suricata alert: convert it to and IDMEF alert (see RFC 4765) - * and send it asynchronously (so, this function does not block and returns - * immediately). - * If the destination Prelude Manager is not available, the alert is spooled - * (and the function also returns immediately). - * An IDMEF object is created, and all available information is added: IP packet - * header and data, rule signature ID, additional data like URL pointing to - * rule description, CVE, etc. - * The IDMEF alert has a reference to all created objects, so freeing it will - * automatically free all allocated memory. - * - * \note This function is thread safe. - * - * \return TM_ECODE_OK if ok, else TM_ECODE_FAILED - */ -static int AlertPreludeLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - AlertPreludeThread *apn = (AlertPreludeThread *)thread_data; - int ret; - idmef_time_t *time; - idmef_alert_t *alert; - prelude_string_t *str; - idmef_message_t *idmef = NULL; - idmef_classification_t *class; - const PacketAlert *pa; - - SCEnter(); - - if (unlikely(apn == NULL || apn->ctx == NULL)) { - SCReturnInt(TM_ECODE_FAILED); - } - - if (p->alerts.cnt == 0) - SCReturnInt(TM_ECODE_OK); - - if ( !IPH_IS_VALID(p) ) - SCReturnInt(TM_ECODE_OK); - - /* XXX which one to add to this alert? Lets see how Snort solves this. - * For now just take last alert. */ - pa = &p->alerts.alerts[p->alerts.cnt-1]; - if (unlikely(pa->s == NULL)) - goto err; - - ret = idmef_message_new(&idmef); - if (unlikely(ret < 0)) - SCReturnInt(TM_ECODE_FAILED); - - ret = idmef_message_new_alert(idmef, &alert); - if (unlikely(ret < 0)) - goto err; - - ret = idmef_alert_new_classification(alert, &class); - if (unlikely(ret < 0)) - goto err; - - if (pa->s->class_msg) { - ret = idmef_classification_new_text(class, &str); - if (unlikely(ret < 0)) - goto err; - - prelude_string_set_ref(str, pa->s->class_msg); - } - - ret = EventToImpact(pa, p, alert); - if (unlikely(ret < 0)) - goto err; - - ret = EventToReference(pa, p, class); - if (unlikely(ret < 0)) - goto err; - - ret = EventToSourceTarget(pa, p, alert); - if (unlikely(ret < 0)) - goto err; - - ret = PacketToData(p, pa, alert, apn->ctx); - if (unlikely(ret < 0)) - goto err; - - if (PKT_IS_TCP(p) && (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH)) { - uint8_t flag; - if (p->flowflags & FLOW_PKT_TOSERVER) { - flag = FLOW_PKT_TOCLIENT; - } else { - flag = FLOW_PKT_TOSERVER; - } - ret = StreamSegmentForEach(p, flag, - PreludePrintStreamSegmentCallback, - (void *)alert); - } - if (unlikely(ret < 0)) - goto err; - - ret = idmef_alert_new_detect_time(alert, &time); - if (unlikely(ret < 0)) - goto err; - idmef_time_set_from_timeval(time, &p->ts); - - ret = idmef_time_new_from_gettimeofday(&time); - if (unlikely(ret < 0)) - goto err; - idmef_alert_set_create_time(alert, time); - - idmef_alert_set_analyzer(alert, idmef_analyzer_ref(apn->analyzer), IDMEF_LIST_PREPEND); - - /* finally, send event */ - prelude_client_send_idmef(apn->ctx->client, idmef); - idmef_message_destroy(idmef); - - SCReturnInt(TM_ECODE_OK); - -err: - if (idmef != NULL) - idmef_message_destroy(idmef); - SCReturnInt(TM_ECODE_FAILED); -} - -void AlertPreludeRegister (void) -{ - OutputRegisterPacketModule(LOGGER_PRELUDE, "AlertPrelude", "alert-prelude", - AlertPreludeInitCtx, AlertPreludeLogger, AlertPreludeCondition, - AlertPreludeThreadInit, AlertPreludeThreadDeinit, NULL); -} -#endif /* PRELUDE */ diff --git a/src/alert-prelude.h b/src/alert-prelude.h deleted file mode 100644 index 0f15961f09..0000000000 --- a/src/alert-prelude.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * - * \file - * - * \author Pierre Chifflier - * \author Yoann Vandoorselaere - */ - -#ifndef __ALERT_PRELUDE_H__ -#define __ALERT_PRELUDE_H__ - -void AlertPreludeRegister(void); - -#endif /* __ALERT_PRELUDE_H__ */ diff --git a/src/output.c b/src/output.c index 66e3090a1f..3dce6aceee 100644 --- a/src/output.c +++ b/src/output.c @@ -42,7 +42,6 @@ #include "alert-fastlog.h" #include "alert-debuglog.h" -#include "alert-prelude.h" #include "alert-syslog.h" #include "output-json.h" #include "output-json-alert.h" @@ -1046,8 +1045,6 @@ void OutputRegisterLoggers(void) AlertFastLogRegister(); /* debug log */ AlertDebugLogRegister(); - /* prelue log */ - AlertPreludeRegister(); /* syslog log */ AlertSyslogRegister(); JsonDropLogRegister(); diff --git a/src/runmode-af-packet.c b/src/runmode-af-packet.c index 4af254927f..f8053ab0f9 100644 --- a/src/runmode-af-packet.c +++ b/src/runmode-af-packet.c @@ -40,7 +40,6 @@ #include "detect-engine-mpm.h" #include "alert-fastlog.h" -#include "alert-prelude.h" #include "alert-debuglog.h" #include "flow-bypass.h" diff --git a/src/runmode-netmap.c b/src/runmode-netmap.c index 27bb845ad1..e3ee89938a 100644 --- a/src/runmode-netmap.c +++ b/src/runmode-netmap.c @@ -40,7 +40,6 @@ #include "detect-engine-mpm.h" #include "alert-fastlog.h" -#include "alert-prelude.h" #include "alert-debuglog.h" #include "util-debug.h" diff --git a/src/runmodes.c b/src/runmodes.c index 3fa436a15e..94618763ce 100644 --- a/src/runmodes.c +++ b/src/runmodes.c @@ -43,7 +43,6 @@ #include "output.h" #include "alert-fastlog.h" -#include "alert-prelude.h" #include "alert-debuglog.h" #include "log-httplog.h" @@ -784,14 +783,6 @@ void RunModeInitializeOutputs(void) SCLogWarning(SC_ERR_NOT_SUPPORTED, "Unified2 is no longer supported."); continue; - } else if (strcmp(output->val, "alert-prelude") == 0) { -#ifndef PRELUDE - SCLogWarning(SC_ERR_NOT_SUPPORTED, - "Prelude support not compiled in. Reconfigure/" - "recompile with --enable-prelude to add Prelude " - "support."); - continue; -#endif } else if (strcmp(output->val, "lua") == 0) { #ifndef HAVE_LUA SCLogWarning(SC_ERR_NOT_SUPPORTED, diff --git a/src/suricata-common.h b/src/suricata-common.h index 06947c13ee..8e8964ec6e 100644 --- a/src/suricata-common.h +++ b/src/suricata-common.h @@ -483,7 +483,6 @@ typedef enum { LOGGER_JSON_NETFLOW, LOGGER_STATS, LOGGER_JSON_STATS, - LOGGER_PRELUDE, LOGGER_PCAP, LOGGER_JSON_METADATA, LOGGER_SIZE, diff --git a/src/util-profiling.c b/src/util-profiling.c index 524a5f4ef3..3947f927f0 100644 --- a/src/util-profiling.c +++ b/src/util-profiling.c @@ -1328,7 +1328,6 @@ const char * PacketProfileLoggertIdToString(LoggerId id) CASE_CODE (LOGGER_JSON_NETFLOW); CASE_CODE (LOGGER_STATS); CASE_CODE (LOGGER_JSON_STATS); - CASE_CODE (LOGGER_PRELUDE); CASE_CODE (LOGGER_PCAP); CASE_CODE (LOGGER_JSON_METADATA); case LOGGER_SIZE: diff --git a/src/util-runmodes.c b/src/util-runmodes.c index c002395df0..10f5bd94d3 100644 --- a/src/util-runmodes.c +++ b/src/util-runmodes.c @@ -36,7 +36,6 @@ #include "detect-engine-mpm.h" #include "alert-fastlog.h" -#include "alert-prelude.h" #include "alert-debuglog.h" #include "util-debug.h" diff --git a/suricata.yaml.in b/suricata.yaml.in index 3c188adf45..517c7e2467 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -403,14 +403,6 @@ outputs: append: yes #filetype: regular # 'regular', 'unix_stream' or 'unix_dgram' - # alert output to prelude (https://www.prelude-siem.org/) only - # available if Suricata has been compiled with --enable-prelude - - alert-prelude: - enabled: no - profile: suricata - log-packet-content: no - log-packet-header: yes - # Stats.log contains data from various counters of the Suricata engine. - stats: enabled: yes