From: Mike Stepanek (mstepane) Date: Tue, 3 Mar 2020 14:35:11 +0000 (+0000) Subject: Merge pull request #2035 in SNORT/snort3 from ~KATHARVE/snort3:h2i_pub_sub to master X-Git-Tag: 3.0.0-269~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2e510d56e91ba4a998293948342bb8dc68359b5;p=thirdparty%2Fsnort3.git Merge pull request #2035 in SNORT/snort3 from ~KATHARVE/snort3:h2i_pub_sub to master Squashed commit of the following: commit 07072478f6c3cd762193531d4bec7f62beb44b0f Author: Katura Harvey Date: Wed Feb 26 11:51:19 2020 -0500 pub_sub: add http2 info to http pub messages --- diff --git a/src/network_inspectors/appid/test/appid_http_event_test.cc b/src/network_inspectors/appid/test/appid_http_event_test.cc index c54f52184..02111b54a 100644 --- a/src/network_inspectors/appid/test/appid_http_event_test.cc +++ b/src/network_inspectors/appid/test/appid_http_event_test.cc @@ -206,7 +206,7 @@ TEST_GROUP(appid_http_event) TEST(appid_http_event, handle_null_appid_data) { - HttpEvent event(nullptr); + HttpEvent event(nullptr, false, 0); HttpEventHandler event_handler(HttpEventHandler::REQUEST_EVENT); mock().expectOneCall("get_appid_session"); event_handler.handle(event, flow); @@ -215,7 +215,7 @@ TEST(appid_http_event, handle_null_appid_data) TEST(appid_http_event, handle_null_msg_header) { - HttpEvent event(nullptr); + HttpEvent event(nullptr, false, 0); HttpEventHandler event_handler(HttpEventHandler::REQUEST_EVENT); mock().strictOrder(); @@ -246,7 +246,7 @@ struct TestData static void run_event_handler(TestData test_data, TestData* expect_data = nullptr) { - HttpEvent event(nullptr); + HttpEvent event(nullptr, false, 0); FakeHttpMsgHeader http_msg_header; HttpEventHandler event_handler(test_data.type); fake_msg_header = &http_msg_header; diff --git a/src/pub_sub/CMakeLists.txt b/src/pub_sub/CMakeLists.txt index 6e8dcc8db..fc79d7568 100644 --- a/src/pub_sub/CMakeLists.txt +++ b/src/pub_sub/CMakeLists.txt @@ -20,3 +20,5 @@ install (FILES ${PUB_SUB_INCLUDES} DESTINATION "${INCLUDE_INSTALL_PATH}/pub_sub" ) +add_subdirectory ( test ) + diff --git a/src/pub_sub/http_events.cc b/src/pub_sub/http_events.cc index 9aa8b2e6c..a54edfa34 100644 --- a/src/pub_sub/http_events.cc +++ b/src/pub_sub/http_events.cc @@ -117,3 +117,12 @@ bool HttpEvent::contains_webdav_method() return HttpMsgRequest::is_webdav(method); } +bool HttpEvent::get_is_http2() const +{ + return is_http2; +} + +uint32_t HttpEvent::get_http2_stream_id() const +{ + return http2_stream_id; +} diff --git a/src/pub_sub/http_events.h b/src/pub_sub/http_events.h index 1cbb965b5..7f6ecca62 100644 --- a/src/pub_sub/http_events.h +++ b/src/pub_sub/http_events.h @@ -36,10 +36,8 @@ namespace snort class SO_PUBLIC HttpEvent : public snort::DataEvent { public: - HttpEvent(HttpMsgHeader* http_msg_header_) : - http_msg_header(http_msg_header_) - { - } + HttpEvent(HttpMsgHeader* http_msg_header_, bool http2, uint32_t stream_id) : + http_msg_header(http_msg_header_), is_http2(http2), http2_stream_id(stream_id) { } const uint8_t* get_content_type(int32_t &length); @@ -54,9 +52,13 @@ public: const uint8_t* get_x_working_with(int32_t &length); int32_t get_response_code(); bool contains_webdav_method(); + bool get_is_http2() const; + uint32_t get_http2_stream_id() const; private: HttpMsgHeader* const http_msg_header; + bool is_http2 = false; + uint32_t http2_stream_id = 0; const uint8_t* get_header(unsigned, uint64_t, int32_t&); diff --git a/src/pub_sub/test/CMakeLists.txt b/src/pub_sub/test/CMakeLists.txt new file mode 100644 index 000000000..b7c36c969 --- /dev/null +++ b/src/pub_sub/test/CMakeLists.txt @@ -0,0 +1,4 @@ +add_cpputest( pub_sub_http_event_test + SOURCES + ../http_events.cc +) diff --git a/src/pub_sub/test/pub_sub_http_event_test.cc b/src/pub_sub/test/pub_sub_http_event_test.cc new file mode 100644 index 000000000..cca033e6e --- /dev/null +++ b/src/pub_sub/test/pub_sub_http_event_test.cc @@ -0,0 +1,68 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 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. +//-------------------------------------------------------------------------- +// pub_sub_http_event_test.cc author Katura Harvey + +// Unit test for the HttpEvent methods to retrieve HTTP/2 information + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pub_sub/http_events.h" +#include "service_inspectors/http_inspect/http_common.h" +#include "service_inspectors/http_inspect/http_msg_section.h" +#include "service_inspectors/http_inspect/http_field.h" + +#include +#include +#include + +using namespace snort; +using namespace HttpCommon; + +// Stubs to make the code link +const Field Field::FIELD_NULL { STAT_NO_SOURCE }; +const Field& HttpMsgSection::get_classic_buffer(unsigned int, unsigned long, unsigned long) + { return Field::FIELD_NULL; } + +TEST_GROUP(pub_sub_http_event_test) +{ +}; + + +TEST(pub_sub_http_event_test, http_traffic) +{ + uint32_t stream_id = 0; + HttpEvent event(nullptr, false, stream_id); + CHECK_FALSE(event.get_is_http2()); + CHECK(event.get_http2_stream_id() == stream_id); +} + +TEST(pub_sub_http_event_test, http2_traffic) +{ + uint32_t stream_id = 3; + HttpEvent event(nullptr, true, stream_id); + CHECK(event.get_is_http2()); + CHECK(event.get_http2_stream_id() == stream_id); +} + +int main(int argc, char** argv) +{ + return CommandLineTestRunner::RunAllTests(argc, argv); +} + diff --git a/src/service_inspectors/http2_inspect/http2_flow_data.cc b/src/service_inspectors/http2_inspect/http2_flow_data.cc index 5075fe530..51d5e362e 100644 --- a/src/service_inspectors/http2_inspect/http2_flow_data.cc +++ b/src/service_inspectors/http2_inspect/http2_flow_data.cc @@ -151,3 +151,8 @@ class Http2Stream* Http2FlowData::get_current_stream(const HttpCommon::SourceId return get_stream(current_stream[source_id]); } +uint32_t Http2FlowData::get_current_stream_id(const HttpCommon::SourceId source_id) +{ + return current_stream[source_id]; +} + diff --git a/src/service_inspectors/http2_inspect/http2_flow_data.h b/src/service_inspectors/http2_inspect/http2_flow_data.h index 93e6cd7f3..51891d6cd 100644 --- a/src/service_inspectors/http2_inspect/http2_flow_data.h +++ b/src/service_inspectors/http2_inspect/http2_flow_data.h @@ -90,6 +90,7 @@ public: ~StreamInfo() { delete stream; } }; class Http2Stream* get_current_stream(const HttpCommon::SourceId source_id); + uint32_t get_current_stream_id(const HttpCommon::SourceId source_id); Http2HpackDecoder* get_hpack_decoder(const HttpCommon::SourceId source_id) { return &hpack_decoder[source_id]; } diff --git a/src/service_inspectors/http_inspect/http_msg_header.cc b/src/service_inspectors/http_inspect/http_msg_header.cc index 4e084c652..c8be9fa29 100644 --- a/src/service_inspectors/http_inspect/http_msg_header.cc +++ b/src/service_inspectors/http_inspect/http_msg_header.cc @@ -32,6 +32,7 @@ #include "http_msg_request.h" #include "http_msg_body.h" #include "pub_sub/http_events.h" +#include "service_inspectors/http2_inspect/http2_flow_data.h" #include "sfip/sf_ip.h" using namespace snort; @@ -49,7 +50,15 @@ HttpMsgHeader::HttpMsgHeader(const uint8_t* buffer, const uint16_t buf_size, void HttpMsgHeader::publish() { - HttpEvent http_event(this); + uint32_t stream_id = 0; + if (session_data->for_http2) + { + Http2FlowData* h2i_flow_data = (Http2FlowData*)flow->get_flow_data(Http2FlowData::inspector_id); + assert(h2i_flow_data); + stream_id = h2i_flow_data->get_current_stream_id(source_id); + } + + HttpEvent http_event(this, session_data->for_http2, stream_id); const char* key = (source_id == SRC_CLIENT) ? HTTP_REQUEST_HEADER_EVENT_KEY : HTTP_RESPONSE_HEADER_EVENT_KEY;