From: Maya Dagon (mdagon) Date: Fri, 11 Oct 2024 11:28:41 +0000 (+0000) Subject: Pull request #4477: Extractor - HTTP fields support: add support for body length... X-Git-Tag: 3.4.0.0~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5edcd82beca4aad7878f7643f04ba2b631a8c340;p=thirdparty%2Fsnort3.git Pull request #4477: Extractor - HTTP fields support: add support for body length, info_code/msg, filename, proxied Merge in SNORT/snort3 from ~MDAGON/snort3:http_fields to master Squashed commit of the following: commit 1fc153936a564191ae716130d477859198d12e2a Author: maya dagon Date: Tue Jul 2 11:02:28 2024 -0400 extractor: add support for body length, info_code/msg, filename, proxied --- diff --git a/src/network_inspectors/extractor/dev_notes.txt b/src/network_inspectors/extractor/dev_notes.txt index 2878b160f..d3acffaa3 100644 --- a/src/network_inspectors/extractor/dev_notes.txt +++ b/src/network_inspectors/extractor/dev_notes.txt @@ -49,4 +49,11 @@ The following fields are supported for HTTP: * status_code * status_msg * trans_depth + * request_body_len + * response_body_len + * info_code + * info_msg + * proxied + * orig_filenames + * resp_filenames diff --git a/src/network_inspectors/extractor/extractor_http_event_handler.cc b/src/network_inspectors/extractor/extractor_http_event_handler.cc index 0d489e8cb..46482a732 100644 --- a/src/network_inspectors/extractor/extractor_http_event_handler.cc +++ b/src/network_inspectors/extractor/extractor_http_event_handler.cc @@ -88,6 +88,41 @@ static uint64_t get_trans_depth(const DataEvent* event, const Packet*, const Flo return ((const HttpTransactionEndEvent*)event)->get_trans_depth(); } +static uint64_t get_request_body_len(const DataEvent* event, const Packet*, const Flow*) +{ + return ((const HttpTransactionEndEvent*)event)->get_request_body_len(); +} + +static uint64_t get_response_body_len(const DataEvent* event, const Packet*, const Flow*) +{ + return ((const HttpTransactionEndEvent*)event)->get_response_body_len(); +} + +static uint64_t get_info_code(const DataEvent* event, const Packet*, const Flow*) +{ + return ((const HttpTransactionEndEvent*)event)->get_info_code(); +} + +static const Field& get_info_msg(const DataEvent* event, const Packet*, const Flow*) +{ + return ((const HttpTransactionEndEvent*)event)->get_info_msg(); +} + +static const char* get_proxied(const DataEvent* event, const Packet*, const Flow*) +{ + return ((const HttpTransactionEndEvent*)event)->get_proxied().c_str(); +} + +static const char* get_orig_filenames(const DataEvent* event, const Packet*, const Flow*) +{ + return ((const HttpTransactionEndEvent*)event)->get_filename(HttpCommon::SRC_CLIENT).c_str(); +} + +static const char* get_resp_filenames(const DataEvent* event, const Packet*, const Flow*) +{ + return ((const HttpTransactionEndEvent*)event)->get_filename(HttpCommon::SRC_SERVER).c_str(); +} + static struct timeval get_timestamp(const DataEvent*, const Packet* p, const Flow*) { return p->pkth->ts; @@ -136,7 +171,10 @@ static const map sip_getters = static const map str_getters = { - {"version", get_version} + {"version", get_version}, + {"proxied", get_proxied}, + {"orig_filenames", get_orig_filenames}, + {"resp_filenames", get_resp_filenames} }; static const map num_getters = @@ -145,7 +183,10 @@ static const map num_getters = {"id.resp_p", get_ip_dst_port}, {"uid", get_uid}, {"pkt_num", get_pkt_num}, - {"trans_depth", get_trans_depth} + {"trans_depth", get_trans_depth}, + {"request_body_len", get_request_body_len}, + {"response_body_len", get_response_body_len}, + {"info_code", get_info_code} }; static const map sub_getters = @@ -157,7 +198,8 @@ static const map sub_getters = {"referrer", get_referrer}, {"origin", get_origin}, {"status_code", get_stat_code}, - {"status_msg", get_stat_msg} + {"status_msg", get_stat_msg}, + {"info_msg", get_info_msg} }; template diff --git a/src/network_inspectors/extractor/extractor_service.cc b/src/network_inspectors/extractor/extractor_service.cc index e7cacb0d1..bfe3b0456 100644 --- a/src/network_inspectors/extractor/extractor_service.cc +++ b/src/network_inspectors/extractor/extractor_service.cc @@ -159,7 +159,14 @@ ServiceBlueprint HttpExtractorService::blueprint = "version", "status_code", "status_msg", - "trans_depth" + "trans_depth", + "request_body_len", + "response_body_len", + "info_code", + "info_msg", + "proxied", + "orig_filenames", + "resp_filenames" }, }; diff --git a/src/pub_sub/http_transaction_end_event.cc b/src/pub_sub/http_transaction_end_event.cc index 0aa8e6829..be35661cd 100644 --- a/src/pub_sub/http_transaction_end_event.cc +++ b/src/pub_sub/http_transaction_end_event.cc @@ -31,6 +31,7 @@ #include "service_inspectors/http_inspect/http_transaction.h" using namespace snort; +using namespace HttpEnums; HttpTransactionEndEvent::HttpTransactionEndEvent(const HttpTransaction* const trans) : transaction(trans) { } @@ -113,3 +114,61 @@ uint64_t HttpTransactionEndEvent::get_trans_depth() const return 0; } + +uint64_t HttpTransactionEndEvent::get_request_body_len() const +{ + return transaction->get_body_len(HttpCommon::SRC_CLIENT); +} + +uint64_t HttpTransactionEndEvent::get_response_body_len() const +{ + return transaction->get_body_len(HttpCommon::SRC_SERVER); +} + +uint8_t HttpTransactionEndEvent::get_info_code() const +{ + return transaction->get_info_code(); +} + +const Field& HttpTransactionEndEvent::get_info_msg() const +{ + return transaction->get_info_msg(); +} + +const std::string& HttpTransactionEndEvent::get_filename(HttpCommon::SourceId src_id) const +{ + return transaction->get_filename(src_id); +} + +const std::string& HttpTransactionEndEvent::get_proxied() const +{ + if (proxies != nullptr) + return *proxies; + + const std::pair proxy_headers[] = + { + { HEAD_FORWARDED, "FORWARDED" }, + { HEAD_X_FORWARDED_FOR, "X-FORWARDED-FOR" }, + { HEAD_X_FORWARDED_FROM, "X-FORWARDED-FROM" }, + { HEAD_CLIENT_IP, "CLIENT-IP" }, + { HEAD_VIA, "VIA" }, + { HEAD_XROXY_CONNECTION, "XROXY-CONNECTION" }, + { HEAD_PROXY_CONNECTION, "PROXY-CONNECTION" } + }; + + proxies = new std::string(); + for (auto& hdr: proxy_headers) + { + const Field& val = get_client_header(hdr.first); + if (val.length() > 0) + { + if (!proxies->empty()) + proxies->append(","); + proxies->append(hdr.second); + proxies->append(" -> "); + proxies->append((const char*)val.start(), val.length()); + } + } + + return *proxies; +} diff --git a/src/pub_sub/http_transaction_end_event.h b/src/pub_sub/http_transaction_end_event.h index 9fe6d4bc6..7fda6f0dd 100644 --- a/src/pub_sub/http_transaction_end_event.h +++ b/src/pub_sub/http_transaction_end_event.h @@ -38,6 +38,8 @@ class SO_PUBLIC HttpTransactionEndEvent : public snort::DataEvent { public: HttpTransactionEndEvent(const HttpTransaction* const); + ~HttpTransactionEndEvent() override + { delete proxies; } const Field& get_host_hdr() const; const Field& get_uri() const; @@ -49,11 +51,18 @@ public: const Field& get_origin_hdr() const; HttpEnums::VersionId get_version() const; uint64_t get_trans_depth() const; + uint64_t get_request_body_len() const; + uint64_t get_response_body_len() const; + uint8_t get_info_code() const; + const Field& get_info_msg() const; + const std::string& get_filename(HttpCommon::SourceId) const; + const std::string& get_proxied() const; private: const Field& get_client_header(uint64_t sub_id) const; const HttpTransaction* const transaction; + mutable std::string* proxies = nullptr; }; } #endif diff --git a/src/pub_sub/test/CMakeLists.txt b/src/pub_sub/test/CMakeLists.txt index f2a21d8aa..00dddc52e 100644 --- a/src/pub_sub/test/CMakeLists.txt +++ b/src/pub_sub/test/CMakeLists.txt @@ -24,6 +24,7 @@ add_cpputest( pub_sub_http_transaction_end_event_test ../../service_inspectors/http_inspect/http_flow_data.cc ../../service_inspectors/http_inspect/http_test_manager.cc ../../service_inspectors/http_inspect/http_test_input.cc + ../../service_inspectors/http_inspect/http_field.cc LIBS ${ZLIB_LIBRARIES} ) add_cpputest( pub_sub_ftp_events_test diff --git a/src/pub_sub/test/pub_sub_http_transaction_end_event_test.cc b/src/pub_sub/test/pub_sub_http_transaction_end_event_test.cc index 0ba37bda6..8762cc6fb 100644 --- a/src/pub_sub/test/pub_sub_http_transaction_end_event_test.cc +++ b/src/pub_sub/test/pub_sub_http_transaction_end_event_test.cc @@ -28,6 +28,7 @@ #include "service_inspectors/http_inspect/http_flow_data.h" #include "service_inspectors/http_inspect/http_inspect.h" #include "service_inspectors/http_inspect/http_module.h" +#include "service_inspectors/http_inspect/http_msg_header.h" #include "service_inspectors/http_inspect/http_msg_section.h" #include "service_inspectors/http_inspect/http_transaction.h" #include "service_inspectors/http_inspect/test/http_unit_test_helpers.h" @@ -70,9 +71,6 @@ unsigned StreamSplitter::max(snort::Flow*) { return 0; } HttpParaList::UriParam::UriParam() { } HttpParaList::JsNormParam::~JsNormParam() { } HttpParaList::~HttpParaList() { } -const Field Field::FIELD_NULL { STAT_NO_SOURCE }; -const Field& HttpMsgSection::get_classic_buffer(unsigned, uint64_t, uint64_t) -{ return Field::FIELD_NULL; } HttpInspect::HttpInspect(const HttpParaList* para) : params(para), xtra_trueip_id(0), xtra_uri_id(0), xtra_host_id(0), xtra_jsnorm_id(0) @@ -106,8 +104,56 @@ const snort::StreamBuffer HttpStreamSplitter::reassemble(snort::Flow*, unsigned, bool HttpStreamSplitter::finish(snort::Flow*) { return false; } void HttpStreamSplitter::prep_partial_flush(snort::Flow*, uint32_t) { } +HttpMsgHeader::HttpMsgHeader(const uint8_t* buffer, const uint16_t buf_size, + HttpFlowData* session_data_, SourceId source_id_, bool buf_owner, Flow* flow_, + const HttpParaList* params_) : + HttpMsgHeadShared(buffer, buf_size, session_data_, source_id_, buf_owner, flow_, params_) +{} +void HttpMsgHeader::publish(unsigned){} +void HttpMsgHeader::gen_events() {} +void HttpMsgHeader::update_flow() {} +void HttpMsgHeader::prepare_body() {} +#ifdef REG_TEST +void HttpMsgHeader::print_section(FILE*) {} +#endif +HttpMsgHeadShared::HttpMsgHeadShared(const uint8_t* buffer, const uint16_t buf_size, + HttpFlowData* session_data_, HttpCommon::SourceId source_id_, bool buf_owner, + snort::Flow* flow_, const HttpParaList* params_): HttpMsgSection(buffer, buf_size, + session_data_, source_id_, buf_owner, flow_, params_), own_msg_buffer(buf_owner) +{} +HttpMsgHeadShared::~HttpMsgHeadShared() {} +HttpMsgSection::HttpMsgSection(const uint8_t* buffer, const uint16_t buf_size, + HttpFlowData* session_data_, SourceId source_id_, bool buf_owner, Flow* flow_, + const HttpParaList* params_) : + msg_text(buf_size, buffer, buf_owner), + session_data(session_data_), + flow(flow_), + params(params_), + transaction(nullptr), + trans_num(0), + status_code_num(STAT_NOT_PRESENT), + source_id(source_id_), + version_id(VERS__NOT_PRESENT), + method_id(METH__NOT_PRESENT), + tcp_close(false) +{} +void HttpMsgSection::clear(){} +bool HttpMsgSection::run_detection(snort::Packet*) { return false; } +void HttpMsgHeadShared::analyze() {} + THREAD_LOCAL PegCount HttpModule::peg_counts[PEG_COUNT_MAX] = { }; +// +// get_classic_buffer mock +// +Field odd (3, (const uint8_t *)"odd", false); +Field even (4, (const uint8_t *)"even", false); +static uint32_t test_number = 0; +const Field& HttpMsgSection::get_classic_buffer(unsigned, uint64_t, uint64_t) +{ + return ((test_number % 2) == 0) ? even : odd; +} + TEST_GROUP(pub_sub_http_transaction_end_event_test) { Flow* const flow = new Flow; @@ -127,17 +173,36 @@ TEST_GROUP(pub_sub_http_transaction_end_event_test) } }; -TEST(pub_sub_http_transaction_end_event_test, version_no_req_no_status) +TEST(pub_sub_http_transaction_end_event_test, no_req_no_status) { section_type[SRC_CLIENT] = SEC_REQUEST; HttpTransaction* trans = HttpTransaction::attach_my_transaction(flow_data, SRC_CLIENT, flow); HttpTransactionEndEvent event(trans); HttpEnums::VersionId version = event.get_version(); CHECK(version == HttpEnums::VERS__NOT_PRESENT); + uint64_t trans_depth = event.get_trans_depth(); + CHECK(trans_depth == 0); +} + +TEST(pub_sub_http_transaction_end_event_test, proxied_str_exists) +{ + section_type[SRC_CLIENT] = SEC_REQUEST; + HttpTransaction* trans = HttpTransaction::attach_my_transaction(flow_data, SRC_CLIENT, flow); + char buf[] = "something"; + HttpMsgHeader* hdr = new HttpMsgHeader((uint8_t*)buf, sizeof(buf), flow_data, SRC_CLIENT, false, flow, ¶ms); + trans->set_header(hdr, SRC_CLIENT); + HttpTransactionEndEvent event(trans); + const std::string result = "FORWARDED -> odd,X-FORWARDED-FOR -> odd,X-FORWARDED-FROM -> odd," + "CLIENT-IP -> odd,VIA -> odd,XROXY-CONNECTION -> odd,PROXY-CONNECTION -> odd"; + test_number = 1; + std::string proxied = event.get_proxied(); + CHECK(proxied == result); + test_number = 2; + proxied = event.get_proxied(); + CHECK(proxied == result); } int main(int argc, char** argv) { return CommandLineTestRunner::RunAllTests(argc, argv); } - diff --git a/src/service_inspectors/http_inspect/http_enum.h b/src/service_inspectors/http_inspect/http_enum.h index 4c5be4a88..19c9eaed7 100755 --- a/src/service_inspectors/http_inspect/http_enum.h +++ b/src/service_inspectors/http_inspect/http_enum.h @@ -156,7 +156,8 @@ enum HeaderId { HEAD__NOT_COMPUTE=-14, HEAD__PROBLEMATIC=-12, HEAD__NOT_PRESENT= HEAD_CONTENT_TYPE, HEAD_EXPIRES, HEAD_LAST_MODIFIED, HEAD_X_FORWARDED_FOR, HEAD_TRUE_CLIENT_IP, HEAD_X_WORKING_WITH, HEAD_CONTENT_TRANSFER_ENCODING, HEAD_MIME_VERSION, HEAD_PROXY_AGENT, HEAD_CONTENT_DISPOSITION, HEAD_HTTP2_SETTINGS, HEAD_RESTRICT_ACCESS_TO_TENANTS, - HEAD_RESTRICT_ACCESS_CONTEXT, HEAD_ORIGIN, HEAD__MAX_VALUE }; + HEAD_RESTRICT_ACCESS_CONTEXT, HEAD_ORIGIN, HEAD_FORWARDED, HEAD_X_FORWARDED_FROM, + HEAD_CLIENT_IP, HEAD_XROXY_CONNECTION, HEAD_PROXY_CONNECTION, HEAD__MAX_VALUE }; // All the infractions we might find while parsing and analyzing a message enum Infraction diff --git a/src/service_inspectors/http_inspect/http_msg_body.cc b/src/service_inspectors/http_inspect/http_msg_body.cc index 80b468158..1599e9d06 100644 --- a/src/service_inspectors/http_inspect/http_msg_body.cc +++ b/src/service_inspectors/http_inspect/http_msg_body.cc @@ -324,6 +324,8 @@ void HttpMsgBody::analyze() } } body_octets += msg_text.length(); + if (!session_data->partial_flush[source_id]) + transaction->add_body_len(source_id, detect_data.length()); partial_inspected_octets = session_data->partial_flush[source_id] ? msg_text.length() : 0; } @@ -715,6 +717,7 @@ void HttpMsgBody::do_file_processing(const Field& file_data) filename_length, 0, get_header(source_id)->get_multi_file_processing_id(), uri_buffer, uri_length); + transaction->set_filename(source_id, (const char*) filename_buffer, filename_length); } } } diff --git a/src/service_inspectors/http_inspect/http_msg_status.h b/src/service_inspectors/http_inspect/http_msg_status.h index 1d40763a6..a68103dcc 100644 --- a/src/service_inspectors/http_inspect/http_msg_status.h +++ b/src/service_inspectors/http_inspect/http_msg_status.h @@ -37,8 +37,8 @@ public: void gen_events() override; void update_flow() override; - const Field& get_status_code() { return status_code; } - const Field& get_reason_phrase() { return reason_phrase; } + const Field& get_status_code() const { return status_code; } + const Field& get_reason_phrase() const { return reason_phrase; } #ifdef REG_TEST void print_section(FILE* output) override; diff --git a/src/service_inspectors/http_inspect/http_normalized_header.cc b/src/service_inspectors/http_inspect/http_normalized_header.cc index 37d2c5321..a4c40e34e 100644 --- a/src/service_inspectors/http_inspect/http_normalized_header.cc +++ b/src/service_inspectors/http_inspect/http_normalized_header.cc @@ -166,6 +166,11 @@ const NormalizedHeader::HeaderNormalizer* const NormalizedHeader::header_norms[H &NORMALIZER_BASIC, // HEAD_RESTRICT_ACCESS_TO_TENANTS &NORMALIZER_BASIC, // HEAD_RESTRICT_ACCESS_CONTEXT &NORMALIZER_URI, // HEAD_ORIGIN + &NORMALIZER_BASIC, // HEAD_FORWARDED + &NORMALIZER_BASIC, // HEAD_X_FORWARDED_FROM + &NORMALIZER_BASIC, // HEAD_CLIENT_IP + &NORMALIZER_BASIC, // HEAD_XROXY_CONNECTION + &NORMALIZER_BASIC, // HEAD_PROXY_CONNECTION &NORMALIZER_BASIC, // HEAD__MAX_VALUE &NORMALIZER_BASIC, // HEAD_CUSTOM_XFF_HEADER &NORMALIZER_BASIC, // HEAD_CUSTOM_XFF_HEADER diff --git a/src/service_inspectors/http_inspect/http_tables.cc b/src/service_inspectors/http_inspect/http_tables.cc index 5cc31714d..0b2e7c505 100755 --- a/src/service_inspectors/http_inspect/http_tables.cc +++ b/src/service_inspectors/http_inspect/http_tables.cc @@ -143,6 +143,11 @@ const StrCode HttpMsgHeadShared::header_list[] = { HEAD_RESTRICT_ACCESS_TO_TENANTS, "restrict-access-to-tenants" }, { HEAD_RESTRICT_ACCESS_CONTEXT, "restrict-access-context" }, { HEAD_ORIGIN, "origin" }, + { HEAD_FORWARDED, "forwarded" }, + { HEAD_X_FORWARDED_FROM, "x-forwarded-from" }, + { HEAD_CLIENT_IP, "client-ip" }, + { HEAD_XROXY_CONNECTION, "xroxy-connection" }, + { HEAD_PROXY_CONNECTION, "proxy-connection" }, { 0, nullptr } }; diff --git a/src/service_inspectors/http_inspect/http_transaction.cc b/src/service_inspectors/http_inspect/http_transaction.cc index 71e040adc..3846065eb 100644 --- a/src/service_inspectors/http_inspect/http_transaction.cc +++ b/src/service_inspectors/http_inspect/http_transaction.cc @@ -81,7 +81,8 @@ HttpTransaction::~HttpTransaction() delete infractions[k]; } delete_section_list(body_list); - delete_section_list(discard_list); + delete_section_list(archive_hdr_list); + delete_section_list(archive_status_list); } HttpTransaction* HttpTransaction::attach_my_transaction(HttpFlowData* session_data, SourceId @@ -155,10 +156,10 @@ HttpTransaction* HttpTransaction::attach_my_transaction(HttpFlowData* session_da session_data->transaction[SRC_SERVER]->second_response_expected) { session_data->transaction[SRC_SERVER]->second_response_expected = false; - session_data->transaction[SRC_SERVER]->discard_section( + session_data->transaction[SRC_SERVER]->archive_status( session_data->transaction[SRC_SERVER]->status); session_data->transaction[SRC_SERVER]->status = nullptr; - session_data->transaction[SRC_SERVER]->discard_section( + session_data->transaction[SRC_SERVER]->archive_header( session_data->transaction[SRC_SERVER]->header[SRC_SERVER]); session_data->transaction[SRC_SERVER]->header[SRC_SERVER] = nullptr; } @@ -217,15 +218,25 @@ HttpTransaction* HttpTransaction::attach_my_transaction(HttpFlowData* session_da return session_data->transaction[source_id]; } -void HttpTransaction::discard_section(HttpMsgSection* section) +void HttpTransaction::archive_section(HttpMsgSection* section, HttpMsgSection** archive_list) { if (section != nullptr) { - section->next = discard_list; - discard_list = section; + section->next = *archive_list; + *archive_list = section; } } +void HttpTransaction::archive_status(HttpMsgStatus* status) +{ + archive_section(status, &archive_status_list); +} + +void HttpTransaction::archive_header(HttpMsgHeader* hdr) +{ + archive_section(hdr, &archive_hdr_list); +} + void HttpTransaction::clear_section() { assert(active_sections > 0); @@ -289,3 +300,50 @@ void HttpTransaction::set_one_hundred_response() one_hundred_response = true; second_response_expected = true; } + +inline bool is_info_code(int32_t code) +{ + return ((99 < code) and (code < 200)); +} + +uint8_t HttpTransaction::get_info_code() const +{ + if (status) + { + const int32_t code = status->get_status_code_num(); + if (is_info_code(code)) + return code; + } + + const HttpMsgStatus* arch_status = (HttpMsgStatus*) archive_status_list; + while (arch_status) + { + const int32_t code = arch_status->get_status_code_num(); + if (is_info_code(code)) + return code; + arch_status = (HttpMsgStatus*)(arch_status->next); + } + + return 0; +} + +const Field& HttpTransaction::get_info_msg() const +{ + if (status) + { + const int32_t code = status->get_status_code_num(); + if (is_info_code(code)) + return status->get_reason_phrase(); + } + + const HttpMsgStatus* arch_status = (HttpMsgStatus*) archive_status_list; + while (arch_status) + { + const int32_t code = arch_status->get_status_code_num(); + if (is_info_code(code)) + return arch_status->get_reason_phrase(); + arch_status = (HttpMsgStatus*)(arch_status->next); + } + + return Field::FIELD_NULL; +} diff --git a/src/service_inspectors/http_inspect/http_transaction.h b/src/service_inspectors/http_inspect/http_transaction.h index c3981da21..d64a6e817 100644 --- a/src/service_inspectors/http_inspect/http_transaction.h +++ b/src/service_inspectors/http_inspect/http_transaction.h @@ -62,6 +62,17 @@ public: void set_one_hundred_response(); bool final_response() const { return !second_response_expected; } + void add_body_len(HttpCommon::SourceId source_id, uint64_t len) + { body_len[source_id] += len; } + uint64_t get_body_len(HttpCommon::SourceId source_id) const + { return body_len[source_id]; } + uint8_t get_info_code() const; + const Field& get_info_msg() const; + void set_filename(HttpCommon::SourceId source_id, const char* fname, uint32_t len) + { filename[source_id].assign(fname, len);} + const std::string& get_filename(HttpCommon::SourceId source_id) const + { return filename[source_id]; } + void clear_section(); bool is_clear() const { return active_sections == 0; } void garbage_collect(); @@ -70,7 +81,9 @@ public: private: HttpTransaction(HttpFlowData*, snort::Flow* const); - void discard_section(HttpMsgSection*); + void archive_section(HttpMsgSection*, HttpMsgSection**); + void archive_status(HttpMsgStatus*); + void archive_header(HttpMsgHeader*); void publish_end_of_transaction(); HttpFlowData* const session_data; @@ -82,7 +95,8 @@ private: HttpMsgHeader* header[2] = { nullptr, nullptr }; HttpMsgTrailer* trailer[2] = { nullptr, nullptr }; HttpMsgBody* body_list = nullptr; - HttpMsgSection* discard_list = nullptr; + HttpMsgSection* archive_status_list = nullptr; + HttpMsgSection* archive_hdr_list = nullptr; HttpInfractions* infractions[2]; bool response_seen = false; @@ -97,6 +111,9 @@ private: unsigned pub_id; snort::Flow* const flow; + uint64_t body_len[2] = { 0, 0 }; + std::string filename[2]; + // Estimates of how much memory http_inspect uses to process a transaction static const uint16_t small_things = 400; // minor memory costs not otherwise accounted for static const uint16_t transaction_memory_usage_estimate; diff --git a/src/service_inspectors/http_inspect/test/http_transaction_test.cc b/src/service_inspectors/http_inspect/test/http_transaction_test.cc index aba0218e7..e643557b0 100644 --- a/src/service_inspectors/http_inspect/test/http_transaction_test.cc +++ b/src/service_inspectors/http_inspect/test/http_transaction_test.cc @@ -113,6 +113,7 @@ bool HttpStreamSplitter::finish(snort::Flow*) { return false; } void HttpStreamSplitter::prep_partial_flush(snort::Flow*, uint32_t) { } THREAD_LOCAL PegCount HttpModule::peg_counts[PEG_COUNT_MAX] = { }; +const Field Field::FIELD_NULL { STAT_NO_SOURCE }; TEST_GROUP(http_transaction_test) {