From: Steve Chew (stechew) Date: Wed, 8 Jul 2020 16:32:26 +0000 (+0000) Subject: Merge pull request #2289 in SNORT/snort3 from ~SBAIGAL/snort3:smtps to master X-Git-Tag: 3.0.2-2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9891dc22050911548642e0e96bf7e9bbf9722740;p=thirdparty%2Fsnort3.git Merge pull request #2289 in SNORT/snort3 from ~SBAIGAL/snort3:smtps to master Squashed commit of the following: commit 31d2d5ff7283c3ca3b64796746bee57cfba75876 Author: Steven Baigal (sbaigal) Date: Wed Jun 10 14:14:56 2020 -0400 smtp: support opportunistic SSL/TLS switch over --- diff --git a/src/framework/data_bus.h b/src/framework/data_bus.h index f355301a3..2e133674f 100644 --- a/src/framework/data_bus.h +++ b/src/framework/data_bus.h @@ -134,6 +134,8 @@ private: // A flow changed its service #define FLOW_SERVICE_CHANGE_EVENT "flow.service_change_event" +// A flow has found the service inspector +#define SERVICE_INSPECTOR_CHANGE_EVENT "flow.service_inspector.changed" // A flow has entered the setup state #define FLOW_STATE_SETUP_EVENT "flow.state_setup" diff --git a/src/network_inspectors/binder/binder.cc b/src/network_inspectors/binder/binder.cc index 0b336f7d8..f4d85f2d4 100644 --- a/src/network_inspectors/binder/binder.cc +++ b/src/network_inspectors/binder/binder.cc @@ -24,6 +24,7 @@ #include #include +#include "detection/detection_engine.h" #include "flow/flow.h" #include "flow/flow_key.h" #include "framework/data_bus.h" @@ -798,6 +799,8 @@ void Stuff::apply_service(Flow* flow, const HostAttributeEntry* host) if ( flow->ssn_state.snort_protocol_id == UNKNOWN_PROTOCOL_ID ) flow->ssn_state.snort_protocol_id = gadget->get_service(); + + DataBus::publish(SERVICE_INSPECTOR_CHANGE_EVENT, DetectionEngine::get_current_packet()); } else if ( wizard ) @@ -1015,6 +1018,7 @@ void Binder::handle_flow_service_change( Flow* flow ) { flow->set_gadget(ins); flow->ssn_state.snort_protocol_id = ins->get_service(); + DataBus::publish(SERVICE_INSPECTOR_CHANGE_EVENT, DetectionEngine::get_current_packet()); } else flow->ssn_state.snort_protocol_id = UNKNOWN_PROTOCOL_ID; diff --git a/src/protocols/ssl.cc b/src/protocols/ssl.cc index 321f04032..3ccb58e13 100644 --- a/src/protocols/ssl.cc +++ b/src/protocols/ssl.cc @@ -114,10 +114,6 @@ static uint32_t SSL_decode_handshake_v3(const uint8_t* pkt, int size, hello = (const SSL_handshake_hello_t*)handshake; retval |= SSL_decode_version_v3(hello->major, hello->minor); - /* Compare version of record with version of handshake */ - if ((cur_flags & SSL_VERFLAGS) != (retval & SSL_VERFLAGS)) - retval |= SSL_BAD_VER_FLAG; - break; case SSL_HS_SHELLO: diff --git a/src/pub_sub/CMakeLists.txt b/src/pub_sub/CMakeLists.txt index 5c62a5681..fe4a0ccdd 100644 --- a/src/pub_sub/CMakeLists.txt +++ b/src/pub_sub/CMakeLists.txt @@ -7,6 +7,7 @@ set (PUB_SUB_INCLUDES expect_events.h finalize_packet_event.h http_events.h + opportunistic_tls_event.h sip_events.h ) diff --git a/src/pub_sub/opportunistic_tls_event.h b/src/pub_sub/opportunistic_tls_event.h new file mode 100644 index 000000000..bc73cf856 --- /dev/null +++ b/src/pub_sub/opportunistic_tls_event.h @@ -0,0 +1,50 @@ +//-------------------------------------------------------------------------- +// 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. +//-------------------------------------------------------------------------- +// opportunistic_tls_event.h author Steven Baigal + +#ifndef OPPORTUNISTIC_TLS_EVENT_H +#define OPPORTUNISTIC_TLS_EVENT_H + +#include "framework/data_bus.h" + +// An opportunistic SSL/TLS session will start from next packet +#define OPPORTUNISTIC_TLS_EVENT "service_inspector.opportunistic.tls" + +namespace snort +{ + +class SO_PUBLIC OpportunisticTlsEvent : public snort::DataEvent +{ +public: + OpportunisticTlsEvent(const snort::Packet* p, const char* service) : + pkt(p), next_service(service) { } + + const snort::Packet* get_packet() override + { return pkt; } + + const char* get_next_service() + { return next_service; } + +private: + const snort::Packet* pkt; + const char* next_service = nullptr; +}; + +} + +#endif diff --git a/src/service_inspectors/smtp/smtp.cc b/src/service_inspectors/smtp/smtp.cc index 4ce1d373e..c2311cdaa 100644 --- a/src/service_inspectors/smtp/smtp.cc +++ b/src/service_inspectors/smtp/smtp.cc @@ -31,6 +31,7 @@ #include "profiler/profiler.h" #include "protocols/packet.h" #include "protocols/ssl.h" +#include "pub_sub/opportunistic_tls_event.h" #include "stream/stream.h" #include "utils/safec.h" #include "utils/util.h" @@ -1090,6 +1091,13 @@ static void SMTP_ProcessServerPacket( /* This is either an initial server response or a STARTTLS response */ if (smtp_ssn->state == STATE_CONNECT) smtp_ssn->state = STATE_COMMAND; + + if (smtp_ssn->state == STATE_TLS_CLIENT_PEND) + { + OpportunisticTlsEvent event(p, p->flow->service); + DataBus::publish(OPPORTUNISTIC_TLS_EVENT, event, p->flow); + } + break; case RESP_250: diff --git a/src/service_inspectors/ssl/ssl_inspector.cc b/src/service_inspectors/ssl/ssl_inspector.cc index cc1e1306d..9b68088b4 100644 --- a/src/service_inspectors/ssl/ssl_inspector.cc +++ b/src/service_inspectors/ssl/ssl_inspector.cc @@ -33,6 +33,8 @@ #include "profiler/profiler.h" #include "protocols/packet.h" #include "protocols/ssl.h" +#include "pub_sub/finalize_packet_event.h" +#include "pub_sub/opportunistic_tls_event.h" #include "stream/stream.h" #include "stream/stream_splitter.h" @@ -403,6 +405,7 @@ static void snort_ssl(SSL_PROTO_CONF* config, Packet* p) //------------------------------------------------------------------------- // class stuff //------------------------------------------------------------------------- +static const char* s_name = "ssl"; class Ssl : public Inspector { @@ -412,6 +415,7 @@ public: void show(const SnortConfig*) const override; void eval(Packet*) override; + bool configure(SnortConfig*) override; StreamSplitter* get_splitter(bool c2s) override { return new SslSplitter(c2s); } @@ -420,6 +424,33 @@ private: SSL_PROTO_CONF* config; }; +class SslStartTlsEventtHandler : public DataHandler +{ +public: + SslStartTlsEventtHandler() : DataHandler(s_name) { } + + void handle(DataEvent&, Flow* flow) override + { + flow->flags.trigger_finalize_event = true; + } +}; + +class SslFinalizePacketHandler : public DataHandler +{ +public: + SslFinalizePacketHandler() : DataHandler(s_name) {} + + void handle(DataEvent& e, Flow*) override + { + FinalizePacketEvent* fp_event = (FinalizePacketEvent*)&e; + const Packet* pkt = fp_event->get_packet(); + + pkt->flow->flags.trigger_finalize_event = false; + pkt->flow->set_proxied(); + pkt->flow->set_service(const_cast(pkt), s_name); + } +}; + Ssl::Ssl(SSL_PROTO_CONF* pc) { config = pc; @@ -450,6 +481,13 @@ void Ssl::eval(Packet* p) snort_ssl(config, p); } +bool Ssl::configure(SnortConfig*) +{ + DataBus::subscribe(FINALIZE_PACKET_EVENT, new SslFinalizePacketHandler()); + DataBus::subscribe(OPPORTUNISTIC_TLS_EVENT, new SslStartTlsEventtHandler()); + return true; +} + //------------------------------------------------------------------------- // api stuff //------------------------------------------------------------------------- @@ -493,7 +531,7 @@ const InspectApi ssl_api = IT_SERVICE, PROTO_BIT__PDU, nullptr, // buffers - "ssl", + s_name, ssl_init, nullptr, // pterm nullptr, // tinit