From 1bb8fcecec825de94ed5cd1f85f4a185e98f2169 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 17 Sep 2018 17:15:13 +0200 Subject: [PATCH] detect/template: switch to v2 API, add MPM --- src/detect-template-buffer.c | 89 +++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/src/detect-template-buffer.c b/src/detect-template-buffer.c index 82b6ead6d3..6cc26bb93b 100644 --- a/src/detect-template-buffer.c +++ b/src/detect-template-buffer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Open Information Security Foundation +/* Copyright (C) 2015-2018 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 @@ -35,15 +35,16 @@ #include "detect.h" #include "detect-parse.h" #include "detect-engine.h" -#include "detect-engine-content-inspection.h" +#include "detect-engine-mpm.h" +#include "detect-engine-prefilter.h" #include "app-layer-template.h" #include "detect-template-buffer.h" static int DetectTemplateBufferSetup(DetectEngineCtx *, Signature *, const char *); -static int DetectEngineInspectTemplateBuffer(ThreadVars *tv, - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - const Signature *s, const SigMatchData *smd, - Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id); +static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, + Flow *_f, const uint8_t flow_flags, + void *txv, const int list_id); static void DetectTemplateBufferRegisterTests(void); static int g_template_buffer_id = 0; @@ -63,13 +64,22 @@ void DetectTemplateBufferRegister(void) sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_NOOPT; - /* register inspect engines */ - DetectAppLayerInspectEngineRegister("template_buffer", + /* register inspect engines - these are called per signature */ + DetectAppLayerInspectEngineRegister2("template_buffer", ALPROTO_TEMPLATE, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectTemplateBuffer); - DetectAppLayerInspectEngineRegister("template_buffer", + DetectEngineInspectBufferGeneric, GetData); + DetectAppLayerInspectEngineRegister2("template_buffer", ALPROTO_TEMPLATE, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectTemplateBuffer); + DetectEngineInspectBufferGeneric, GetData); + + /* register mpm engines - these are called in the prefilter stage */ + DetectAppLayerMpmRegister2("template_buffer", SIG_FLAG_TOSERVER, 0, + PrefilterGenericMpmRegister, GetData, + ALPROTO_TEMPLATE, 0); + DetectAppLayerMpmRegister2("template_buffer", SIG_FLAG_TOCLIENT, 0, + PrefilterGenericMpmRegister, GetData, + ALPROTO_TEMPLATE, 0); + g_template_buffer_id = DetectBufferTypeGetByName("template_buffer"); @@ -79,37 +89,54 @@ void DetectTemplateBufferRegister(void) static int DetectTemplateBufferSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) { + /* store list id. Content, pcre, etc will be added to the list at this + * id. */ s->init_data->list = g_template_buffer_id; + /* set the app proto for this signature. This means it will only be + * evaluated against flows that are ALPROTO_TEMPLATE */ if (DetectSignatureSetAppProto(s, ALPROTO_TEMPLATE) != 0) return -1; return 0; } -static int DetectEngineInspectTemplateBuffer(ThreadVars *tv, - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - const Signature *s, const SigMatchData *smd, - Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id) +/** \internal + * \brief get the data to inspect from the transaction. + * This function gets the data, sets up the InspectionBuffer object + * and applies transformations (if any). + * + * \retval buffer or NULL in case of error + */ +static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, + Flow *_f, const uint8_t flow_flags, + void *txv, const int list_id) { - TemplateTransaction *tx = (TemplateTransaction *)txv; - int ret = 0; - - if (flags & STREAM_TOSERVER && tx->request_buffer != NULL) { - ret = DetectEngineContentInspection(de_ctx, det_ctx, s, smd, - f, tx->request_buffer, tx->request_buffer_len, - 0, DETECT_CI_FLAGS_SINGLE, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL); - } - else if (flags & STREAM_TOCLIENT && tx->response_buffer != NULL) { - ret = DetectEngineContentInspection(de_ctx, det_ctx, s, smd, - f, tx->response_buffer, tx->response_buffer_len, - 0, DETECT_CI_FLAGS_SINGLE, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL); + const uint8_t *data = NULL; + uint32_t data_len = 0; + + BUG_ON(det_ctx->inspect_buffers == NULL); + + InspectionBuffer *buffer = &det_ctx->inspect_buffers[list_id]; + if (buffer->inspect == NULL) { + const TemplateTransaction *tx = (TemplateTransaction *)txv; + + if (flow_flags & STREAM_TOSERVER) { + data = tx->request_buffer; + data_len = tx->request_buffer_len; + } else if (flow_flags & STREAM_TOCLIENT) { + data = tx->response_buffer; + data_len = tx->response_buffer_len; + } else { + return NULL; /* no buffer */ + } + + InspectionBufferSetup(buffer, data, data_len); + InspectionBufferApplyTransforms(buffer, transforms); } - SCLogNotice("Returning %d.", ret); - return ret; + return buffer; } #ifdef UNITTESTS