]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2001 in SNORT/snort3 from ~KATHARVE/snort3:h2i_disable_detection...
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 18 Feb 2020 15:27:42 +0000 (15:27 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 18 Feb 2020 15:27:42 +0000 (15:27 +0000)
Squashed commit of the following:

commit 3f544dd8749a9ea7f25cdbafa29582b0396ade31
Author: Katura Harvey <katharve@cisco.com>
Date:   Fri Feb 7 13:32:24 2020 -0500

    http2_inspect: support disabling detection for uninteresting HTTP/2 frames

    http_inspect: when detection is disabled, disable all rules not just content rules

src/detection/detection_engine.cc
src/service_inspectors/http2_inspect/http2_dummy_packet.h [new file with mode: 0644]
src/service_inspectors/http2_inspect/http2_frame.h
src/service_inspectors/http2_inspect/http2_headers_frame.cc
src/service_inspectors/http2_inspect/http2_headers_frame.h
src/service_inspectors/http2_inspect/http2_inspect.cc
src/service_inspectors/http2_inspect/http2_settings_frame.h
src/service_inspectors/http2_inspect/http2_stream.h
src/service_inspectors/http_inspect/http_inspect.cc
src/service_inspectors/http_inspect/http_inspect.h

index 25d13c2f41d1edadf3bff30ca584961dc7a48d9f..18dd43897ae06a9f3ddedfebb1d9388d764fe55a 100644 (file)
@@ -324,7 +324,11 @@ void DetectionEngine::clear_replacement()
 }
 
 void DetectionEngine::disable_all(Packet* p)
-{ p->context->active_rules = IpsContext::NONE; }
+{
+    p->context->active_rules = IpsContext::NONE;
+    trace_logf(detection, TRACE_PKT_DETECTION,
+        "Disabled all detect, packet %" PRIu64"\n", p->context->packet_number);
+}
 
 bool DetectionEngine::all_disabled(Packet* p)
 { return p->context->active_rules == IpsContext::NONE; }
diff --git a/src/service_inspectors/http2_inspect/http2_dummy_packet.h b/src/service_inspectors/http2_inspect/http2_dummy_packet.h
new file mode 100644 (file)
index 0000000..1ab7e16
--- /dev/null
@@ -0,0 +1,43 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// http2_dummy_packet.h author Katura Harvey <katharve@cisco.com>
+
+/* 
+ * The purpose of this Packet subclass is to enable H2I to take direction from http_inspect on
+ * whether or not to send a frame to detection. When http_inspect is processing normal HTTP/1.1
+ * traffic it is dealing with a 'real' packet that has a context, the field on which disable_all()
+ * is called to disable detection on that packet. With HTTP/2 traffic, http_inspect is processing a
+ * dummy packet that H2I created, which does not contain a context object. Rather than create an
+ * entire new context object when we really only need a bool, http_inspect checks if the flow is
+ * HTTP/2 and sets a bool instead of calling it's usual disable_all(). H2I checks the bool and can
+ * then call disable_all() on the real packet.
+ */
+
+#ifndef HTTP2_DUMMY_PACKET_H
+#define HTTP2_DUMMY_PACKET_H
+
+#include "protocols/packet.h"
+
+class Http2DummyPacket : public snort::Packet
+{
+public:
+    Http2DummyPacket() : snort::Packet(false) { }
+    bool is_detection_required() { return !disable_inspect; }
+};
+
+#endif
index cd131e44ce90042c89917865686af568f2653f67..861f43e9651938fad7dbe8a9b2ac909be818b8f1 100644 (file)
@@ -43,6 +43,8 @@ public:
     virtual void clear() { }
     virtual const Field& get_buf(unsigned id);
     virtual uint32_t get_xtradata_mask() { return 0; }
+    virtual bool is_detection_required() const { return true; }
+
 #ifdef REG_TEST
     virtual void print_frame(FILE* output);
 #endif
index a771f3f77d2b39df1a75d308db088d0baf83b453..07ab5632b92bfe439cfafab194556df432e727c5 100644 (file)
@@ -28,6 +28,7 @@
 #include "service_inspectors/http_inspect/http_inspect.h"
 #include "service_inspectors/http_inspect/http_stream_splitter.h"
 
+#include "http2_dummy_packet.h"
 #include "http2_enum.h"
 #include "http2_flow_data.h"
 #include "http2_hpack.h"
@@ -79,7 +80,7 @@ Http2HeadersFrame::Http2HeadersFrame(const uint8_t* header_buffer, const int32_t
     session_data->stream_in_hi = session_data->current_stream[source_id];
     {
         uint32_t flush_offset;
-        Packet dummy_pkt(false);
+        Http2DummyPacket dummy_pkt;
         dummy_pkt.flow = session_data->flow;
         const uint32_t unused = 0;
         const StreamSplitter::Status start_scan_result =
@@ -103,7 +104,7 @@ Http2HeadersFrame::Http2HeadersFrame(const uint8_t* header_buffer, const int32_t
 
     // http_inspect eval() and clear() of start line
     {
-        Packet dummy_pkt(false);
+        Http2DummyPacket dummy_pkt;
         dummy_pkt.flow = session_data->flow;
         dummy_pkt.packet_flags = (source_id == SRC_CLIENT) ? PKT_FROM_CLIENT : PKT_FROM_SERVER;
         dummy_pkt.dsize = stream_buf.length;
@@ -115,7 +116,7 @@ Http2HeadersFrame::Http2HeadersFrame(const uint8_t* header_buffer, const int32_t
     // http_inspect scan() of headers
     {
         uint32_t flush_offset;
-        Packet dummy_pkt(false);
+        Http2DummyPacket dummy_pkt;
         dummy_pkt.flow = session_data->flow;
         const uint32_t unused = 0;
         const StreamSplitter::Status header_scan_result =
@@ -143,13 +144,14 @@ Http2HeadersFrame::Http2HeadersFrame(const uint8_t* header_buffer, const int32_t
 
     // http_inspect eval() of headers
     {
-        Packet dummy_pkt(false);
+        Http2DummyPacket dummy_pkt;
         dummy_pkt.flow = session_data->flow;
         dummy_pkt.packet_flags = (source_id == SRC_CLIENT) ? PKT_FROM_CLIENT : PKT_FROM_SERVER;
         dummy_pkt.dsize = stream_buf.length;
         dummy_pkt.data = stream_buf.data;
         dummy_pkt.xtradata_mask = 0;
         session_data->hi->eval(&dummy_pkt);
+        detection_required = dummy_pkt.is_detection_required();
         xtradata_mask = dummy_pkt.xtradata_mask;
     }
 }
index 9772b3aa64830e5a409cf43e09ca91a2730296ee..27722facc261175b4a2bc17f7bacf72e3ea3b5b8 100644 (file)
@@ -35,6 +35,7 @@ public:
 
     const Field& get_buf(unsigned id) override;
     uint32_t get_xtradata_mask() override { return xtradata_mask; }
+    bool is_detection_required() const override { return detection_required; }
 
     friend Http2Frame* Http2Frame::new_frame(const uint8_t*, const int32_t, const uint8_t*,
         const int32_t, Http2FlowData*, HttpCommon::SourceId);
@@ -56,5 +57,6 @@ private:
     bool error_during_decode = false;
     bool hi_abort = false;
     uint32_t xtradata_mask = 0;
+    bool detection_required = false;
 };
 #endif
index 836d7936510e54512e0e44d1f1f9802720cfce69..77de26ffdef80c274d0d4f8b37646326a7d6b2f2 100644 (file)
@@ -129,6 +129,8 @@ void Http2Inspect::eval(Packet* p)
         session_data->frame_header_size[source_id], session_data->frame_data[source_id],
         session_data->frame_data_size[source_id], source_id);
 
+    if (!stream->get_current_frame()->is_detection_required())
+        DetectionEngine::disable_all(p);
     p->xtradata_mask |= stream->get_xtradata_mask();
 
     // The current frame now owns these buffers, clear them from the flow data
index 00e194d69aaa676b6b408ff58b8459d0b56b0643..f788038194749eaba0ac2c084f2f4bb3f817b973 100644 (file)
@@ -31,6 +31,7 @@ class Http2SettingsFrame : public Http2Frame
 public:
     friend Http2Frame* Http2Frame::new_frame(const uint8_t*, const int32_t, const uint8_t*,
         const int32_t, Http2FlowData*, HttpCommon::SourceId);
+    bool is_detection_required() const override { return false; }
 
 #ifdef REG_TEST
     void print_frame(FILE* output) override;
index 777b2e2b3e680830a5c3466916d6aa17d8d2016b..a267335b37760e7dfa99ae9d939be24470acc6c7 100644 (file)
@@ -46,6 +46,7 @@ public:
     void set_hi_msg_section(HttpMsgSection* section) { hi_msg_section = section; }
     uint32_t get_xtradata_mask() { return (current_frame != nullptr) ? 
         current_frame->get_xtradata_mask() : 0; }
+    Http2Frame *get_current_frame() { return current_frame; }
 #ifdef REG_TEST
     void print_frame(FILE* output);
 #endif
index 7c555a7b0bbb801759f3361442ab97af1b11b8db..39f522d86c094dd39f5e975d92b6e84597f9bd2c 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "detection/detection_engine.h"
 #include "detection/detection_util.h"
+#include "service_inspectors/http2_inspect/http2_dummy_packet.h"
 #include "service_inspectors/http2_inspect/http2_flow_data.h"
 #include "log/unified2.h"
 #include "protocols/packet.h"
@@ -310,6 +311,18 @@ int HttpInspect::get_xtra_jsnorm(Flow* flow, uint8_t** buf, uint32_t* len, uint3
     return 1;
 }
 
+void HttpInspect::disable_detection(Packet* p)
+{
+    HttpFlowData* session_data = http_get_flow_data(p->flow);
+    if (session_data->for_http2)
+        p->disable_inspect = true;
+    else
+    {
+        assert(p->context);
+        DetectionEngine::disable_all(p);
+    }
+}
+
 HttpFlowData* HttpInspect::http_get_flow_data(const Flow* flow)
 {
     Http2FlowData* h2i_flow_data = nullptr;
@@ -363,10 +376,7 @@ void HttpInspect::eval(Packet* p)
 
     const bool buf_owner = !session_data->partial_flush[source_id];
     if (!process(p->data, p->dsize, p->flow, source_id, buf_owner))
-    {
-        if (!session_data->for_http2)
-            DetectionEngine::disable_content(p);
-    }
+        disable_detection(p);
 
 #ifdef REG_TEST
     else
index 40ebda7e0cf580c1f5eacaf1534349978a7b87ff..77b02480492024bb04b389b345810153ff215f80 100644 (file)
@@ -56,6 +56,7 @@ public:
     }
     static HttpEnums::InspectSection get_latest_is(const snort::Packet* p);
     static HttpCommon::SourceId get_latest_src(const snort::Packet* p);
+    void disable_detection(snort::Packet *p);
 
     // Callbacks that provide "extra data"
     static int get_xtra_trueip(snort::Flow*, uint8_t**, uint32_t*, uint32_t*);