http1: implement http.request_header

So that it is generic for HTTP1 and HTTP2

Ticket: #5780
pull/9001/head
Philippe Antoine 2 years ago committed by Victor Julien
parent 7256ec8a6e
commit 415b036dca

@ -684,6 +684,43 @@ like ``distance``, ``offset``, ``within``, etc.
The ``nocase`` keyword is not allowed anymore. Keep in mind that you need
to specify a lowercase pattern.
http.request_header
-------------------
Match on the name and value of a HTTP request header (HTTP1 or HTTP2).
For HTTP2, name and value get concatenated by ": ", colon and space.
To detect if a http2 header name contains ':',
the keyword ``http2.header_name`` can be used.
Examples::
http.request_header; content:"agent: nghttp2";
http.request_header; content:"custom-header: I love::colons";
``http.request_header`` is a 'sticky buffer'.
``http.request_header`` can be used as ``fast_pattern``.
http.response_header
--------------------
Match on the name and value of a HTTP response header (HTTP1 or HTTP2).
For HTTP2, name and value get concatenated by ": ", colon and space.
To detect if a http2 header name contains ':',
the keyword ``http2.header_name`` can be used.
Examples::
http.response_header; content:"server: nghttp2";
http.response_header; content:"custom-header: I love::colons";
``http.response_header`` is a 'sticky buffer'.
``http.response_header`` can be used as ``fast_pattern``.
Notes
~~~~~

@ -110,37 +110,6 @@ Examples::
``http2.header_name`` can be used as ``fast_pattern``.
http.request_header
-------------------
Match on the name and value of a HTTP2 request header from a HEADER frame (or PUSH_PROMISE or CONTINUATION).
Name and value get concatenated by ": ", colon and space.
Examples::
http.request_header; content:"agent: nghttp2";
http.request_header; content:"custom-header: I love::colons";
``http.request_header`` is a 'sticky buffer'.
``http.request_header`` can be used as ``fast_pattern``.
http.response_header
--------------------
Match on the name and value of a HTTP2 response header from a HEADER frame (or PUSH_PROMISE or CONTINUATION).
Name and value get concatenated by ": ", colon and space.
Examples::
http.response_header; content:"server: nghttp2";
http.response_header; content:"custom-header: I love::colons";
``http.response_header`` is a 'sticky buffer'.
``http.response_header`` can be used as ``fast_pattern``.
Additional information
----------------------

@ -477,6 +477,8 @@ void SigTableSetup(void)
DetectHttpResponseLineRegister();
DetectHttpServerBodyRegister();
DetectHttpHeaderRegister();
DetectHttpRequestHeaderRegister();
DetectHttpResponseHeaderRegister();
DetectHttpHeaderNamesRegister();
DetectHttpHeadersRegister();
DetectHttpProtocolRegister();

