Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eve-filetypes: separate from plugins, as eve filetypes are not plugins: plugins can register eve filetypes - v1 #10591

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/plugins/c-json-filetype/filetype.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "suricata-common.h"
#include "suricata-plugin.h"
#include "output-eve.h"
#include "util-mem.h"
#include "util-debug.h"

Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,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 \
Expand Down Expand Up @@ -1056,6 +1057,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 \
Expand Down
1 change: 1 addition & 0 deletions src/decode-erspan.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "util-validate.h"
#include "util-unittest.h"
#include "util-debug.h"
#include "conf.h"

/**
* \brief Functions to decode ERSPAN Type I and II packets
Expand Down
1 change: 1 addition & 0 deletions src/defrag-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "defrag-config.h"
#include "util-misc.h"
#include "util-radix-tree.h"
#include "conf.h"

static SCRadixTree *defrag_tree = NULL;

Expand Down
1 change: 1 addition & 0 deletions src/output-eve-null.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "output.h" /* DEFAULT_LOG_* */
#include "output-eve-null.h"
#include "output-eve.h"

#ifdef OS_WIN32
void NullLogInitialize(void)
Expand Down
1 change: 1 addition & 0 deletions src/output-eve-syslog.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
82 changes: 82 additions & 0 deletions src/output-eve.c
Original file line number Diff line number Diff line change
@@ -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;
}
60 changes: 60 additions & 0 deletions src/output-eve.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* 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__
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why SURICATA part of the define here? We normally only base on the file name

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an include that is part of the library, it should be name spaced as well. __OUTPUT_EVE_H__ is probably not that generic, but something simpler like __OUTPUT_H__ is more generic with a higher chance of conflicting with a user header.

LibHTP, libcurl, etc. all do this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this type of change go into the whole codebase? Perhaps as a separate change/commit?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm somewhat indifferent here as its not an introducer of merge conflicts like some other changes we have discussed would be. But would be nice I guess, should we also remove the leading double underscores (and trailing) as they are in reserved namespace?

#define __SURICATA_OUTPUT_EVE_H__

#include "suricata-common.h"
#include "conf.h"

/**
* Structure used to define an Eve output file type plugin.
*/
typedef struct SCEveFileType_ {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to tighten the function signatures a bit, esp with adding const where appropriate

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DIdn't want to change or break the API with this PR, I have some breaking changes coming for 8.0 that hopefully make it easier, that would be where to change the signatures.

/* 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*/
int (*ThreadInit)(void *init_data, int 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
21 changes: 8 additions & 13 deletions src/output-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,13 @@
#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"
#include "flow-storage.h"

#include "source-pcap-file-helper.h"

#include "suricata-plugin.h"

#define DEFAULT_LOG_FILENAME "eve.json"
#define MODULE_NAME "OutputJSON"

Expand Down Expand Up @@ -1011,19 +1008,19 @@ static int LogFileTypePrepare(
}
}
#endif
else if (log_filetype == LOGFILE_TYPE_PLUGIN) {
else if (log_filetype == LOGFILE_TYPE_FILETYPE) {
if (json_ctx->file_ctx->threaded) {
/* Prepare for threaded log output. */
if (!SCLogOpenThreadedFile(NULL, NULL, json_ctx->file_ctx)) {
return -1;
}
}
void *init_data = NULL;
if (json_ctx->plugin->Init(conf, json_ctx->file_ctx->threaded, &init_data) < 0) {
if (json_ctx->filetype->Init(conf, json_ctx->file_ctx->threaded, &init_data) < 0) {
return -1;
}
json_ctx->file_ctx->plugin.plugin = json_ctx->plugin;
json_ctx->file_ctx->plugin.init_data = init_data;
json_ctx->file_ctx->filetype.filetype = json_ctx->filetype;
json_ctx->file_ctx->filetype.init_data = init_data;
}

return 0;
Expand Down Expand Up @@ -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);
if (plugin != NULL) {
log_filetype = LOGFILE_TYPE_PLUGIN;
json_ctx->plugin = plugin;
SCEveFileType *filetype = SCEveFindFileType(output_s);
if (filetype != NULL) {
log_filetype = LOGFILE_TYPE_FILETYPE;
json_ctx->filetype = filetype;
} else
#endif
FatalError("Invalid JSON output option: %s", output_s);
}

Expand Down
4 changes: 1 addition & 3 deletions src/output-json.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@
#include "util-buffer.h"
#include "util-logopenfile.h"
#include "output.h"
#include "rust.h"

#include "app-layer-htp-xff.h"
#include "suricata-plugin.h"

void OutputJsonRegister(void);

Expand Down Expand Up @@ -83,7 +81,7 @@ typedef struct OutputJsonCtx_ {
enum LogFileType json_out;
OutputJsonCommonSettings cfg;
HttpXFFCfg *xff_cfg;
SCEveFileType *plugin;
SCEveFileType *filetype;
} OutputJsonCtx;

typedef struct OutputJsonThreadCtx_ {
Expand Down
1 change: 1 addition & 0 deletions src/source-pcap-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "util-checksum.h"
#include "runmode-unix-socket.h"
#include "suricata.h"
#include "conf.h"

extern uint16_t max_pending_packets;
PcapFileGlobalVars pcap_g;
Expand Down
25 changes: 1 addition & 24 deletions src/suricata-plugin.h
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we combine the SCPlugin and SCCapturePlugin types?

I think that SCPlugin would suffice for both (maybe all?) plugin types and then a backing type for the capture plugins can be created in a similar way that SCEveFileType is a backing type for SCPlugin.

Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only catch here is that the filetypes don't require anything from the engine, but the captures do, at least now -- the "slot" they fit into. So capture plugins need that extra hook from the engine that file types do not.

Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@

#include <stdint.h>
#include <stdbool.h>

#include "conf.h"
#include <queue.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this meant to "queue.h"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, oops.


/**
* The size of the data chunk inside each packet structure a plugin
Expand All @@ -41,28 +40,6 @@ typedef struct SCPlugin_ {

typedef SCPlugin *(*SCPluginRegisterFunc)(void);

/**
* 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*/
int (*ThreadInit)(void *init_data, int 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;
void (*Init)(const char *args, int plugin_slot, int receive_slot, int decode_slot);
Expand Down
1 change: 1 addition & 0 deletions src/util-ebpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define __UTIL_EBPF_H__

#include "flow-bypass.h"
#include "conf.h"

#ifdef HAVE_PACKET_EBPF

Expand Down
1 change: 1 addition & 0 deletions src/util-exception-policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "util-misc.h"
#include "stream-tcp-reassemble.h"
#include "action-globals.h"
#include "conf.h"

enum ExceptionPolicy g_eps_master_switch = EXCEPTION_POLICY_NOT_SET;
/** true if exception policy was defined in config */
Expand Down