From: Tom Peters (thopeter) Date: Fri, 22 Jul 2022 19:55:27 +0000 (+0000) Subject: Pull request #3516: http2_inspect: add support for PRIORITY frames X-Git-Tag: 3.1.38.0~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=552029b9b4b9fbb34055c437fbbabcb6f3867953;p=thirdparty%2Fsnort3.git Pull request #3516: http2_inspect: add support for PRIORITY frames Merge in SNORT/snort3 from ~ADMAMOLE/snort3:priority_frames to master Squashed commit of the following: commit fb64edf07d7b0506cc32513b58612eb8cc57adb1 Author: Adrian Mamolea Date: Mon Jul 11 12:20:07 2022 -0400 http2_inspect: add support for PRIORITY frames --- diff --git a/doc/reference/builtin_stubs.txt b/doc/reference/builtin_stubs.txt index e269124b8..4b6fda14b 100644 --- a/doc/reference/builtin_stubs.txt +++ b/doc/reference/builtin_stubs.txt @@ -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 diff --git a/src/service_inspectors/http2_inspect/dev_notes.txt b/src/service_inspectors/http2_inspect/dev_notes.txt index 37e042eb7..1b3af79d2 100644 --- a/src/service_inspectors/http2_inspect/dev_notes.txt +++ b/src/service_inspectors/http2_inspect/dev_notes.txt @@ -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 diff --git a/src/service_inspectors/http2_inspect/http2_enum.h b/src/service_inspectors/http2_inspect/http2_enum.h index 1f36c9a2e..ec2df0cc3 100644 --- a/src/service_inspectors/http2_inspect/http2_enum.h +++ b/src/service_inspectors/http2_inspect/http2_enum.h @@ -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 }; diff --git a/src/service_inspectors/http2_inspect/http2_flow_data.h b/src/service_inspectors/http2_inspect/http2_flow_data.h index 5ffcedaed..4e1442047 100644 --- a/src/service_inspectors/http2_inspect/http2_flow_data.h +++ b/src/service_inspectors/http2_inspect/http2_flow_data.h @@ -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; diff --git a/src/service_inspectors/http2_inspect/http2_frame.cc b/src/service_inspectors/http2_inspect/http2_frame.cc index 1905e68d9..3be6f7be0 100644 --- a/src/service_inspectors/http2_inspect/http2_frame.cc +++ b/src/service_inspectors/http2_inspect/http2_frame.cc @@ -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); diff --git a/src/service_inspectors/http2_inspect/http2_ping_frame.h b/src/service_inspectors/http2_inspect/http2_ping_frame.h index e3a228f77..5616257ec 100644 --- a/src/service_inspectors/http2_inspect/http2_ping_frame.h +++ b/src/service_inspectors/http2_inspect/http2_ping_frame.h @@ -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 index 000000000..64da97080 --- /dev/null +++ b/src/service_inspectors/http2_inspect/http2_priority_frame.h @@ -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 + +#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 + diff --git a/src/service_inspectors/http2_inspect/http2_tables.cc b/src/service_inspectors/http2_inspect/http2_tables.cc index f4e3caca4..500f46779 100644 --- a/src/service_inspectors/http2_inspect/http2_tables.cc +++ b/src/service_inspectors/http2_inspect/http2_tables.cc @@ -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 } };