]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2571 in SNORT/snort3 from ~MDAGON/snort3:react2 to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Mon, 26 Oct 2020 15:45:07 +0000 (15:45 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Mon, 26 Oct 2020 15:45:07 +0000 (15:45 +0000)
Squashed commit of the following:

commit 83f8deb2a7dd18a555f348ae36cf4ee81da612fe
Author: mdagon <mdagon@cisco.com>
Date:   Mon Sep 28 14:15:25 2020 -0400

    actions: react supports HTTP/2

src/actions/act_react.cc
src/payload_injector/payload_injector_module.cc
src/payload_injector/payload_injector_module.h
src/payload_injector/test/payload_injector_test.cc
src/service_inspectors/http2_inspect/http2_flow_data.h

index 98f6f85132e41782c4202df5211b60774ffadbcd..dbc05ebd5b7392585b66ad28eb26646df59f5566 100644 (file)
 #include "payload_injector/payload_injector_module.h"
 #include "profiler/profiler.h"
 #include "protocols/packet.h"
+#include "service_inspectors/http2_inspect/http2_flow_data.h"
 #include "utils/util.h"
 #include "utils/util_cstring.h"
 
 using namespace snort;
+using namespace HttpCommon;
+using namespace Http2Enums;
 
 #define s_name "react"
 
@@ -100,7 +103,7 @@ public:
     {
         if ( page.empty())
         {
-            resp_buf = DEFAULT_HTTP + std::to_string(sizeof(DEFAULT_HTML));
+            resp_buf = DEFAULT_HTTP + std::to_string(strlen(DEFAULT_HTML));
             resp_buf.append("\r\n\r\n");
             resp_buf.append(DEFAULT_HTML);
         }
@@ -148,6 +151,19 @@ private:
         InjectionControl control;
         control.http_page = (const uint8_t*)config->get_resp_buf();
         control.http_page_len = config->get_buf_len();
+        if (p->flow && p->flow->gadget &&
+            (strcmp(p->flow->gadget->get_name(), "http2_inspect") == 0))
+        {
+            Http2FlowData* const session_data =
+                (Http2FlowData*)p->flow->get_flow_data(Http2FlowData::inspector_id);
+            assert(session_data != nullptr);
+            const SourceId source_id = p->is_from_client() ? SRC_CLIENT : SRC_SERVER;
+            if (session_data != nullptr)
+            {
+                control.stream_id = session_data->get_current_stream_id(source_id);
+                assert(control.stream_id != NO_STREAM_ID);
+            }
+        }
         InjectionReturnStatus status = PayloadInjectorModule::inject_http_payload(p, control);
 #ifdef DEBUG_MSGS
         if (status != INJECTION_SUCCESS)
index 5df57a9b0f8003bd6781dac86c8d3e07232d1768..b33a69075280259820bd1c25fc437c67b068752d 100644 (file)
@@ -60,7 +60,8 @@ static const std::map <InjectionReturnStatus, const char*> InjectionErrorToStrin
     { ERR_TRANSLATED_HDRS_SIZE,
       "HTTP/2 translated header size is bigger than expected. Update max size." },
     { ERR_HTTP2_BODY_SIZE, "HTTP/2 body is > 16k. Currently not supported." },
-    { ERR_HTTP2_EVEN_STREAM_ID, "HTTP/2 - injection to server initiated stream" }
+    { ERR_HTTP2_EVEN_STREAM_ID, "HTTP/2 - injection to server initiated stream" },
+    { ERR_PKT_FROM_SERVER, "Packet is from server" }
 };
 
 bool PayloadInjectorModule::configured = false;
@@ -135,25 +136,30 @@ InjectionReturnStatus PayloadInjectorModule::inject_http_payload(Packet* p,
 
     if (configured)
     {
-        EncodeFlags df = (p->packet_flags & PKT_FROM_SERVER) ? ENC_FLAG_FWD : 0;
-        df |= ENC_FLAG_RST_SRVR; // Send RST to server.
-
-        if (p->packet_flags & PKT_STREAM_EST)
+        if (p->packet_flags & PKT_FROM_SERVER)
+            status =  ERR_PKT_FROM_SERVER;
+        else
         {
-            if (!p->flow)
-                status = ERR_UNIDENTIFIED_PROTOCOL;
-            else if (!p->flow->gadget || strcmp(p->flow->gadget->get_name(),"http_inspect") == 0)
+            EncodeFlags df = ENC_FLAG_RST_SRVR; // Send RST to server.
+
+            if (p->packet_flags & PKT_STREAM_EST)
             {
-                payload_injector_stats.http_injects++;
-                p->active->send_data(p, df, control.http_page, control.http_page_len);
+                if (!p->flow)
+                    status = ERR_UNIDENTIFIED_PROTOCOL;
+                else if (!p->flow->gadget || strcmp(p->flow->gadget->get_name(),"http_inspect") ==
+                    0)
+                {
+                    payload_injector_stats.http_injects++;
+                    p->active->send_data(p, df, control.http_page, control.http_page_len);
+                }
+                else if (strcmp(p->flow->gadget->get_name(),"http2_inspect") == 0)
+                    status = inject_http2_payload(p, control, df);
+                else
+                    status = ERR_UNIDENTIFIED_PROTOCOL;
             }
-            else if (strcmp(p->flow->gadget->get_name(),"http2_inspect") == 0)
-                status = inject_http2_payload(p, control, df);
             else
-                status = ERR_UNIDENTIFIED_PROTOCOL;
+                status = ERR_STREAM_NOT_ESTABLISHED;
         }
-        else
-            status = ERR_STREAM_NOT_ESTABLISHED;
     }
     else
         status = ERR_INJECTOR_NOT_CONFIGURED;
index 069ff2d0471c27540a16873f9cb31098338abf1c..466319213940a0023f9063e065e93a9554e560bf 100644 (file)
@@ -50,7 +50,8 @@ enum InjectionReturnStatus : int8_t
     ERR_HTTP2_MID_FRAME = -6,
     ERR_TRANSLATED_HDRS_SIZE = -7,
     ERR_HTTP2_BODY_SIZE = -8,
-    ERR_HTTP2_EVEN_STREAM_ID = -9
+    ERR_HTTP2_EVEN_STREAM_ID = -9,
+    ERR_PKT_FROM_SERVER = -10,  
     // Update InjectionErrorToString when adding/removing error codes
 };
 
index 322399aaa0e03af21fdc61d130a4ba91bb84735a..12a8abebe326f95b88d55d03f4bfc96543e85bbe 100644 (file)
@@ -318,6 +318,19 @@ TEST(payload_injector_test, http2_continuation_expected)
     delete flow.gadget;
 }
 
+TEST(payload_injector_test, http2_pkt_from_srvr)
+{
+    mod.set_configured(true);
+    Packet p(false);
+    p.packet_flags = PKT_FROM_SERVER;
+    flow.gadget = new MockInspector();
+    p.flow = &flow;
+    InjectionReturnStatus status = mod.inject_http_payload(&p, control);
+    CHECK(status == ERR_PKT_FROM_SERVER);
+    CHECK(flow.flow_state == Flow::FlowState::BLOCK);
+    delete flow.gadget;
+}
+
 TEST_GROUP(payload_injector_translate_err_test)
 {
     PayloadInjectorModule mod;
index b38e354d1ebd9f5bc39a3fbc37e47fa13f01fcce..a8c75daca3565443a9bebc96883829a5a496ba4d 100644 (file)
@@ -47,7 +47,7 @@ class HttpMsgSection;
 class HttpInspect;
 class HttpStreamSplitter;
 
-class Http2FlowData : public snort::FlowData
+class SO_PUBLIC Http2FlowData : public snort::FlowData
 {
 public:
     Http2FlowData(snort::Flow* flow_);