65static int g_http_header_buffer_id = 0;
66static int g_keyword_thread_id = 0;
68#define BUFFER_SIZE_STEP 1024
71static uint8_t *GetBufferForTX(
83 const htp_headers_t *headers;
84 if (
flags & STREAM_TOSERVER) {
86 HTP_REQUEST_PROGRESS_HEADERS)
88 headers = htp_tx_request_headers(tx);
91 HTP_RESPONSE_PROGRESS_HEADERS)
93 headers = htp_tx_response_headers(tx);
99 size_t no_of_headers = htp_headers_size(headers);
100 for (; i < no_of_headers; i++) {
101 const htp_header_t *h = htp_headers_get_index(headers, i);
102 size_t size1 = htp_header_name_len(h);
103 size_t size2 = htp_header_value_len(h);
105 if (
flags & STREAM_TOSERVER) {
106 if (size1 == 6 && SCMemcmpLowercase(
"cookie", htp_header_name_ptr(h), 6) == 0) {
110 if (size1 == 10 && SCMemcmpLowercase(
"set-cookie", htp_header_name_ptr(h), 10) == 0) {
115 size_t size = size1 + size2 + 4;
117 if (i + 1 == no_of_headers)
120 if (size + buf->
len > buf->
size) {
126 memcpy(buf->
buffer + buf->
len, htp_header_name_ptr(h), htp_header_name_len(h));
127 buf->
len += htp_header_name_len(h);
130 memcpy(buf->
buffer + buf->
len, htp_header_value_ptr(h), htp_header_value_len(h));
131 buf->
len += htp_header_value_len(h);
135 if (i + 1 == no_of_headers) {
142 *buffer_len = buf->
len;
153 const uint8_t *b = NULL;
155 if (SCHttp2TxGetHeaders(txv, flow_flags, &b, &b_len) != 1)
157 if (b == NULL || b_len == 0)
175 const int list_id = engine->
sm_list;
180 SCLogDebug(
"setting up inspect buffer %d", list_id);
188 uint32_t rawdata_len = 0;
189 uint8_t *rawdata = GetBufferForTX(txv, det_ctx, f,
flags, &rawdata_len);
190 if (rawdata_len == 0) {
199 det_ctx, list_id, buffer, rawdata, rawdata_len, transforms);
203 const uint8_t *data = buffer->
inspect;
244 const int list_id =
ctx->list_id;
247 uint32_t rawdata_len = 0;
248 uint8_t *rawdata = GetBufferForTX(txv, det_ctx, f,
flags, &rawdata_len);
249 if (rawdata_len == 0)
254 det_ctx, list_id, buffer, rawdata, rawdata_len,
ctx->transforms);
258 const uint8_t *data = buffer->
inspect;
263 if (data != NULL && data_len >= mpm_ctx->
minlen) {
265 mpm_ctx, &det_ctx->
mtc, &det_ctx->
pmq, data, data_len);
282 PrefilterMpmHttpHeader(det_ctx, pectx, p, f, txv, idx, _txd,
flags);
286static void PrefilterMpmHttpHeaderFree(
void *ptr)
305 HTP_REQUEST_PROGRESS_HEADERS, pectx, PrefilterMpmHttpHeaderFree, mpm_reg->
pname);
312 pectx =
SCCalloc(1,
sizeof(*pectx));
320 HTP_REQUEST_PROGRESS_TRAILER, pectx, PrefilterMpmHttpHeaderFree, mpm_reg->
pname);
341 HTP_RESPONSE_PROGRESS_HEADERS, pectx, PrefilterMpmHttpHeaderFree, mpm_reg->
pname);
348 pectx =
SCCalloc(1,
sizeof(*pectx));
356 HTP_RESPONSE_PROGRESS_TRAILER, pectx, PrefilterMpmHttpHeaderFree, mpm_reg->
pname);
408 "content modifier to match only on the HTTP header-buffer";
410 "/rules/http-keywords.html#http-header-and-http-raw-header";
428 HTP_REQUEST_PROGRESS_HEADERS, DetectEngineInspectBufferHttpHeader, NULL);
434 HTP_RESPONSE_PROGRESS_HEADERS, DetectEngineInspectBufferHttpHeader, NULL);
458static int g_http_request_header_buffer_id = 0;
459static int g_http_response_header_buffer_id = 0;
460static int g_request_header_thread_id = 0;
461static int g_response_header_thread_id = 0;
477static void *HttpMultiBufHeaderThreadDataInit(
void *data)
483 SCLogError(
"failed to allocate %" PRIuMAX
" bytes: %s", (uintmax_t)
sizeof(*td),
490static void HttpMultiBufHeaderThreadDataFree(
void *data)
493 for (
size_t i = 0; i < td->
cap; i++) {
501 uint32_t local_id,
const uint8_t **buf, uint32_t *buf_len)
506 if (
flags & STREAM_TOSERVER) {
507 kw_thread_id = g_request_header_thread_id;
509 kw_thread_id = g_response_header_thread_id;
517 htp_tx_t *tx = (htp_tx_t *)txv;
518 const htp_headers_t *headers;
519 if (
flags & STREAM_TOSERVER) {
520 headers = htp_tx_request_headers(tx);
522 headers = htp_tx_response_headers(tx);
524 size_t no_of_headers = htp_headers_size(headers);
529 if (hdr_td->
cap < no_of_headers) {
534 hdr_td->
items = new_buffer;
536 memset(hdr_td->
items + hdr_td->
cap, 0,
538 hdr_td->
cap = no_of_headers;
540 for (
size_t i = 0; i < no_of_headers; i++) {
541 const htp_header_t *h = htp_headers_get_index(headers, i);
542 uint32_t size1 = (uint32_t)htp_header_name_len(h);
543 uint32_t size2 = (uint32_t)htp_header_value_len(h);
544 uint32_t size = size1 + size2 + 2;
553 memcpy(hdr_td->
items[i].
buffer, htp_header_name_ptr(h), size1);
556 memcpy(hdr_td->
items[i].
buffer + size1 + 2, htp_header_value_ptr(h), size2);
559 hdr_td->
len = no_of_headers;
564 if (local_id < hdr_td->
len) {
567 *buf_len = hdr_td->
items[local_id].
len;
588 "sticky buffer to match on only one HTTP header name and value";
595 HTTP2StateOpen, SCHttp2TxGetHeader, 2);
597 HTP_REQUEST_PROGRESS_HEADERS, GetHttp1HeaderData, 2);
603 HttpMultiBufHeaderThreadDataInit, NULL, HttpMultiBufHeaderThreadDataFree);
621 "sticky buffer to match on only one HTTP header name and value";
628 HTTP2StateOpen, SCHttp2TxGetHeader, 2);
630 HTP_RESPONSE_PROGRESS_HEADERS, GetHttp1HeaderData, 2);
636 HttpMultiBufHeaderThreadDataInit, NULL, HttpMultiBufHeaderThreadDataFree);
int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto, void *alstate, uint8_t flags)
get the progress value for a tx/protocol
struct AppLayerTxData AppLayerTxData
int SCDetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int list)
bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, const uint32_t buffer_len, const uint64_t stream_start_offset, const uint8_t flags, const enum DetectContentInspectionType inspection_mode)
wrapper around DetectEngineContentInspectionInternal to return true/false only
@ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
#define DETECT_CI_FLAGS_SINGLE
void InspectionBufferSetupAndApplyTransforms(DetectEngineThreadCtx *det_ctx, const int list_id, InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len, const DetectEngineTransforms *transforms)
setup the buffer with our initial data
InspectionBuffer * InspectionBufferGet(DetectEngineThreadCtx *det_ctx, const int list_id)
void DetectAppLayerMpmRegister(const char *name, int direction, int priority, PrefilterRegisterFunc PrefilterRegister, InspectionBufferGetDataPtr GetData, AppProto alproto, int tx_min_progress)
register an app layer keyword for mpm
int PrefilterGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
int PrefilterAppendTxEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, PrefilterTxFn PrefilterTxFunc, AppProto alproto, int tx_min_progress, void *pectx, void(*FreeFunc)(void *pectx), const char *name)
@ DETECT_HTTP_REQUEST_HEADER
@ DETECT_HTTP_RESPONSE_HEADER
Data structures and function prototypes for keeping state for the detection engine.
#define DETECT_ENGINE_INSPECT_SIG_MATCH
#define DETECT_ENGINE_INSPECT_SIG_CANT_MATCH
#define DETECT_ENGINE_INSPECT_SIG_NO_MATCH
int DetectRegisterThreadCtxGlobalFuncs(const char *name, void *(*InitFunc)(void *), void *data, void(*FreeFunc)(void *))
Register Thread keyword context Funcs (Global)
void DetectBufferTypeSetDescriptionByName(const char *name, const char *desc)
void DetectBufferTypeSupportsMultiInstance(const char *name)
uint8_t DetectEngineInspectBufferGeneric(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)
Do the content inspection & validation for a signature.
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
void * DetectThreadCtxGetGlobalKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id)
Retrieve thread local keyword ctx by id.
void DetectAppLayerMultiRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectionMultiBufferGetDataPtr GetData, int priority)
int DetectBufferTypeGetByName(const char *name)
int SCDetectSignatureSetAppProto(Signature *s, AppProto alproto)
int DetectEngineContentModifierBufferSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg, int sm_type, int sm_list, AppProto alproto)
SigTableElmt * sigmatch_table
#define SIG_FLAG_TOCLIENT
#define SIGMATCH_INFO_STICKY_BUFFER
#define SIG_FLAG_TOSERVER
#define SIGMATCH_INFO_CONTENT_MODIFIER
int HttpHeaderExpandBuffer(HttpHeaderThreadData *td, HttpHeaderBuffer *buf, size_t size)
HttpHeaderBuffer * HttpHeaderGetBufferSpace(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, const int keyword_id, HttpHeaderThreadData **ret_hdr_td)
void * HttpHeaderThreadDataInit(void *data)
void HttpHeaderThreadDataFree(void *data)
one time registration of keywords at start up
DetectEngineTransforms transforms
struct DetectBufferMpmRegistry_::@98::@100 app_v2
const DetectEngineTransforms * transforms
struct DetectEngineAppInspectionEngine_::@90 v2
main detection engine ctx
AppProto alproto
application level protocol
uint8_t request_has_trailers
uint8_t response_has_trailers
uint32_t(* Search)(const struct MpmCtx_ *, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t)
Container for matching data for a signature group.
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
void(* RegisterTests)(void)
#define SCLogError(...)
Macro used to log ERROR messages.
#define SCRealloc(ptr, sz)
MpmTableElmt mpm_table[MPM_TABLE_SIZE]
#define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes)