From: Shijin Bose (shibose) Date: Fri, 22 Sep 2023 09:08:33 +0000 (+0000) Subject: Pull request #3995: appid, http_inspect, http2_inspect: create appid session if not... X-Git-Tag: 3.1.71.0~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d76ef4d85f73dbfdf8c1c97b1acc843bf77d2227;p=thirdparty%2Fsnort3.git Pull request #3995: appid, http_inspect, http2_inspect: create appid session if not present in decrypt event handler, add message section as part of StreamFlowIntf for httpx Merge in SNORT/snort3 from ~SHIBOSE/snort3:ac_rule_match to master Squashed commit of the following: commit df546681b874d2c88e6d1af67c1bccdb9d6d28e5 Author: shibose Date: Wed Sep 6 17:44:39 2023 +0000 appid, http_inspect, http2_inspect: create appid session if not present in decrypt event handler, add message section as part of StreamFlowIntf for httpx --- diff --git a/src/flow/flow.h b/src/flow/flow.h index 836e04024..96abf805d 100644 --- a/src/flow/flow.h +++ b/src/flow/flow.h @@ -164,6 +164,8 @@ public: virtual FlowData* get_stream_flow_data(const Flow* flow) = 0; virtual void set_stream_flow_data(Flow* flow, FlowData* flow_data) = 0; virtual void get_stream_id(const Flow* flow, int64_t& stream_id) = 0; + virtual void* get_hi_msg_section(const Flow* flow) = 0; + virtual void set_hi_msg_section(Flow* flow, void* section) = 0; virtual AppId get_appid_from_stream(const Flow*) { return APP_ID_NONE; } // Stream based flows should override this interface to return parent flow // when child flow is passed as input diff --git a/src/network_inspectors/appid/CMakeLists.txt b/src/network_inspectors/appid/CMakeLists.txt index 6d2afd949..af177e5d2 100644 --- a/src/network_inspectors/appid/CMakeLists.txt +++ b/src/network_inspectors/appid/CMakeLists.txt @@ -148,6 +148,7 @@ set ( APPID_SOURCES appid_config.h appid_cip_event_handler.cc appid_cip_event_handler.h + appid_data_decrypt_event_handler.cc appid_data_decrypt_event_handler.h appid_debug.cc appid_debug.h diff --git a/src/network_inspectors/appid/appid_data_decrypt_event_handler.cc b/src/network_inspectors/appid/appid_data_decrypt_event_handler.cc new file mode 100644 index 000000000..77795aa70 --- /dev/null +++ b/src/network_inspectors/appid/appid_data_decrypt_event_handler.cc @@ -0,0 +1,70 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2023 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. +//-------------------------------------------------------------------------- + +// appid_data_decrypt_event_handler.cc author Shibin + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "appid_data_decrypt_event_handler.h" + +#include "pub_sub/data_decrypt_event.h" + +#include "app_info_table.h" +#include "appid_debug.h" +#include "appid_discovery.h" +#include "appid_http_session.h" +#include "appid_inspector.h" +#include "appid_session.h" +#include "appid_session_api.h" +#include "detection/detection_engine.h" + +using namespace snort; + +void DataDecryptEventHandler::handle(snort::DataEvent& event, snort::Flow* flow) +{ + assert(flow); + AppIdSession* asd = snort::appid_api.get_appid_session(*flow); + if (!asd) + { + Packet* p = DetectionEngine::get_current_packet(); + auto direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER; + asd = AppIdSession::allocate_session( p, p->get_ip_proto_next(), direction, + inspector, *pkt_thread_odp_ctxt ); + if (appidDebug->is_enabled()) + { + appidDebug->activate(flow, asd, inspector.get_ctxt().config.log_all_sessions); + if (appidDebug->is_active()) + LogMessage("AppIdDbg %s New AppId session at Decryption event\n", + appidDebug->get_debug_session()); + } + } + + if (!asd->get_session_flags(APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED)) + return; + + const DataDecryptEvent& data_decrypt_event = static_cast(event); + DataDecryptEvent::StateEventType state = data_decrypt_event.get_type(); + if (DataDecryptEvent::DATA_DECRYPT_MONITOR_EVENT == state) + asd->set_session_flags(APPID_SESSION_DECRYPT_MONITOR); + // Set a do not decrypt flag, so that an event can be generated after appid processes the packet + else if (DataDecryptEvent::DATA_DECRYPT_DO_NOT_DECRYPT_EVENT == state) + asd->set_session_flags(APPID_SESSION_DO_NOT_DECRYPT); +} + diff --git a/src/network_inspectors/appid/appid_data_decrypt_event_handler.h b/src/network_inspectors/appid/appid_data_decrypt_event_handler.h index 0a2c5a2b9..e6aac68d3 100644 --- a/src/network_inspectors/appid/appid_data_decrypt_event_handler.h +++ b/src/network_inspectors/appid/appid_data_decrypt_event_handler.h @@ -21,29 +21,20 @@ #ifndef APPID_DATA_DECRYPT_EVENT_HANDLER_H #define APPID_DATA_DECRYPT_EVENT_HANDLER_H -#include "pub_sub/data_decrypt_event.h" +#include "framework/data_bus.h" -#include "appid_session.h" +#include "appid_module.h" class DataDecryptEventHandler : public snort::DataHandler { public: - DataDecryptEventHandler() : DataHandler(MOD_NAME){ } - - void handle(snort::DataEvent& event, snort::Flow* flow) override - { - assert(flow); - AppIdSession* asd = snort::appid_api.get_appid_session(*flow); - if (!asd or !asd->get_session_flags(APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED)) - return; - const DataDecryptEvent& data_decrypt_event = static_cast(event); - DataDecryptEvent::StateEventType state = data_decrypt_event.get_type(); - if (DataDecryptEvent::DATA_DECRYPT_MONITOR_EVENT== state) - asd->set_session_flags(APPID_SESSION_DECRYPT_MONITOR); - // Set a do not decrypt flag, so that an event can be generated after appid processes the packet - else if (DataDecryptEvent::DATA_DECRYPT_DO_NOT_DECRYPT_EVENT == state) - asd->set_session_flags(APPID_SESSION_DO_NOT_DECRYPT); - } + DataDecryptEventHandler(AppIdInspector& inspector) : DataHandler(MOD_NAME), inspector(inspector) + { } + + void handle(snort::DataEvent& event, snort::Flow* flow) override; + +private: + AppIdInspector& inspector; }; #endif diff --git a/src/network_inspectors/appid/appid_http_session.cc b/src/network_inspectors/appid/appid_http_session.cc index 5e1866360..4c798e2b5 100644 --- a/src/network_inspectors/appid/appid_http_session.cc +++ b/src/network_inspectors/appid/appid_http_session.cc @@ -558,6 +558,15 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, asd.set_service_id(APP_ID_HTTP, asd.get_odp_ctxt()); asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED); asd.service_disco_state = APPID_DISCO_STATE_FINISHED; + if (asd.get_service_id() == APP_ID_HTTP3) + { + if(asd.misc_app_id == APP_ID_NONE) + { + asd.update_encrypted_app_id(APP_ID_HTTP3); + misc_app_id = APP_ID_QUIC; + change_bits.set(APPID_MISC_BIT); + } + } } if (!chp_finished or chp_hold_flow) diff --git a/src/network_inspectors/appid/appid_inspector.cc b/src/network_inspectors/appid/appid_inspector.cc index 9d78e29a4..c29fd75be 100644 --- a/src/network_inspectors/appid/appid_inspector.cc +++ b/src/network_inspectors/appid/appid_inspector.cc @@ -158,7 +158,7 @@ bool AppIdInspector::configure(SnortConfig* sc) DataBus::subscribe_global(dce_tcp_pub_key, DceTcpEventIds::EXP_SESSION, new DceExpSsnEventHandler(), *sc); DataBus::subscribe_global(ssh_pub_key, SshEventIds::STATE_CHANGE, new SshEventHandler(), *sc); DataBus::subscribe_global(cip_pub_key, CipEventIds::DATA, new CipEventHandler(*this), *sc); - DataBus::subscribe_global(external_pub_key, ExternalEventIds::DATA_DECRYPT, new DataDecryptEventHandler(), *sc); + DataBus::subscribe_global(external_pub_key, ExternalEventIds::DATA_DECRYPT, new DataDecryptEventHandler(*this), *sc); DataBus::subscribe_global(external_pub_key, ExternalEventIds::EVE_PROCESS, new AppIdEveProcessEventHandler(*this), *sc); diff --git a/src/network_inspectors/appid/service_plugins/service_ssl.cc b/src/network_inspectors/appid/service_plugins/service_ssl.cc index cbcd67c06..0b0687fbd 100644 --- a/src/network_inspectors/appid/service_plugins/service_ssl.cc +++ b/src/network_inspectors/appid/service_plugins/service_ssl.cc @@ -614,6 +614,7 @@ bool is_service_over_ssl(AppId appId) case APP_ID_MSFT_GC_SSL: case APP_ID_SF_APPLIANCE_MGMT: case APP_ID_SSL: + case APP_ID_QUIC: return true; } diff --git a/src/network_inspectors/appid/test/appid_http_session_test.cc b/src/network_inspectors/appid/test/appid_http_session_test.cc index ceaf94a71..dd89907a8 100644 --- a/src/network_inspectors/appid/test/appid_http_session_test.cc +++ b/src/network_inspectors/appid/test/appid_http_session_test.cc @@ -144,6 +144,10 @@ bool AppIdSession::is_tp_appid_available() const return true; } +void AppIdSession::update_encrypted_app_id(AppId) +{ +} + void AppIdModule::reset_stats() {} // AppIdDebug mock functions diff --git a/src/packet_io/active.h b/src/packet_io/active.h index b6611efff..14fa5cc54 100644 --- a/src/packet_io/active.h +++ b/src/packet_io/active.h @@ -192,6 +192,9 @@ public: bool get_tunnel_bypass() const { return active_tunnel_bypass > 0; } + ActiveActionType get_delayed_action() const + { return delayed_active_action; } + void set_delayed_action(ActiveActionType, bool force = false); void set_delayed_action(ActiveActionType, ActiveAction* act, bool force = false); void apply_delayed_action(Packet*); diff --git a/src/service_inspectors/http2_inspect/http2_flow_data.cc b/src/service_inspectors/http2_inspect/http2_flow_data.cc index 49878e181..5f3a05e3f 100644 --- a/src/service_inspectors/http2_inspect/http2_flow_data.cc +++ b/src/service_inspectors/http2_inspect/http2_flow_data.cc @@ -25,6 +25,7 @@ #include "main/snort_types.h" #include "service_inspectors/http_inspect/http_inspect.h" +#include "service_inspectors/http_inspect/http_msg_section.h" #include "service_inspectors/http_inspect/http_test_manager.h" #include "http2_enum.h" @@ -289,3 +290,22 @@ AppId Http2FlowStreamIntf::get_appid_from_stream(const Flow* flow) return APP_ID_HTTP2; } + +void* Http2FlowStreamIntf::get_hi_msg_section(const Flow* flow) +{ + const Http2FlowData* const h2i_flow_data = + (Http2FlowData*)flow->get_flow_data(Http2FlowData::inspector_id); + HttpMsgSection* current_section = nullptr; + if (h2i_flow_data) + current_section = h2i_flow_data->get_hi_msg_section(); + return current_section; +} + +void Http2FlowStreamIntf::set_hi_msg_section(Flow* flow, void* section) +{ + Http2FlowData* h2i_flow_data = + (Http2FlowData*)flow->get_flow_data(Http2FlowData::inspector_id); + if (h2i_flow_data) + h2i_flow_data->set_hi_msg_section((HttpMsgSection*)section); + +} diff --git a/src/service_inspectors/http2_inspect/http2_flow_data.h b/src/service_inspectors/http2_inspect/http2_flow_data.h index 7d3d43d5f..e671203c4 100644 --- a/src/service_inspectors/http2_inspect/http2_flow_data.h +++ b/src/service_inspectors/http2_inspect/http2_flow_data.h @@ -214,6 +214,8 @@ public: void set_stream_flow_data(snort::Flow* flow, snort::FlowData* flow_data) override; void get_stream_id(const snort::Flow* flow, int64_t& stream_id) override; AppId get_appid_from_stream(const snort::Flow* flow) override; + void* get_hi_msg_section(const snort::Flow* flow) override; + void set_hi_msg_section(snort::Flow* flow, void* section) override; }; #endif diff --git a/src/service_inspectors/http_inspect/http_context_data.cc b/src/service_inspectors/http_inspect/http_context_data.cc index b611b2fbe..6f9c0a778 100644 --- a/src/service_inspectors/http_inspect/http_context_data.cc +++ b/src/service_inspectors/http_inspect/http_context_data.cc @@ -41,12 +41,9 @@ HttpMsgSection* HttpContextData::get_snapshot(const Flow* flow, IpsContext* cont { assert(flow != nullptr); - if (Http2FlowData::inspector_id != 0) + if (flow->stream_intf) { - const Http2FlowData* const h2i_flow_data = - (Http2FlowData*)flow->get_flow_data(Http2FlowData::inspector_id); - if (h2i_flow_data != nullptr) - return h2i_flow_data->get_hi_msg_section(); + return (HttpMsgSection*)flow->stream_intf->get_hi_msg_section(flow); } HttpContextData* hcd = (HttpContextData*)DetectionEngine::get_data(HttpContextData::ips_id, diff --git a/src/service_inspectors/http_inspect/http_inspect.cc b/src/service_inspectors/http_inspect/http_inspect.cc index f296d9953..76cc2cf7a 100755 --- a/src/service_inspectors/http_inspect/http_inspect.cc +++ b/src/service_inspectors/http_inspect/http_inspect.cc @@ -645,18 +645,12 @@ void HttpInspect::clear(Packet* p) return; } - Http2FlowData* h2i_flow_data = nullptr; - if (Http2FlowData::inspector_id != 0) - { - h2i_flow_data = (Http2FlowData*)p->flow->get_flow_data(Http2FlowData::inspector_id); - } - HttpMsgSection* current_section = nullptr; - if (h2i_flow_data != nullptr) + if(p->flow->stream_intf) { - current_section = h2i_flow_data->get_hi_msg_section(); + current_section = (HttpMsgSection*)p->flow->stream_intf->get_hi_msg_section(p->flow); assert(current_section != nullptr); - h2i_flow_data->set_hi_msg_section(nullptr); + p->flow->stream_intf->set_hi_msg_section(p->flow, nullptr); } else current_section = HttpContextData::clear_snapshot(p->context); diff --git a/src/service_inspectors/http_inspect/http_msg_section.cc b/src/service_inspectors/http_inspect/http_msg_section.cc index ef2ba26ca..f81607f00 100644 --- a/src/service_inspectors/http_inspect/http_msg_section.cc +++ b/src/service_inspectors/http_inspect/http_msg_section.cc @@ -63,14 +63,10 @@ HttpMsgSection::HttpMsgSection(const uint8_t* buffer, const uint16_t buf_size, { assert((source_id == SRC_CLIENT) || (source_id == SRC_SERVER)); - if (Http2FlowData::inspector_id != 0) + if (flow->stream_intf) { - Http2FlowData* const h2i_flow_data = (Http2FlowData*)flow->get_flow_data(Http2FlowData::inspector_id); - if (h2i_flow_data != nullptr) - { - h2i_flow_data->set_hi_msg_section(this); - return; - } + flow->stream_intf->set_hi_msg_section(flow, this); + return; } HttpContextData::save_snapshot(this);