From: Mike Stepanek (mstepane) Date: Tue, 23 Feb 2021 13:01:41 +0000 (+0000) Subject: Merge pull request #2756 in SNORT/snort3 from ~MDAGON/snort3:rst_frame to master X-Git-Tag: 3.1.2.0~33 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a8f16c89f6caed007650be15eae17dee596ca58;p=thirdparty%2Fsnort3.git Merge pull request #2756 in SNORT/snort3 from ~MDAGON/snort3:rst_frame to master Squashed commit of the following: commit 54dc3d9568f8cc05da2b84a6457f131bc589912f Author: mdagon Date: Fri Jan 22 15:18:07 2021 -0500 http2_inspect: process rst_stream frame --- diff --git a/src/service_inspectors/http2_inspect/CMakeLists.txt b/src/service_inspectors/http2_inspect/CMakeLists.txt index 732d6cc74..f8f7b3d60 100644 --- a/src/service_inspectors/http2_inspect/CMakeLists.txt +++ b/src/service_inspectors/http2_inspect/CMakeLists.txt @@ -40,6 +40,8 @@ set (FILE_LIST http2_push_promise_frame.h http2_request_line.cc http2_request_line.h + http2_rst_stream_frame.cc + http2_rst_stream_frame.h http2_settings_frame.cc http2_settings_frame.h http2_start_line.cc diff --git a/src/service_inspectors/http2_inspect/http2_enum.h b/src/service_inspectors/http2_inspect/http2_enum.h index d2c57bb64..0757095d4 100644 --- a/src/service_inspectors/http2_inspect/http2_enum.h +++ b/src/service_inspectors/http2_inspect/http2_enum.h @@ -82,6 +82,8 @@ enum EventSid EVENT_BAD_PUSH_SEQUENCE = 25, EVENT_BAD_SETTINGS_VALUE = 26, EVENT_TOO_MANY_STREAMS = 27, + EVENT_INVALID_RST_STREAM_FRAME = 28, + EVENT_BAD_RST_STREAM_SEQUENCE = 29, EVENT__MAX_VALUE }; @@ -132,6 +134,8 @@ enum Infraction INF_REQUEST_WITHOUT_METHOD = 40, INF_CONNECT_WITHOUT_AUTHORITY = 41, INF_TOO_MANY_STREAMS = 42, + INF_INVALID_RST_STREAM_FRAME = 43, + INF_BAD_RST_STREAM_SEQUENCE = 44, 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 49e63da53..4a2a39b42 100644 --- a/src/service_inspectors/http2_inspect/http2_flow_data.h +++ b/src/service_inspectors/http2_inspect/http2_flow_data.h @@ -75,6 +75,7 @@ public: friend class Http2Inspect; friend class Http2PushPromiseFrame; friend class Http2RequestLine; + friend class Http2RstStreamFrame; friend class Http2SettingsFrame; friend class Http2StartLine; friend class Http2StatusLine; diff --git a/src/service_inspectors/http2_inspect/http2_frame.cc b/src/service_inspectors/http2_inspect/http2_frame.cc index bbeed292b..03ce37605 100644 --- a/src/service_inspectors/http2_inspect/http2_frame.cc +++ b/src/service_inspectors/http2_inspect/http2_frame.cc @@ -30,6 +30,7 @@ #include "http2_headers_frame_trailer.h" #include "http2_ping_frame.h" #include "http2_push_promise_frame.h" +#include "http2_rst_stream_frame.h" #include "http2_settings_frame.h" #include "http2_stream.h" #include "service_inspectors/http_inspect/http_field.h" @@ -84,6 +85,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_RST_STREAM: + frame = new Http2RstStreamFrame(header, header_len, data, data_len, session_data, + source_id, stream); + break; default: frame = new Http2Frame(header, header_len, data, data_len, session_data, source_id, stream); diff --git a/src/service_inspectors/http2_inspect/http2_rst_stream_frame.cc b/src/service_inspectors/http2_inspect/http2_rst_stream_frame.cc new file mode 100644 index 000000000..abda97153 --- /dev/null +++ b/src/service_inspectors/http2_inspect/http2_rst_stream_frame.cc @@ -0,0 +1,69 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2021-2021 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_rst_stream_frame.cc author Maya Dagon + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "http2_rst_stream_frame.h" + +#include "service_inspectors/http_inspect/http_test_manager.h" + +#include "http2_enum.h" +#include "http2_flow_data.h" + +using namespace HttpCommon; +using namespace Http2Enums; + +Http2RstStreamFrame::Http2RstStreamFrame(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) or (data.length() != 4)) + { + session_data->events[source_id]->create_event(EVENT_INVALID_RST_STREAM_FRAME); + *session_data->infractions[source_id] += INF_INVALID_RST_STREAM_FRAME; + } +} + +bool Http2RstStreamFrame::valid_sequence(Http2Enums::StreamState) +{ + if (stream->get_state(SRC_CLIENT) == STREAM_EXPECT_HEADERS and + stream->get_state(SRC_SERVER) == STREAM_EXPECT_HEADERS) + { + session_data->events[source_id]->create_event(EVENT_BAD_RST_STREAM_SEQUENCE); + *session_data->infractions[source_id] += INF_BAD_RST_STREAM_SEQUENCE; + } + return true; +} + +void Http2RstStreamFrame::update_stream_state() +{ + if (stream->get_state(source_id) < STREAM_COMPLETE) + stream->set_state(source_id, STREAM_COMPLETE); +} + +#ifdef REG_TEST +void Http2RstStreamFrame::print_frame(FILE* output) +{ + fprintf(output, "rst_stream frame\n"); + Http2Frame::print_frame(output); +} +#endif diff --git a/src/service_inspectors/http2_inspect/http2_rst_stream_frame.h b/src/service_inspectors/http2_inspect/http2_rst_stream_frame.h new file mode 100644 index 000000000..42e6b092f --- /dev/null +++ b/src/service_inspectors/http2_inspect/http2_rst_stream_frame.h @@ -0,0 +1,46 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2021-2021 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_rst_stream_frame.h author Maya Dagon + +#ifndef HTTP2_RST_STREAM_FRAME_H +#define HTTP2_RST_STREAM_FRAME_H + +#include "http2_frame.h" + +class Http2Frame; + +class Http2RstStreamFrame : 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; } + bool valid_sequence(Http2Enums::StreamState state) override; + void update_stream_state() override; + +#ifdef REG_TEST + void print_frame(FILE* output) override; +#endif + +private: + Http2RstStreamFrame(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 diff --git a/src/service_inspectors/http2_inspect/http2_tables.cc b/src/service_inspectors/http2_inspect/http2_tables.cc index 8f7186b0a..1ab80e7ef 100644 --- a/src/service_inspectors/http2_inspect/http2_tables.cc +++ b/src/service_inspectors/http2_inspect/http2_tables.cc @@ -58,6 +58,8 @@ const RuleMap Http2Module::http2_events[] = { EVENT_BAD_PUSH_SEQUENCE, "HTTP/2 push promise frame sent at invalid time" }, { EVENT_BAD_SETTINGS_VALUE, "invalid parameter value sent in HTTP/2 settings frame" }, { EVENT_TOO_MANY_STREAMS, "excessive concurrent HTTP/2 streams" }, + { EVENT_INVALID_RST_STREAM_FRAME, "invalid HTTP/2 rst stream frame" }, + { EVENT_BAD_RST_STREAM_SEQUENCE, "HTTP/2 rst stream frame sent at invalid time" }, { 0, nullptr } };