]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
http2_inspect: add support for GOAWAY frames
authorAdrian Mamolea <admamole@cisco.com>
Tue, 19 Jul 2022 18:34:22 +0000 (14:34 -0400)
committerTom Peters (thopeter) <thopeter@cisco.com>
Tue, 26 Jul 2022 20:59:43 +0000 (20:59 +0000)
doc/reference/builtin_stubs.txt
src/service_inspectors/http2_inspect/CMakeLists.txt
src/service_inspectors/http2_inspect/dev_notes.txt
src/service_inspectors/http2_inspect/http2_enum.h
src/service_inspectors/http2_inspect/http2_flow_data.h
src/service_inspectors/http2_inspect/http2_frame.cc
src/service_inspectors/http2_inspect/http2_goaway_frame.cc [new file with mode: 0644]
src/service_inspectors/http2_inspect/http2_goaway_frame.h [new file with mode: 0644]
src/service_inspectors/http2_inspect/http2_tables.cc

index 4b6fda14baeb731e70f12ed34cf1232ec0ff25c5..52eec8bcff6b1948b72a2b1efd815d09d66425df 100644 (file)
@@ -1501,6 +1501,10 @@ direction of the flow. The opposite direction may be OK.
 
 Invalid HTTP/2 PRIORITY frame. Stream ID is 0 or length is not 5.
 
+121:41
+
+Invalid HTTP/2 GOAWAY frame. R bit is set or stream ID is not 0 or length is less than 8.
+
 122:1
 
 Basic one host to one host TCP portscan where multiple TCP ports are scanned on
index 5327ca0e05443334207e7783f3541ac6e261ffef..bb05cf9d5399e1c359f760ce2950f44913ad390e 100644 (file)
@@ -11,6 +11,8 @@ set (FILE_LIST
     http2_flow_data.h
     http2_frame.cc
     http2_frame.h
+    http2_goaway_frame.cc
+    http2_goaway_frame.h
     http2_headers_frame.cc
     http2_headers_frame.h
     http2_headers_frame_header.cc
@@ -38,6 +40,7 @@ set (FILE_LIST
     http2_module.cc
     http2_module.h
     http2_ping_frame.h
+    http2_priority_frame.h
     http2_push_promise_frame.cc
     http2_push_promise_frame.h
     http2_request_line.cc
index 1b3af79d2414020bcf1b89b9f447704fa2b8966c..6362509e0bc2b3fe7f3709b4118e5f2cefbd353b 100644 (file)
@@ -22,6 +22,7 @@ HTTP/2 frames are stored in frame objects for processing.
 9. Http2RstStreamFrame : Http2Frame
 10. Http2WindowUpdateFrame: Http2Frame
 11. Http2PriorityFrame: Http2Frame
+12. Http2GoAwayFrame: Http2Frame
 
 Http2Frame virtual methods:
 1. bool valid_sequence(Http2Enums::StreamState state) - Returns if the current frame has been sent
index ec2df0cc3543f7f5bf2dc41667f9e26231a50d7d..edaa4bd8e0ccfe03b425fa2ff8e11783ad88dda9 100644 (file)
@@ -96,6 +96,7 @@ enum EventSid
     EVENT_NON_DATA_FRAME_TOO_LONG = 38,
     EVENT_LOSS_OF_SYNC = 39,
     EVENT_INVALID_PRIORITY_FRAME = 40,
+    EVENT_INVALID_GOAWAY_FRAME = 41,
     EVENT__MAX_VALUE
 };
 
@@ -155,6 +156,9 @@ enum Infraction
     INF_NON_DATA_FRAME_TOO_LONG = 49,
     INF_BAD_PRIORITY_FRAME_STREAM_ID = 50,
     INF_BAD_PRIORITY_FRAME_LENGTH = 51,
+    INF_BAD_GOAWAY_FRAME_STREAM_ID = 52,
+    INF_BAD_GOAWAY_FRAME_LENGTH = 53,
+    INF_BAD_GOAWAY_FRAME_R_BIT = 54,
     INF__MAX_VALUE
 };
 
index 4e1442047c80a04860ea909374f1f2f711e89ac5..63b84b6796d3df9552c04949d583c8f57aa7a47b 100644 (file)
@@ -67,6 +67,7 @@ public:
     friend class Http2Frame;
     friend class Http2DataFrame;
     friend class Http2DataCutter;
+    friend class Http2GoAwayFrame;
     friend class Http2HeadersFrame;
     friend class Http2HeadersFrameHeader;
     friend class Http2HeadersFrameTrailer;
