Skip to content

Commit

Permalink
plugins: app-layer plugins
Browse files Browse the repository at this point in the history
Ticket: 5053
  • Loading branch information
catenacyber committed Nov 11, 2024
1 parent d535a4e commit 8cf93af
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 28 deletions.
10 changes: 10 additions & 0 deletions src/app-layer-parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include "app-layer-ike.h"
#include "app-layer-http2.h"
#include "app-layer-imap.h"
#include "util-plugin.h"

struct AppLayerParserThreadCtx_ {
void *(*alproto_local_storage)[FLOW_PROTO_MAX];
Expand Down Expand Up @@ -1745,6 +1746,15 @@ void AppLayerParserRegisterProtocolParsers(void)
} else {
SCLogInfo("Protocol detection and parser disabled for pop3 protocol.");
}
#ifdef HAVE_PLUGINS
for (size_t i = 0; i < app_layer_plugins_nb; i++) {
SCAppLayerPlugin *app_layer_plugin = SCPluginFindAppLayerByIndex(i);
if (app_layer_plugin == NULL) {
break;
}
app_layer_plugin->Register();
}
#endif

ValidateParsers();
}
Expand Down
3 changes: 3 additions & 0 deletions src/detect-engine-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ uint8_t DetectFileInspectGeneric(DetectEngineCtx *de_ctx, DetectEngineThreadCtx
const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f,
uint8_t flags, void *_alstate, void *tx, uint64_t tx_id);

void DetectFileRegisterProto(
AppProto alproto, int direction, int to_client_progress, int to_server_progress);

#endif /* SURICATA_DETECT_ENGINE_FILE_H */
13 changes: 13 additions & 0 deletions src/detect-engine-register.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@
#include "util-path.h"
#include "util-mpm-ac.h"
#include "runmodes.h"
#include "util-plugin.h"

int DETECT_TBLSIZE = 0;
int DETECT_TBLSIZE_IDX = DETECT_TBLSIZE_STATIC;
Expand Down Expand Up @@ -684,6 +685,18 @@ void SigTableSetup(void)
ScDetectSipRegister();
ScDetectTemplateRegister();

#ifdef HAVE_PLUGINS
for (size_t i = 0; i < app_layer_plugins_nb; i++) {
SCAppLayerPlugin *app_layer_plugin = SCPluginFindAppLayerByIndex(i);
if (app_layer_plugin == NULL) {
break;
}
if (app_layer_plugin->KeywordsRegister != NULL) {
app_layer_plugin->KeywordsRegister();
}
}
#endif

/* close keyword registration */
DetectBufferTypeCloseRegistration();
}
Expand Down
81 changes: 53 additions & 28 deletions src/detect-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,55 +68,80 @@
#include "string.h"
#include "detect-parse.h"
#include "detect-engine-iponly.h"
#include "detect-engine-file.h"
#include "app-layer-detect-proto.h"

#include "action-globals.h"
#include "util-validate.h"

// file protocols with common file handling
typedef struct {
AppProto alproto;
int direction;
int to_client_progress;
int to_server_progress;
} DetectFileHandlerProtocol_t;

/* Table with all filehandler registrations */
DetectFileHandlerTableElmt filehandler_table[DETECT_TBLSIZE_STATIC];

#define ALPROTO_WITHFILES_MAX 16

