From: Russ Combs (rucombs) Date: Tue, 30 Jan 2018 01:46:12 +0000 (-0500) Subject: Merge pull request #1102 in SNORT/snort3 from nhi_perf to master X-Git-Tag: 3.0.0-243~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=468842b7cd708c4db59ed4877f2287dc152fd98b;p=thirdparty%2Fsnort3.git Merge pull request #1102 in SNORT/snort3 from nhi_perf to master Squashed commit of the following: commit fb74224d1fa1541ca576104bca12e43ffe3976fa Author: Tom Peters Date: Mon Jan 29 15:57:50 2018 -0500 http_inspect: suppress raw packet inspection beyond request/response depth flow: support episodic detection --- diff --git a/src/detection/fp_detect.cc b/src/detection/fp_detect.cc index 7be9a84f5..6882f931b 100644 --- a/src/detection/fp_detect.cc +++ b/src/detection/fp_detect.cc @@ -970,25 +970,16 @@ static int fp_search( return 0; } -/* -** DESCRIPTION -** This function does a set-wise match on content, and walks an otn list -** for non-content. The otn list search will eventually be redone for -** for performance purposes. -** -** FORMAL INPUTS -** PortGroup * - the port group to inspect -** Packet * - the packet to inspect -** int - whether src/dst ports should be checked (udp/tcp or icmp) -** char - whether the rule is an IP rule (change the packet payload pointer) -** -** FORMAL OUTPUTS -** int - 0 for failed pattern match -** 1 for successful pattern match -*/ +// This function does a set-wise match on content, and walks an otn list +// for non-content. The otn list search will eventually be redone for +// for performance purposes. + static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p, int check_ports, char ip_rule, int type, OtnxMatchData* omd) { + if ( p->flow and !p->flow->is_detection_enabled(p->packet_flags & PKT_FROM_CLIENT) ) + return 0; + const uint8_t* tmp_payload = nullptr; int8_t curr_ip_layer = 0; bool repeat = false; diff --git a/src/flow/flow.h b/src/flow/flow.h index a819281be..da719ff82 100644 --- a/src/flow/flow.h +++ b/src/flow/flow.h @@ -63,6 +63,8 @@ #define SSNFLAG_CLIENT_SWAPPED 0x00400000 #define SSNFLAG_PROXIED 0x01000000 +#define SSNFLAG_NO_DETECT_TO_CLIENT 0x02000000 +#define SSNFLAG_NO_DETECT_TO_SERVER 0x04000000 #define SSNFLAG_ABORT_CLIENT 0x10000000 #define SSNFLAG_ABORT_SERVER 0x20000000 @@ -186,6 +188,10 @@ public: uint32_t clear_session_flags(uint32_t flags) { return ssn_state.session_flags &= ~flags; } + void set_to_client_detection(bool enable); + void set_to_server_detection(bool enable); + bool is_detection_enabled(bool to_server); + int get_ignore_direction() { return ssn_state.ignore_direction; } @@ -343,5 +349,29 @@ private: void clean(); }; +inline void Flow::set_to_client_detection(bool enable) +{ + if ( enable ) + ssn_state.session_flags &= ~SSNFLAG_NO_DETECT_TO_CLIENT; + else + ssn_state.session_flags |= SSNFLAG_NO_DETECT_TO_CLIENT; +} + +inline void Flow::set_to_server_detection(bool enable) +{ + if ( enable ) + ssn_state.session_flags &= ~SSNFLAG_NO_DETECT_TO_SERVER; + else + ssn_state.session_flags |= SSNFLAG_NO_DETECT_TO_SERVER; +} + +inline bool Flow::is_detection_enabled(bool to_server) +{ + if ( to_server ) + return !(ssn_state.session_flags & SSNFLAG_NO_DETECT_TO_SERVER); + + return !(ssn_state.session_flags & SSNFLAG_NO_DETECT_TO_CLIENT); +} + #endif diff --git a/src/service_inspectors/http_inspect/http_enum.h b/src/service_inspectors/http_inspect/http_enum.h index 2256e6017..afb2f20eb 100644 --- a/src/service_inspectors/http_inspect/http_enum.h +++ b/src/service_inspectors/http_inspect/http_enum.h @@ -49,6 +49,8 @@ enum SectionType { SEC_DISCARD = -19, SEC_ABORT = -18, SEC__NOT_COMPUTE=-14, SEC SEC_REQUEST = 2, SEC_STATUS, SEC_HEADER, SEC_BODY_CL, SEC_BODY_CHUNK, SEC_TRAILER, SEC_BODY_OLD }; +enum DetectionStatus { DET_REACTIVATING = 1, DET_ON, DET_DEACTIVATING, DET_OFF }; + // Message buffers available to clients // This enum must remain synchronized with HttpApi::classic_buffer_names[] enum HTTP_BUFFER { HTTP_BUFFER_CLIENT_BODY = 1, HTTP_BUFFER_COOKIE, HTTP_BUFFER_HEADER, diff --git a/src/service_inspectors/http_inspect/http_flow_data.cc b/src/service_inspectors/http_inspect/http_flow_data.cc index 71d7eb224..08fd261c1 100644 --- a/src/service_inspectors/http_inspect/http_flow_data.cc +++ b/src/service_inspectors/http_inspect/http_flow_data.cc @@ -103,6 +103,8 @@ void HttpFlowData::half_reset(SourceId source_id) section_size_max[source_id] = 0; file_depth_remaining[source_id] = STAT_NOT_PRESENT; detect_depth_remaining[source_id] = STAT_NOT_PRESENT; + detection_status[source_id] = DET_REACTIVATING; + compression[source_id] = CMP_NONE; if (compress_stream[source_id] != nullptr) { @@ -155,6 +157,7 @@ void HttpFlowData::trailer_prep(SourceId source_id) delete compress_stream[source_id]; compress_stream[source_id] = nullptr; } + detection_status[source_id] = DET_REACTIVATING; } bool HttpFlowData::add_to_pipeline(HttpTransaction* latest) diff --git a/src/service_inspectors/http_inspect/http_flow_data.h b/src/service_inspectors/http_inspect/http_flow_data.h index baeb28c59..0586889cd 100644 --- a/src/service_inspectors/http_inspect/http_flow_data.h +++ b/src/service_inspectors/http_inspect/http_flow_data.h @@ -119,6 +119,8 @@ private: z_stream* compress_stream[2] = { nullptr, nullptr }; uint64_t zero_nine_expected = 0; + HttpEnums::DetectionStatus detection_status[2] = { HttpEnums::DET_ON, HttpEnums::DET_ON }; + // *** Inspector's internal data about the current message HttpEnums::VersionId version_id[2] = { HttpEnums::VERS__NOT_PRESENT, HttpEnums::VERS__NOT_PRESENT }; diff --git a/src/service_inspectors/http_inspect/http_inspect.cc b/src/service_inspectors/http_inspect/http_inspect.cc index 291db45e7..fe252baeb 100644 --- a/src/service_inspectors/http_inspect/http_inspect.cc +++ b/src/service_inspectors/http_inspect/http_inspect.cc @@ -379,6 +379,19 @@ void HttpInspect::clear(Packet* p) const SourceId source_id = (p->is_from_client()) ? SRC_CLIENT : SRC_SERVER; + if (session_data->detection_status[source_id] == DET_DEACTIVATING) + { + if (source_id == SRC_CLIENT) + { + p->flow->set_to_server_detection(false); + } + else + { + p->flow->set_to_client_detection(false); + } + session_data->detection_status[source_id] = DET_OFF; + } + if (session_data->transaction[source_id] == nullptr) return; diff --git a/src/service_inspectors/http_inspect/http_msg_section.cc b/src/service_inspectors/http_inspect/http_msg_section.cc index 89eb3bcad..5eb8b6861 100644 --- a/src/service_inspectors/http_inspect/http_msg_section.cc +++ b/src/service_inspectors/http_inspect/http_msg_section.cc @@ -70,6 +70,12 @@ void HttpMsgSection::create_event(int sid) void HttpMsgSection::update_depth() const { + if ((session_data->detect_depth_remaining[source_id] <= 0) && + (session_data->detection_status[source_id] == DET_ON)) + { + session_data->detection_status[source_id] = DET_DEACTIVATING; + } + if ((session_data->file_depth_remaining[source_id] <= 0) && (session_data->detect_depth_remaining[source_id] <= 0)) { diff --git a/src/service_inspectors/http_inspect/http_stream_splitter_scan.cc b/src/service_inspectors/http_inspect/http_stream_splitter_scan.cc index 27042973d..e33c75378 100644 --- a/src/service_inspectors/http_inspect/http_stream_splitter_scan.cc +++ b/src/service_inspectors/http_inspect/http_stream_splitter_scan.cc @@ -128,6 +128,19 @@ StreamSplitter::Status HttpStreamSplitter::scan(Flow* flow, const uint8_t* data, HttpModule::increment_peg_counts(PEG_SCAN); + if (session_data->detection_status[source_id] == DET_REACTIVATING) + { + if (source_id == SRC_CLIENT) + { + flow->set_to_server_detection(true); + } + else + { + flow->set_to_client_detection(true); + } + session_data->detection_status[source_id] = DET_ON; + } + // Check for 0.9 response message if ((type == SEC_STATUS) && (session_data->expected_trans_num[SRC_SERVER] == session_data->zero_nine_expected))