]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1102 in SNORT/snort3 from nhi_perf to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 30 Jan 2018 01:46:12 +0000 (20:46 -0500)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 30 Jan 2018 01:46:12 +0000 (20:46 -0500)
Squashed commit of the following:

commit fb74224d1fa1541ca576104bca12e43ffe3976fa
Author: Tom Peters <thopeter@cisco.com>
Date:   Mon Jan 29 15:57:50 2018 -0500

    http_inspect: suppress raw packet inspection beyond request/response depth

    flow: support episodic detection

src/detection/fp_detect.cc
src/flow/flow.h
src/service_inspectors/http_inspect/http_enum.h
src/service_inspectors/http_inspect/http_flow_data.cc
src/service_inspectors/http_inspect/http_flow_data.h
src/service_inspectors/http_inspect/http_inspect.cc
src/service_inspectors/http_inspect/http_msg_section.cc
src/service_inspectors/http_inspect/http_stream_splitter_scan.cc

index 7be9a84f506831ca96ab2c014cb7ac26ceab6ab4..6882f931bbabab132ed12eb0d441af6f4696a545 100644 (file)
@@ -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;
index a819281be7755e7a47b3784f6543a7d1e633527e..da719ff8259673ddd7430dd1564aed6258324909 100644 (file)
@@ -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
 
index 2256e6017882836c2122381f7588edcb88637191..afb2f20eb6f9588509c162ca6b7f2a62aa521abe 100644 (file)
@@ -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,
index 71d7eb2246e20ae06fdb20cf7a9e3c11db680ed5..08fd261c18cdccaa87bcc10e6aa361ea6ba98059 100644 (file)
@@ -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)
index baeb28c597d31c8fe0ab7c731d666cb544363567..0586889cdd64f67fe11eb7f2be2a74ede176c753 100644 (file)
@@ -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 };
index 291db45e718e6a23cccb39866bca3568b59d758b..fe252baebf8540d225533e7f4727f5b955de1973 100644 (file)
@@ -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;
 
index 89eb3bcad3842f419d654bb4038b543173fcadc7..5eb8b6861f3f9a6d1cc1b82fb7258d48fdc71e3c 100644 (file)
@@ -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))
     {
index 27042973dff695957438a446bf655839afe2ff88..e33c753785539196b901b7b9f063584f8abb3851 100644 (file)
@@ -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))