detect/template: switch to v2 API, add MPM

pull/3487/head
Victor Julien 7 years ago
parent 234d113838
commit 1bb8fcecec

@ -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 * You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free * the GNU General Public License version 2 as published by the Free
@ -35,15 +35,16 @@
#include "detect.h" #include "detect.h"
#include "detect-parse.h" #include "detect-parse.h"
#include "detect-engine.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 "app-layer-template.h"
#include "detect-template-buffer.h" #include "detect-template-buffer.h"
static int DetectTemplateBufferSetup(DetectEngineCtx *, Signature *, const char *); static int DetectTemplateBufferSetup(DetectEngineCtx *, Signature *, const char *);
static int DetectEngineInspectTemplateBuffer(ThreadVars *tv, static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectEngineTransforms *transforms,
const Signature *s, const SigMatchData *smd, Flow *_f, const uint8_t flow_flags,
Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id); void *txv, const int list_id);
static void DetectTemplateBufferRegisterTests(void); static void DetectTemplateBufferRegisterTests(void);
static int g_template_buffer_id = 0; static int g_template_buffer_id = 0;
@ -63,13 +64,22 @@ void DetectTemplateBufferRegister(void)
sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_NOOPT; sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_NOOPT;
/* register inspect engines */ /* register inspect engines - these are called per signature */
DetectAppLayerInspectEngineRegister("template_buffer", DetectAppLayerInspectEngineRegister2("template_buffer",
ALPROTO_TEMPLATE, SIG_FLAG_TOSERVER, 0, ALPROTO_TEMPLATE, SIG_FLAG_TOSERVER, 0,
DetectEngineInspectTemplateBuffer); DetectEngineInspectBufferGeneric, GetData);
DetectAppLayerInspectEngineRegister("template_buffer", DetectAppLayerInspectEngineRegister2("template_buffer",
ALPROTO_TEMPLATE, SIG_FLAG_TOCLIENT, 0, 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"); g_template_buffer_id = DetectBufferTypeGetByName("template_buffer");
@ -79,37 +89,54 @@ void DetectTemplateBufferRegister(void)
static int DetectTemplateBufferSetup(DetectEngineCtx *de_ctx, Signature *s, static int DetectTemplateBufferSetup(DetectEngineCtx *de_ctx, Signature *s,
const char *str) 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; 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) if (DetectSignatureSetAppProto(s, ALPROTO_TEMPLATE) != 0)
return -1; return -1;
return 0; return 0;
} }
static int DetectEngineInspectTemplateBuffer(ThreadVars *tv, /** \internal
DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, * \brief get the data to inspect from the transaction.
const Signature *s, const SigMatchData *smd, * This function gets the data, sets up the InspectionBuffer object
Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id) * 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; const uint8_t *data = NULL;
int ret = 0; uint32_t data_len = 0;
if (flags & STREAM_TOSERVER && tx->request_buffer != NULL) { BUG_ON(det_ctx->inspect_buffers == NULL);
ret = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f, tx->request_buffer, tx->request_buffer_len, InspectionBuffer *buffer = &det_ctx->inspect_buffers[list_id];
0, DETECT_CI_FLAGS_SINGLE, if (buffer->inspect == NULL) {
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL); const TemplateTransaction *tx = (TemplateTransaction *)txv;
}
else if (flags & STREAM_TOCLIENT && tx->response_buffer != NULL) { if (flow_flags & STREAM_TOSERVER) {
ret = DetectEngineContentInspection(de_ctx, det_ctx, s, smd, data = tx->request_buffer;
f, tx->response_buffer, tx->response_buffer_len, data_len = tx->request_buffer_len;
0, DETECT_CI_FLAGS_SINGLE, } else if (flow_flags & STREAM_TOCLIENT) {
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL); 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 buffer;
return ret;
} }
#ifdef UNITTESTS #ifdef UNITTESTS

Loading…
Cancel
Save