65 static int g_http_header_buffer_id = 0;
66 static int g_keyword_thread_id = 0;
67 static int g_http2_thread_id = 0;
69 #define BUFFER_SIZE_STEP 1024
72 static 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);
134 #if 0 // looks like this breaks existing rules
135 if (i + 1 == no_of_headers) {
142 *buffer_len = buf->
len;
153 const uint8_t *b = NULL;
156 if (thread_buf == NULL)
158 if (SCHttp2TxGetHeaders(txv, flow_flags, &b, &b_len, thread_buf) != 1)
160 if (b == NULL || b_len == 0)
175 uint32_t data_len = 0;
176 uint8_t *data = GetBufferForTX(txv, det_ctx,
flags, &data_len);
178 det_ctx, list_id, buffer, data, data_len, transforms);
207 const int list_id =
ctx->list_id;
210 uint32_t rawdata_len = 0;
211 uint8_t *rawdata = GetBufferForTX(txv, det_ctx,
flags, &rawdata_len);
212 if (rawdata_len == 0)
217 det_ctx, list_id, buffer, rawdata, rawdata_len,
ctx->transforms);
221 const uint8_t *data = buffer->
inspect;
226 if (data != NULL && data_len >= mpm_ctx->
minlen) {
228 mpm_ctx, &det_ctx->
mtc, &det_ctx->
pmq, data, data_len);
245 PrefilterMpmHttpHeader(det_ctx, pectx,
p, f, txv, idx, _txd,
flags);
249 static void PrefilterMpmHttpHeaderFree(
void *ptr)
268 HTP_REQUEST_PROGRESS_HEADERS, pectx, PrefilterMpmHttpHeaderFree, mpm_reg->
pname);
275 pectx =
SCCalloc(1,
sizeof(*pectx));
283 HTP_REQUEST_PROGRESS_TRAILER, pectx, PrefilterMpmHttpHeaderFree, mpm_reg->
pname);
304 HTP_RESPONSE_PROGRESS_HEADERS, pectx, PrefilterMpmHttpHeaderFree, mpm_reg->
pname);
311 pectx =
SCCalloc(1,
sizeof(*pectx));
319 HTP_RESPONSE_PROGRESS_TRAILER, pectx, PrefilterMpmHttpHeaderFree, mpm_reg->
pname);
371 "content modifier to match only on the HTTP header-buffer";
422 "http2.header", SCDetectThreadBufDataInit, NULL, SCDetectThreadBufDataFree);
425 static int g_http_request_header_buffer_id = 0;
426 static int g_http_response_header_buffer_id = 0;
427 static int g_request_header_thread_id = 0;
428 static int g_response_header_thread_id = 0;
429 static int g_h2_request_header_thread_id = 0;
430 static int g_h2_response_header_thread_id = 0;
446 static void *HttpMultiBufHeaderThreadDataInit(
void *data)
452 SCLogError(
"failed to allocate %" PRIuMAX
" bytes: %s", (uintmax_t)
sizeof(*td),
459 static void HttpMultiBufHeaderThreadDataFree(
void *data)
462 for (
size_t i = 0; i < td->
cap; i++) {
470 uint32_t local_id,
const uint8_t **buf, uint32_t *buf_len)
473 if (
flags & STREAM_TOSERVER) {
474 kw_thread_id = g_h2_request_header_thread_id;
476 kw_thread_id = g_h2_response_header_thread_id;
482 return SCHttp2TxGetHeader(hdr_td, txv,
flags, local_id, buf, buf_len);
486 uint32_t local_id,
const uint8_t **buf, uint32_t *buf_len)
491 if (
flags & STREAM_TOSERVER) {
492 kw_thread_id = g_request_header_thread_id;
494 kw_thread_id = g_response_header_thread_id;
502 htp_tx_t *tx = (htp_tx_t *)txv;
503 const htp_headers_t *headers;
504 if (
flags & STREAM_TOSERVER) {
505 headers = htp_tx_request_headers(tx);
507 headers = htp_tx_response_headers(tx);
509 size_t no_of_headers = htp_headers_size(headers);
514 if (hdr_td->
cap < no_of_headers) {
519 hdr_td->
items = new_buffer;
521 memset(hdr_td->
items + hdr_td->
cap, 0,
523 hdr_td->
cap = no_of_headers;
525 for (
size_t i = 0; i < no_of_headers; i++) {
526 const htp_header_t *h = htp_headers_get_index(headers, i);
527 uint32_t size1 = (uint32_t)htp_header_name_len(h);
528 uint32_t size2 = (uint32_t)htp_header_value_len(h);
529 uint32_t size = size1 + size2 + 2;
538 memcpy(hdr_td->
items[i].
buffer, htp_header_name_ptr(h), size1);
541 memcpy(hdr_td->
items[i].
buffer + size1 + 2, htp_header_value_ptr(h), size2);
544 hdr_td->
len = no_of_headers;
549 if (local_id < hdr_td->
len) {
552 *buf_len = hdr_td->
items[local_id].
len;
573 "sticky buffer to match on only one HTTP header name and value";
575 "/rules/http-keywords.html#http-request-header";
581 HTTP2TxTypeStream, HTTP2ProgHeaders, GetHttp2HeaderData, 2);
584 HTP_REQUEST_PROGRESS_HEADERS, GetHttp1HeaderData, 2);
590 HttpMultiBufHeaderThreadDataInit, NULL, HttpMultiBufHeaderThreadDataFree);
592 SCHttp2ThreadMultiBufDataInit, NULL, SCHttp2ThreadMultiBufDataFree);
610 "sticky buffer to match on only one HTTP header name and value";
612 "/rules/http-keywords.html#http-response-header";
618 HTTP2TxTypeStream, HTTP2ProgHeaders, GetHttp2HeaderData, 2);
620 HTP_RESPONSE_PROGRESS_HEADERS, GetHttp1HeaderData, 2);
626 HttpMultiBufHeaderThreadDataInit, NULL, HttpMultiBufHeaderThreadDataFree);
628 SCHttp2ThreadMultiBufDataInit, NULL, SCHttp2ThreadMultiBufDataFree);