index 3be6f7be0596f41d0af2bd85e45cd951df817b7b..3cfae512c666d8873edb51740da35c1177ad8a8c 100644 (file)
@@ -26,6 +26,7 @@
 #include "http2_data_frame.h"
 #include "http2_enum.h"
 #include "http2_flow_data.h"
+#include "http2_goaway_frame.h"
 #include "http2_headers_frame_header.h"
 #include "http2_headers_frame_trailer.h"
 #include "http2_ping_frame.h"
@@ -90,6 +91,10 @@ Http2Frame* Http2Frame::new_frame(const uint8_t* header, const uint32_t header_l
             frame = new Http2PingFrame(header, header_len, data, data_len, session_data,
                 source_id, stream);
             break;
+        case FT_GOAWAY:
+            frame = new Http2GoAwayFrame(header, header_len, data, data_len, session_data,
+                source_id, stream);
+            break;
         case FT_RST_STREAM:
             frame = new Http2RstStreamFrame(header, header_len, data, data_len, session_data,
                 source_id, stream);
diff --git a/src/service_inspectors/http2_inspect/http2_goaway_frame.cc b/src/service_inspectors/http2_inspect/http2_goaway_frame.cc
new file mode 100644 (file)
index 0000000..48afe2c
--- /dev/null
@@ -0,0 +1,52 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2022-2022 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_goaway_frame.cc author Adrian Mamolea <admamole@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "http2_goaway_frame.h"
+
+#include "http2_enum.h"
+#include "http2_frame.h"
+
+using namespace Http2Enums;
+
+Http2GoAwayFrame::Http2GoAwayFrame(const uint8_t* header_buffer, const uint32_t header_len,
+    const uint8_t* data_buffer, const uint32_t data_len, Http2FlowData* ssn_data,
+    HttpCommon::SourceId src_id, Http2Stream* _stream) :
+    Http2Frame(header_buffer, header_len, data_buffer, data_len, ssn_data, src_id, _stream)
+{
+    if (get_stream_id() != 0)
+    {
+        session_data->events[source_id]->create_event(EVENT_INVALID_GOAWAY_FRAME);
+        *session_data->infractions[source_id] += INF_BAD_GOAWAY_FRAME_STREAM_ID;
+    }
+    if (data.length() < 8)
+    {
+        session_data->events[source_id]->create_event(EVENT_INVALID_GOAWAY_FRAME);
+        *session_data->infractions[source_id] += INF_BAD_GOAWAY_FRAME_LENGTH;
+    }
+    else if (data.start()[0] & 0x80)
+    {
+        session_data->events[source_id]->create_event(EVENT_INVALID_GOAWAY_FRAME);
+        *session_data->infractions[source_id] += INF_BAD_GOAWAY_FRAME_R_BIT;
+    }
+}
+
diff --git a/src/service_inspectors/http2_inspect/http2_goaway_frame.h b/src/service_inspectors/http2_inspect/http2_goaway_frame.h
new file mode 100644 (file)
index 0000000..dcbc32f
--- /dev/null
@@ -0,0 +1,40 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2022-2022 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_goaway_frame.h author Adrian Mamolea <admamole@cisco.com>
+
+#ifndef HTTP2_GOAWAY_FRAME_H
+#define HTTP2_GOAWAY_FRAME_H
+
+#include "http2_flow_data.h"
+
+class Http2Frame;
+
+class Http2GoAwayFrame : public Http2Frame
+{
+public:
+    friend Http2Frame* Http2Frame::new_frame(const uint8_t*, const uint32_t, const uint8_t*,
+        const uint32_t, Http2FlowData*, HttpCommon::SourceId, Http2Stream* stream);
+    bool is_detection_required() const override { return false; }
+
+private:
+    Http2GoAwayFrame(const uint8_t* header_buffer, const uint32_t header_len,
+        const uint8_t* data_buffer, const uint32_t data_len, Http2FlowData* ssn_data,
+        HttpCommon::SourceId src_id, Http2Stream* _stream);
+};
+#endif
+
index 500f46779ed9dec8078798d1c30df44178d8e7c5..1c91b9b4688b61acadd7e4c3b8a6fdf5c190f5b9 100644 (file)
@@ -74,6 +74,7 @@ const RuleMap Http2Module::http2_events[] =
     { EVENT_NON_DATA_FRAME_TOO_LONG, "HTTP/2 non-Data frame longer than 63780 bytes" },
     { EVENT_LOSS_OF_SYNC,  "not HTTP/2 traffic or unrecoverable HTTP/2 protocol error" },
     { EVENT_INVALID_PRIORITY_FRAME, "invalid HTTP/2 PRIORITY frame" },
+    { EVENT_INVALID_GOAWAY_FRAME, "invalid HTTP/2 GOAWAY frame" },
     { 0, nullptr }
 };