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
* 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);
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 */
}
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);
InspectionBufferSetup(buffer, data, data_len);
InspectionBufferApplyTransforms(buffer, transforms);
}
SCLogNotice("Returning %d.", ret);
return ret;
return buffer;
}
#ifdef UNITTESTS

Loading…
Cancel
Save