diff --git a/rust/src/http2/detect.rs b/rust/src/http2/detect.rs index 069c2e6178..e78c6d28d5 100644 --- a/rust/src/http2/detect.rs +++ b/rust/src/http2/detect.rs @@ -678,6 +678,44 @@ fn http2_escape_header(hd: &parser::HTTP2FrameHeaders, i: u32) -> Vec { return vec; } +#[no_mangle] +pub unsafe extern "C" fn rs_http2_tx_get_header_names( + tx: &mut HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, +) -> u8 { + let mut vec = Vec::new(); + vec.push('\r' as u8); + vec.push('\n' as u8); + let frames = if direction & STREAM_TOSERVER != 0 { + &tx.frames_ts + } else { + &tx.frames_tc + }; + for i in 0..frames.len() { + match &frames[i].data { + HTTP2FrameTypeData::HEADERS(hd) => { + for j in 0..hd.blocks.len() { + // we do not escape linefeeds in headers names + vec.extend_from_slice(&hd.blocks[j].name); + vec.push('\r' as u8); + vec.push('\n' as u8); + } + } + _ => {} + } + } + if vec.len() > 2 { + vec.push('\r' as u8); + vec.push('\n' as u8); + tx.escaped.push(vec); + let idx = tx.escaped.len() - 1; + let value = &tx.escaped[idx]; + *buffer = value.as_ptr(); //unsafe + *buffer_len = value.len() as u32; + return 1; + } + return 0; +} + #[no_mangle] pub unsafe extern "C" fn rs_http2_tx_get_header( tx: &mut HTTP2Transaction, direction: u8, nb: u32, buffer: *mut *const u8, buffer_len: *mut u32, diff --git a/src/detect-http-header-names.c b/src/detect-http-header-names.c index 32a5a88de0..bc6115e170 100644 --- a/src/detect-http-header-names.c +++ b/src/detect-http-header-names.c @@ -150,6 +150,27 @@ static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id, return buf->buffer; } +static InspectionBuffer *GetBuffer2ForTX(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *_f, const uint8_t flow_flags, void *txv, + const int list_id) +{ + InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); + if (buffer->inspect == NULL) { + uint32_t b_len = 0; + const uint8_t *b = NULL; + + if (rs_http2_tx_get_header_names(txv, flow_flags, &b, &b_len) != 1) + return NULL; + if (b == NULL || b_len == 0) + return NULL; + + InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len); + InspectionBufferApplyTransforms(buffer, transforms); + } + + return buffer; +} + typedef struct PrefilterMpmHttpHeaderCtx { int list_id; const MpmCtx *mpm_ctx; @@ -381,7 +402,7 @@ static int DetectHttpHeaderNamesSetup(DetectEngineCtx *de_ctx, Signature *s, con if (DetectBufferSetActiveList(s, g_buffer_id) < 0) return -1; - if (DetectSignatureSetAppProto(s, ALPROTO_HTTP1) < 0) + if (DetectSignatureSetAppProto(s, ALPROTO_HTTP) < 0) return -1; return 0; @@ -410,6 +431,16 @@ void DetectHttpHeaderNamesRegister(void) DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP1, SIG_FLAG_TOCLIENT, HTP_RESPONSE_HEADERS, InspectEngineHttpHeaderNames, NULL); + DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, + GetBuffer2ForTX, ALPROTO_HTTP2, HTTP2StateDataClient); + DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, + GetBuffer2ForTX, ALPROTO_HTTP2, HTTP2StateDataServer); + + DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP2, SIG_FLAG_TOSERVER, + HTTP2StateDataClient, DetectEngineInspectBufferGeneric, GetBuffer2ForTX); + DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP2, SIG_FLAG_TOCLIENT, + HTTP2StateDataServer, DetectEngineInspectBufferGeneric, GetBuffer2ForTX); + DetectBufferTypeSetDescriptionByName(BUFFER_NAME, BUFFER_DESC);