diff --git a/examples/plugins/c-json-filetype/filetype.c b/examples/plugins/c-json-filetype/filetype.c index cf8ca64d28..e85273d768 100644 --- a/examples/plugins/c-json-filetype/filetype.c +++ b/examples/plugins/c-json-filetype/filetype.c @@ -17,6 +17,7 @@ #include "suricata-common.h" #include "suricata-plugin.h" +#include "output-eve.h" #include "util-mem.h" #include "util-debug.h" diff --git a/src/Makefile.am b/src/Makefile.am index 21cb34c39b..df37a5e9dc 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -393,6 +393,7 @@ noinst_HEADERS = \ log-tcp-data.h \ log-tlslog.h \ log-tlsstore.h \ + output-eve.h \ output-eve-stream.h \ output-eve-null.h \ output-filedata.h \ @@ -1058,6 +1059,7 @@ libsuricata_c_a_SOURCES = \ output-json-template.c \ output-json-tftp.c \ output-json-tls.c \ + output-eve.c \ output-eve-syslog.c \ output-eve-null.c \ output-lua.c \ diff --git a/src/output-eve-null.c b/src/output-eve-null.c index 298c3527a7..afe11afc06 100644 --- a/src/output-eve-null.c +++ b/src/output-eve-null.c @@ -27,6 +27,7 @@ #include "output.h" /* DEFAULT_LOG_* */ #include "output-eve-null.h" +#include "output-eve.h" #ifdef OS_WIN32 void NullLogInitialize(void) diff --git a/src/output-eve-syslog.c b/src/output-eve-syslog.c index 5d71b5d807..0787e4b750 100644 --- a/src/output-eve-syslog.c +++ b/src/output-eve-syslog.c @@ -26,6 +26,7 @@ #include "suricata-common.h" /* errno.h, string.h, etc. */ #include "output.h" /* DEFAULT_LOG_* */ +#include "output-eve.h" #include "output-eve-syslog.h" #include "util-syslog.h" diff --git a/src/output-eve.c b/src/output-eve.c new file mode 100644 index 0000000000..d0d775cba7 --- /dev/null +++ b/src/output-eve.c @@ -0,0 +1,82 @@ +/* Copyright (C) 2024 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. + */ + +#include "output-eve.h" +#include "util-debug.h" + +static TAILQ_HEAD(, SCEveFileType_) output_types = TAILQ_HEAD_INITIALIZER(output_types); + +static bool IsBuiltinTypeName(const char *name) +{ + const char *builtin[] = { + "regular", + "unix_dgram", + "unix_stream", + "redis", + NULL, + }; + for (int i = 0;; i++) { + if (builtin[i] == NULL) { + break; + } + if (strcmp(builtin[i], name) == 0) { + return true; + } + } + return false; +} + +SCEveFileType *SCEveFindFileType(const char *name) +{ + SCEveFileType *plugin = NULL; + TAILQ_FOREACH (plugin, &output_types, entries) { + if (strcmp(name, plugin->name) == 0) { + return plugin; + } + } + return NULL; +} + +/** + * \brief Register an Eve file type. + * + * \retval true if registered successfully, false if the file type name + * conflicts with a built-in or previously registered + * file type. + */ +bool SCRegisterEveFileType(SCEveFileType *plugin) +{ + /* First check that the name doesn't conflict with a built-in filetype. */ + if (IsBuiltinTypeName(plugin->name)) { + SCLogError("Eve file type name conflicts with built-in type: %s", plugin->name); + return false; + } + + /* Now check against previously registered file types. */ + SCEveFileType *existing = NULL; + TAILQ_FOREACH (existing, &output_types, entries) { + if (strcmp(existing->name, plugin->name) == 0) { + SCLogError("Eve file type name conflicts with previously registered type: %s", + plugin->name); + return false; + } + } + + SCLogDebug("Registering EVE file type plugin %s", plugin->name); + TAILQ_INSERT_TAIL(&output_types, plugin, entries); + return true; +} diff --git a/src/output-eve.h b/src/output-eve.h new file mode 100644 index 0000000000..e8c4199622 --- /dev/null +++ b/src/output-eve.h @@ -0,0 +1,63 @@ +/* Copyright (C) 2024 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 + * + * \brief EVE logging subsystem + * + * This file will attempt to the main module for EVE logging + * sub-system. Currently most of the API resides in output-json.[ch], + * but due to some circular dependencies between EVE, and LogFileCtx, + * it made it hard to add EVE filetype modules there until some + * include issues are figured out. + */ + +#ifndef SURICATA_OUTPUT_EVE_H +#define SURICATA_OUTPUT_EVE_H + +#include "suricata-common.h" +#include "conf.h" + +typedef uint32_t ThreadId; + +/** + * Structure used to define an Eve output file type plugin. + */ +typedef struct SCEveFileType_ { + /* The name of the output, used to specify the output in the filetype section + * of the eve-log configuration. */ + const char *name; + /* Init Called on first access */ + int (*Init)(ConfNode *conf, bool threaded, void **init_data); + /* Write - Called on each write to the object */ + int (*Write)(const char *buffer, int buffer_len, void *init_data, void *thread_data); + /* Close - Called on final close */ + void (*Deinit)(void *init_data); + /* ThreadInit - Called for each thread using file object; non-zero thread_ids correlate + * to Suricata's worker threads; 0 correlates to the Suricata main thread */ + int (*ThreadInit)(void *init_data, ThreadId thread_id, void **thread_data); + /* ThreadDeinit - Called for each thread using file object */ + int (*ThreadDeinit)(void *init_data, void *thread_data); + TAILQ_ENTRY(SCEveFileType_) entries; +} SCEveFileType; + +bool SCRegisterEveFileType(SCEveFileType *); + +SCEveFileType *SCEveFindFileType(const char *name); + +#endif diff --git a/src/output-json.c b/src/output-json.c index 1dd2f948ab..ab46abb14b 100644 --- a/src/output-json.c +++ b/src/output-json.c @@ -65,7 +65,6 @@ #include "util-log-redis.h" #include "util-device.h" #include "util-validate.h" -#include "util-plugin.h" #include "flow-var.h" #include "flow-bit.h" @@ -73,8 +72,6 @@ #include "source-pcap-file-helper.h" -#include "suricata-plugin.h" - #define DEFAULT_LOG_FILENAME "eve.json" #define MODULE_NAME "OutputJSON" @@ -1088,13 +1085,11 @@ OutputInitResult OutputJsonInitCtx(ConfNode *conf) enum LogFileType log_filetype = FileTypeFromConf(output_s); if (log_filetype == LOGFILE_TYPE_NOTSET) { -#ifdef HAVE_PLUGINS - SCEveFileType *plugin = SCPluginFindFileType(output_s); + SCEveFileType *plugin = SCEveFindFileType(output_s); if (plugin != NULL) { log_filetype = LOGFILE_TYPE_PLUGIN; json_ctx->plugin = plugin; } else -#endif FatalError("Invalid JSON output option: %s", output_s); } diff --git a/src/suricata-plugin.h b/src/suricata-plugin.h index 4ba5697691..85a91ef663 100644 --- a/src/suricata-plugin.h +++ b/src/suricata-plugin.h @@ -21,6 +21,8 @@ #include #include +#include "queue.h" + #include "conf.h" /** @@ -40,30 +42,6 @@ typedef struct SCPlugin_ { } SCPlugin; typedef SCPlugin *(*SCPluginRegisterFunc)(void); -typedef uint32_t ThreadId; - -/** - * Structure used to define an Eve output file type plugin. - */ -typedef struct SCEveFileType_ { - /* The name of the output, used to specify the output in the filetype section - * of the eve-log configuration. */ - const char *name; - /* Init Called on first access */ - int (*Init)(ConfNode *conf, bool threaded, void **init_data); - /* Write - Called on each write to the object */ - int (*Write)(const char *buffer, int buffer_len, void *init_data, void *thread_data); - /* Close - Called on final close */ - void (*Deinit)(void *init_data); - /* ThreadInit - Called for each thread using file object; non-zero thread_ids correlate - * to Suricata's worker threads; 0 correlates to the Suricata main thread */ - int (*ThreadInit)(void *init_data, ThreadId thread_id, void **thread_data); - /* ThreadDeinit - Called for each thread using file object */ - int (*ThreadDeinit)(void *init_data, void *thread_data); - TAILQ_ENTRY(SCEveFileType_) entries; -} SCEveFileType; - -bool SCRegisterEveFileType(SCEveFileType *); typedef struct SCCapturePlugin_ { char *name; diff --git a/src/util-logopenfile.h b/src/util-logopenfile.h index 7b78c9cc45..f3ab81565a 100644 --- a/src/util-logopenfile.h +++ b/src/util-logopenfile.h @@ -34,6 +34,7 @@ #endif /* HAVE_LIBHIREDIS */ #include "suricata-plugin.h" +#include "output-eve.h" enum LogFileType { LOGFILE_TYPE_FILE, diff --git a/src/util-plugin.c b/src/util-plugin.c index 3a08aa8876..472c555b89 100644 --- a/src/util-plugin.c +++ b/src/util-plugin.c @@ -19,7 +19,6 @@ #include "suricata-plugin.h" #include "suricata.h" #include "runmodes.h" -#include "output-eve-syslog.h" #include "util-plugin.h" #include "util-debug.h" @@ -41,8 +40,6 @@ typedef struct PluginListNode_ { */ static TAILQ_HEAD(, PluginListNode_) plugins = TAILQ_HEAD_INITIALIZER(plugins); -static TAILQ_HEAD(, SCEveFileType_) output_types = TAILQ_HEAD_INITIALIZER(output_types); - static TAILQ_HEAD(, SCCapturePlugin_) capture_plugins = TAILQ_HEAD_INITIALIZER(capture_plugins); bool RegisterPlugin(SCPlugin *plugin, void *lib) @@ -133,67 +130,6 @@ void SCPluginsLoad(const char *capture_plugin_name, const char *capture_plugin_a } } -static bool IsBuiltinTypeName(const char *name) -{ - const char *builtin[] = { - "regular", - "unix_dgram", - "unix_stream", - "redis", - NULL, - }; - for (int i = 0;; i++) { - if (builtin[i] == NULL) { - break; - } - if (strcmp(builtin[i], name) == 0) { - return true; - } - } - return false; -} - -/** - * \brief Register an Eve file type. - * - * \retval true if registered successfully, false if the file type name - * conflicts with a built-in or previously registered - * file type. - */ -bool SCRegisterEveFileType(SCEveFileType *plugin) -{ - /* First check that the name doesn't conflict with a built-in filetype. */ - if (IsBuiltinTypeName(plugin->name)) { - SCLogError("Eve file type name conflicts with built-in type: %s", plugin->name); - return false; - } - - /* Now check against previously registered file types. */ - SCEveFileType *existing = NULL; - TAILQ_FOREACH (existing, &output_types, entries) { - if (strcmp(existing->name, plugin->name) == 0) { - SCLogError("Eve file type name conflicts with previously registered type: %s", - plugin->name); - return false; - } - } - - SCLogDebug("Registering EVE file type plugin %s", plugin->name); - TAILQ_INSERT_TAIL(&output_types, plugin, entries); - return true; -} - -SCEveFileType *SCPluginFindFileType(const char *name) -{ - SCEveFileType *plugin = NULL; - TAILQ_FOREACH(plugin, &output_types, entries) { - if (strcmp(name, plugin->name) == 0) { - return plugin; - } - } - return NULL; -} - int SCPluginRegisterCapture(SCCapturePlugin *plugin) { TAILQ_INSERT_TAIL(&capture_plugins, plugin, entries); diff --git a/src/util-plugin.h b/src/util-plugin.h index 7b5531c816..f749e287a3 100644 --- a/src/util-plugin.h +++ b/src/util-plugin.h @@ -21,7 +21,6 @@ #include "suricata-plugin.h" void SCPluginsLoad(const char *capture_plugin_name, const char *capture_plugin_args); -SCEveFileType *SCPluginFindFileType(const char *name); SCCapturePlugin *SCPluginFindCaptureByName(const char *name); bool RegisterPlugin(SCPlugin *, void *);