diff --git a/src/detect-dns-answer-name.c b/src/detect-dns-answer-name.c index bc64f55fbf..dc1272d475 100644 --- a/src/detect-dns-answer-name.c +++ b/src/detect-dns-answer-name.c @@ -30,12 +30,6 @@ #include "util-profiling.h" #include "rust.h" -typedef struct PrefilterMpm { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpm; - static int detect_buffer_id = 0; static int DetectSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) @@ -50,8 +44,9 @@ static int DetectSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) return 0; } -static InspectionBuffer *GetBuffer(DetectEngineThreadCtx *det_ctx, uint8_t flags, - const DetectEngineTransforms *transforms, void *txv, uint32_t index, int list_id) +static InspectionBuffer *GetBuffer(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, uint8_t flags, void *txv, int list_id, + uint32_t index) { InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, index); if (buffer == NULL) { @@ -74,74 +69,6 @@ static InspectionBuffer *GetBuffer(DetectEngineThreadCtx *det_ctx, uint8_t flags return buffer; } -static uint8_t DetectEngineInspectCb(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f, - uint8_t flags, void *alstate, void *txv, uint64_t tx_id) -{ - const DetectEngineTransforms *transforms = NULL; - if (!engine->mpm) { - transforms = engine->v2.transforms; - } - - for (uint32_t i = 0;; i++) { - InspectionBuffer *buffer = GetBuffer(det_ctx, flags, transforms, txv, i, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) { - break; - } - - const bool match = DetectEngineContentInspectionBuffer(de_ctx, det_ctx, s, engine->smd, - NULL, f, buffer, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - } - - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -static void PrefilterTx(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 PrefilterMpm *ctx = (const PrefilterMpm *)pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - const int list_id = ctx->list_id; - - for (uint32_t i = 0;; i++) { - InspectionBuffer *buffer = GetBuffer(det_ctx, flags, ctx->transforms, txv, i, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - } -} - -static void PrefilterMpmFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, - const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpm *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, PrefilterTx, mpm_reg->app_v2.alproto, - mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMpmFree, mpm_reg->pname); -} - void DetectDnsAnswerNameRegister(void) { static const char *keyword = "dns.answer.name"; @@ -154,16 +81,9 @@ void DetectDnsAnswerNameRegister(void) /* Register in the TO_SERVER direction, even though this is not normal, it could be provided as part of a request. */ - DetectAppLayerInspectEngineRegister( - keyword, ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, DetectEngineInspectCb, NULL); - DetectAppLayerMpmRegister( - keyword, SIG_FLAG_TOSERVER, 2, PrefilterMpmRegister, NULL, ALPROTO_DNS, 1); - + DetectAppLayerMultiRegister(keyword, ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, GetBuffer, 2, 1); /* Register in the TO_CLIENT direction. */ - DetectAppLayerInspectEngineRegister( - keyword, ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectCb, NULL); - DetectAppLayerMpmRegister( - keyword, SIG_FLAG_TOCLIENT, 2, PrefilterMpmRegister, NULL, ALPROTO_DNS, 1); + DetectAppLayerMultiRegister(keyword, ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, GetBuffer, 2, 1); DetectBufferTypeSetDescriptionByName(keyword, "dns answer name"); DetectBufferTypeSupportsMultiInstance(keyword); diff --git a/src/detect-dns-query-name.c b/src/detect-dns-query-name.c index a3983bf575..ca1cc79fa4 100644 --- a/src/detect-dns-query-name.c +++ b/src/detect-dns-query-name.c @@ -30,12 +30,6 @@ #include "util-profiling.h" #include "rust.h" -typedef struct PrefilterMpm { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpm; - static int detect_buffer_id = 0; static int DetectSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) @@ -50,8 +44,9 @@ static int DetectSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) return 0; } -static InspectionBuffer *GetBuffer(DetectEngineThreadCtx *det_ctx, const uint8_t flags, - const DetectEngineTransforms *transforms, void *txv, uint32_t index, int list_id) +static InspectionBuffer *GetBuffer(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t index) { InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, index); if (buffer == NULL) { @@ -74,74 +69,6 @@ static InspectionBuffer *GetBuffer(DetectEngineThreadCtx *det_ctx, const uint8_t return buffer; } -static uint8_t DetectEngineInspectCb(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f, - uint8_t flags, void *alstate, void *txv, uint64_t tx_id) -{ - const DetectEngineTransforms *transforms = NULL; - if (!engine->mpm) { - transforms = engine->v2.transforms; - } - - for (uint32_t i = 0;; i++) { - InspectionBuffer *buffer = GetBuffer(det_ctx, flags, transforms, txv, i, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) { - break; - } - - const bool match = DetectEngineContentInspectionBuffer(de_ctx, det_ctx, s, engine->smd, - NULL, f, buffer, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - } - - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -static void PrefilterTx(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 PrefilterMpm *ctx = (const PrefilterMpm *)pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - const int list_id = ctx->list_id; - - for (uint32_t i = 0;; i++) { - InspectionBuffer *buffer = GetBuffer(det_ctx, flags, ctx->transforms, txv, i, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - } -} - -static void PrefilterMpmFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, - const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpm *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, PrefilterTx, mpm_reg->app_v2.alproto, - mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMpmFree, mpm_reg->pname); -} - void DetectDnsQueryNameRegister(void) { static const char *keyword = "dns.query.name"; @@ -154,15 +81,8 @@ void DetectDnsQueryNameRegister(void) /* Register in both directions as the query is usually echoed back in the response. */ - DetectAppLayerInspectEngineRegister( - keyword, ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, DetectEngineInspectCb, NULL); - DetectAppLayerMpmRegister( - keyword, SIG_FLAG_TOSERVER, 2, PrefilterMpmRegister, NULL, ALPROTO_DNS, 1); - - DetectAppLayerInspectEngineRegister( - keyword, ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectCb, NULL); - DetectAppLayerMpmRegister( - keyword, SIG_FLAG_TOCLIENT, 2, PrefilterMpmRegister, NULL, ALPROTO_DNS, 1); + DetectAppLayerMultiRegister(keyword, ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, GetBuffer, 2, 1); + DetectAppLayerMultiRegister(keyword, ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, GetBuffer, 2, 1); DetectBufferTypeSetDescriptionByName(keyword, "dns query name"); DetectBufferTypeSupportsMultiInstance(keyword); diff --git a/src/detect-dns-query.c b/src/detect-dns-query.c index 3225f126f2..2cf0f7610f 100644 --- a/src/detect-dns-query.c +++ b/src/detect-dns-query.c @@ -67,19 +67,13 @@ static void DetectDnsQueryRegisterTests(void); #endif static int g_dns_query_buffer_id = 0; -struct DnsQueryGetDataArgs { - uint32_t local_id; /**< used as index into thread inspect array */ - void *txv; -}; - static InspectionBuffer *DnsQueryGetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, struct DnsQueryGetDataArgs *cbdata, - int list_id) + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) { SCEnter(); - InspectionBuffer *buffer = - InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); if (buffer == NULL) return NULL; if (buffer->initialized) @@ -87,7 +81,7 @@ static InspectionBuffer *DnsQueryGetData(DetectEngineThreadCtx *det_ctx, const uint8_t *data; uint32_t data_len; - if (SCDnsTxGetQueryName(cbdata->txv, false, cbdata->local_id, &data, &data_len) == 0) { + if (SCDnsTxGetQueryName(txv, false, local_id, &data, &data_len) == 0) { InspectionBufferSetupMultiEmpty(buffer); return NULL; } @@ -97,96 +91,6 @@ static InspectionBuffer *DnsQueryGetData(DetectEngineThreadCtx *det_ctx, SCReturnPtr(buffer, "InspectionBuffer"); } -static uint8_t DetectEngineInspectDnsQuery(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 DnsQueryGetDataArgs cbdata = { local_id, txv, }; - InspectionBuffer *buffer = - DnsQueryGetData(det_ctx, transforms, f, &cbdata, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) - break; - - const bool match = DetectEngineContentInspectionBuffer(de_ctx, det_ctx, s, engine->smd, - NULL, f, buffer, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - local_id++; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -typedef struct PrefilterMpmDnsQuery { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmDnsQuery; - -/** \brief DnsQuery DnsQuery Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxDnsQuery(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 PrefilterMpmDnsQuery *ctx = (const PrefilterMpmDnsQuery *)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 DnsQueryGetDataArgs cbdata = { local_id, txv }; - InspectionBuffer *buffer = DnsQueryGetData(det_ctx, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - - local_id++; - } -} - -static void PrefilterMpmDnsQueryFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterMpmDnsQueryRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, - const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpmDnsQuery *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, PrefilterTxDnsQuery, - mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress, - pectx, PrefilterMpmDnsQueryFree, mpm_reg->pname); -} - /** * \brief Registration function for keyword: dns_query */ @@ -203,11 +107,8 @@ void DetectDnsQueryRegister (void) sigmatch_table[DETECT_AL_DNS_QUERY].flags |= SIGMATCH_NOOPT; sigmatch_table[DETECT_AL_DNS_QUERY].flags |= SIGMATCH_INFO_STICKY_BUFFER; - DetectAppLayerMpmRegister( - "dns_query", SIG_FLAG_TOSERVER, 2, PrefilterMpmDnsQueryRegister, NULL, ALPROTO_DNS, 1); - - DetectAppLayerInspectEngineRegister( - "dns_query", ALPROTO_DNS, SIG_FLAG_TOSERVER, 1, DetectEngineInspectDnsQuery, NULL); + DetectAppLayerMultiRegister( + "dns_query", ALPROTO_DNS, SIG_FLAG_TOSERVER, 1, DnsQueryGetData, 2, 1); DetectBufferTypeSetDescriptionByName("dns_query", "dns request query"); diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 6ceeaa63f2..f1b302abce 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -86,9 +86,9 @@ static int g_mpm_list_cnt[DETECT_BUFFER_MPM_TYPE_SIZE] = { 0, 0, 0 }; * * \note to be used at start up / registration only. Errors are fatal. */ -void DetectAppLayerMpmRegister(const char *name, int direction, int priority, +static void RegisterInternal(const char *name, int direction, int priority, PrefilterRegisterFunc PrefilterRegister, InspectionBufferGetDataPtr GetData, - AppProto alproto, int tx_min_progress) + InspectionMultiBufferGetDataPtr GetMultiData, AppProto alproto, int tx_min_progress) { SCLogDebug("registering %s/%d/%d/%p/%p/%u/%d", name, direction, priority, PrefilterRegister, GetData, alproto, tx_min_progress); @@ -119,7 +119,11 @@ void DetectAppLayerMpmRegister(const char *name, int direction, int priority, am->type = DETECT_BUFFER_MPM_TYPE_APP; am->PrefilterRegisterWithListId = PrefilterRegister; - am->app_v2.GetData = GetData; + if (GetData != NULL) { + am->app_v2.GetData = GetData; + } else if (GetMultiData != NULL) { + am->app_v2.GetMultiData = GetMultiData; + } am->app_v2.alproto = alproto; am->app_v2.tx_min_progress = tx_min_progress; @@ -139,6 +143,22 @@ void DetectAppLayerMpmRegister(const char *name, int direction, int priority, SupportFastPatternForSigMatchList(sm_list, priority); } +void DetectAppLayerMpmRegister(const char *name, int direction, int priority, + PrefilterRegisterFunc PrefilterRegister, InspectionBufferGetDataPtr GetData, + AppProto alproto, int tx_min_progress) +{ + RegisterInternal( + name, direction, priority, PrefilterRegister, GetData, NULL, alproto, tx_min_progress); +} + +void DetectAppLayerMpmMultiRegister(const char *name, int direction, int priority, + PrefilterRegisterFunc PrefilterRegister, InspectionMultiBufferGetDataPtr GetData, + AppProto alproto, int tx_min_progress) +{ + RegisterInternal( + name, direction, priority, PrefilterRegister, NULL, GetData, alproto, tx_min_progress); +} + /** \brief copy a mpm engine from parent_id, add in transforms */ void DetectAppLayerMpmRegisterByParentId(DetectEngineCtx *de_ctx, const int id, const int parent_id, diff --git a/src/detect-engine-mpm.h b/src/detect-engine-mpm.h index 197416fdc9..f11b7e231e 100644 --- a/src/detect-engine-mpm.h +++ b/src/detect-engine-mpm.h @@ -90,6 +90,9 @@ typedef int (*PrefilterRegisterFunc)(DetectEngineCtx *de_ctx, SigGroupHead *sgh, void DetectAppLayerMpmRegister(const char *name, int direction, int priority, PrefilterRegisterFunc PrefilterRegister, InspectionBufferGetDataPtr GetData, AppProto alproto, int tx_min_progress); +void DetectAppLayerMpmMultiRegister(const char *name, int direction, int priority, + PrefilterRegisterFunc PrefilterRegister, InspectionMultiBufferGetDataPtr GetData, + AppProto alproto, int tx_min_progress); void DetectAppLayerMpmRegisterByParentId( DetectEngineCtx *de_ctx, const int id, const int parent_id, @@ -122,6 +125,7 @@ int PrefilterGenericMpmFrameRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, typedef struct PrefilterMpmListId { int list_id; const MpmCtx *mpm_ctx; + InspectionMultiBufferGetDataPtr GetData; const DetectEngineTransforms *transforms; } PrefilterMpmListId; diff --git a/src/detect-engine-prefilter.c b/src/detect-engine-prefilter.c index e40a5175da..3c06e7a01c 100644 --- a/src/detect-engine-prefilter.c +++ b/src/detect-engine-prefilter.c @@ -763,6 +763,59 @@ int PrefilterGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmC return r; } +static void PrefilterMultiGenericMpmFree(void *ptr) +{ + // PrefilterMpmListId + SCFree(ptr); +} + +static void PrefilterMultiMpm(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; + SCLogDebug("running on list %d", ctx->list_id); + uint32_t local_id = 0; + + do { + // loop until we get a NULL + InspectionBuffer *buffer = + ctx->GetData(det_ctx, ctx->transforms, f, flags, txv, ctx->list_id, local_id); + if (buffer == NULL) + break; + + if (buffer->inspect_len >= mpm_ctx->minlen) { + (void)mpm_table[mpm_ctx->mpm_type].Search( + mpm_ctx, &det_ctx->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); + PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); + } + + local_id++; + } while (1); +} + +int PrefilterMultiGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, + const DetectBufferMpmRegistry *mpm_reg, int list_id) +{ + SCEnter(); + PrefilterMpmListId *pectx = SCCalloc(1, sizeof(*pectx)); + if (pectx == NULL) + return -1; + pectx->list_id = list_id; + pectx->GetData = mpm_reg->app_v2.GetMultiData; + pectx->mpm_ctx = mpm_ctx; + pectx->transforms = &mpm_reg->transforms; + + int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterMultiMpm, mpm_reg->app_v2.alproto, + mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMultiGenericMpmFree, mpm_reg->pname); + if (r != 0) { + SCFree(pectx); + } + return r; +} + /* generic mpm for pkt engines */ typedef struct PrefilterMpmPktCtx { diff --git a/src/detect-engine-prefilter.h b/src/detect-engine-prefilter.h index 58daeca6e7..fc61c47f3c 100644 --- a/src/detect-engine-prefilter.h +++ b/src/detect-engine-prefilter.h @@ -89,6 +89,9 @@ void PrefilterDeinit(DetectEngineCtx *de_ctx); int PrefilterGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id); +int PrefilterMultiGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, + const DetectBufferMpmRegistry *mpm_reg, int list_id); + int PrefilterGenericMpmPktRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id); diff --git a/src/detect-engine.c b/src/detect-engine.c index d23edb80d2..60297fb7b0 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -166,8 +166,9 @@ void DetectPktInspectEngineRegister(const char *name, /** \brief register inspect engine at start up time * * \note errors are fatal */ -void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, - int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData) +static void AppLayerInspectEngineRegisterInternal(const char *name, AppProto alproto, uint32_t dir, + int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData, + InspectionMultiBufferGetDataPtr GetMultiData) { BUG_ON(progress >= 48); @@ -187,6 +188,10 @@ void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uin SCLogError("Invalid arguments: must register " "GetData with DetectEngineInspectBufferGeneric"); BUG_ON(1); + } else if (Callback == DetectEngineInspectMultiBufferGeneric && GetMultiData == NULL) { + SCLogError("Invalid arguments: must register " + "GetData with DetectEngineInspectMultiBufferGeneric"); + BUG_ON(1); } uint8_t direction; @@ -207,7 +212,11 @@ void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uin new_engine->sm_list_base = (uint16_t)sm_list; new_engine->progress = (int16_t)progress; new_engine->v2.Callback = Callback; - new_engine->v2.GetData = GetData; + if (Callback == DetectEngineInspectBufferGeneric) { + new_engine->v2.GetData = GetData; + } else if (Callback == DetectEngineInspectMultiBufferGeneric) { + new_engine->v2.GetMultiData = GetMultiData; + } if (g_app_inspect_engines == NULL) { g_app_inspect_engines = new_engine; @@ -221,6 +230,12 @@ void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uin } } +void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, + int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData) +{ + AppLayerInspectEngineRegisterInternal(name, alproto, dir, progress, Callback, GetData, NULL); +} + /* copy an inspect engine with transforms to a new list id. */ static void DetectAppLayerInspectEngineCopy( DetectEngineCtx *de_ctx, @@ -2164,6 +2179,46 @@ uint8_t DetectEngineInspectBufferGeneric(DetectEngineCtx *de_ctx, DetectEngineTh } } +// wrapper for both DetectAppLayerInspectEngineRegister and DetectAppLayerMpmRegister +// with cast of callback function +void DetectAppLayerMultiRegister(const char *name, AppProto alproto, uint32_t dir, int progress, + InspectionMultiBufferGetDataPtr GetData, int priority, int tx_min_progress) +{ + AppLayerInspectEngineRegisterInternal( + name, alproto, dir, progress, DetectEngineInspectMultiBufferGeneric, NULL, GetData); + DetectAppLayerMpmMultiRegister(name, dir, priority, PrefilterMultiGenericMpmRegister, GetData, + alproto, tx_min_progress); +} + +uint8_t DetectEngineInspectMultiBufferGeneric(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; + } + + do { + InspectionBuffer *buffer = engine->v2.GetMultiData( + det_ctx, transforms, f, flags, txv, engine->sm_list, local_id); + + if (buffer == NULL || buffer->inspect == NULL) + break; + + // The GetData functions set buffer->flags to DETECT_CI_FLAGS_SINGLE + // This is not meant for streaming buffers + const bool match = DetectEngineContentInspectionBuffer(de_ctx, det_ctx, s, engine->smd, + NULL, f, buffer, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); + if (match) { + return DETECT_ENGINE_INSPECT_SIG_MATCH; + } + local_id++; + } while (1); + return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; +} + /** * \brief Do the content inspection & validation for a signature * diff --git a/src/detect-engine.h b/src/detect-engine.h index 0741aabc0c..b0e443e127 100644 --- a/src/detect-engine.h +++ b/src/detect-engine.h @@ -146,6 +146,10 @@ uint8_t DetectEngineInspectBufferGeneric(DetectEngineCtx *de_ctx, DetectEngineTh const DetectEngineAppInspectionEngine *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id); +uint8_t DetectEngineInspectMultiBufferGeneric(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); + int DetectEngineInspectPktBufferGeneric( DetectEngineThreadCtx *det_ctx, const DetectEnginePktInspectionEngine *engine, @@ -164,6 +168,9 @@ int DetectEngineInspectPktBufferGeneric( void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback2, InspectionBufferGetDataPtr GetData); +void DetectAppLayerMultiRegister(const char *name, AppProto alproto, uint32_t dir, int progress, + InspectionMultiBufferGetDataPtr GetData, int priority, int tx_min_progress); + void DetectPktInspectEngineRegister(const char *name, InspectionBufferGetPktDataPtr GetPktData, InspectionBufferPktInspectFunc Callback); diff --git a/src/detect-http-header.c b/src/detect-http-header.c index f433d9fc9f..be825e5ec7 100644 --- a/src/detect-http-header.c +++ b/src/detect-http-header.c @@ -466,113 +466,6 @@ static int g_http_response_header_buffer_id = 0; static int g_request_header_thread_id = 0; static int g_response_header_thread_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->mtc, &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; - - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - 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); -} - typedef struct HttpMultiBufItem { uint8_t *buffer; size_t len; @@ -610,14 +503,42 @@ static void HttpMultiBufHeaderThreadDataFree(void *data) SCFree(td); } -static InspectionBuffer *GetHttp1HeaderData(DetectEngineThreadCtx *det_ctx, const uint8_t flags, - const DetectEngineTransforms *transforms, Flow *f, const struct MpmListIdDataArgs *cbdata, - int list_id) +static InspectionBuffer *GetHttp2HeaderData(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) { SCEnter(); - InspectionBuffer *buffer = - InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, 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(txv, flags, 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); + buffer->flags = DETECT_CI_FLAGS_SINGLE; + + SCReturnPtr(buffer, "InspectionBuffer"); +} + +static InspectionBuffer *GetHttp1HeaderData(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) +{ + SCEnter(); + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); if (buffer == NULL) return NULL; if (buffer->initialized) @@ -635,7 +556,7 @@ static InspectionBuffer *GetHttp1HeaderData(DetectEngineThreadCtx *det_ctx, cons return NULL; } - htp_tx_t *tx = (htp_tx_t *)cbdata->txv; + htp_tx_t *tx = (htp_tx_t *)txv; htp_table_t *headers; if (flags & STREAM_TOSERVER) { headers = tx->request_headers; @@ -643,7 +564,7 @@ static InspectionBuffer *GetHttp1HeaderData(DetectEngineThreadCtx *det_ctx, cons headers = tx->response_headers; } size_t no_of_headers = htp_table_size(headers); - if (cbdata->local_id == 0) { + if (local_id == 0) { // We initialize a big buffer on first item // Then, we will just use parts of it hdr_td->len = 0; @@ -682,93 +603,17 @@ static InspectionBuffer *GetHttp1HeaderData(DetectEngineThreadCtx *det_ctx, cons // cbdata->local_id is the index of the requested header buffer // hdr_td->len is the number of header buffers - if (cbdata->local_id < hdr_td->len) { + if (local_id < hdr_td->len) { // we have one valid header buffer - InspectionBufferSetupMulti(buffer, transforms, hdr_td->items[cbdata->local_id].buffer, - hdr_td->items[cbdata->local_id].len); + InspectionBufferSetupMulti( + buffer, transforms, hdr_td->items[local_id].buffer, hdr_td->items[local_id].len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; SCReturnPtr(buffer, "InspectionBuffer"); } // else there are no more header buffer to get InspectionBufferSetupMultiEmpty(buffer); return NULL; } -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->mtc, &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; - - const bool 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) { - 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) @@ -790,14 +635,10 @@ void DetectHttpRequestHeaderRegister(void) sigmatch_table[DETECT_HTTP_REQUEST_HEADER].flags |= SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER; - DetectAppLayerMpmRegister("http_request_header", SIG_FLAG_TOSERVER, 2, - PrefilterMpmHttp2HeaderRegister, NULL, ALPROTO_HTTP2, HTTP2StateOpen); - DetectAppLayerInspectEngineRegister("http_request_header", ALPROTO_HTTP2, SIG_FLAG_TOSERVER, - HTTP2StateOpen, DetectEngineInspectHttp2Header, NULL); - DetectAppLayerMpmRegister("http_request_header", SIG_FLAG_TOSERVER, 2, - PrefilterMpmHttp1HeaderRegister, NULL, ALPROTO_HTTP1, 0); - DetectAppLayerInspectEngineRegister("http_request_header", ALPROTO_HTTP1, SIG_FLAG_TOSERVER, - HTP_REQUEST_HEADERS, DetectEngineInspectHttp1Header, NULL); + DetectAppLayerMultiRegister("http_request_header", ALPROTO_HTTP2, SIG_FLAG_TOSERVER, + HTTP2StateOpen, GetHttp2HeaderData, 2, HTTP2StateOpen); + DetectAppLayerMultiRegister("http_request_header", ALPROTO_HTTP1, SIG_FLAG_TOSERVER, + HTP_REQUEST_HEADERS, GetHttp1HeaderData, 2, 0); DetectBufferTypeSetDescriptionByName("http_request_header", "HTTP header name and value"); g_http_request_header_buffer_id = DetectBufferTypeGetByName("http_request_header"); @@ -827,14 +668,10 @@ void DetectHttpResponseHeaderRegister(void) sigmatch_table[DETECT_HTTP_RESPONSE_HEADER].flags |= SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER; - DetectAppLayerMpmRegister("http_response_header", SIG_FLAG_TOCLIENT, 2, - PrefilterMpmHttp2HeaderRegister, NULL, ALPROTO_HTTP2, HTTP2StateOpen); - DetectAppLayerInspectEngineRegister("http_response_header", ALPROTO_HTTP2, SIG_FLAG_TOCLIENT, - HTTP2StateOpen, DetectEngineInspectHttp2Header, NULL); - DetectAppLayerMpmRegister("http_response_header", SIG_FLAG_TOCLIENT, 2, - PrefilterMpmHttp1HeaderRegister, NULL, ALPROTO_HTTP1, 0); - DetectAppLayerInspectEngineRegister("http_response_header", ALPROTO_HTTP1, SIG_FLAG_TOCLIENT, - HTP_RESPONSE_HEADERS, DetectEngineInspectHttp1Header, NULL); + DetectAppLayerMultiRegister("http_response_header", ALPROTO_HTTP2, SIG_FLAG_TOCLIENT, + HTTP2StateOpen, GetHttp2HeaderData, 2, HTTP2StateOpen); + DetectAppLayerMultiRegister("http_response_header", ALPROTO_HTTP1, SIG_FLAG_TOCLIENT, + HTP_RESPONSE_HEADERS, GetHttp1HeaderData, 2, 0); DetectBufferTypeSetDescriptionByName("http_response_header", "HTTP header name and value"); g_http_response_header_buffer_id = DetectBufferTypeGetByName("http_response_header"); diff --git a/src/detect-http2.c b/src/detect-http2.c index 25c77e11a2..1e047e57cd 100644 --- a/src/detect-http2.c +++ b/src/detect-http2.c @@ -86,11 +86,6 @@ static int DetectHTTP2settingsSetup (DetectEngineCtx *, Signature *, const char void DetectHTTP2settingsFree (DetectEngineCtx *, void *); static int DetectHTTP2headerNameSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg); -static int PrefilterMpmHttp2HeaderNameRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id); -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); #ifdef UNITTESTS void DetectHTTP2RegisterTests (void); @@ -103,6 +98,36 @@ static int g_http2_header_name_buffer_id = 0; * \brief Registration function for HTTP2 keywords */ +static InspectionBuffer *GetHttp2HNameData(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *_f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) +{ + SCEnter(); + + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, 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_name(txv, flags, 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); + buffer->flags = DETECT_CI_FLAGS_SINGLE; + + SCReturnPtr(buffer, "InspectionBuffer"); +} + void DetectHttp2Register(void) { sigmatch_table[DETECT_HTTP2_FRAMETYPE].name = "http2.frametype"; @@ -177,14 +202,10 @@ void DetectHttp2Register(void) sigmatch_table[DETECT_HTTP2_HEADERNAME].Setup = DetectHTTP2headerNameSetup; sigmatch_table[DETECT_HTTP2_HEADERNAME].flags |= SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER; - DetectAppLayerMpmRegister("http2_header_name", SIG_FLAG_TOCLIENT, 2, - PrefilterMpmHttp2HeaderNameRegister, NULL, ALPROTO_HTTP2, HTTP2StateOpen); - DetectAppLayerInspectEngineRegister("http2_header_name", ALPROTO_HTTP2, SIG_FLAG_TOCLIENT, - HTTP2StateOpen, DetectEngineInspectHttp2HeaderName, NULL); - DetectAppLayerMpmRegister("http2_header_name", SIG_FLAG_TOSERVER, 2, - PrefilterMpmHttp2HeaderNameRegister, NULL, ALPROTO_HTTP2, HTTP2StateOpen); - DetectAppLayerInspectEngineRegister("http2_header_name", ALPROTO_HTTP2, SIG_FLAG_TOSERVER, - HTTP2StateOpen, DetectEngineInspectHttp2HeaderName, NULL); + DetectAppLayerMultiRegister("http2_header_name", ALPROTO_HTTP2, SIG_FLAG_TOCLIENT, + HTTP2StateOpen, GetHttp2HNameData, 2, HTTP2StateOpen); + DetectAppLayerMultiRegister("http2_header_name", ALPROTO_HTTP2, SIG_FLAG_TOSERVER, + HTTP2StateOpen, GetHttp2HNameData, 2, HTTP2StateOpen); DetectBufferTypeSupportsMultiInstance("http2_header_name"); DetectBufferTypeSetDescriptionByName("http2_header_name", "HTTP2 header name"); @@ -597,119 +618,6 @@ static int DetectHTTP2headerNameSetup(DetectEngineCtx *de_ctx, Signature *s, con return 0; } -static void PrefilterMpmHttp2HNameFree(void *ptr) -{ - SCFree(ptr); -} - -static InspectionBuffer *GetHttp2HNameData(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_name(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 PrefilterTxHttp2HName(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 = - GetHttp2HNameData(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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - - local_id++; - } -} - -static int PrefilterMpmHttp2HeaderNameRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - //TODOask use PrefilterMpmListId elsewhere - 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, PrefilterTxHttp2HName, - mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress, - pectx, PrefilterMpmHttp2HNameFree, mpm_reg->name); -} - -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) -{ - uint32_t local_id = 0; - - const DetectEngineTransforms *transforms = NULL; - if (!engine->mpm) { - transforms = engine->v2.transforms; - } - - while (1) { - //TODOask use MpmListIdDataArgs elsewhere - struct MpmListIdDataArgs cbdata = { local_id, txv, }; - InspectionBuffer *buffer = - GetHttp2HNameData(det_ctx, flags, transforms, f, &cbdata, engine->sm_list); - - if (buffer == NULL || buffer->inspect == NULL) - break; - - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - local_id++; - } - - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - #ifdef UNITTESTS #include "tests/detect-http2.c" #endif diff --git a/src/detect-ike-vendor.c b/src/detect-ike-vendor.c index 5baf24c875..e3c09e9a44 100644 --- a/src/detect-ike-vendor.c +++ b/src/detect-ike-vendor.c @@ -37,31 +37,15 @@ static int DetectIkeVendorSetup(DetectEngineCtx *, Signature *, const char *); -typedef struct { - char *vendor; -} DetectIkeVendorData; - -struct IkeVendorGetDataArgs { - uint32_t local_id; - void *txv; -}; - -typedef struct PrefilterMpmIkeVendor { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmIkeVendor; - static int g_ike_vendor_buffer_id = 0; static InspectionBuffer *IkeVendorGetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, struct IkeVendorGetDataArgs *cbdata, - int list_id) + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) { SCEnter(); - InspectionBuffer *buffer = - InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); if (buffer == NULL) return NULL; if (buffer->initialized) @@ -69,103 +53,17 @@ static InspectionBuffer *IkeVendorGetData(DetectEngineThreadCtx *det_ctx, const uint8_t *data; uint32_t data_len; - if (rs_ike_tx_get_vendor(cbdata->txv, cbdata->local_id, &data, &data_len) == 0) { + if (rs_ike_tx_get_vendor(txv, local_id, &data, &data_len) == 0) { InspectionBufferSetupMultiEmpty(buffer); return NULL; } InspectionBufferSetupMulti(buffer, transforms, data, data_len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; SCReturnPtr(buffer, "InspectionBuffer"); } -/** \brief IkeVendor Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxIkeVendor(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 PrefilterMpmIkeVendor *ctx = (const PrefilterMpmIkeVendor *)pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - const int list_id = ctx->list_id; - - uint32_t local_id = 0; - while (1) { - struct IkeVendorGetDataArgs cbdata = { local_id, txv }; - InspectionBuffer *buffer = IkeVendorGetData(det_ctx, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - local_id++; - } - - SCReturn; -} - -static void PrefilterMpmIkeVendorFree(void *ptr) -{ - if (ptr != NULL) - SCFree(ptr); -} - -static int PrefilterMpmIkeVendorRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpmIkeVendor *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, PrefilterTxIkeVendor, mpm_reg->app_v2.alproto, - mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMpmIkeVendorFree, mpm_reg->pname); -} - -static uint8_t DetectEngineInspectIkeVendor(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 IkeVendorGetDataArgs cbdata = { - local_id, - txv, - }; - InspectionBuffer *buffer = - IkeVendorGetData(det_ctx, transforms, f, &cbdata, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) - break; - - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - local_id++; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - /** * \brief Registration function for ike.vendor keyword. */ @@ -178,11 +76,8 @@ void DetectIkeVendorRegister(void) sigmatch_table[DETECT_AL_IKE_VENDOR].flags |= SIGMATCH_NOOPT; sigmatch_table[DETECT_AL_IKE_VENDOR].flags |= SIGMATCH_INFO_STICKY_BUFFER; - DetectAppLayerMpmRegister("ike.vendor", SIG_FLAG_TOSERVER, 1, PrefilterMpmIkeVendorRegister, - NULL, ALPROTO_IKE, 1); - - DetectAppLayerInspectEngineRegister( - "ike.vendor", ALPROTO_IKE, SIG_FLAG_TOSERVER, 1, DetectEngineInspectIkeVendor, NULL); + DetectAppLayerMultiRegister( + "ike.vendor", ALPROTO_IKE, SIG_FLAG_TOSERVER, 1, IkeVendorGetData, 1, 1); g_ike_vendor_buffer_id = DetectBufferTypeGetByName("ike.vendor"); diff --git a/src/detect-krb5-cname.c b/src/detect-krb5-cname.c index 37b6c72c3d..1411f73808 100644 --- a/src/detect-krb5-cname.c +++ b/src/detect-krb5-cname.c @@ -38,11 +38,6 @@ static int g_krb5_cname_buffer_id = 0; -struct Krb5PrincipalNameDataArgs { - uint32_t local_id; /**< used as index into thread inspect array */ - void *txv; -}; - static int DetectKrb5CNameSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) { if (DetectBufferSetActiveList(de_ctx, s, g_krb5_cname_buffer_id) < 0) @@ -55,13 +50,12 @@ static int DetectKrb5CNameSetup(DetectEngineCtx *de_ctx, Signature *s, const cha } static InspectionBuffer *GetKrb5CNameData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *_f, - const struct Krb5PrincipalNameDataArgs *cbdata, int list_id) + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) { SCEnter(); - InspectionBuffer *buffer = - InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); if (buffer == NULL) return NULL; if (buffer->initialized) @@ -70,7 +64,7 @@ static InspectionBuffer *GetKrb5CNameData(DetectEngineThreadCtx *det_ctx, uint32_t b_len = 0; const uint8_t *b = NULL; - if (rs_krb5_tx_get_cname(cbdata->txv, cbdata->local_id, &b, &b_len) != 1) { + if (rs_krb5_tx_get_cname(txv, local_id, &b, &b_len) != 1) { InspectionBufferSetupMultiEmpty(buffer); return NULL; } @@ -80,103 +74,11 @@ static InspectionBuffer *GetKrb5CNameData(DetectEngineThreadCtx *det_ctx, } InspectionBufferSetupMulti(buffer, transforms, b, b_len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; SCReturnPtr(buffer, "InspectionBuffer"); } -static uint8_t DetectEngineInspectKrb5CName(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 Krb5PrincipalNameDataArgs cbdata = { local_id, txv, }; - InspectionBuffer *buffer = - GetKrb5CNameData(det_ctx, transforms, f, &cbdata, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) - break; - - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - local_id++; - } - - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -typedef struct PrefilterMpmKrb5Name { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmKrb5Name; - -/** \brief Krb5CName Krb5CName Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxKrb5CName(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 PrefilterMpmKrb5Name *ctx = (const PrefilterMpmKrb5Name *)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 Krb5PrincipalNameDataArgs cbdata = { local_id, txv }; - InspectionBuffer *buffer = GetKrb5CNameData(det_ctx, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - - local_id++; - } -} - -static void PrefilterMpmKrb5NameFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterMpmKrb5CNameRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpmKrb5Name *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, PrefilterTxKrb5CName, - mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress, - pectx, PrefilterMpmKrb5NameFree, mpm_reg->name); -} - void DetectKrb5CNameRegister(void) { sigmatch_table[DETECT_AL_KRB5_CNAME].name = "krb5.cname"; @@ -186,11 +88,8 @@ void DetectKrb5CNameRegister(void) sigmatch_table[DETECT_AL_KRB5_CNAME].flags |= SIGMATCH_NOOPT|SIGMATCH_INFO_STICKY_BUFFER; sigmatch_table[DETECT_AL_KRB5_CNAME].desc = "sticky buffer to match on Kerberos 5 client name"; - DetectAppLayerMpmRegister("krb5_cname", SIG_FLAG_TOCLIENT, 2, PrefilterMpmKrb5CNameRegister, - NULL, ALPROTO_KRB5, 1); - - DetectAppLayerInspectEngineRegister( - "krb5_cname", ALPROTO_KRB5, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectKrb5CName, NULL); + DetectAppLayerMultiRegister( + "krb5_cname", ALPROTO_KRB5, SIG_FLAG_TOCLIENT, 0, GetKrb5CNameData, 2, 1); DetectBufferTypeSetDescriptionByName("krb5_cname", "Kerberos 5 ticket client name"); diff --git a/src/detect-krb5-sname.c b/src/detect-krb5-sname.c index ff52c1a28d..3cd6f0e222 100644 --- a/src/detect-krb5-sname.c +++ b/src/detect-krb5-sname.c @@ -38,11 +38,6 @@ static int g_krb5_sname_buffer_id = 0; -struct Krb5PrincipalNameDataArgs { - uint32_t local_id; /**< used as index into thread inspect array */ - void *txv; -}; - static int DetectKrb5SNameSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) { if (DetectBufferSetActiveList(de_ctx, s, g_krb5_sname_buffer_id) < 0) @@ -55,13 +50,12 @@ static int DetectKrb5SNameSetup(DetectEngineCtx *de_ctx, Signature *s, const cha } static InspectionBuffer *GetKrb5SNameData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *_f, - const struct Krb5PrincipalNameDataArgs *cbdata, int list_id) + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) { SCEnter(); - InspectionBuffer *buffer = - InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); if (buffer == NULL) return NULL; if (buffer->initialized) @@ -70,7 +64,7 @@ static InspectionBuffer *GetKrb5SNameData(DetectEngineThreadCtx *det_ctx, uint32_t b_len = 0; const uint8_t *b = NULL; - if (rs_krb5_tx_get_sname(cbdata->txv, cbdata->local_id, &b, &b_len) != 1) { + if (rs_krb5_tx_get_sname(txv, local_id, &b, &b_len) != 1) { InspectionBufferSetupMultiEmpty(buffer); return NULL; } @@ -85,98 +79,6 @@ static InspectionBuffer *GetKrb5SNameData(DetectEngineThreadCtx *det_ctx, SCReturnPtr(buffer, "InspectionBuffer"); } -static uint8_t DetectEngineInspectKrb5SName(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 Krb5PrincipalNameDataArgs cbdata = { local_id, txv, }; - InspectionBuffer *buffer = - GetKrb5SNameData(det_ctx, transforms, f, &cbdata, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) - break; - - const bool match = DetectEngineContentInspectionBuffer(de_ctx, det_ctx, s, engine->smd, - NULL, f, buffer, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - local_id++; - } - - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -typedef struct PrefilterMpmKrb5Name { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmKrb5Name; - -/** \brief Krb5SName Krb5SName Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxKrb5SName(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 PrefilterMpmKrb5Name *ctx = (const PrefilterMpmKrb5Name *)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 Krb5PrincipalNameDataArgs cbdata = { local_id, txv }; - InspectionBuffer *buffer = GetKrb5SNameData(det_ctx, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - - local_id++; - } -} - -static void PrefilterMpmKrb5NameFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterMpmKrb5SNameRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpmKrb5Name *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, PrefilterTxKrb5SName, - mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress, - pectx, PrefilterMpmKrb5NameFree, mpm_reg->name); -} - void DetectKrb5SNameRegister(void) { sigmatch_table[DETECT_AL_KRB5_SNAME].name = "krb5.sname"; @@ -186,11 +88,8 @@ void DetectKrb5SNameRegister(void) sigmatch_table[DETECT_AL_KRB5_SNAME].flags |= SIGMATCH_NOOPT|SIGMATCH_INFO_STICKY_BUFFER; sigmatch_table[DETECT_AL_KRB5_SNAME].desc = "sticky buffer to match on Kerberos 5 server name"; - DetectAppLayerMpmRegister("krb5_sname", SIG_FLAG_TOCLIENT, 2, PrefilterMpmKrb5SNameRegister, - NULL, ALPROTO_KRB5, 1); - - DetectAppLayerInspectEngineRegister( - "krb5_sname", ALPROTO_KRB5, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectKrb5SName, NULL); + DetectAppLayerMultiRegister( + "krb5_sname", ALPROTO_KRB5, SIG_FLAG_TOCLIENT, 0, GetKrb5SNameData, 2, 1); DetectBufferTypeSetDescriptionByName("krb5_sname", "Kerberos 5 ticket server name"); diff --git a/src/detect-mqtt-subscribe-topic.c b/src/detect-mqtt-subscribe-topic.c index 0dbcedb48f..12e882aed0 100644 --- a/src/detect-mqtt-subscribe-topic.c +++ b/src/detect-mqtt-subscribe-topic.c @@ -59,19 +59,16 @@ static int g_mqtt_subscribe_topic_buffer_id = 0; static uint32_t subscribe_topic_match_limit = 100; -struct MQTTSubscribeTopicGetDataArgs { - uint32_t local_id; - void *txv; -}; - static InspectionBuffer *MQTTSubscribeTopicGetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, - struct MQTTSubscribeTopicGetDataArgs *cbdata, int list_id) + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) { SCEnter(); - InspectionBuffer *buffer = - InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); + if (subscribe_topic_match_limit > 0 && local_id >= subscribe_topic_match_limit) + return NULL; + + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); if (buffer == NULL) return NULL; if (buffer->initialized) @@ -79,107 +76,17 @@ static InspectionBuffer *MQTTSubscribeTopicGetData(DetectEngineThreadCtx *det_ct const uint8_t *data; uint32_t data_len; - if (rs_mqtt_tx_get_subscribe_topic(cbdata->txv, cbdata->local_id, &data, &data_len) == 0) { + if (rs_mqtt_tx_get_subscribe_topic(txv, local_id, &data, &data_len) == 0) { InspectionBufferSetupMultiEmpty(buffer); return NULL; } InspectionBufferSetupMulti(buffer, transforms, data, data_len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; SCReturnPtr(buffer, "InspectionBuffer"); } -static uint8_t DetectEngineInspectMQTTSubscribeTopic(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 ((subscribe_topic_match_limit == 0) || local_id < subscribe_topic_match_limit) { - struct MQTTSubscribeTopicGetDataArgs cbdata = { local_id, txv, }; - InspectionBuffer *buffer = - MQTTSubscribeTopicGetData(det_ctx, transforms, f, &cbdata, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) - break; - - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - local_id++; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -typedef struct PrefilterMpmMQTTSubscribeTopic { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmMQTTSubscribeTopic; - -/** \brief MQTTSubscribeTopic MQTTSubscribeTopic Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxMQTTSubscribeTopic(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 PrefilterMpmMQTTSubscribeTopic *ctx = (const PrefilterMpmMQTTSubscribeTopic *)pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - const int list_id = ctx->list_id; - - uint32_t local_id = 0; - while ((subscribe_topic_match_limit == 0) || local_id < subscribe_topic_match_limit) { - struct MQTTSubscribeTopicGetDataArgs cbdata = { local_id, txv }; - InspectionBuffer *buffer = - MQTTSubscribeTopicGetData(det_ctx, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - local_id++; - } -} - -static void PrefilterMpmMQTTSubscribeTopicFree(void *ptr) -{ - if (ptr != NULL) - SCFree(ptr); -} - -static int PrefilterMpmMQTTSubscribeTopicRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpmMQTTSubscribeTopic *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, PrefilterTxMQTTSubscribeTopic, - mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress, - pectx, PrefilterMpmMQTTSubscribeTopicFree, mpm_reg->pname); -} - /** * \brief Registration function for keyword: mqtt.subscribe.topic */ @@ -203,11 +110,8 @@ void DetectMQTTSubscribeTopicRegister (void) subscribe_topic_match_limit); } - DetectAppLayerMpmRegister("mqtt.subscribe.topic", SIG_FLAG_TOSERVER, 1, - PrefilterMpmMQTTSubscribeTopicRegister, NULL, ALPROTO_MQTT, 1); - - DetectAppLayerInspectEngineRegister("mqtt.subscribe.topic", ALPROTO_MQTT, SIG_FLAG_TOSERVER, 1, - DetectEngineInspectMQTTSubscribeTopic, NULL); + DetectAppLayerMultiRegister("mqtt.subscribe.topic", ALPROTO_MQTT, SIG_FLAG_TOSERVER, 1, + MQTTSubscribeTopicGetData, 1, 1); DetectBufferTypeSetDescriptionByName("mqtt.subscribe.topic", "subscribe topic query"); diff --git a/src/detect-mqtt-unsubscribe-topic.c b/src/detect-mqtt-unsubscribe-topic.c index 27ae75a6c3..7b4b8a00f4 100644 --- a/src/detect-mqtt-unsubscribe-topic.c +++ b/src/detect-mqtt-unsubscribe-topic.c @@ -59,19 +59,16 @@ static int g_mqtt_unsubscribe_topic_buffer_id = 0; static uint32_t unsubscribe_topic_match_limit = 100; -struct MQTTUnsubscribeTopicGetDataArgs { - uint32_t local_id; - void *txv; -}; - static InspectionBuffer *MQTTUnsubscribeTopicGetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, - struct MQTTUnsubscribeTopicGetDataArgs *cbdata, int list_id) + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) { SCEnter(); - InspectionBuffer *buffer = - InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); + if (unsubscribe_topic_match_limit > 0 && local_id >= unsubscribe_topic_match_limit) + return NULL; + + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); if (buffer == NULL) return NULL; if (buffer->initialized) @@ -79,107 +76,17 @@ static InspectionBuffer *MQTTUnsubscribeTopicGetData(DetectEngineThreadCtx *det_ const uint8_t *data; uint32_t data_len; - if (rs_mqtt_tx_get_unsubscribe_topic(cbdata->txv, cbdata->local_id, &data, &data_len) == 0) { + if (rs_mqtt_tx_get_unsubscribe_topic(txv, local_id, &data, &data_len) == 0) { InspectionBufferSetupMultiEmpty(buffer); return NULL; } InspectionBufferSetupMulti(buffer, transforms, data, data_len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; SCReturnPtr(buffer, "InspectionBuffer"); } -static uint8_t DetectEngineInspectMQTTUnsubscribeTopic(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 ((unsubscribe_topic_match_limit == 0) || local_id < unsubscribe_topic_match_limit) { - struct MQTTUnsubscribeTopicGetDataArgs cbdata = { local_id, txv, }; - InspectionBuffer *buffer = - MQTTUnsubscribeTopicGetData(det_ctx, transforms, f, &cbdata, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) - break; - - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - local_id++; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -typedef struct PrefilterMpmMQTTUnsubscribeTopic { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmMQTTUnsubscribeTopic; - -/** \brief MQTTUnsubscribeTopic MQTTUnsubscribeTopic Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxMQTTUnsubscribeTopic(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 PrefilterMpmMQTTUnsubscribeTopic *ctx = (const PrefilterMpmMQTTUnsubscribeTopic *)pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - const int list_id = ctx->list_id; - - uint32_t local_id = 0; - while ((unsubscribe_topic_match_limit == 0) || local_id < unsubscribe_topic_match_limit) { - struct MQTTUnsubscribeTopicGetDataArgs cbdata = { local_id, txv }; - InspectionBuffer *buffer = - MQTTUnsubscribeTopicGetData(det_ctx, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - local_id++; - } -} - -static void PrefilterMpmMQTTUnsubscribeTopicFree(void *ptr) -{ - if (ptr != NULL) - SCFree(ptr); -} - -static int PrefilterMpmMQTTUnsubscribeTopicRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpmMQTTUnsubscribeTopic *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, PrefilterTxMQTTUnsubscribeTopic, - mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress, - pectx, PrefilterMpmMQTTUnsubscribeTopicFree, mpm_reg->pname); -} - /** * \brief Registration function for keyword: mqtt.unsubscribe.topic */ @@ -203,11 +110,8 @@ void DetectMQTTUnsubscribeTopicRegister (void) unsubscribe_topic_match_limit); } - DetectAppLayerMpmRegister("mqtt.unsubscribe.topic", SIG_FLAG_TOSERVER, 1, - PrefilterMpmMQTTUnsubscribeTopicRegister, NULL, ALPROTO_MQTT, 1); - - DetectAppLayerInspectEngineRegister("mqtt.unsubscribe.topic", ALPROTO_MQTT, SIG_FLAG_TOSERVER, - 1, DetectEngineInspectMQTTUnsubscribeTopic, NULL); + DetectAppLayerMultiRegister("mqtt.unsubscribe.topic", ALPROTO_MQTT, SIG_FLAG_TOSERVER, 1, + MQTTUnsubscribeTopicGetData, 1, 1); DetectBufferTypeSetDescriptionByName("mqtt.unsubscribe.topic", "unsubscribe topic query"); diff --git a/src/detect-quic-cyu-hash.c b/src/detect-quic-cyu-hash.c index 309e722cfc..17836d1596 100644 --- a/src/detect-quic-cyu-hash.c +++ b/src/detect-quic-cyu-hash.c @@ -44,11 +44,6 @@ static void DetectQuicCyuHashRegisterTests(void); #define BUFFER_DESC "QUIC CYU Hash" static int g_buffer_id = 0; -struct QuicHashGetDataArgs { - uint32_t local_id; /**< used as index into thread inspect array */ - void *txv; -}; - static int DetectQuicCyuHashSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) { if (DetectBufferSetActiveList(de_ctx, s, g_buffer_id) < 0) @@ -61,13 +56,14 @@ static int DetectQuicCyuHashSetup(DetectEngineCtx *de_ctx, Signature *s, const c } static InspectionBuffer *QuicHashGetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, struct QuicHashGetDataArgs *cbdata, - int list_id) + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) { SCEnter(); - InspectionBuffer *buffer = - InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); + if (local_id > UINT16_MAX) + return NULL; + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); if (buffer == NULL) return NULL; if (buffer->initialized) @@ -75,109 +71,17 @@ static InspectionBuffer *QuicHashGetData(DetectEngineThreadCtx *det_ctx, const uint8_t *data; uint32_t data_len; - if (rs_quic_tx_get_cyu_hash(cbdata->txv, (uint16_t)cbdata->local_id, &data, &data_len) == 0) { + if (rs_quic_tx_get_cyu_hash(txv, local_id, &data, &data_len) == 0) { InspectionBufferSetupMultiEmpty(buffer); return NULL; } InspectionBufferSetupMulti(buffer, transforms, data, data_len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; SCReturnPtr(buffer, "InspectionBuffer"); } -static uint8_t DetectEngineInspectQuicHash(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 QuicHashGetDataArgs cbdata = { - local_id, - txv, - }; - InspectionBuffer *buffer = - QuicHashGetData(det_ctx, transforms, f, &cbdata, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) - break; - - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - local_id++; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -typedef struct PrefilterMpmQuicHash { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmQuicHash; - -/** \brief QuicHash Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxQuicHash(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 PrefilterMpmQuicHash *ctx = (const PrefilterMpmQuicHash *)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 QuicHashGetDataArgs cbdata = { local_id, txv }; - InspectionBuffer *buffer = QuicHashGetData(det_ctx, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - - local_id++; - } -} - -static void PrefilterMpmQuicHashFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterMpmQuicHashRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, - const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpmQuicHash *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, PrefilterTxQuicHash, mpm_reg->app_v2.alproto, - mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMpmQuicHashFree, mpm_reg->pname); -} - static bool DetectQuicHashValidateCallback(const Signature *s, const char **sigerror) { for (uint32_t x = 0; x < s->init_data->buffer_index; x++) { @@ -230,11 +134,8 @@ void DetectQuicCyuHashRegister(void) sigmatch_table[DETECT_AL_QUIC_CYU_HASH].RegisterTests = DetectQuicCyuHashRegisterTests; #endif - DetectAppLayerMpmRegister( - BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterMpmQuicHashRegister, NULL, ALPROTO_QUIC, 1); - - DetectAppLayerInspectEngineRegister( - BUFFER_NAME, ALPROTO_QUIC, SIG_FLAG_TOSERVER, 0, DetectEngineInspectQuicHash, NULL); + DetectAppLayerMultiRegister( + BUFFER_NAME, ALPROTO_QUIC, SIG_FLAG_TOSERVER, 0, QuicHashGetData, 2, 1); DetectBufferTypeSetDescriptionByName(BUFFER_NAME, BUFFER_DESC); diff --git a/src/detect-quic-cyu-string.c b/src/detect-quic-cyu-string.c index 3cc846d6a4..c2460f1154 100644 --- a/src/detect-quic-cyu-string.c +++ b/src/detect-quic-cyu-string.c @@ -42,11 +42,6 @@ static void DetectQuicCyuStringRegisterTests(void); #define BUFFER_DESC "QUIC CYU String" static int g_buffer_id = 0; -struct QuicStringGetDataArgs { - uint32_t local_id; /**< used as index into thread inspect array */ - void *txv; -}; - static int DetectQuicCyuStringSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) { if (DetectBufferSetActiveList(de_ctx, s, g_buffer_id) < 0) @@ -59,13 +54,12 @@ static int DetectQuicCyuStringSetup(DetectEngineCtx *de_ctx, Signature *s, const } static InspectionBuffer *QuicStringGetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, struct QuicStringGetDataArgs *cbdata, - int list_id) + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) { SCEnter(); - InspectionBuffer *buffer = - InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); if (buffer == NULL) return NULL; if (buffer->initialized) @@ -73,103 +67,17 @@ static InspectionBuffer *QuicStringGetData(DetectEngineThreadCtx *det_ctx, const uint8_t *data; uint32_t data_len; - if (rs_quic_tx_get_cyu_string(cbdata->txv, cbdata->local_id, &data, &data_len) == 0) { + if (rs_quic_tx_get_cyu_string(txv, local_id, &data, &data_len) == 0) { InspectionBufferSetupMultiEmpty(buffer); return NULL; } InspectionBufferSetupMulti(buffer, transforms, data, data_len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; SCReturnPtr(buffer, "InspectionBuffer"); } -static uint8_t DetectEngineInspectQuicString(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 QuicStringGetDataArgs cbdata = { - local_id, - txv, - }; - InspectionBuffer *buffer = - QuicStringGetData(det_ctx, transforms, f, &cbdata, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) - break; - - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - local_id++; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -/** \brief QuicString Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxQuicString(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 QuicStringGetDataArgs cbdata = { local_id, txv }; - InspectionBuffer *buffer = QuicStringGetData(det_ctx, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - - local_id++; - } -} - -static void PrefilterMpmListIdFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterMpmListIdRegister(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, PrefilterTxQuicString, mpm_reg->app_v2.alproto, - mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMpmListIdFree, mpm_reg->pname); -} - void DetectQuicCyuStringRegister(void) { /* quic.cyu.string sticky buffer */ @@ -183,11 +91,8 @@ void DetectQuicCyuStringRegister(void) sigmatch_table[DETECT_AL_QUIC_CYU_STRING].RegisterTests = DetectQuicCyuStringRegisterTests; #endif - DetectAppLayerMpmRegister( - BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterMpmListIdRegister, NULL, ALPROTO_QUIC, 1); - - DetectAppLayerInspectEngineRegister( - BUFFER_NAME, ALPROTO_QUIC, SIG_FLAG_TOSERVER, 0, DetectEngineInspectQuicString, NULL); + DetectAppLayerMultiRegister( + BUFFER_NAME, ALPROTO_QUIC, SIG_FLAG_TOSERVER, 0, QuicStringGetData, 2, 1); DetectBufferTypeSetDescriptionByName(BUFFER_NAME, BUFFER_DESC); diff --git a/src/detect-tls-certs.c b/src/detect-tls-certs.c index f1adb040d0..f34c5e23bf 100644 --- a/src/detect-tls-certs.c +++ b/src/detect-tls-certs.c @@ -59,25 +59,53 @@ static int DetectTlsCertsSetup(DetectEngineCtx *, Signature *, const char *); #ifdef UNITTESTS static void DetectTlsCertsRegisterTests(void); #endif -static uint8_t DetectEngineInspectTlsCerts(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 PrefilterMpmTlsCertsRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, - const DetectBufferMpmRegistry *mpm_reg, int list_id); static int g_tls_certs_buffer_id = 0; -struct TlsCertsGetDataArgs { - uint32_t local_id; /**< used as index into thread inspect array */ +static InspectionBuffer *TlsCertsGetData(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, + int list_id, uint32_t local_id) +{ + SCEnter(); + + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); + if (buffer == NULL || buffer->initialized) + return buffer; + + const SSLState *ssl_state = (SSLState *)f->alstate; + const SSLStateConnp *connp; + + if (flags & STREAM_TOSERVER) { + connp = &ssl_state->client_connp; + } else { + connp = &ssl_state->server_connp; + } + + if (TAILQ_EMPTY(&connp->certs)) { + InspectionBufferSetupMultiEmpty(buffer); + return NULL; + } + SSLCertsChain *cert; - const uint8_t flags; -}; + if (local_id == 0) { + cert = TAILQ_FIRST(&connp->certs); + } else { + // TODO optimize ? + cert = TAILQ_FIRST(&connp->certs); + for (uint32_t i = 0; i < local_id; i++) { + cert = TAILQ_NEXT(cert, next); + } + } + if (cert == NULL) { + InspectionBufferSetupMultiEmpty(buffer); + return NULL; + } + + InspectionBufferSetupMulti(buffer, transforms, cert->cert_data, cert->cert_len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; -typedef struct PrefilterMpmTlsCerts { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmTlsCerts; + SCReturnPtr(buffer, "InspectionBuffer"); +} /** * \brief Registration function for keyword: tls.certs @@ -94,17 +122,10 @@ void DetectTlsCertsRegister(void) sigmatch_table[DETECT_AL_TLS_CERTS].flags |= SIGMATCH_NOOPT; sigmatch_table[DETECT_AL_TLS_CERTS].flags |= SIGMATCH_INFO_STICKY_BUFFER; - DetectAppLayerInspectEngineRegister("tls.certs", ALPROTO_TLS, SIG_FLAG_TOCLIENT, - TLS_STATE_CERT_READY, DetectEngineInspectTlsCerts, NULL); - - DetectAppLayerMpmRegister("tls.certs", SIG_FLAG_TOCLIENT, 2, PrefilterMpmTlsCertsRegister, NULL, - ALPROTO_TLS, TLS_STATE_CERT_READY); - - DetectAppLayerInspectEngineRegister("tls.certs", ALPROTO_TLS, SIG_FLAG_TOSERVER, - TLS_STATE_CERT_READY, DetectEngineInspectTlsCerts, NULL); - - DetectAppLayerMpmRegister("tls.certs", SIG_FLAG_TOSERVER, 2, PrefilterMpmTlsCertsRegister, NULL, - ALPROTO_TLS, TLS_STATE_CERT_READY); + DetectAppLayerMultiRegister("tls.certs", ALPROTO_TLS, SIG_FLAG_TOCLIENT, TLS_STATE_CERT_READY, + TlsCertsGetData, 2, 1); + DetectAppLayerMultiRegister("tls.certs", ALPROTO_TLS, SIG_FLAG_TOSERVER, TLS_STATE_CERT_READY, + TlsCertsGetData, 2, 1); DetectBufferTypeSetDescriptionByName("tls.certs", "TLS certificate"); @@ -135,126 +156,6 @@ static int DetectTlsCertsSetup(DetectEngineCtx *de_ctx, Signature *s, return 0; } -static InspectionBuffer *TlsCertsGetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, - struct TlsCertsGetDataArgs *cbdata, int list_id) -{ - SCEnter(); - - InspectionBuffer *buffer = - InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); - if (buffer == NULL || buffer->initialized) - return buffer; - - const SSLState *ssl_state = (SSLState *)f->alstate; - const SSLStateConnp *connp; - - if (cbdata->flags & STREAM_TOSERVER) { - connp = &ssl_state->client_connp; - } else { - connp = &ssl_state->server_connp; - } - - if (TAILQ_EMPTY(&connp->certs)) { - InspectionBufferSetupMultiEmpty(buffer); - return NULL; - } - - if (cbdata->cert == NULL) { - cbdata->cert = TAILQ_FIRST(&connp->certs); - } else { - cbdata->cert = TAILQ_NEXT(cbdata->cert, next); - } - if (cbdata->cert == NULL) { - InspectionBufferSetupMultiEmpty(buffer); - return NULL; - } - - InspectionBufferSetupMulti(buffer, transforms, cbdata->cert->cert_data, cbdata->cert->cert_len); - - SCReturnPtr(buffer, "InspectionBuffer"); -} - -static uint8_t DetectEngineInspectTlsCerts(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) -{ - const DetectEngineTransforms *transforms = NULL; - if (!engine->mpm) { - transforms = engine->v2.transforms; - } - - struct TlsCertsGetDataArgs cbdata = { .local_id = 0, .cert = NULL, .flags = flags }; - - while (1) - { - InspectionBuffer *buffer = TlsCertsGetData(det_ctx, transforms, f, - &cbdata, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) - break; - - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - - cbdata.local_id++; - } - - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -static void PrefilterTxTlsCerts(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 PrefilterMpmTlsCerts *ctx = (const PrefilterMpmTlsCerts *)pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - const int list_id = ctx->list_id; - - struct TlsCertsGetDataArgs cbdata = { .local_id = 0, .cert = NULL, .flags = flags }; - - while (1) - { - InspectionBuffer *buffer = TlsCertsGetData(det_ctx, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - - cbdata.local_id++; - } -} - -static void PrefilterMpmTlsCertsFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterMpmTlsCertsRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, - const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpmTlsCerts *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, PrefilterTxTlsCerts, - mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress, - pectx, PrefilterMpmTlsCertsFree, mpm_reg->name); -} - static int g_tls_cert_buffer_id = 0; #define BUFFER_NAME "tls_validity" #define KEYWORD_ID DETECT_AL_TLS_CHAIN_LEN diff --git a/src/detect-tls-subjectaltname.c b/src/detect-tls-subjectaltname.c index cf61aa0b8c..350db5d6f6 100644 --- a/src/detect-tls-subjectaltname.c +++ b/src/detect-tls-subjectaltname.c @@ -52,20 +52,12 @@ #include "util-profiling.h" static int DetectTlsSubjectAltNameSetup(DetectEngineCtx *, Signature *, const char *); -static uint8_t DetectEngineInspectTlsSubjectAltName(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 PrefilterMpmTlsSubjectAltNameRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id); +static InspectionBuffer *TlsSubjectAltNameGetData(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, uint8_t flags, void *txv, int list_id, + uint32_t index); static int g_tls_subjectaltname_buffer_id = 0; -typedef struct PrefilterMpmTlsSubjectAltName { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmTlsSubjectAltName; - /** * \brief Registration function for keyword: tls.subjectaltname */ @@ -80,11 +72,8 @@ void DetectTlsSubjectAltNameRegister(void) sigmatch_table[DETECT_AL_TLS_SUBJECTALTNAME].flags |= SIGMATCH_NOOPT; sigmatch_table[DETECT_AL_TLS_SUBJECTALTNAME].flags |= SIGMATCH_INFO_STICKY_BUFFER; - DetectAppLayerInspectEngineRegister("tls.subjectaltname", ALPROTO_TLS, SIG_FLAG_TOCLIENT, - TLS_STATE_CERT_READY, DetectEngineInspectTlsSubjectAltName, NULL); - - DetectAppLayerMpmRegister("tls.subjectaltname", SIG_FLAG_TOCLIENT, 2, - PrefilterMpmTlsSubjectAltNameRegister, NULL, ALPROTO_TLS, TLS_STATE_CERT_READY); + DetectAppLayerMultiRegister("tls.subjectaltname", ALPROTO_TLS, SIG_FLAG_TOCLIENT, 0, + TlsSubjectAltNameGetData, 2, TLS_STATE_CERT_READY); DetectBufferTypeSetDescriptionByName("tls.subjectaltname", "TLS Subject Alternative Name"); @@ -115,7 +104,8 @@ static int DetectTlsSubjectAltNameSetup(DetectEngineCtx *de_ctx, Signature *s, c } static InspectionBuffer *TlsSubjectAltNameGetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, uint8_t flags, uint16_t idx, int list_id) + const DetectEngineTransforms *transforms, Flow *f, uint8_t flags, void *txv, int list_id, + uint32_t idx) { SCEnter(); InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, idx); @@ -133,76 +123,7 @@ static InspectionBuffer *TlsSubjectAltNameGetData(DetectEngineThreadCtx *det_ctx InspectionBufferSetupMulti(buffer, transforms, (const uint8_t *)connp->cert0_sans[idx], strlen(connp->cert0_sans[idx])); + buffer->flags = DETECT_CI_FLAGS_SINGLE; SCReturnPtr(buffer, "InspectionBuffer"); } - -static uint8_t DetectEngineInspectTlsSubjectAltName(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) -{ - const DetectEngineTransforms *transforms = NULL; - if (!engine->mpm) { - transforms = engine->v2.transforms; - } - - for (uint16_t i = 0;; i++) { - InspectionBuffer *buffer = - TlsSubjectAltNameGetData(det_ctx, transforms, f, flags, i, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) - break; - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (match) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } - } - - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -static void PrefilterTxTlsSubjectAltName(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 PrefilterMpmTlsSubjectAltName *ctx = (const PrefilterMpmTlsSubjectAltName *)pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - const int list_id = ctx->list_id; - - for (uint16_t i = 0;; i++) { - InspectionBuffer *buffer = - TlsSubjectAltNameGetData(det_ctx, ctx->transforms, f, flags, i, 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->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); - PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); - } - } -} - -static void PrefilterMpmTlsSubjectAltNameFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterMpmTlsSubjectAltNameRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id) -{ - PrefilterMpmTlsSubjectAltName *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, PrefilterTxTlsSubjectAltName, - mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress, pectx, - PrefilterMpmTlsSubjectAltNameFree, mpm_reg->name); -} diff --git a/src/detect.h b/src/detect.h index e9576c0310..17556902e7 100644 --- a/src/detect.h +++ b/src/detect.h @@ -417,6 +417,9 @@ typedef InspectionBuffer *(*InspectionBufferGetDataPtr)( const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, const int list_id); +typedef InspectionBuffer *(*InspectionMultiBufferGetDataPtr)(struct DetectEngineThreadCtx_ *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, + const int list_id, const uint32_t local_id); struct DetectEngineAppInspectionEngine_; typedef uint8_t (*InspectEngineFuncPtr)(struct DetectEngineCtx_ *de_ctx, @@ -435,7 +438,10 @@ typedef struct DetectEngineAppInspectionEngine_ { int16_t progress; struct { - InspectionBufferGetDataPtr GetData; + union { + InspectionBufferGetDataPtr GetData; + InspectionMultiBufferGetDataPtr GetMultiData; + }; InspectEngineFuncPtr Callback; /** pointer to the transforms in the 'DetectBuffer entry for this list */ const DetectEngineTransforms *transforms; @@ -695,7 +701,10 @@ typedef struct DetectBufferMpmRegistry_ { union { /* app-layer matching: use if type == DETECT_BUFFER_MPM_TYPE_APP */ struct { - InspectionBufferGetDataPtr GetData; + union { + InspectionBufferGetDataPtr GetData; + InspectionMultiBufferGetDataPtr GetMultiData; + }; AppProto alproto; int tx_min_progress; } app_v2;