@ -465,6 +465,327 @@ void DetectHttpHeaderRegister(void)
HttpHeaderThreadDataInit, &g_td_config, HttpHeaderThreadDataFree);
}
static int g_http_request_header_buffer_id = 0;
static int g_http_response_header_buffer_id = 0;
static InspectionBuffer *GetHttp2HeaderData(DetectEngineThreadCtx *det_ctx, const uint8_t flags,
const DetectEngineTransforms *transforms, Flow *_f, const struct MpmListIdDataArgs *cbdata,
int list_id)
{
SCEnter();
InspectionBuffer *buffer =
InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id);
if (buffer == NULL)
return NULL;
if (buffer->initialized)
return buffer;
uint32_t b_len = 0;
const uint8_t *b = NULL;
if (rs_http2_tx_get_header(cbdata->txv, flags, cbdata->local_id, &b, &b_len) != 1) {
InspectionBufferSetupMultiEmpty(buffer);
return NULL;
}
if (b == NULL || b_len == 0) {
InspectionBufferSetupMultiEmpty(buffer);
return NULL;
}
InspectionBufferSetupMulti(buffer, transforms, b, b_len);
SCReturnPtr(buffer, "InspectionBuffer");
}
static void PrefilterTxHttp2Header(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p,
Flow *f, void *txv, const uint64_t idx, const AppLayerTxData *_txd, const uint8_t flags)
{
SCEnter();
const PrefilterMpmListId *ctx = (const PrefilterMpmListId *)pectx;
const MpmCtx *mpm_ctx = ctx->mpm_ctx;
const int list_id = ctx->list_id;
uint32_t local_id = 0;
while (1) {
// loop until we get a NULL
struct MpmListIdDataArgs cbdata = { local_id, txv };
InspectionBuffer *buffer =
GetHttp2HeaderData(det_ctx, flags, ctx->transforms, f, &cbdata, list_id);
if (buffer == NULL)
break;
if (buffer->inspect_len >= mpm_ctx->minlen) {
(void)mpm_table[mpm_ctx->mpm_type].Search(
mpm_ctx, &det_ctx->mtcu, &det_ctx->pmq, buffer->inspect, buffer->inspect_len);
PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len);
}
local_id++;
}
}
static uint8_t DetectEngineInspectHttp2Header(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine,
const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
{
uint32_t local_id = 0;
const DetectEngineTransforms *transforms = NULL;
if (!engine->mpm) {
transforms = engine->v2.transforms;
}
while (1) {
struct MpmListIdDataArgs cbdata = {
local_id,
txv,
};
InspectionBuffer *buffer =
GetHttp2HeaderData(det_ctx, flags, transforms, f, &cbdata, engine->sm_list);
if (buffer == NULL || buffer->inspect == NULL)
break;
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f,
(uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset,
DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
if (match == 1) {
return DETECT_ENGINE_INSPECT_SIG_MATCH;
}
local_id++;
}
return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
static int PrefilterMpmHttp2HeaderRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
{
PrefilterMpmListId *pectx = SCCalloc(1, sizeof(*pectx));
if (pectx == NULL)
return -1;
pectx->list_id = list_id;
pectx->mpm_ctx = mpm_ctx;
pectx->transforms = &mpm_reg->transforms;
return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttp2Header, mpm_reg->app_v2.alproto,
mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMpmHttpHeaderFree, mpm_reg->name);
}
static InspectionBuffer *GetHttp1HeaderData(DetectEngineThreadCtx *det_ctx, const uint8_t flags,
const DetectEngineTransforms *transforms, Flow *f, const struct MpmListIdDataArgs *cbdata,
int list_id)
{
SCEnter();
InspectionBuffer *buffer =
InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id);
if (buffer == NULL)
return NULL;
if (buffer->initialized)
return buffer;
HttpHeaderThreadData *hdr_td = NULL;
HttpHeaderBuffer *buf =
HttpHeaderGetBufferSpace(det_ctx, f, flags, g_keyword_thread_id, &hdr_td);
if (unlikely(buf == NULL)) {
return NULL;
}
htp_tx_t *tx = (htp_tx_t *)cbdata->txv;
htp_table_t *headers;
if (flags & STREAM_TOSERVER) {
headers = tx->request_headers;
} else {
headers = tx->response_headers;
}
if (cbdata->local_id < htp_table_size(headers)) {
htp_header_t *h = htp_table_get_index(headers, cbdata->local_id, NULL);
size_t size1 = bstr_size(h->name);
size_t size2 = bstr_size(h->value);
size_t b_len = size1 + 2 + size2;
if (b_len > buf->size) {
if (HttpHeaderExpandBuffer(hdr_td, buf, b_len) != 0) {
return NULL;
}
}
memcpy(buf->buffer, bstr_ptr(h->name), bstr_size(h->name));
buf->buffer[size1] = ':';
buf->buffer[size1 + 1] = ' ';
memcpy(buf->buffer + size1 + 2, bstr_ptr(h->value), bstr_size(h->value));
buf->len = b_len;
} else {
InspectionBufferSetupMultiEmpty(buffer);
return NULL;
}
if (buf->len == 0) {
InspectionBufferSetupMultiEmpty(buffer);
return NULL;
}
InspectionBufferSetupMulti(buffer, transforms, buf->buffer, buf->len);
SCReturnPtr(buffer, "InspectionBuffer");
}
static void PrefilterTxHttp1Header(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p,
Flow *f, void *txv, const uint64_t idx, const AppLayerTxData *_txd, const uint8_t flags)
{
SCEnter();
const PrefilterMpmListId *ctx = (const PrefilterMpmListId *)pectx;
const MpmCtx *mpm_ctx = ctx->mpm_ctx;
const int list_id = ctx->list_id;
uint32_t local_id = 0;
while (1) {
// loop until we get a NULL
struct MpmListIdDataArgs cbdata = { local_id, txv };
InspectionBuffer *buffer =
GetHttp1HeaderData(det_ctx, flags, ctx->transforms, f, &cbdata, list_id);
if (buffer == NULL)
break;
if (buffer->inspect_len >= mpm_ctx->minlen) {
(void)mpm_table[mpm_ctx->mpm_type].Search(
mpm_ctx, &det_ctx->mtcu, &det_ctx->pmq, buffer->inspect, buffer->inspect_len);
PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len);
}
local_id++;
}
}
static int PrefilterMpmHttp1HeaderRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
{
PrefilterMpmListId *pectx = SCCalloc(1, sizeof(*pectx));
if (pectx == NULL)
return -1;
pectx->list_id = list_id;
pectx->mpm_ctx = mpm_ctx;
pectx->transforms = &mpm_reg->transforms;
return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttp1Header, mpm_reg->app_v2.alproto,
mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMpmHttpHeaderFree, mpm_reg->name);
}
static uint8_t DetectEngineInspectHttp1Header(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine,
const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
{
uint32_t local_id = 0;
const DetectEngineTransforms *transforms = NULL;
if (!engine->mpm) {
transforms = engine->v2.transforms;
}
while (1) {
struct MpmListIdDataArgs cbdata = {
local_id,
txv,
};
InspectionBuffer *buffer =
GetHttp1HeaderData(det_ctx, flags, transforms, f, &cbdata, engine->sm_list);
if (buffer == NULL || buffer->inspect == NULL)
break;
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f,
(uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset,
DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
if (match == 1) {
return DETECT_ENGINE_INSPECT_SIG_MATCH;
}
local_id++;
}
return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
static int DetectHTTPRequestHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{
if (DetectBufferSetActiveList(de_ctx, s, g_http_request_header_buffer_id) < 0)
return -1;
if (DetectSignatureSetAppProto(s, ALPROTO_HTTP) != 0)
return -1;
return 0;
}
void DetectHttpRequestHeaderRegister(void)
{
sigmatch_table[DETECT_HTTP_REQUEST_HEADER].name = "http.request_header";
sigmatch_table[DETECT_HTTP_REQUEST_HEADER].desc =
"sticky buffer to match on only one HTTP header name and value";
sigmatch_table[DETECT_HTTP_REQUEST_HEADER].url = "/rules/http-keywords.html#request_header";
sigmatch_table[DETECT_HTTP_REQUEST_HEADER].Setup = DetectHTTPRequestHeaderSetup;
sigmatch_table[DETECT_HTTP_REQUEST_HEADER].flags |=
SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER;
DetectAppLayerMpmRegister2("http_request_header", SIG_FLAG_TOSERVER, 2,
PrefilterMpmHttp2HeaderRegister, NULL, ALPROTO_HTTP2, HTTP2StateOpen);
DetectAppLayerInspectEngineRegister2("http_request_header", ALPROTO_HTTP2, SIG_FLAG_TOSERVER,
HTTP2StateOpen, DetectEngineInspectHttp2Header, NULL);
DetectAppLayerMpmRegister2("http_request_header", SIG_FLAG_TOSERVER, 2,
PrefilterMpmHttp1HeaderRegister, NULL, ALPROTO_HTTP1, 0);
DetectAppLayerInspectEngineRegister2("http_request_header", ALPROTO_HTTP1, SIG_FLAG_TOSERVER,
HTP_REQUEST_HEADERS, DetectEngineInspectHttp1Header, NULL);
DetectBufferTypeSetDescriptionByName("http_request_header", "HTTP header name and value");
g_http_request_header_buffer_id = DetectBufferTypeGetByName("http_request_header");
}
static int DetectHTTPResponseHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{
if (DetectBufferSetActiveList(de_ctx, s, g_http_response_header_buffer_id) < 0)
return -1;
if (DetectSignatureSetAppProto(s, ALPROTO_HTTP) != 0)
return -1;
return 0;
}
void DetectHttpResponseHeaderRegister(void)
{
sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].name = "http.response_header";
sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].desc =
"sticky buffer to match on only one HTTP header name and value";
sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].url = "/rules/http2-keywords.html#response_header";
sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].Setup = DetectHTTPResponseHeaderSetup;
sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].flags |=
SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER;
DetectAppLayerMpmRegister2("http_response_header", SIG_FLAG_TOCLIENT, 2,
PrefilterMpmHttp2HeaderRegister, NULL, ALPROTO_HTTP2, HTTP2StateOpen);
DetectAppLayerInspectEngineRegister2("http_response_header", ALPROTO_HTTP2, SIG_FLAG_TOCLIENT,
HTTP2StateOpen, DetectEngineInspectHttp2Header, NULL);
DetectAppLayerMpmRegister2("http_response_header", SIG_FLAG_TOCLIENT, 2,
PrefilterMpmHttp1HeaderRegister, NULL, ALPROTO_HTTP1, 0);
DetectAppLayerInspectEngineRegister2("http_response_header", ALPROTO_HTTP1, SIG_FLAG_TOCLIENT,
HTP_RESPONSE_HEADERS, DetectEngineInspectHttp1Header, NULL);
DetectBufferTypeSetDescriptionByName("http_response_header", "HTTP header name and value");
g_http_response_header_buffer_id = DetectBufferTypeGetByName("http_response_header");
}
/************************************Unittests*********************************/
#ifdef UNITTESTS

