]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3516: http2_inspect: add support for PRIORITY frames
authorTom Peters (thopeter) <thopeter@cisco.com>
Fri, 22 Jul 2022 19:55:27 +0000 (19:55 +0000)
committerTom Peters (thopeter) <thopeter@cisco.com>
Fri, 22 Jul 2022 19:55:27 +0000 (19:55 +0000)
Merge in SNORT/snort3 from ~ADMAMOLE/snort3:priority_frames to master

Squashed commit of the following:

commit fb64edf07d7b0506cc32513b58612eb8cc57adb1
Author: Adrian Mamolea <admamole@cisco.com>
Date:   Mon Jul 11 12:20:07 2022 -0400

    http2_inspect: add support for PRIORITY frames

doc/reference/builtin_stubs.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_ping_frame.h
src/service_inspectors/http2_inspect/http2_priority_frame.h [new file with mode: 0644]
src/service_inspectors/http2_inspect/http2_tables.cc

index e269124b8da57da988b96a85b27f31fe88a4e9fc..4b6fda14baeb731e70f12ed34cf1232ec0ff25c5 100644 (file)
@@ -1497,6 +1497,10 @@ HTTP/2 inspector is unable to parse this flow. Either the connection is not actu
 some sort of unrecoverable HTTP/2 protocol error has occurred. This conclusion applies only to one
 direction of the flow. The opposite direction may be OK.
 
+121:40
+
+Invalid HTTP/2 PRIORITY frame. Stream ID is 0 or length is not 5.
+
 122:1
 
 Basic one host to one host TCP portscan where multiple TCP ports are scanned on
index 37e042eb7b758b7e07e227451ab772562c3ab189..1b3af79d2414020bcf1b89b9f447704fa2b8966c 100644 (file)
@@ -21,6 +21,7 @@ HTTP/2 frames are stored in frame objects for processing.
 8. Http2SettingsFrame : Http2Frame
 9. Http2RstStreamFrame : Http2Frame
 10. Http2WindowUpdateFrame: Http2Frame
+11. Http2PriorityFrame: Http2Frame
 
 Http2Frame virtual methods:
 1. bool valid_sequence(Http2Enums::StreamState state) - Returns if the current frame has been sent
index 1f36c9a2e396112551e56f4c359d45df11986d83..ec2df0cc3543f7f5bf2dc41667f9e26231a50d7d 100644 (file)
@@ -95,6 +95,7 @@ enum EventSid
     EVENT_UNEXPECTED_DATA_FRAME = 37,
     EVENT_NON_DATA_FRAME_TOO_LONG = 38,
     EVENT_LOSS_OF_SYNC = 39,
+    EVENT_INVALID_PRIORITY_FRAME = 40,
     EVENT__MAX_VALUE
 };
 
@@ -152,6 +153,8 @@ enum Infraction
     INF_WINDOW_UPDATE_FRAME_ZERO_INCREMENT = 47,
     INF_UNEXPECTED_DATA_FRAME = 48,
     INF_NON_DATA_FRAME_TOO_LONG = 49,
+    INF_BAD_PRIORITY_FRAME_STREAM_ID = 50,
+    INF_BAD_PRIORITY_FRAME_LENGTH = 51,
     INF__MAX_VALUE
 };
 
index 5ffcedaed10fdddfdc5ac2b46a6774c53e5a2eca..4e1442047c80a04860ea909374f1f2f711e89ac5 100644 (file)
@@ -73,6 +73,7 @@ public:
     friend class Http2HeadersFrameWithStartline;
     friend class Http2Hpack;
     friend class Http2Inspect;
+    friend class Http2PriorityFrame;
     friend class Http2PushPromiseFrame;
     friend class Http2RequestLine;
     friend class Http2RstStreamFrame;
index 1905e68d956b01b5c895b9ff7a05ac2a524edce1..3be6f7be0596f41d0af2bd85e45cd951df817b7b 100644 (file)
@@ -29,6 +29,7 @@
 #include "http2_headers_frame_header.h"
 #include "http2_headers_frame_trailer.h"
 #include "http2_ping_frame.h"
+#include "http2_priority_frame.h"
 #include "http2_push_promise_frame.h"
 #include "http2_rst_stream_frame.h"
 #include "http2_settings_frame.h"
@@ -59,7 +60,6 @@ Http2Frame* Http2Frame::new_frame(const uint8_t* header, const uint32_t header_l
 {
     Http2Frame* frame = nullptr;
 
-    // FIXIT-E call the appropriate frame subclass constructor based on the type
     switch(session_data->frame_type[source_id])
     {
         case FT_HEADERS:
@@ -70,6 +70,10 @@ Http2Frame* Http2Frame::new_frame(const uint8_t* header, const uint32_t header_l
                 frame = new Http2HeadersFrameTrailer(header, header_len, data, data_len,
                     session_data, source_id, stream);
             break;
+        case FT_PRIORITY:
+            frame = new Http2PriorityFrame(header, header_len, data, data_len, session_data,
+                source_id, stream);
+            break;
         case FT_SETTINGS:
             frame = new Http2SettingsFrame(header, header_len, data, data_len, session_data,
                 source_id, stream);
index e3a228f77d9b615c368281beebaa93d477bc6103..5616257ec7758c84ece5a68cccf4702bc89a7ee5 100644 (file)
@@ -30,6 +30,7 @@ class Http2PingFrame : 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:
     Http2PingFrame(const uint8_t* header_buffer, const uint32_t header_len,
diff --git a/src/service_inspectors/http2_inspect/http2_priority_frame.h b/src/service_inspectors/http2_inspect/http2_priority_frame.h
new file mode 100644 (file)
index 0000000..64da970
--- /dev/null
@@ -0,0 +1,53 @@
+//--------------------------------------------------------------------------
+// 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_priority_frame.h author Adrian Mamolea <admamole@cisco.com>
+
+#ifndef HTTP2_PRIORITY_FRAME_H
+#define HTTP2_PRIORITY_FRAME_H
+
+#include "http2_enum.h"
+#include "http2_flow_data.h"
+#include "http2_frame.h"
+
+class Http2PriorityFrame : 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:
+    Http2PriorityFrame(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->infractions[source_id] += Http2Enums::INF_BAD_PRIORITY_FRAME_STREAM_ID;
+            session_data->events[source_id]->create_event(Http2Enums::EVENT_INVALID_PRIORITY_FRAME);
+        }
+        if (data.length() != 5)
+        {
+            *session_data->infractions[source_id] += Http2Enums::INF_BAD_PRIORITY_FRAME_LENGTH;
+            session_data->events[source_id]->create_event(Http2Enums::EVENT_INVALID_PRIORITY_FRAME);
+        }
+    }
+};
+#endif
+
index f4e3caca474cb6cae0f35f0c5d14678d22346ff1..500f46779ed9dec8078798d1c30df44178d8e7c5 100644 (file)
@@ -73,6 +73,7 @@ const RuleMap Http2Module::http2_events[] =
     { EVENT_UNEXPECTED_DATA_FRAME, "Nonempty HTTP/2 Data frame where message body not expected" },
     { 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" },
     { 0, nullptr }
 };