From: Steve Chew (stechew) Date: Wed, 17 Sep 2025 03:11:02 +0000 (+0000) Subject: Pull request #4910: http_inspect,pub_sub: Provide an API in HttpEvent to find whether... X-Git-Tag: 3.9.6.0~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e357b6048db8d12efcdd9f27b0edb47a9c3d277;p=thirdparty%2Fsnort3.git Pull request #4910: http_inspect,pub_sub: Provide an API in HttpEvent to find whether the HTTP response is using a supported encoding type. Merge in SNORT/snort3 from ~STECHEW/snort3:has_unsupported_encoding to master Squashed commit of the following: commit 47f2a9f7e3c594da9d12da174042652342f0b0ec Author: Steve Chew Date: Mon Sep 15 17:24:39 2025 -0400 http_inspect,pub_sub: Provide an API in HttpEvent to find whether the HTTP response is using a supported encoding type. --- diff --git a/src/pub_sub/http_events.cc b/src/pub_sub/http_events.cc index 75676adde..067ceaa65 100644 --- a/src/pub_sub/http_events.cc +++ b/src/pub_sub/http_events.cc @@ -196,3 +196,9 @@ int64_t HttpEvent::get_httpx_stream_id() const { return httpx_stream_id; } + +bool HttpEvent::has_supported_encoding() const +{ + return http_msg_header->has_supported_encoding(); +} + diff --git a/src/pub_sub/http_events.h b/src/pub_sub/http_events.h index debe7f87a..ba5a19a12 100644 --- a/src/pub_sub/http_events.h +++ b/src/pub_sub/http_events.h @@ -57,6 +57,7 @@ public: bool contains_webdav_method(); bool get_is_httpx() const; int64_t get_httpx_stream_id() const; + bool has_supported_encoding() const; private: HttpMsgHeader* const http_msg_header; diff --git a/src/pub_sub/test/pub_sub_http_event_test.cc b/src/pub_sub/test/pub_sub_http_event_test.cc index 0851de65f..2aa8ce5d9 100644 --- a/src/pub_sub/test/pub_sub_http_event_test.cc +++ b/src/pub_sub/test/pub_sub_http_event_test.cc @@ -56,6 +56,12 @@ const Field& HttpMsgSection::get_classic_buffer(unsigned buffer_type, uint64_t, return (*out); } +bool HttpMsgHeader::has_supported_encoding() const +{ + mock().actualCall("has_supported_encoding"); + return (bool) mock().getData("has_supported_encoding").getIntValue(); +} + const Field& HttpMsgHeader::get_true_ip_addr() { Field *out = (Field*)mock().getData("output").getObjectPointer(); @@ -72,10 +78,29 @@ TEST_GROUP(pub_sub_http_event_test) void teardown() override { + mock().checkExpectations(); mock().clear(); } }; +TEST(pub_sub_http_event_test, has_supported_encoding_true) +{ + mock().expectOneCall("has_supported_encoding"); + mock().setData("has_supported_encoding", (int)true); + HttpEvent event(nullptr, false, 0); + + CHECK(event.has_supported_encoding()); +} + +TEST(pub_sub_http_event_test, has_supported_encoding_false) +{ + mock().expectOneCall("has_supported_encoding"); + mock().setData("has_supported_encoding", (int)false); + HttpEvent event(nullptr, false, 0); + + CHECK_FALSE(event.has_supported_encoding()); +} + TEST(pub_sub_http_event_test, http_traffic) { int64_t stream_id = 0; @@ -102,7 +127,6 @@ TEST(pub_sub_http_event_test, no_true_ip_addr) header_start = event.get_trueip_addr(header_length); CHECK(header_length == 0); CHECK(header_start == nullptr); - mock().checkExpectations(); } TEST(pub_sub_http_event_test, true_ip_addr) @@ -115,7 +139,6 @@ TEST(pub_sub_http_event_test, true_ip_addr) header_start = event.get_trueip_addr(header_length); CHECK(header_length == 7); CHECK(memcmp(header_start, "1.1.1.1", 7) == 0); - mock().checkExpectations(); } TEST(pub_sub_http_event_test, get_method) @@ -130,7 +153,6 @@ TEST(pub_sub_http_event_test, get_method) header_start = event.get_method(header_length); CHECK(7 == header_length); CHECK(memcmp(header_start, "CONNECT", 7) == 0); - mock().checkExpectations(); } TEST(pub_sub_http_event_test, get_response_phrase) @@ -146,7 +168,6 @@ TEST(pub_sub_http_event_test, get_response_phrase) header_start = event.get_response_phrase(header_length); CHECK(7 == header_length); CHECK(memcmp(header_start, "CONNECT", 7) == 0); - mock().checkExpectations(); } TEST(pub_sub_http_event_test, get_all_raw_headers) @@ -164,7 +185,6 @@ TEST(pub_sub_http_event_test, get_all_raw_headers) header_start = event.get_all_raw_headers(discovered_length); CHECK(discovered_length == header_length); CHECK(memcmp(header_start, headers, header_length) == 0); - mock().checkExpectations(); } int main(int argc, char** argv) diff --git a/src/service_inspectors/http_inspect/http_msg_header.cc b/src/service_inspectors/http_inspect/http_msg_header.cc index aa268a5cc..393636713 100755 --- a/src/service_inspectors/http_inspect/http_msg_header.cc +++ b/src/service_inspectors/http_inspect/http_msg_header.cc @@ -74,6 +74,11 @@ void HttpMsgHeader::publish(unsigned pub_id) DataBus::publish(pub_id, evid, http_header_event, flow); } +bool HttpMsgHeader::has_supported_encoding() const +{ + return encoding_supported; +} + const Field& HttpMsgHeader::get_true_ip() { if (true_ip.length() != STAT_NOT_COMPUTE) @@ -173,13 +178,13 @@ int32_t HttpMsgHeader::get_num_cookies() return num_cookies; } - std::string HttpMsgHeader::get_host_header_field() const - { +std::string HttpMsgHeader::get_host_header_field() const +{ if (host_name.length() > STAT_EMPTY_STRING) return std::string((const char*)host_name.start(), host_name.length()); return ""; - } +} void HttpMsgHeader::gen_events() { @@ -655,6 +660,7 @@ void HttpMsgHeader::setup_encoding_decompression() add_infraction(INF_STACKED_ENCODINGS); create_event(EVENT_STACKED_ENCODINGS); compression = CMP_NONE; + encoding_supported = false; } switch (content_code) { @@ -671,18 +677,21 @@ void HttpMsgHeader::setup_encoding_decompression() case CONTENTCODE_CHUNKED: add_infraction(INF_CONTENT_ENCODING_CHUNKED); create_event(EVENT_CONTENT_ENCODING_CHUNKED); + encoding_supported = false; break; case CONTENTCODE__OTHER: // The ones we never heard of HttpModule::increment_peg_counts(PEG_COMPRESSED_UNKNOWN); add_infraction(INF_UNKNOWN_ENCODING); create_event(EVENT_UNKNOWN_ENCODING); + encoding_supported = false; break; default: // The ones we know by name but don't support HttpModule::increment_peg_counts(PEG_COMPRESSED_NOT_SUPPORTED); add_infraction(INF_UNSUPPORTED_ENCODING); create_event(EVENT_UNSUPPORTED_ENCODING); + encoding_supported = false; break; } } diff --git a/src/service_inspectors/http_inspect/http_msg_header.h b/src/service_inspectors/http_inspect/http_msg_header.h index eaaaa459e..be989876f 100644 --- a/src/service_inspectors/http_inspect/http_msg_header.h +++ b/src/service_inspectors/http_inspect/http_msg_header.h @@ -51,6 +51,8 @@ public: bool has_mime_boundary() const { return mime_boundary_found; } + bool has_supported_encoding() const; + // The multi_file_processing_id is unique for each file transferred within a single connection // and is used by file processing to store partially processed file contexts in the flow data. void set_multi_file_processing_id(const uint64_t transaction_id, const uint32_t stream_id); @@ -70,6 +72,7 @@ private: snort::MailLogConfig mime_conf; bool mime_boundary_found = false; + bool encoding_supported = true; Field host_name; Field true_ip;