@ -26,5 +26,7 @@
void DetectHttpHeaderRegister(void);
void DetectHttpRawHeaderRegister(void);
void DetectHttpRequestHeaderRegister(void);
void DetectHttpResponseHeaderRegister(void);
#endif /* __DETECT_HTTP_HEADER_H__ */

@ -92,22 +92,12 @@ static uint8_t DetectEngineInspectHttp2HeaderName(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine,
const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id);
static int DetectHTTPRequestHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg);
static int DetectHTTPResponseHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg);
static int PrefilterMpmHttp2HeaderRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id);
static uint8_t DetectEngineInspectHttp2Header(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine,
const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id);
#ifdef UNITTESTS
void DetectHTTP2RegisterTests (void);
#endif
static int g_http2_match_buffer_id = 0;
static int g_http2_header_name_buffer_id = 0;
static int g_http_request_header_buffer_id = 0;
static int g_http_response_header_buffer_id = 0;
/**
* \brief Registration function for HTTP2 keywords
@ -204,36 +194,6 @@ void DetectHttp2Register(void)
"HTTP2 header name");
g_http2_header_name_buffer_id = DetectBufferTypeGetByName("http2_header_name");
sigmatch_table[DETECT_HTTP_REQUEST_HEADER].name = "http.request_header";
sigmatch_table[DETECT_HTTP_REQUEST_HEADER].desc =
"sticky buffer to match on only one HTTP header name and value";
sigmatch_table[DETECT_HTTP_REQUEST_HEADER].url = "/rules/http2-keywords.html#request_header";
sigmatch_table[DETECT_HTTP_REQUEST_HEADER].Setup = DetectHTTPRequestHeaderSetup;
sigmatch_table[DETECT_HTTP_REQUEST_HEADER].flags |=
SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER;
DetectAppLayerMpmRegister2("http_request_header", SIG_FLAG_TOSERVER, 2,
PrefilterMpmHttp2HeaderRegister, NULL, ALPROTO_HTTP2, HTTP2StateOpen);
DetectAppLayerInspectEngineRegister2("http_request_header", ALPROTO_HTTP2, SIG_FLAG_TOSERVER,
HTTP2StateOpen, DetectEngineInspectHttp2Header, NULL);
DetectBufferTypeSetDescriptionByName("http_request_header", "HTTP header name and value");
g_http_request_header_buffer_id = DetectBufferTypeGetByName("http_request_header");
sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].name = "http.response_header";
sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].desc =
"sticky buffer to match on only one HTTP header name and value";
sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].url = "/rules/http2-keywords.html#response_header";
sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].Setup = DetectHTTPResponseHeaderSetup;
sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].flags |=
SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER;
DetectAppLayerMpmRegister2("http_response_header", SIG_FLAG_TOCLIENT, 2,
PrefilterMpmHttp2HeaderRegister, NULL, ALPROTO_HTTP2, HTTP2StateOpen);
DetectAppLayerInspectEngineRegister2("http_response_header", ALPROTO_HTTP2, SIG_FLAG_TOCLIENT,
HTTP2StateOpen, DetectEngineInspectHttp2Header, NULL);
DetectBufferTypeSetDescriptionByName("http_response_header", "HTTP header name and value");
g_http_response_header_buffer_id = DetectBufferTypeGetByName("http_response_header");
DetectAppLayerInspectEngineRegister2(
"http2", ALPROTO_HTTP2, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL);
DetectAppLayerInspectEngineRegister2(
@ -792,147 +752,6 @@ static uint8_t DetectEngineInspectHttp2HeaderName(DetectEngineCtx *de_ctx,
return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
static int DetectHTTPRequestHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{
if (DetectBufferSetActiveList(de_ctx, s, g_http_request_header_buffer_id) < 0)
return -1;
if (DetectSignatureSetAppProto(s, ALPROTO_HTTP2) != 0)
return -1;
return 0;
}
static int DetectHTTPResponseHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{
if (DetectBufferSetActiveList(de_ctx, s, g_http_response_header_buffer_id) < 0)
return -1;
if (DetectSignatureSetAppProto(s, ALPROTO_HTTP2) != 0)
return -1;
return 0;
}
static void PrefilterMpmHttp2HeaderFree(void *ptr)
{
SCFree(ptr);
}
static InspectionBuffer *GetHttp2HeaderData(DetectEngineThreadCtx *det_ctx, const uint8_t flags,
const DetectEngineTransforms *transforms, Flow *_f, const struct MpmListIdDataArgs *cbdata,
int list_id)
{
SCEnter();
InspectionBuffer *buffer =
InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id);
if (buffer == NULL)
return NULL;
if (buffer->initialized)
return buffer;
uint32_t b_len = 0;
const uint8_t *b = NULL;
if (rs_http2_tx_get_header(cbdata->txv, flags, cbdata->local_id, &b, &b_len) != 1) {
InspectionBufferSetupMultiEmpty(buffer);
return NULL;
}
if (b == NULL || b_len == 0) {
InspectionBufferSetupMultiEmpty(buffer);
return NULL;
}
InspectionBufferSetupMulti(buffer, transforms, b, b_len);
SCReturnPtr(buffer, "InspectionBuffer");
}
static void PrefilterTxHttp2Header(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p,
Flow *f, void *txv, const uint64_t idx, const AppLayerTxData *_txd, const uint8_t flags)
{
SCEnter();
const PrefilterMpmListId *ctx = (const PrefilterMpmListId *)pectx;
const MpmCtx *mpm_ctx = ctx->mpm_ctx;
const int list_id = ctx->list_id;
uint32_t local_id = 0;
while(1) {
// loop until we get a NULL
struct MpmListIdDataArgs cbdata = { local_id, txv };
InspectionBuffer *buffer =
GetHttp2HeaderData(det_ctx, flags, ctx->transforms, f, &cbdata, list_id);
if (buffer == NULL)
break;
if (buffer->inspect_len >= mpm_ctx->minlen) {
(void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
&det_ctx->mtcu, &det_ctx->pmq,
buffer->inspect, buffer->inspect_len);
PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len);
}
local_id++;
}
}
static int PrefilterMpmHttp2HeaderRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
{
PrefilterMpmListId *pectx = SCCalloc(1, sizeof(*pectx));
if (pectx == NULL)
return -1;
pectx->list_id = list_id;
pectx->mpm_ctx = mpm_ctx;
pectx->transforms = &mpm_reg->transforms;
return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttp2Header,
mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress,
pectx, PrefilterMpmHttp2HeaderFree, mpm_reg->name);
}
static uint8_t DetectEngineInspectHttp2Header(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine,
const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
{
uint32_t local_id = 0;
const DetectEngineTransforms *transforms = NULL;
if (!engine->mpm) {
transforms = engine->v2.transforms;
}
while (1) {
struct MpmListIdDataArgs cbdata = { local_id, txv, };
InspectionBuffer *buffer =
GetHttp2HeaderData(det_ctx, flags, transforms, f, &cbdata, engine->sm_list);
if (buffer == NULL || buffer->inspect == NULL)
break;
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd,
NULL, f,
(uint8_t *)buffer->inspect,
buffer->inspect_len,
buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
if (match == 1) {
return DETECT_ENGINE_INSPECT_SIG_MATCH;
}
local_id++;
}
return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
#ifdef UNITTESTS
#include "tests/detect-http2.c"
#endif

Loading…
Cancel
Save