// file protocols with common file handling
DetectFileHandlerProtocol_t al_protocols[ALPROTO_WITHFILES_MAX] = {
{ .alproto = ALPROTO_NFS, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
{ .alproto = ALPROTO_SMB, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
{ .alproto = ALPROTO_FTP, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
{ .alproto = ALPROTO_FTPDATA, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
{ .alproto = ALPROTO_HTTP1,
.direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT,
.to_client_progress = HTP_RESPONSE_BODY,
.to_server_progress = HTP_REQUEST_BODY },
{ .alproto = ALPROTO_HTTP2,
.direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT,
.to_client_progress = HTTP2StateDataServer,
.to_server_progress = HTTP2StateDataClient },
{ .alproto = ALPROTO_SMTP, .direction = SIG_FLAG_TOSERVER }, { .alproto = ALPROTO_UNKNOWN }
};

void DetectFileRegisterProto(
AppProto alproto, int direction, int to_client_progress, int to_server_progress)
{
size_t i = 0;
while (i < ALPROTO_WITHFILES_MAX && al_protocols[i].alproto != ALPROTO_UNKNOWN) {
i++;
}
if (i == ALPROTO_WITHFILES_MAX) {
return;
}
al_protocols[i].alproto = alproto;
al_protocols[i].direction = direction;
al_protocols[i].to_client_progress = to_client_progress;
al_protocols[i].to_server_progress = to_server_progress;
al_protocols[i + 1].alproto = ALPROTO_UNKNOWN;
}

void DetectFileRegisterFileProtocols(DetectFileHandlerTableElmt *reg)
{
// file protocols with common file handling
typedef struct {
AppProto al_proto;
int direction;
int to_client_progress;
int to_server_progress;
} DetectFileHandlerProtocol_t;
static DetectFileHandlerProtocol_t al_protocols[] = {
{ .al_proto = ALPROTO_NFS, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
{ .al_proto = ALPROTO_SMB, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
{ .al_proto = ALPROTO_FTP, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
{ .al_proto = ALPROTO_FTPDATA, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
{ .al_proto = ALPROTO_HTTP1,
.direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT,
.to_client_progress = HTP_RESPONSE_BODY,
.to_server_progress = HTP_REQUEST_BODY },
{ .al_proto = ALPROTO_HTTP2,
.direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT,
.to_client_progress = HTTP2StateDataServer,
.to_server_progress = HTTP2StateDataClient },
{ .al_proto = ALPROTO_SMTP, .direction = SIG_FLAG_TOSERVER }
};

for (size_t i = 0; i < ARRAY_SIZE(al_protocols); i++) {
for (size_t i = 0; i < AlprotoMax; i++) {
if (al_protocols[i].alproto == ALPROTO_UNKNOWN) {
break;
}
int direction = al_protocols[i].direction == 0
? (int)(SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT)
: al_protocols[i].direction;

if (direction & SIG_FLAG_TOCLIENT) {
DetectAppLayerMpmRegister(reg->name, SIG_FLAG_TOCLIENT, reg->priority, reg->PrefilterFn,
reg->GetData, al_protocols[i].al_proto, al_protocols[i].to_client_progress);
DetectAppLayerInspectEngineRegister(reg->name, al_protocols[i].al_proto,
reg->GetData, al_protocols[i].alproto, al_protocols[i].to_client_progress);
DetectAppLayerInspectEngineRegister(reg->name, al_protocols[i].alproto,
SIG_FLAG_TOCLIENT, al_protocols[i].to_client_progress, reg->Callback,
reg->GetData);
}
if (direction & SIG_FLAG_TOSERVER) {
DetectAppLayerMpmRegister(reg->name, SIG_FLAG_TOSERVER, reg->priority, reg->PrefilterFn,
reg->GetData, al_protocols[i].al_proto, al_protocols[i].to_server_progress);
DetectAppLayerInspectEngineRegister(reg->name, al_protocols[i].al_proto,
reg->GetData, al_protocols[i].alproto, al_protocols[i].to_server_progress);
DetectAppLayerInspectEngineRegister(reg->name, al_protocols[i].alproto,
SIG_FLAG_TOSERVER, al_protocols[i].to_server_progress, reg->Callback,
reg->GetData);
}
Expand Down
18 changes: 18 additions & 0 deletions src/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
#include "app-layer-parser.h"
#include "output-filestore.h"
#include "output-json-arp.h"
#include "util-plugin.h"

typedef struct RootLogger_ {
OutputLogFunc LogFunc;
Expand Down Expand Up @@ -1105,4 +1106,21 @@ void OutputRegisterLoggers(void)
}
/* ARP JSON logger */
JsonArpLogRegister();

#ifdef HAVE_PLUGINS
for (size_t i = 0; i < app_layer_plugins_nb; i++) {
SCAppLayerPlugin *app_layer_plugin = SCPluginFindAppLayerByIndex(i);
if (app_layer_plugin == NULL) {
break;
}

OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", app_layer_plugin->logname,
app_layer_plugin->confname, OutputJsonLogInitSub,
(AppProto)(ALPROTO_MAX_STATIC + i), JsonGenericDirFlowLogger, JsonLogThreadInit,
JsonLogThreadDeinit);
SCLogNotice("%s JSON logger registered.", app_layer_plugin->name);
RegisterSimpleJsonApplayerLogger((AppProto)(ALPROTO_MAX_STATIC + i),
(EveJsonSimpleTxLogFunc)app_layer_plugin->Logger, NULL);
}
#endif
}
11 changes: 11 additions & 0 deletions src/suricata-plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,15 @@ typedef struct SCCapturePlugin_ {

int SCPluginRegisterCapture(SCCapturePlugin *);

typedef struct SCAppLayerPlugin_ {
char *name;
char *logname;
char *confname;
void (*Register)(void);
bool (*Logger)(void *tx, void *jb);
void (*KeywordsRegister)(void);
} SCAppLayerPlugin;

int SCPluginRegisterAppLayer(SCAppLayerPlugin *);

#endif /* __SURICATA_PLUGIN_H */
35 changes: 35 additions & 0 deletions src/util-plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "util-plugin.h"
#include "util-debug.h"
#include "conf.h"
#include "app-layer-protos.h"

#ifdef HAVE_PLUGINS

Expand Down Expand Up @@ -148,4 +149,38 @@ SCCapturePlugin *SCPluginFindCaptureByName(const char *name)
}
return plugin;
}

static SCAppLayerPlugin **app_layer_plugins = NULL;
size_t app_layer_plugins_nb = 0;
#define ARRAY_CAP_STEP 16
static size_t app_layer_plugins_cap = 0;

int SCPluginRegisterAppLayer(SCAppLayerPlugin *plugin)
{
if (app_layer_plugins_nb == app_layer_plugins_cap) {
void *tmp = SCRealloc(app_layer_plugins,
sizeof(SCAppLayerPlugin *) * (app_layer_plugins_cap + ARRAY_CAP_STEP));
if (tmp == NULL) {
return 1;
}
app_layer_plugins_cap += ARRAY_CAP_STEP;
app_layer_plugins = tmp;
}
if (app_layer_plugins_nb < app_layer_plugins_cap) {
app_layer_plugins[app_layer_plugins_nb] = plugin;
AppProtoRegisterProtoString(
(AppProto)(ALPROTO_MAX_STATIC + app_layer_plugins_nb), plugin->name);
app_layer_plugins_nb++;
return 0;
}
return 1;
}

SCAppLayerPlugin *SCPluginFindAppLayerByIndex(size_t i)
{
if (i < app_layer_plugins_nb) {
return app_layer_plugins[i];
}
return NULL;
}
#endif
4 changes: 4 additions & 0 deletions src/util-plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ SCCapturePlugin *SCPluginFindCaptureByName(const char *name);

bool RegisterPlugin(SCPlugin *, void *);

SCAppLayerPlugin *SCPluginFindAppLayerByIndex(size_t i);

extern size_t app_layer_plugins_nb;

#endif /* SURICATA_UTIL_PLUGIN_H */

0 comments on commit 8cf93af

Please sign in to comment.