]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4626: Appid flow data
authorRon Dempster (rdempste) <rdempste@cisco.com>
Tue, 11 Mar 2025 18:31:25 +0000 (18:31 +0000)
committerRon Dempster (rdempste) <rdempste@cisco.com>
Tue, 11 Mar 2025 18:31:25 +0000 (18:31 +0000)
Merge in SNORT/snort3 from ~RDEMPSTE/snort3:appid_flow_data to master

Squashed commit of the following:

commit 17d3c097c366d0624f25424a0d1f5d4705ec686a
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Thu Jan 30 10:22:48 2025 -0500

    appid: fixes for coverity and cppcheck issues

commit e5932f8567cbd7eef6ca8569691328b101803734
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Tue Feb 18 10:25:11 2025 -0500

    appid: change get_appid_session_api to use the stash

commit fb1fe44bbe2e8204cff7d84d4d6ab7e29df6375e
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Wed Nov 27 11:57:09 2024 -0500

    appid: convert appid flow data to use objects

62 files changed:
src/network_inspectors/appid/CMakeLists.txt
src/network_inspectors/appid/appid_api.cc
src/network_inspectors/appid/appid_config.h
src/network_inspectors/appid/appid_detector.cc
src/network_inspectors/appid/appid_detector.h
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_flow_data.h [new file with mode: 0644]
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/appid_session_api.h
src/network_inspectors/appid/appid_ssh_event_handler.cc
src/network_inspectors/appid/appid_ssh_event_handler.h
src/network_inspectors/appid/client_plugins/client_app_bit.cc
src/network_inspectors/appid/client_plugins/client_app_bit_tracker.cc
src/network_inspectors/appid/client_plugins/client_app_rtp.cc
src/network_inspectors/appid/client_plugins/client_app_timbuktu.cc
src/network_inspectors/appid/client_plugins/client_app_tns.cc
src/network_inspectors/appid/client_plugins/client_app_vnc.cc
src/network_inspectors/appid/detector_plugins/detector_dns.cc
src/network_inspectors/appid/detector_plugins/detector_imap.cc
src/network_inspectors/appid/detector_plugins/detector_imap.h
src/network_inspectors/appid/detector_plugins/detector_kerberos.cc
src/network_inspectors/appid/detector_plugins/detector_kerberos.h
src/network_inspectors/appid/detector_plugins/detector_pop3.cc
src/network_inspectors/appid/detector_plugins/detector_pop3.h
src/network_inspectors/appid/detector_plugins/detector_sip.cc
src/network_inspectors/appid/detector_plugins/detector_smtp.cc
src/network_inspectors/appid/detector_plugins/detector_smtp.h
src/network_inspectors/appid/detector_plugins/test/detector_sip_test.cc
src/network_inspectors/appid/host_port_app_cache.cc
src/network_inspectors/appid/host_port_app_cache.h
src/network_inspectors/appid/service_plugins/service_bgp.cc
src/network_inspectors/appid/service_plugins/service_bit.cc
src/network_inspectors/appid/service_plugins/service_dcerpc.cc
src/network_inspectors/appid/service_plugins/service_dcerpc.h
src/network_inspectors/appid/service_plugins/service_ftp.cc
src/network_inspectors/appid/service_plugins/service_irc.cc
src/network_inspectors/appid/service_plugins/service_lpr.cc
src/network_inspectors/appid/service_plugins/service_mdns.cc
src/network_inspectors/appid/service_plugins/service_netbios.cc
src/network_inspectors/appid/service_plugins/service_nntp.cc
src/network_inspectors/appid/service_plugins/service_radius.cc
src/network_inspectors/appid/service_plugins/service_rexec.cc
src/network_inspectors/appid/service_plugins/service_rexec.h
src/network_inspectors/appid/service_plugins/service_rlogin.cc
src/network_inspectors/appid/service_plugins/service_rpc.cc
src/network_inspectors/appid/service_plugins/service_rpc.h
src/network_inspectors/appid/service_plugins/service_rshell.cc
src/network_inspectors/appid/service_plugins/service_rshell.h
src/network_inspectors/appid/service_plugins/service_rsync.cc
src/network_inspectors/appid/service_plugins/service_rtmp.cc
src/network_inspectors/appid/service_plugins/service_snmp.cc
src/network_inspectors/appid/service_plugins/service_ssl.cc
src/network_inspectors/appid/service_plugins/service_telnet.cc
src/network_inspectors/appid/service_plugins/service_tftp.cc
src/network_inspectors/appid/service_plugins/service_timbuktu.cc
src/network_inspectors/appid/service_plugins/service_tns.cc
src/network_inspectors/appid/service_plugins/test/service_plugin_mock.h
src/network_inspectors/appid/test/appid_discovery_test.cc
src/network_inspectors/appid/test/appid_mock_flow.h
src/network_inspectors/appid/test/appid_mock_session.h
src/network_inspectors/appid/test/service_state_test.cc

index 0799344f221ac789b94d5f6e8218f6cb61e93268..4faa99fb783418ccefa83e4afebd9ff53f5549db 100644 (file)
@@ -159,6 +159,7 @@ set ( APPID_SOURCES
     appid_dns_session.h
     appid_eve_process_event_handler.cc
     appid_eve_process_event_handler.h
+    appid_flow_data.h
     appid_ha.cc
     appid_ha.h
     appid_http_session.cc
index eadd2b00f55bd87bd33010d29d65d86f29876667..e27aadbb735b3052e1aff2346347624be6447858 100644 (file)
@@ -145,7 +145,7 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
         {
             asd->tsession->process_sni_mismatch();
         }
-            
+
 
         if (sni_mismatch)
             asd->scan_flags |= SCAN_SPOOFED_SNI_FLAG;
@@ -246,12 +246,8 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
 
 const AppIdSessionApi* AppIdApi::get_appid_session_api(const Flow& flow) const
 {
-    AppIdSession* asd = (AppIdSession*)flow.get_flow_data(AppIdSession::inspector_id);
-
-    if (asd)
-        return &asd->get_api();
-
-    return nullptr;
+    StashGenericObject* item;
+    return flow.get_attr(STASH_APPID_DATA, item) ? static_cast<AppIdSessionApi*>(item) : nullptr;
 }
 
 bool AppIdApi::is_inspection_needed(const Inspector& inspector) const
index e161da3454b43e3719649e25a020d9dd25a56655..f68385a4ce075be0362d15fe16e739bb9e6cc5e9 100644 (file)
@@ -188,7 +188,7 @@ public:
         return service_disco_mgr;
     }
 
-    HostPortVal* host_port_cache_find(const snort::SfIp* ip, uint16_t port, IpProtocol proto)
+    const HostPortVal* host_port_cache_find(const snort::SfIp* ip, uint16_t port, IpProtocol proto)
     {
         return host_port_cache.find(ip, port, proto, *this);
     }
@@ -205,7 +205,7 @@ public:
         return first_pkt_cache.add_host(sc, ip, netmask, port, proto, protocol_appid, client_appid, web_appid, reinspect);
     }
 
-    HostAppIdsVal* host_first_pkt_find(const snort::SfIp* ip, uint16_t port, IpProtocol proto)
+    const HostAppIdsVal* host_first_pkt_find(const snort::SfIp* ip, uint16_t port, IpProtocol proto)
     {
         return first_pkt_cache.find_on_first_pkt(ip, port, proto, *this);
     }
index 4c554a51178c86c6965c66e2ad8fb1e5fb467eba..c2ee2fe0856af23f6e0f30736a829020d3df73d5 100644 (file)
@@ -60,14 +60,14 @@ int AppIdDetector::initialize(AppIdInspector& inspector)
     return APPID_SUCCESS;
 }
 
-void* AppIdDetector::data_get(const AppIdSession& asd)
+AppIdFlowData* AppIdDetector::data_get(const AppIdSession& asd)
 {
     return asd.get_flow_data(flow_data_index);
 }
 
-int AppIdDetector::data_add(AppIdSession& asd, void* data, AppIdFreeFCN fcn)
+int AppIdDetector::data_add(AppIdSession& asd, AppIdFlowData* data)
 {
-    return asd.add_flow_data(data, flow_data_index, fcn);
+    return asd.add_flow_data(data, flow_data_index);
 }
 
 void AppIdDetector::add_user(AppIdSession& asd, const char* username, AppId appId, bool success,
index e50a795ead4c7c9ddeea77860bcaef76dc782383..a377e000802c2a4d3aff6bdffd6c19d9428168fd 100644 (file)
@@ -117,8 +117,8 @@ public:
     virtual int validate(AppIdDiscoveryArgs&) = 0;
     virtual void register_appid(AppId, unsigned extractsInfo, OdpContext& odp_ctxt) = 0;
 
-    void* data_get(const AppIdSession&);
-    int data_add(AppIdSession&, void*, AppIdFreeFCN);
+    AppIdFlowData* data_get(const AppIdSession&);
+    int data_add(AppIdSession&, AppIdFlowData*);
     void add_user(AppIdSession&, const char*, AppId, bool, AppidChangeBits&);
     void add_payload(AppIdSession&, AppId);
     void add_app(AppIdSession& asd, AppId service_id, AppId client_id, const char* version, AppidChangeBits& change_bits)
@@ -157,9 +157,6 @@ public:
     bool is_client() const
     { return client; }
 
-    virtual LuaStateDescriptor* validate_lua_state(bool /*packet_context*/)
-    { return nullptr; }
-
 protected:
     AppIdDiscovery* handler = nullptr;
     std::string name;     // unique name to map detector; can be UUID file name for lua-detector
index 94e608e45f3741cfcba03341144e78ece71946b2..436832a6bde69b3c418f50e6c823167d720e96b5 100644 (file)
@@ -482,7 +482,7 @@ bool AppIdDiscovery::do_host_port_based_discovery(Packet* p, AppIdSession& asd,
             port = p->ptrs.sp;
         }
     }
-    HostPortVal* hv = nullptr;
+    const HostPortVal* hv = nullptr;
 
     if (check_static and
         (hv = asd.get_odp_ctxt().host_port_cache_find(ip, port, protocol)))
@@ -574,8 +574,7 @@ bool AppIdDiscovery::detect_on_first_pkt(Packet* p, AppIdSession& asd,
         port = p->ptrs.sp;
     }
 
-    HostAppIdsVal* hv = nullptr;
-    hv = asd.get_odp_ctxt().host_first_pkt_find(ip, port, protocol);
+    const HostAppIdsVal* hv = asd.get_odp_ctxt().host_first_pkt_find(ip, port, protocol);
     if (hv)
     {
         const char *service_app_name = nullptr, *client_app_name = nullptr, *payload_app_name = nullptr;
diff --git a/src/network_inspectors/appid/appid_flow_data.h b/src/network_inspectors/appid/appid_flow_data.h
new file mode 100644 (file)
index 0000000..c0612f2
--- /dev/null
@@ -0,0 +1,31 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2024-2025 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_flow_data.h author Ron Dempster <rdempste@cisco.com>
+
+#ifndef APPID_FLOW_DATA_H
+#define APPID_FLOW_DATA_H
+
+class AppIdFlowData
+{
+public:
+    AppIdFlowData() = default;
+    virtual ~AppIdFlowData() = default;
+};
+
+#endif
index 17b281fa0c1c12d503b6de1b3e27972648d730c5..c8d28da8921aa78a237efacbb151e4e800958763 100644 (file)
@@ -721,41 +721,44 @@ void AppIdSession::delete_session_data()
     delete tsession;
 }
 
-int AppIdSession::add_flow_data(void* data, unsigned id, AppIdFreeFCN fcn)
+int AppIdSession::add_flow_data(AppIdFlowData* data, unsigned id)
 {
-    AppIdFlowDataIter it = flow_data.find(id);
+    auto it = flow_data.find(id);
     if (it != flow_data.end())
         return -1;
 
-    AppIdFlowData* fd = new AppIdFlowData(data, id, fcn);
-    flow_data[id] = fd;
+    flow_data[id] = data;
     return 0;
 }
 
-void* AppIdSession::get_flow_data(unsigned id) const
+AppIdFlowData* AppIdSession::get_flow_data(unsigned id) const
 {
-    AppIdFlowDataIter it = flow_data.find(id);
+    auto it = flow_data.find(id);
     if (it != flow_data.end())
-        return it->second->fd_data;
+    {
+        assert(id == it->first);
+        return it->second;
+    }
     else
         return nullptr;
 }
 
 void AppIdSession::free_flow_data()
 {
-    for (AppIdFlowDataIter it = flow_data.cbegin();
-         it != flow_data.cend();
-         ++it)
-        delete it->second;
-
+    std::for_each(std::cbegin(flow_data), std::cend(flow_data),
+        [](const std::pair<unsigned, AppIdFlowData*>& p)
+        {
+            delete p.second;
+        });
     flow_data.clear();
 }
 
 void AppIdSession::free_flow_data_by_id(unsigned id)
 {
-    AppIdFlowDataIter it = flow_data.find(id);
+    auto it = flow_data.find(id);
     if (it != flow_data.end())
     {
+        assert(id == it->first);
         delete it->second;
         flow_data.erase(it);
     }
@@ -763,14 +766,16 @@ void AppIdSession::free_flow_data_by_id(unsigned id)
 
 void AppIdSession::free_flow_data_by_mask(unsigned mask)
 {
-    for (AppIdFlowDataIter it = flow_data.cbegin(); it != flow_data.cend();)
-        if (!mask or (it->second->fd_id & mask))
+    for (auto it = flow_data.cbegin(); it != flow_data.cend();)
+    {
+        if (!mask or (it->first & mask))
         {
             delete it->second;
             it = flow_data.erase(it);
         }
         else
             ++it;
+    }
 }
 
 int AppIdSession::add_flow_data_id(uint16_t port, ServiceDetector* service)
index ca7ed8369bf4e03410329067b71986a5077ab572..45c93c0400bb0cc1bad2c8806e139ad1a9ab1772 100644 (file)
@@ -35,6 +35,7 @@
 #include "appid_api.h"
 #include "appid_app_descriptor.h"
 #include "appid_config.h"
+#include "appid_flow_data.h"
 #include "appid_http_session.h"
 #include "appid_types.h"
 #include "application_ids.h"
@@ -54,8 +55,6 @@ class AppIdDnsSession;
 class AppIdHttpSession;
 class ThirdPartyAppIdSession;
 
-using AppIdFreeFCN = void (*)(void*);
-
 const uint8_t* service_strstr(const uint8_t* haystack, unsigned haystack_len,
     const uint8_t* needle, unsigned needle_len);
 
@@ -75,25 +74,6 @@ enum APPID_DISCOVERY_STATE
     APPID_DISCO_STATE_FINISHED
 };
 
-class AppIdFlowData
-{
-public:
-    AppIdFlowData(void* data, unsigned id, AppIdFreeFCN fcn) :
-        fd_data(data), fd_id(id), fd_free(fcn)
-    { }
-
-    ~AppIdFlowData()
-    {
-        if (fd_data && fd_free)
-            fd_free(fd_data);
-    }
-
-    void* fd_data;
-    unsigned fd_id;
-    AppIdFreeFCN fd_free;
-};
-typedef std::unordered_map<unsigned, AppIdFlowData*>::const_iterator AppIdFlowDataIter;
-
 enum MatchedTlsType
 {
     MATCHED_TLS_NONE = 0,
@@ -374,8 +354,8 @@ public:
     bool is_decrypted() const { return ((flags & APPID_SESSION_DECRYPTED) == 0) ? false : true; }
     bool is_svc_taking_too_much_time() const;
 
-    void* get_flow_data(unsigned id) const;
-    int add_flow_data(void* data, unsigned id, AppIdFreeFCN);
+    AppIdFlowData* get_flow_data(unsigned id) const;
+    int add_flow_data(AppIdFlowData* data, unsigned id);
     int add_flow_data_id(uint16_t port, ServiceDetector*);
     void free_flow_data_by_id(unsigned id);
     void free_flow_data_by_mask(unsigned mask);
index 64ec611519b3ee94a9f66fc2d7ebd87cbb6aa53b..c5e2e127dcc59ac095cc91287807b994fafac89a 100644 (file)
@@ -206,10 +206,15 @@ private:
     {
         delete_all_http_sessions();
         snort_free(tls_host);
+        tls_host = nullptr;
         snort_free(netbios_name);
+        netbios_name = nullptr;
         snort_free(netbios_domain);
+        netbios_domain = nullptr;
         snort_free(tls_sni);
+        tls_sni = nullptr;
         delete dsession;
+        dsession = nullptr;
     }
 
     void delete_all_http_sessions()
@@ -221,8 +226,7 @@ private:
     {
         if (host)
         {
-            if (tls_host)
-                snort_free(tls_host);
+            snort_free(tls_host);
             tls_host = snort_strdup(host);
         }
     }
@@ -231,8 +235,7 @@ private:
     {
         if (sni and sni != tls_sni)
         {
-            if (tls_sni)
-                snort_free(tls_sni);
+            snort_free(tls_sni);
             tls_sni = snort_strdup(sni);
         }
     }
index 330d872405abdef3655fcdf78155dfc844ed7404..3cfc832bee00f53356eb10abf8cd0cd103501f8e 100644 (file)
@@ -141,12 +141,6 @@ static void handle_success(SshEventFlowData& data, const SshEvent& event,
     APPID_LOG(CURRENT_PACKET, TRACE_DEBUG_LEVEL, "SSH event handler service detected\n");
 }
 
-
-static void free_ssh_flow_data(void* data)
-{
-    delete (SshEventFlowData* )data;
-}
-
 unsigned int SshEventHandler::id;
 
 void SshEventHandler::handle(DataEvent& event, Flow* flow)
@@ -181,7 +175,7 @@ void SshEventHandler::handle(DataEvent& event, Flow* flow)
     if (!data)
     {
         data = new SshEventFlowData;
-        asd->add_flow_data(data, id, &free_ssh_flow_data);
+        asd->add_flow_data(data, id);
     }
 
     SshEvent& ssh_event = (SshEvent&)event;
index 498ce3bbd7ef1333421882fbc9b592710b0e6bcd..0b3012f228b7af3e687f04dff461c4b10d0d2ac7 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "pub_sub/ssh_events.h"
 
+#include "appid_flow_data.h"
 #include "appid_module.h"
 
 class SshEventHandler : public snort::DataHandler
@@ -43,8 +44,10 @@ struct SshAppIdInfo
     bool finished = false;
 };
 
-struct SshEventFlowData
+class SshEventFlowData : public AppIdFlowData
 {
+public:
+    ~SshEventFlowData() override = default;
     SshAppIdInfo service_info;
     SshAppIdInfo client_info;
     bool failed = false;
index 39d8b919cd1d401f16c6aeb9818eaac4b886b4fe..38ad83ebd201e5ad0e64b8ae3b47a6ca7aee9406 100644 (file)
@@ -47,16 +47,19 @@ enum BITState
     BIT_STATE_MESSAGE_DATA
 };
 
-struct ClientBITData
+class ClientBITData : public AppIdFlowData
 {
-    BITState state;
-    unsigned stringlen;
-    unsigned pos;
+public:
+    ~ClientBITData() override = default;
+
+    BITState state = BIT_STATE_BANNER;
+    unsigned stringlen = 0;
+    unsigned pos = 0;
     union
     {
         uint32_t len;
         uint8_t raw_len[4];
-    } l;
+    } l = {};
 };
 
 #pragma pack(1)
@@ -100,9 +103,8 @@ int BitClientDetector::validate(AppIdDiscoveryArgs& args)
     fd = (ClientBITData*)data_get(args.asd);
     if (!fd)
     {
-        fd = (ClientBITData*)snort_calloc(sizeof(ClientBITData));
-        data_add(args.asd, fd, &snort_free);
-        fd->state = BIT_STATE_BANNER;
+        fd = new ClientBITData;
+        data_add(args.asd, fd);
     }
 
     offset = 0;
index 8cc4f3dec770220c1a1e8f1bf04e72e0f2d99fb6..540a0e1b477492362282f2cd5e80c436a9f4d0da 100644 (file)
@@ -61,11 +61,14 @@ enum BITType
     BIT_TYPE_ERROR
 };
 
-struct ClientBITData
+class ClientBITData : public AppIdFlowData
 {
-    BITState state;
-    BITType type;
-    unsigned pos;
+public:
+    ~ClientBITData() override = default;
+
+    BITState state = BIT_STATE_BANNER;
+    BITType type = {};
+    unsigned pos = 0;
 };
 } // anonymous
 
@@ -95,21 +98,17 @@ BitTrackerClientDetector::BitTrackerClientDetector(ClientDiscovery* cdm)
 
 int BitTrackerClientDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ClientBITData* fd;
-    uint16_t offset;
-
     if (args.size < (UDP_BIT_FIRST_LEN + UDP_BIT_END_LEN + 3))
         return APPID_EINVALID;
 
-    fd = (ClientBITData*)data_get(args.asd);
+    ClientBITData* fd = (ClientBITData*)data_get(args.asd);
     if (!fd)
     {
-        fd = (ClientBITData*)snort_calloc(sizeof(ClientBITData));
-        data_add(args.asd, fd, &snort_free);
-        fd->state = BIT_STATE_BANNER;
+        fd = new ClientBITData;
+        data_add(args.asd, fd);
     }
 
-    offset = 0;
+    uint16_t offset = 0;
     while (offset < args.size)
     {
         switch (fd->state)
index b37970e82bf458a70bdcb6ae2674bc78eeeabb84..b3e9df403f5f35d8f195cb7693ce0c592557f870 100644 (file)
@@ -40,18 +40,21 @@ enum RTPState
 #define MAX_REMOTE_SIZE    128
 #define NUMBER_OF_PACKETS  3
 
-struct ClientRTPData
+class ClientRTPData : public AppIdFlowData
 {
-    RTPState state;
-    uint8_t pos;
-    uint16_t init_seq;
-    uint16_t resp_seq;
-    uint8_t init_count;
-    uint8_t resp_count;
-    uint32_t init_timestamp;
-    uint32_t resp_timestamp;
-    uint32_t init_ssrc;
-    uint32_t resp_ssrc;
+public:
+    ~ClientRTPData() override = default;
+
+    RTPState state = RTP_STATE_CONNECTION;
+    uint8_t pos = 0;
+    uint16_t init_seq = 0;
+    uint16_t resp_seq = 0;
+    uint8_t init_count = 0;
+    uint8_t resp_count = 0;
+    uint32_t init_timestamp = 0;
+    uint32_t resp_timestamp = 0;
+    uint32_t init_ssrc = 0;
+    uint32_t resp_ssrc = 0;
 };
 
 #pragma pack(1)
@@ -212,20 +215,17 @@ RtpClientDetector::RtpClientDetector(ClientDiscovery* cdm)
 
 int RtpClientDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ClientRTPData* fd;
-    const ClientRTPMsg* hdr;
-
     if (!args.size)
         return APPID_INPROCESS;
 
-    fd = (ClientRTPData*)data_get(args.asd);
+    ClientRTPData* fd = (ClientRTPData*)data_get(args.asd);
     if (!fd)
     {
-        fd = (ClientRTPData*)snort_calloc(sizeof(ClientRTPData));
-        data_add(args.asd, fd, &snort_free);
-        fd->state = RTP_STATE_CONNECTION;
+        fd = new ClientRTPData;
+        data_add(args.asd, fd);
     }
 
+    const ClientRTPMsg* hdr;
     switch (fd->state)
     {
     case RTP_STATE_CONNECTION:
index a69b6acb742e889d60365db598931f2a9a151fa5..a4d38e3b056883216e02e8549ad03df02de10d3a 100644 (file)
@@ -48,16 +48,19 @@ enum TIMBUKTUState
 };
 }
 
-struct ClientTIMBUKTUData
+class ClientTIMBUKTUData : public AppIdFlowData
 {
-    TIMBUKTUState state;
-    uint16_t stringlen;
-    unsigned pos;
+public:
+    ~ClientTIMBUKTUData() override = default;
+
+    TIMBUKTUState state = TIMBUKTU_STATE_BANNER;
+    uint16_t stringlen = 0;
+    unsigned pos = 0;
     union
     {
         uint16_t len;
         uint8_t raw_len[2];
-    } l;
+    } l = {};
 };
 
 #pragma pack(1)
@@ -92,21 +95,17 @@ TimbuktuClientDetector::TimbuktuClientDetector(ClientDiscovery* cdm)
 
 int TimbuktuClientDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ClientTIMBUKTUData* fd;
-    uint16_t offset;
-
     if (args.dir != APP_ID_FROM_INITIATOR)
         return APPID_INPROCESS;
 
-    fd = (ClientTIMBUKTUData*)data_get(args.asd);
+    ClientTIMBUKTUData* fd = (ClientTIMBUKTUData*)data_get(args.asd);
     if (!fd)
     {
-        fd = (ClientTIMBUKTUData*)snort_calloc(sizeof(ClientTIMBUKTUData));
-        data_add(args.asd, fd, &snort_free);
-        fd->state = TIMBUKTU_STATE_BANNER;
+        fd = new ClientTIMBUKTUData;
+        data_add(args.asd, fd);
     }
 
-    offset = 0;
+    uint16_t offset = 0;
     while (offset < args.size)
     {
         switch (fd->state)
index 9eab6ac1ff56014acc582ce5dd4cc24882a2c11d..4970c894f377effb246b152cf6722608b0848ba5 100644 (file)
@@ -51,39 +51,38 @@ static const char TNS_BANNER[] = "\000\000";
 #define USER_STRING "user="
 #define MAX_USER_POS ((int)sizeof(USER_STRING) - 2)
 
-namespace
+enum TNSClntState
 {
-enum TNSState
-{
-    TNS_STATE_MESSAGE_LEN = 0,
-    TNS_STATE_MESSAGE_CHECKSUM,
-    TNS_STATE_MESSAGE,
-    TNS_STATE_MESSAGE_RES,
-    TNS_STATE_MESSAGE_HD_CHECKSUM,
-    TNS_STATE_MESSAGE_DATA,
-    TNS_STATE_MESSAGE_CONNECT,
-    TNS_STATE_MESSAGE_CONNECT_OFFSET_DC,
-    TNS_STATE_MESSAGE_CONNECT_OFFSET,
-    TNS_STATE_MESSAGE_CONNECT_PREDATA,
-    TNS_STATE_MESSAGE_CONNECT_DATA,
-    TNS_STATE_COLLECT_USER
+    CLNT_MSG_LEN = 0,
+    CLNT_MSG_CHECKSUM,
+    CLNT_MSG,
+    CLNT_MSG_RES,
+    CLNT_MSG_HD_CHECKSUM,
+    CLNT_MSG_DATA,
+    CLNT_MSG_CONNECT,
+    CLNT_MSG_CONNECT_OFFSET_DC,
+    CLNT_MSG_CONNECT_OFFSET,
+    CLNT_MSG_CONNECT_PREDATA,
+    CLNT_MSG_CONNECT_DATA,
+    CLNT_COLLECT_USER
 };
-}
 
-struct ClientTNSData
+class ClientTNSData : public AppIdFlowData
 {
-    TNSState state;
-    unsigned stringlen;
-    unsigned offsetlen;
-    unsigned pos;
-    unsigned message;
+public:
+    ~ClientTNSData() override = default;
+
+    const char* version = nullptr;
+    TNSClntState state = CLNT_MSG_LEN;
+    unsigned stringlen = 0;
+    unsigned offsetlen = 0;
+    unsigned pos = 0;
+    unsigned message = 0;
     union
     {
         uint16_t len;
         uint8_t raw_len[2];
-    } l;
-    const char* version;
-    uint8_t* data;
+    } l = {};
 };
 
 #pragma pack(1)
@@ -120,44 +119,40 @@ TnsClientDetector::TnsClientDetector(ClientDiscovery* cdm)
 }
 
 
-static int reset_flow_data(ClientTNSData* fd)
+static int reset_flow_data(ClientTNSData& fd)
 {
-    memset(fd, '\0', sizeof(ClientTNSData));
-    fd->state = TNS_STATE_MESSAGE_LEN;
+    fd = {};
     return APPID_EINVALID;
 }
 
 #define TNS_MAX_INFO_SIZE    63
 int TnsClientDetector::validate(AppIdDiscoveryArgs& args)
 {
-    char username[TNS_MAX_INFO_SIZE + 1];
-    ClientTNSData* fd;
-    uint16_t offset;
-    int user_pos = 0;
-    int user_size = 0;
-    uint16_t user_start = 0;
-    uint16_t user_end = 0;
-
     if (args.dir != APP_ID_FROM_INITIATOR)
         return APPID_INPROCESS;
 
-    fd = (ClientTNSData*)data_get(args.asd);
+    ClientTNSData* fd = (ClientTNSData*)data_get(args.asd);
     if (!fd)
     {
-        fd = (ClientTNSData*)snort_calloc(sizeof(ClientTNSData));
-        data_add(args.asd, fd, &snort_free);
-        fd->state = TNS_STATE_MESSAGE_LEN;
+        fd = new ClientTNSData;
+        data_add(args.asd, fd);
     }
 
-    offset = 0;
+    char username[TNS_MAX_INFO_SIZE + 1];
+    int user_pos = 0;
+    int user_size = 0;
+    uint16_t user_start = 0;
+    uint16_t user_end = 0;
+
+    uint16_t offset = 0;
     while (offset < args.size)
     {
+        // For some reason, coverity cannot follow the state machine. It does state transitions that are not possible
+        // This makes the coverity overrun exceptions necessary
         switch (fd->state)
         {
-        case TNS_STATE_MESSAGE_LEN:
-            if (fd->pos >= 2)
-                    break;
-
+        case CLNT_MSG_LEN:
+            // coverity[overrun]
             fd->l.raw_len[fd->pos++] = args.data[offset];
             if (fd->pos >= offsetof(ClientTNSMsg, checksum))
             {
@@ -166,44 +161,43 @@ int TnsClientDetector::validate(AppIdDiscoveryArgs& args)
                 {
                     if (offset == args.size - 1)
                         goto done;
-                    return reset_flow_data(fd);
+                    return reset_flow_data(*fd);
                 }
                 else if (fd->stringlen < 2)
-                    return reset_flow_data(fd);
+                    return reset_flow_data(*fd);
                 else if (fd->stringlen > args.size)
-                    return reset_flow_data(fd);
-                else
-                    fd->state = TNS_STATE_MESSAGE_CHECKSUM;
+                    return reset_flow_data(*fd);
+                fd->state = CLNT_MSG_CHECKSUM;
             }
             break;
 
-        case TNS_STATE_MESSAGE_CHECKSUM:
+        case CLNT_MSG_CHECKSUM:
             if (args.data[offset] != 0)
-                return reset_flow_data(fd);
+                return reset_flow_data(*fd);
             fd->pos++;
             if (fd->pos >= offsetof(ClientTNSMsg, msg))
-                fd->state = TNS_STATE_MESSAGE;
+                fd->state = CLNT_MSG;
             break;
 
-        case TNS_STATE_MESSAGE:
+        case CLNT_MSG:
             fd->message = args.data[offset];
             if (fd->message < TNS_TYPE_CONNECT || fd->message > TNS_TYPE_MAX)
-                return reset_flow_data(fd);
+                return reset_flow_data(*fd);
             fd->pos++;
-            fd->state = TNS_STATE_MESSAGE_RES;
+            fd->state = CLNT_MSG_RES;
             break;
-        case TNS_STATE_MESSAGE_RES:
-            fd->state = TNS_STATE_MESSAGE_HD_CHECKSUM;
+        case CLNT_MSG_RES:
+            fd->state = CLNT_MSG_HD_CHECKSUM;
             fd->pos++;
             break;
-        case TNS_STATE_MESSAGE_HD_CHECKSUM:
+        case CLNT_MSG_HD_CHECKSUM:
             fd->pos++;
             if (fd->pos >= offsetof(ClientTNSMsg, data))
             {
                 switch (fd->message)
                 {
                 case TNS_TYPE_CONNECT:
-                    fd->state = TNS_STATE_MESSAGE_CONNECT;
+                    fd->state = CLNT_MSG_CONNECT;
                     break;
                 case TNS_TYPE_ACK:
                 case TNS_TYPE_REFUSE:
@@ -218,78 +212,72 @@ int TnsClientDetector::validate(AppIdDiscoveryArgs& args)
                     {
                         if (offset == (args.size - 1))
                             goto done;
-                        return reset_flow_data(fd);
+                        return reset_flow_data(*fd);
                     }
-                    fd->state = TNS_STATE_MESSAGE_DATA;
+                    fd->state = CLNT_MSG_DATA;
                     break;
                 case TNS_TYPE_ACCEPT:
                 case TNS_TYPE_REDIRECT:
                 default:
-                    return reset_flow_data(fd);
+                    return reset_flow_data(*fd);
                 }
             }
             break;
-        case TNS_STATE_MESSAGE_CONNECT:
-            if (fd->pos >= (CONNECT_VERSION_OFFSET + 2))
-                break;
+        case CLNT_MSG_CONNECT:
+            // coverity[overrun]
             fd->l.raw_len[fd->pos - CONNECT_VERSION_OFFSET] = args.data[offset];
             fd->pos++;
             if (fd->pos == (CONNECT_VERSION_OFFSET + 2))
             {
+                switch (ntohs(fd->l.len))
                 {
-                    switch (ntohs(fd->l.len))
-                    {
-                    case 0x136:
-                        fd->version = "8";
-                        break;
-                    case 0x137:
-                        fd->version = "9i R1";
-                        break;
-                    case 0x138:
-                        fd->version = "9i R2";
-                        break;
-                    case 0x139:
-                        fd->version = "10g R1/R2";
-                        break;
-                    case 0x13A:
-                        fd->version = "11g R1";
-                        break;
-                    default:
-                        break;
-                    }
+                case 0x136:
+                    fd->version = "8";
+                    break;
+                case 0x137:
+                    fd->version = "9i R1";
+                    break;
+                case 0x138:
+                    fd->version = "9i R2";
+                    break;
+                case 0x139:
+                    fd->version = "10g R1/R2";
+                    break;
+                case 0x13A:
+                    fd->version = "11g R1";
+                    break;
+                default:
+                    break;
                 }
                 fd->l.len = 0;
-                fd->state = TNS_STATE_MESSAGE_CONNECT_OFFSET_DC;
+                fd->state = CLNT_MSG_CONNECT_OFFSET_DC;
             }
             break;
-        case TNS_STATE_MESSAGE_CONNECT_OFFSET_DC:
+        case CLNT_MSG_CONNECT_OFFSET_DC:
             fd->pos++;
             if (fd->pos >= CONNECT_DATA_OFFSET)
-                fd->state = TNS_STATE_MESSAGE_CONNECT_OFFSET;
+                fd->state = CLNT_MSG_CONNECT_OFFSET;
             break;
-        case TNS_STATE_MESSAGE_CONNECT_OFFSET:
+        case CLNT_MSG_CONNECT_OFFSET:
             if (fd->pos >= CONNECT_DATA_OFFSET + 2)
-                break; 
+                break;
+            // coverity[overrun]
             fd->l.raw_len[fd->pos - CONNECT_DATA_OFFSET] = args.data[offset];
             fd->pos++;
             if (fd->pos == (CONNECT_DATA_OFFSET + 2))
             {
                 fd->offsetlen = ntohs(fd->l.len);
                 if (fd->offsetlen > args.size)
-                {
-                    return reset_flow_data(fd);
-                }
-                fd->state = TNS_STATE_MESSAGE_CONNECT_PREDATA;
+                    return reset_flow_data(*fd);
+                fd->state = CLNT_MSG_CONNECT_PREDATA;
             }
             break;
-        case TNS_STATE_MESSAGE_CONNECT_PREDATA:
+        case CLNT_MSG_CONNECT_PREDATA:
             fd->pos++;
             if (fd->pos >= fd->offsetlen)
-            {
-                fd->state = TNS_STATE_MESSAGE_CONNECT_DATA;
-            }
+                fd->state = CLNT_MSG_CONNECT_DATA;
             break;
-        case TNS_STATE_MESSAGE_CONNECT_DATA:
+        case CLNT_MSG_CONNECT_DATA:
             if (tolower(args.data[offset]) != USER_STRING[user_pos])
             {
                 user_pos = 0;
@@ -299,7 +287,7 @@ int TnsClientDetector::validate(AppIdDiscoveryArgs& args)
             else if (++user_pos > MAX_USER_POS)
             {
                 user_start = offset+1;
-                fd->state = TNS_STATE_COLLECT_USER;
+                fd->state = CLNT_COLLECT_USER;
             }
 
             fd->pos++;
@@ -307,30 +295,28 @@ int TnsClientDetector::validate(AppIdDiscoveryArgs& args)
             {
                 if (offset == (args.size - 1))
                     goto done;
-                return reset_flow_data(fd);
+                return reset_flow_data(*fd);
             }
             break;
-        case TNS_STATE_COLLECT_USER:
+        case CLNT_COLLECT_USER:
             if (user_end == 0 && args.data[offset] == ')')
-            {
                 user_end = offset;
-            }
 
             fd->pos++;
-            if (fd->pos  >= fd->stringlen)
+            if (fd->pos >= fd->stringlen)
             {
                 if (offset == (args.size - 1))
                     goto done;
-                return reset_flow_data(fd);
+                return reset_flow_data(*fd);
             }
             break;
-        case TNS_STATE_MESSAGE_DATA:
+        case CLNT_MSG_DATA:
             fd->pos++;
             if (fd->pos >= fd->stringlen)
             {
                 if (offset == (args.size - 1))
                     goto done;
-                return reset_flow_data(fd);
+                return reset_flow_data(*fd);
             }
             break;
         default:
index a7eaf8aebee21fd332c41de970edaad3cfc6fa2a..289a089e54066b9c96195f03cc544efb6a6061df 100644 (file)
@@ -40,11 +40,14 @@ enum VNCState
 };
 
 #define MAX_VNC_VERSION_SIZE    8
-struct ClientVNCData
+class ClientVNCData : public AppIdFlowData
 {
-    VNCState state;
-    unsigned pos;
-    uint8_t version[MAX_VNC_VERSION_SIZE];
+public:
+    ~ClientVNCData() override = default;
+
+    VNCState state = VNC_STATE_BANNER;
+    unsigned pos = 0;
+    uint8_t version[MAX_VNC_VERSION_SIZE] = {};
 };
 
 VncClientDetector::VncClientDetector(ClientDiscovery* cdm)
@@ -73,21 +76,17 @@ VncClientDetector::VncClientDetector(ClientDiscovery* cdm)
 
 int VncClientDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ClientVNCData* fd;
-    uint16_t offset;
-
     if (args.dir != APP_ID_FROM_INITIATOR)
         return APPID_INPROCESS;
 
-    fd = (ClientVNCData*)data_get(args.asd);
+    ClientVNCData* fd = (ClientVNCData*)data_get(args.asd);
     if (!fd)
     {
-        fd = (ClientVNCData*)snort_calloc(sizeof(ClientVNCData));
-        data_add(args.asd, fd, &snort_free);
-        fd->state = VNC_STATE_BANNER;
+        fd = new ClientVNCData;
+        data_add(args.asd, fd);
     }
 
-    offset = 0;
+    uint16_t offset = 0;
     while (offset < args.size)
     {
         switch (fd->state)
index ede22253a4e9a827f55eaa91c62d2cb438392a03..f35d4a125c87bac4caf5308d4e1c61b978e600a2 100644 (file)
@@ -134,10 +134,13 @@ enum DNSState
     DNS_STATE_RESPONSE
 };
 
-struct ServiceDNSData
+class ServiceDNSData : public AppIdFlowData
 {
-    DNSState state;
-    uint16_t id;
+public:
+    ~ServiceDNSData() override = default;
+
+    DNSState state = DNS_STATE_QUERY;
+    uint16_t id = 0;
 };
 
 DnsTcpServiceDetector::DnsTcpServiceDetector(ServiceDiscovery* sd)
@@ -563,6 +566,8 @@ int DnsUdpServiceDetector::validate(AppIdDiscoveryArgs& args)
             {
                 // To get here, we missed the initial query, but now we've got
                 // a response.
+                // Coverity doesn't realize that validate_packet() checks the packet data for valid values
+                // coverity[tainted_scalar]
                 rval = validate_packet(args.data, args.size, args.dir,
                     args.asd.get_odp_ctxt().dns_host_reporting, args.asd, args.change_bits);
                 if (rval == APPID_SUCCESS)
@@ -577,6 +582,8 @@ int DnsUdpServiceDetector::validate(AppIdDiscoveryArgs& args)
         goto udp_done;
     }
 
+    // Coverity doesn't realize that validate_packet() checks the packet data for valid values
+    // coverity[tainted_scalar]
     rval = validate_packet(args.data, args.size, args.dir,
         args.asd.get_odp_ctxt().dns_host_reporting, args.asd, args.change_bits);
     if ((rval == APPID_SUCCESS) && (args.dir == APP_ID_FROM_INITIATOR))
@@ -642,6 +649,8 @@ int DnsTcpServiceDetector::validate(AppIdDiscoveryArgs& args)
                 goto fail;
         }
 
+        // Coverity doesn't realize that validate_packet() checks the packet data for valid values
+        // coverity[tainted_scalar]
         rval = validate_packet(data, size, args.dir,
             args.asd.get_odp_ctxt().dns_host_reporting, args.asd, args.change_bits);
         if (rval != APPID_SUCCESS)
@@ -650,9 +659,8 @@ int DnsTcpServiceDetector::validate(AppIdDiscoveryArgs& args)
         ServiceDNSData* dd = static_cast<ServiceDNSData*>(data_get(args.asd));
         if (!dd)
         {
-            dd = static_cast<ServiceDNSData*>(snort_calloc(sizeof(ServiceDNSData)));
-            if (data_add(args.asd, dd, &snort_free))
-                dd->state = DNS_STATE_QUERY;
+            dd = new ServiceDNSData;
+            data_add(args.asd, dd);
         }
 
         if (dd->state == DNS_STATE_QUERY)
index 61bbe03e55355b62c0623f2d27df5a99f415fa0e..4df7b20ff523e502044678fd815b9f5c7f020e57 100644 (file)
@@ -149,11 +149,19 @@ struct ImapServiceData
     char tagValue[IMAP_TAG_MAX_LEN+1];
 };
 
-struct ImapDetectorData
+class ImapDetectorData : public AppIdFlowData
 {
-    ImapClientData client;
-    ImapServiceData server;
-    int need_continue;
+public:
+    ImapDetectorData()
+    {
+        server.state = IMAP_STATE_BEGIN;
+        server.flags = IMAP_FLAG_FIRST_PACKET;
+    }
+    ~ImapDetectorData() override = default;
+
+    ImapClientData client = {};
+    ImapServiceData server = {};
+    int need_continue = 1;
 };
 
 static int isImapTagChar(uint8_t tag)
@@ -556,11 +564,8 @@ ImapDetectorData* ImapClientDetector::get_common_data(AppIdSession& asd)
     ImapDetectorData* dd = (ImapDetectorData*)data_get(asd);
     if (!dd)
     {
-        dd = (ImapDetectorData*)snort_calloc(sizeof(ImapDetectorData));
-        data_add(asd, dd, &snort_free);
-        dd->server.state = IMAP_STATE_BEGIN;
-        dd->server.flags = IMAP_FLAG_FIRST_PACKET;
-        dd->need_continue = 1;
+        dd = new ImapDetectorData;
+        data_add(asd, dd);
         asd.set_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
     }
 
index 91b1fe732947c2de9c832f4e1a9ef960a64c871b..ec4ebe3346ab5ef7600518c0a89fab5c00ebf93a 100644 (file)
@@ -26,7 +26,7 @@
 #include "service_plugins/service_detector.h"
 
 class AppIdSession;
-struct ImapDetectorData;
+class ImapDetectorData;
 
 class ImapClientDetector : public ClientDetector
 {
index 77f4aaaa8f967026146a527a5695355b04f930eb..4be648a51f0bace6d303b60b87660ad034e7cd5b 100644 (file)
@@ -95,11 +95,14 @@ struct KRBState
     unsigned flags;
 };
 
-struct KerberosDetectorData
+class KerberosDetectorData : public AppIdFlowData
 {
-    KRBState clnt_state;
-    KRBState svr_state;
-    int need_continue;
+public:
+    ~KerberosDetectorData() override = default;
+
+    KRBState clnt_state = {};
+    KRBState svr_state = {};
+    int need_continue = 1;
 };
 
 #define ASN_1_APPLICATION   0x40
@@ -865,8 +868,8 @@ KerberosDetectorData* KerberosClientDetector::get_common_data(AppIdSession& asd)
     KerberosDetectorData* dd = (KerberosDetectorData*)data_get(asd);
     if (!dd)
     {
-        dd = (KerberosDetectorData*)snort_calloc(sizeof(KerberosDetectorData));
-        data_add(asd, dd, &snort_free);
+        dd = new KerberosDetectorData;
+        data_add(asd, dd);
         if (asd.protocol == IpProtocol::TCP)
         {
             dd->clnt_state.state = KRB_STATE_TCP_LENGTH;
@@ -878,7 +881,6 @@ KerberosDetectorData* KerberosClientDetector::get_common_data(AppIdSession& asd)
             dd->svr_state.state = KRB_STATE_APP;
         }
 
-        dd->need_continue = 1;
         asd.set_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
     }
 
index bb89245e886c38b7f212c7978559cb2d745ede84..5dd9d829d2b9d960a8bc79264308198f041eebc8 100644 (file)
@@ -32,7 +32,7 @@ struct Packet;
 }
 
 struct KRBState;
-struct KerberosDetectorData;
+class KerberosDetectorData;
 class KerberosServiceDetector;
 
 class KerberosClientDetector : public ClientDetector
index 249169a426f0412ffa00c8fe226ab7623ccfbffa..d598c1b941cb48b0e47285711d4e0c8d1cf7775a 100644 (file)
@@ -121,11 +121,19 @@ struct ServicePOP3Data
     int error;
 };
 
-struct POP3DetectorData
+class POP3DetectorData : public AppIdFlowData
 {
-    ClientPOP3Data client;
-    ServicePOP3Data server;
-    int need_continue;
+public:
+    POP3DetectorData()
+    {
+        server.state = POP3_STATE_CONNECT;
+        client.state = POP3_CLIENT_STATE_AUTH;
+    }
+    ~POP3DetectorData() override;
+
+    ClientPOP3Data client = {};
+    ServicePOP3Data server = {};
+    int need_continue = 1;
 };
 
 static AppIdFlowContentPattern pop3_client_patterns[] =
@@ -247,23 +255,16 @@ static int pop3_pattern_match(void* id, void*, int match_end_pos, void* data, vo
     return 1;
 }
 
-static void pop3_free_state(void* data)
+POP3DetectorData::~POP3DetectorData()
 {
-    POP3DetectorData* dd = (POP3DetectorData*)data;
-    if (dd)
+    while (server.subtype)
     {
-        ServicePOP3Data* sd = &dd->server;
-        while (sd->subtype)
-        {
-            AppIdServiceSubtype* sub = sd->subtype;
-            sd->subtype = sub->next;
-            delete sub;
-        }
-        ClientPOP3Data* cd = &dd->client;
-        if (cd->username)
-            snort_free(cd->username);
-        snort_free(dd);
+        AppIdServiceSubtype* sub = server.subtype;
+        server.subtype = sub->next;
+        delete sub;
     }
+    if (client.username)
+        snort_free(client.username);
 }
 
 static int pop3_check_line(const uint8_t** data, const uint8_t* end)
@@ -549,11 +550,8 @@ POP3DetectorData* Pop3ClientDetector::get_common_data(AppIdSession& asd)
     POP3DetectorData* dd = (POP3DetectorData*)data_get(asd);
     if (!dd)
     {
-        dd = (POP3DetectorData*)snort_calloc(sizeof(POP3DetectorData));
-        data_add(asd, dd, &pop3_free_state);
-        dd->server.state = POP3_STATE_CONNECT;
-        dd->client.state = POP3_CLIENT_STATE_AUTH;
-        dd->need_continue = 1;
+        dd = new POP3DetectorData;
+        data_add(asd, dd);
         asd.set_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
     }
 
index aee3d776c5c3c4fe6aa873b4856f45da80cec075..71cd962f89ce29e3f89afa6434260d172b60c494 100644 (file)
@@ -25,7 +25,7 @@
 #include "client_plugins/client_detector.h"
 #include "service_plugins/service_detector.h"
 
-struct POP3DetectorData;
+class POP3DetectorData;
 class Pop3ServiceDetector;
 
 class Pop3ClientDetector : public ClientDetector
index 48ed509497d5b8bb4a4d6c248b70d11cbfe32f08..ca5eefa3f34e5c83883cb40ff4a77a773d615cbb 100644 (file)
@@ -68,8 +68,13 @@ enum tSIP_FLAGS
     SIP_FLAG_SERVER_CHECKED = (1<< 0)
 };
 
-struct ClientSIPData
+class ClientSIPData : public AppIdFlowData
 {
+public:
+    explicit ClientSIPData(void* owner) : owner(owner)
+    { }
+    ~ClientSIPData() override = default;
+
     void* owner = nullptr;
     SIPState state = SIP_STATE_INIT;
     uint32_t flags = 0;
@@ -78,11 +83,6 @@ struct ClientSIPData
     std::string from;
 };
 
-static void clientDataFree(void* data)
-{
-    delete (ClientSIPData*)data;
-}
-
 SipUdpClientDetector::SipUdpClientDetector(ClientDiscovery* cdm)
 {
     handler = cdm;
@@ -116,9 +116,8 @@ int SipUdpClientDetector::validate(AppIdDiscoveryArgs& args)
     ClientSIPData* fd = (ClientSIPData*)data_get(args.asd);
     if ( !fd )
     {
-        fd = new ClientSIPData();
-        data_add(args.asd, fd, &clientDataFree);
-        fd->owner = this;
+        fd = new ClientSIPData(this);
+        data_add(args.asd, fd);
         args.asd.set_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
     }
 
@@ -160,19 +159,21 @@ int SipTcpClientDetector::validate(AppIdDiscoveryArgs& args)
     ClientSIPData* fd = (ClientSIPData*)data_get(args.asd);
     if ( !fd )
     {
-        fd = new ClientSIPData();
-        data_add(args.asd, fd, &clientDataFree);
-        fd->owner = this;
+        fd = new ClientSIPData(this);
+        data_add(args.asd, fd);
         args.asd.set_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
     }
 
     return APPID_INPROCESS;
 }
 
-struct ServiceSIPData
+class ServiceSIPData : public AppIdFlowData
 {
-    uint8_t serverPkt;
-    char vendor[MAX_VENDOR_SIZE];
+public:
+    ~ServiceSIPData() override = default;
+
+    uint8_t serverPkt = 0;
+    char vendor[MAX_VENDOR_SIZE] = {};
 };
 
 void SipServiceDetector::createRtpFlow(AppIdSession& asd, const Packet* pkt, const SfIp* cliIp,
@@ -280,8 +281,8 @@ int SipServiceDetector::validate(AppIdDiscoveryArgs& args)
     ServiceSIPData* ss = (ServiceSIPData*)data_get(args.asd);
     if (!ss)
     {
-        ss = (ServiceSIPData*)snort_calloc(sizeof(ServiceSIPData));
-        data_add(args.asd, ss, &snort_free);
+        ss = new ServiceSIPData;
+        data_add(args.asd, ss);
     }
 
     if (args.size && args.dir == APP_ID_FROM_RESPONDER)
@@ -349,9 +350,8 @@ void SipEventHandler::client_handler(SipEvent& sip_event, AppIdSession& asd,
     ClientSIPData* fd = (ClientSIPData*)client->data_get(asd);
     if ( !fd )
     {
-        fd = new ClientSIPData();
-        client->data_add(asd, fd, &clientDataFree);
-        fd->owner = client;
+        fd = new ClientSIPData(client);
+        client->data_add(asd, fd);
         asd.set_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
     }
 
@@ -408,10 +408,10 @@ void SipEventHandler::service_handler(SipEvent& sip_event, AppIdSession& asd,
         return;
 
     ServiceSIPData* ss = (ServiceSIPData*)service->data_get(asd);
-    if ( !ss )
+    if (!ss)
     {
-        ss = (ServiceSIPData*)snort_calloc(sizeof(ServiceSIPData));
-        service->data_add(asd, ss, &snort_free);
+        ss = new ServiceSIPData;
+        service->data_add(asd, ss);
     }
 
     ss->serverPkt = 0;
index a9247d34470ae7e17ff651848922adca8ef633d8..6f8c3c76c761697d16b56f0430ca47e52265efcd 100644 (file)
@@ -81,11 +81,18 @@ struct ServiceSMTPData
     int multiline;
 };
 
-struct SMTPDetectorData
+class SMTPDetectorData : public AppIdFlowData
 {
-    ClientSMTPData client;
-    ServiceSMTPData server;
-    int need_continue;
+public:
+    SMTPDetectorData()
+    {
+        client.state = SMTP_CLIENT_STATE_HELO;
+    }
+    ~SMTPDetectorData() override;
+
+    ClientSMTPData client = {};
+    ServiceSMTPData server = {};
+    int need_continue = 1;
 };
 
 #define HELO "HELO "
@@ -342,16 +349,10 @@ int SmtpClientDetector::identify_client_version(ClientSMTPData* const fd, const
     return 1;
 }
 
-static void smtp_free_state(void* data)
+SMTPDetectorData::~SMTPDetectorData()
 {
-    SMTPDetectorData* dd = (SMTPDetectorData*)data;
-    if (dd)
-    {
-        ClientSMTPData* cd = &dd->client;
-        if (cd->headerline)
-            snort_free(cd->headerline);
-        snort_free(dd);
-    }
+    if (client.headerline)
+        snort_free(client.headerline);
 }
 
 SMTPDetectorData* SmtpClientDetector::get_common_data(AppIdSession& asd)
@@ -359,8 +360,8 @@ SMTPDetectorData* SmtpClientDetector::get_common_data(AppIdSession& asd)
     SMTPDetectorData* dd = (SMTPDetectorData*)data_get(asd);
     if (!dd)
     {
-        dd = (SMTPDetectorData*)snort_calloc(1, sizeof(*dd));
-        data_add(asd, dd, &smtp_free_state);
+        dd = new SMTPDetectorData;
+        data_add(asd, dd);
 
         if (asd.get_session_flags(APPID_SESSION_DECRYPTED))
         {
@@ -370,8 +371,6 @@ SMTPDetectorData* SmtpClientDetector::get_common_data(AppIdSession& asd)
         else
             dd->server.state = SMTP_SERVICE_STATE_CONNECTION;
 
-        dd->client.state = SMTP_CLIENT_STATE_HELO;
-        dd->need_continue = 1;
         asd.set_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
     }
 
index e52408ddc1e1b1a2311dc24beddba7a9b4e7fda5..83b735cbab2bcb21e3ba93d4262b040acbf00a46 100644 (file)
@@ -27,7 +27,7 @@
 #include "framework/counts.h"
 
 struct ClientSMTPData;
-struct SMTPDetectorData;
+class SMTPDetectorData;
 
 class SmtpClientDetector : public ClientDetector
 {
index 187b7853416844bb820c41a8e7ff35c3877ed4ca..3b8c230010b7446cb3f6d10b9bf464e50e3f5a94 100644 (file)
@@ -174,7 +174,7 @@ ClientDetector::ClientDetector() { }
 // LCOV_EXCL_START
 void ClientDetector::register_appid(int, unsigned int, OdpContext&) { }
 int AppIdDetector::initialize(AppIdInspector&) { return 1; }
-int AppIdDetector::data_add(AppIdSession&, void*, void (*)(void*)) { return 1; }
+int AppIdDetector::data_add(AppIdSession&, AppIdFlowData*) { return 1; }
 void AppIdDetector::add_user(AppIdSession&, char const*, int, bool, AppidChangeBits&) { }
 void AppIdDetector::add_payload(AppIdSession&, int) { }
 void AppIdDetector::add_app(snort::Packet const&, AppIdSession&, AppidSessionDirection, int,
@@ -189,11 +189,11 @@ bool SipEvent::is_dialog_established() const { return false; }
 int SipPatternMatchers::get_client_from_ua(char const*, unsigned int, int&, char*&) { return 0; }  // LCOV_EXCL_LINE
 void SipEventHandler::service_handler(SipEvent&, AppIdSession&, AppidChangeBits&) { }
 
-void* AppIdDetector::data_get(const AppIdSession&)
+AppIdFlowData* AppIdDetector::data_get(const AppIdSession&)
 {
-    sip_data = new ClientSIPData();
+    sip_data = new ClientSIPData(nullptr);
     sip_data->from = "<sip:1001@51.1.1.130:11810>";
-    return (void*)sip_data;
+    return sip_data;
 }
 
 TEST_GROUP(detector_sip_tests)
index f2695a831bb63c679252baaa9d3b2323b709a66a..b7d4d2b29a4bf98ed892d4be155e0afcb128337e 100644 (file)
@@ -142,7 +142,7 @@ bool HostPortCache::add(const SnortConfig* sc, const SfIp* ip, uint16_t port, Ip
     return true;
 }
 
-HostAppIdsVal* HostPortCache::find_on_first_pkt(const SfIp* ip, uint16_t port, IpProtocol protocol,
+const HostAppIdsVal* HostPortCache::find_on_first_pkt(const SfIp* ip, uint16_t port, IpProtocol protocol,
     const OdpContext& odp_ctxt)
 {
     uint16_t lookup_port = (odp_ctxt.allow_port_wildcard_host_cache)? 0 : port;
@@ -161,7 +161,7 @@ HostAppIdsVal* HostPortCache::find_on_first_pkt(const SfIp* ip, uint16_t port, I
             return &check_cache->second;
     }
 
-    for (std::map<FirstPktkey ,HostAppIdsVal>::iterator iter = cache_first_subnet.begin(); iter != cache_first_subnet.end(); ++iter)
+    for (auto iter = cache_first_subnet.begin(); iter != cache_first_subnet.end(); ++iter)
     {
         if (iter->first.port == lookup_port and iter->first.proto == protocol and
             check_ip_range(iter->first.max_network_range, iter->first.network_address, *ip, &iter->first.netmask[0]))
index 27653d3689c31b48a73591443b033ce5d028f56e..25d5da072fcde40e67aa29ef5d2554e3ba94f5cb 100644 (file)
@@ -109,7 +109,7 @@ public:
     bool add(const snort::SnortConfig*, const snort::SfIp*, uint16_t port, IpProtocol,
         unsigned type, AppId);
 
-    HostAppIdsVal* find_on_first_pkt(const snort::SfIp*, uint16_t port, IpProtocol, const OdpContext&);
+    const HostAppIdsVal* find_on_first_pkt(const snort::SfIp*, uint16_t port, IpProtocol, const OdpContext&);
     bool add_host(const snort::SnortConfig*, const snort::SfIp*, uint32_t* netmask, uint16_t port, IpProtocol,
         AppId, AppId, AppId, unsigned reinspect);
     void dump();
index 4b341b0ea45e671339de0cf55f344ab2d618512c..5f08cd6d1ed7c3522ee75c995de2706ae5856108 100644 (file)
@@ -43,14 +43,17 @@ enum BGPState
     BGP_STATE_OPENSENT
 };
 
-#pragma pack(1)
-
-struct ServiceBGPData
+class ServiceBGPData : public AppIdFlowData
 {
-    BGPState state;
-    int v1;
+public:
+    ~ServiceBGPData() override = default;
+
+    BGPState state = BGP_STATE_CONNECTION;
+    bool v1 = false;
 };
 
+#pragma pack(1)
+
 union ServiceBGPHeader
 {
     struct
@@ -119,28 +122,28 @@ BgpServiceDetector::BgpServiceDetector(ServiceDiscovery* sd)
 
 int BgpServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceBGPData* bd;
-    const ServiceBGPHeader* bh;
-    const uint8_t* data = args.data;
-    uint16_t len;
 
-    if (!args.size)
-        goto inprocess;
-    if (args.dir != APP_ID_FROM_RESPONDER)
-        goto inprocess;
+    if (!args.size || args.dir != APP_ID_FROM_RESPONDER)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
     if (args.size < sizeof(ServiceBGPHeader))
-        goto fail;
+    {
+        fail_service(args.asd, args.pkt, args.dir);
+        return APPID_NOMATCH;
+    }
 
-    bd = (ServiceBGPData*)data_get(args.asd);
+    ServiceBGPData* bd = (ServiceBGPData*)data_get(args.asd);
     if (!bd)
     {
-        bd = (ServiceBGPData*)snort_calloc(sizeof(ServiceBGPData));
-        data_add(args.asd, bd, &snort_free);
-        bd->state = BGP_STATE_CONNECTION;
+        bd = new ServiceBGPData;
+        data_add(args.asd, bd);
     }
 
-    bh = (const ServiceBGPHeader*)data;
+    const uint8_t* data = args.data;
+    const ServiceBGPHeader* bh = (const ServiceBGPHeader*)data;
     switch (bd->state)
     {
     case BGP_STATE_CONNECTION:
@@ -148,15 +151,13 @@ int BgpServiceDetector::validate(AppIdDiscoveryArgs& args)
             bh->v1.marker == 0xFFFF &&
             bh->v1.version == 0x01 && bh->v1.type == BGP_V1_TYPE_OPEN)
         {
-            const ServiceBGPV1Open* open;
-
-            len = ntohs(bh->v1.len);
+            uint16_t len = ntohs(bh->v1.len);
             if (len > 1024)
                 goto fail;
-            open = (const ServiceBGPV1Open*)(data + sizeof(bh->v1));
+            const ServiceBGPV1Open* open = (const ServiceBGPV1Open*)(data + sizeof(bh->v1));
             if (open->link > BGP_OPEN_LINK_MAX)
                 goto fail;
-            bd->v1 = 1;
+            bd->v1 = true;
         }
         else if (args.size >= sizeof(bh->v) + sizeof(ServiceBGPOpen) &&
             bh->v.marker[0] == 0xFFFFFFFF &&
@@ -165,18 +166,16 @@ int BgpServiceDetector::validate(AppIdDiscoveryArgs& args)
             bh->v.marker[3] == 0xFFFFFFFF &&
             bh->v.type == BGP_TYPE_OPEN)
         {
-            const ServiceBGPOpen* open;
-
-            len = ntohs(bh->v.len);
+            uint16_t len = ntohs(bh->v.len);
             if (len > 4096)
                 goto fail;
-            open = (const ServiceBGPOpen*)(data + sizeof(bh->v));
+            const ServiceBGPOpen* open = (const ServiceBGPOpen*)(data + sizeof(bh->v));
             if (open->version > BGP_VERSION_MAX ||
                 open->version < BGP_VERSION_MIN)
             {
                 goto fail;
             }
-            bd->v1 = 0;
+            bd->v1 = false;
         }
         else
             goto fail;
@@ -189,7 +188,7 @@ int BgpServiceDetector::validate(AppIdDiscoveryArgs& args)
                 bh->v1.version == 0x01 &&
                 bh->v1.type == BGP_V1_TYPE_OPEN_CONFIRM)
             {
-                len = ntohs(bh->v1.len);
+                uint16_t len = ntohs(bh->v1.len);
                 if (len != sizeof(bh->v1))
                     goto fail;
                 goto success;
@@ -200,7 +199,7 @@ int BgpServiceDetector::validate(AppIdDiscoveryArgs& args)
             if (args.size >= sizeof(bh->v) &&
                 bh->v.type == BGP_TYPE_KEEPALIVE)
             {
-                len = ntohs(bh->v.len);
+                uint16_t len = ntohs(bh->v.len);
                 if (len != sizeof(bh->v))
                     goto fail;
                 goto success;
@@ -210,7 +209,6 @@ int BgpServiceDetector::validate(AppIdDiscoveryArgs& args)
         goto fail;
     }
 
-inprocess:
     service_inprocess(args.asd, args.pkt, args.dir);
     return APPID_INPROCESS;
 
index 318fca454fd75373295e33987daad2c7a0f54f5d..12321facf0c1e42bf7c2a51cf7dfdc46a2dc57d8 100644 (file)
@@ -43,16 +43,19 @@ enum BITState
     BIT_STATE_MESSAGE_DATA
 };
 
-struct ServiceBITData
+class ServiceBITData : public AppIdFlowData
 {
-    BITState state;
-    unsigned stringlen;
-    unsigned pos;
+public:
+    ~ServiceBITData() override = default;
+
+    BITState state = BIT_STATE_BANNER;
+    unsigned stringlen = 0;
+    unsigned pos = 0;
     union
     {
         uint32_t len;
         uint8_t raw_len[4];
-    } l;
+    } l = {};
 };
 
 #pragma pack(1)
@@ -99,24 +102,21 @@ BitServiceDetector::BitServiceDetector(ServiceDiscovery* sd)
 
 int BitServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceBITData* ss;
-    const uint8_t* data = args.data;
-    uint16_t offset;
-
-    if (!args.size)
-        goto inprocess;
-    if (args.dir != APP_ID_FROM_RESPONDER)
-        goto inprocess;
+    if (!args.size || args.dir != APP_ID_FROM_RESPONDER)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    ss = (ServiceBITData*)data_get(args.asd);
+    ServiceBITData* ss = (ServiceBITData*)data_get(args.asd);
     if (!ss)
     {
-        ss = (ServiceBITData*)snort_calloc(sizeof(ServiceBITData));
-        data_add(args.asd, ss, &snort_free);
-        ss->state = BIT_STATE_BANNER;
+        ss = new ServiceBITData;
+        data_add(args.asd, ss);
     }
 
-    offset = 0;
+    const uint8_t* data = args.data;
+    uint16_t offset  = 0;
     while (offset < args.size)
     {
         switch (ss->state)
@@ -167,7 +167,6 @@ int BitServiceDetector::validate(AppIdDiscoveryArgs& args)
         offset++;
     }
 
-inprocess:
     service_inprocess(args.asd, args.pkt, args.dir);
     return APPID_INPROCESS;
 
index 5a52db562a5c58750b4790bc979194c26144d065..6dcd1f9c3c346ef83496a208ffae124cd50386c9 100644 (file)
 
 #define min(x,y) ((x)<(y) ? (x) : (y))
 
-struct ServiceDCERPCData
+class ServiceDCERPCData : public AppIdFlowData
 {
-    unsigned count;
+public:
+    ~ServiceDCERPCData() override = default;
+
+    unsigned count = 0;
 };
 
 DceRpcServiceDetector::DceRpcServiceDetector(ServiceDiscovery* sd)
@@ -69,24 +72,25 @@ int DceRpcServiceDetector::validate(AppIdDiscoveryArgs& args)
 
 int DceRpcServiceDetector::tcp_validate(AppIdDiscoveryArgs& args)
 {
-    ServiceDCERPCData* dd;
-    int retval = APPID_INPROCESS;
-    int length;
-    const uint8_t* data = args.data;
-    uint16_t size = args.size;
 
-    if (args.dir != APP_ID_FROM_RESPONDER)
-        goto inprocess;
-    if (!size)
-        goto inprocess;
+    if (!args.size || args.dir != APP_ID_FROM_RESPONDER)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    dd = (ServiceDCERPCData*)data_get(args.asd);
+    ServiceDCERPCData* dd = (ServiceDCERPCData*)data_get(args.asd);
     if (!dd)
     {
-        dd = (ServiceDCERPCData*)snort_calloc(sizeof(ServiceDCERPCData));
-        data_add(args.asd, dd, &snort_free);
+        dd = new ServiceDCERPCData;
+        data_add(args.asd, dd);
     }
 
+    int retval = APPID_INPROCESS;
+    int length;
+    const uint8_t* data = args.data;
+    uint16_t size = args.size;
+
     while (size)
     {
         length = dcerpc_validate(data, size);
@@ -101,7 +105,6 @@ int DceRpcServiceDetector::tcp_validate(AppIdDiscoveryArgs& args)
     if (retval == APPID_SUCCESS)
         return add_service(args.change_bits, args.asd, args.pkt, args.dir, APP_ID_DCE_RPC);
 
-inprocess:
     service_inprocess(args.asd, args.pkt, args.dir);
     return APPID_INPROCESS;
 
@@ -112,24 +115,24 @@ fail:
 
 int DceRpcServiceDetector::udp_validate(AppIdDiscoveryArgs& args)
 {
-    ServiceDCERPCData* dd;
-    int retval = APPID_NOMATCH;
-    int length;
-    const uint8_t* data = args.data;
-    uint16_t size = args.size;
-
-    if (args.dir != APP_ID_FROM_RESPONDER)
-        goto inprocess;
-    if (!size)
-        goto inprocess;
+    if (!args.size || args.dir != APP_ID_FROM_RESPONDER)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    dd = (ServiceDCERPCData*)data_get(args.asd);
+    ServiceDCERPCData* dd = (ServiceDCERPCData*)data_get(args.asd);
     if (!dd)
     {
-        dd = (ServiceDCERPCData*)snort_calloc(sizeof(ServiceDCERPCData));
-        data_add(args.asd, dd, &snort_free);
+        dd = new ServiceDCERPCData;
+        data_add(args.asd, dd);
     }
 
+    int retval = APPID_NOMATCH;
+    int length;
+    const uint8_t* data = args.data;
+    uint16_t size = args.size;
+
     while (size)
     {
         length = dcerpc_validate(data, size);
@@ -144,7 +147,6 @@ int DceRpcServiceDetector::udp_validate(AppIdDiscoveryArgs& args)
     if (retval == APPID_SUCCESS)
         return add_service(args.change_bits, args.asd, args.pkt, args.dir, APP_ID_DCE_RPC);
 
-inprocess:
     service_inprocess(args.asd, args.pkt, args.dir);
     return APPID_INPROCESS;
 
index d223da33df43af6792276d6ddc1943dec36c9199..1d6f0e9f952ea26e32c54615202a7f7a58962e1c 100644 (file)
@@ -25,7 +25,7 @@
 
 class AppIdSession;
 class ServiceDiscovery;
-struct ServiceRPCData;
+class ServiceRPCData;
 
 class DceRpcServiceDetector : public ServiceDetector
 {
index ac4e8799fda11af903eec6bbf140135a2ba447fa..0f119ba55ebf2e9249732f9e4dce2640965f2547 100644 (file)
@@ -71,19 +71,21 @@ enum FTPCmd
 };
 
 #define MAX_STRING_SIZE 64
-struct ServiceFTPData
+class ServiceFTPData : public AppIdFlowData
 {
-    FTPState state;
-    FTPReplyState rstate;
-    int code;
-    char vendor[MAX_STRING_SIZE];
-    char version[MAX_STRING_SIZE];
-    FTPCmd cmd;
-    SfIp address;
-    uint16_t port;
-    int part_code_resp = 0;
-    int part_code_len;
+public:
+    ~ServiceFTPData() override = default;
 
+    FTPState state = FTP_STATE_CONNECTION;
+    FTPReplyState rstate = FTP_REPLY_BEGIN;
+    int code = 0;
+    char vendor[MAX_STRING_SIZE] = {};
+    char version[MAX_STRING_SIZE] = {};
+    FTPCmd cmd = FTP_CMD_NONE;
+    SfIp address = {};
+    int part_code_resp = 0;
+    int part_code_len = 0;
+    uint16_t port = 0;
 };
 
 #pragma pack(1)
@@ -919,42 +921,36 @@ int FtpServiceDetector::validate(AppIdDiscoveryArgs& args)
     static const char FTP_EPSV_CMD[] = "EPSV";
     static const char FTP_PORT_CMD[] = "PORT ";
     static const char FTP_EPRT_CMD[] = "EPRT ";
-    ServiceFTPData* fd = nullptr;
-    uint16_t offset = 0;
-    uint16_t init_offset = 0;
-    int code = 0;
-    int code_index = 0;
-    uint32_t address = 0;
-    uint16_t port = 0;
-    int retval = APPID_INPROCESS;
-    const uint8_t* data = args.data;
-    uint16_t size = args.size;
-
-    if (!size)
-        goto inprocess;
 
     //ignore packets while encryption is on in explicit mode. In future, this will be changed
     //to direct traffic to SSL detector to extract payload from certs. This will require
     // maintaining
     //two detector states at the same time.
-    if (args.asd.get_session_flags(APPID_SESSION_ENCRYPTED))
+    if (!args.size
+        || APPID_SESSION_ENCRYPTED == args.asd.get_session_flags(APPID_SESSION_ENCRYPTED | APPID_SESSION_DECRYPTED))
     {
-        if (!args.asd.get_session_flags(APPID_SESSION_DECRYPTED))
-        {
-            goto inprocess;
-        }
+        if (!args.asd.is_service_detected())
+            service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
     }
 
-    fd = (ServiceFTPData*)data_get(args.asd);
+    ServiceFTPData* fd = (ServiceFTPData*)data_get(args.asd);
     if (!fd)
     {
-        fd = (ServiceFTPData*)snort_calloc(sizeof(ServiceFTPData));
-        data_add(args.asd, fd, &snort_free);
-        fd->state = FTP_STATE_CONNECTION;
-        fd->rstate = FTP_REPLY_BEGIN;
-        fd->cmd = FTP_CMD_NONE;
+        fd = new ServiceFTPData;
+        data_add(args.asd, fd);
     }
 
+    uint16_t offset = 0;
+    uint16_t init_offset = 0;
+    int code = 0;
+    int code_index = 0;
+    uint32_t address = 0;
+    uint16_t port = 0;
+    int retval = APPID_INPROCESS;
+    const uint8_t* data = args.data;
+    uint16_t size = args.size;
+
     if (args.dir != APP_ID_FROM_RESPONDER)
     {
         if (data[size-1] != 0x0a)
index 3d5384e05f6a23865b5bf10ae8a2b6fe51aec3f7..b9b659e07880e9cb589523dfb574540df32e1183 100644 (file)
@@ -51,15 +51,18 @@ enum IRCState
     IRC_STATE_USER_MID_TERM
 };
 
-struct ServiceIRCData
+class ServiceIRCData : public AppIdFlowData
 {
-    IRCState state;
-    unsigned pos;
-    const char* command;
-    IRCState initiator_state;
-    unsigned initiator_pos;
-    const char* initiator_command;
-    unsigned count;
+public:
+    ~ServiceIRCData() override = default;
+
+    const char* command = nullptr;
+    const char* initiator_command = nullptr;
+    IRCState state = IRC_STATE_BEGIN;
+    unsigned pos = 0;
+    IRCState initiator_state = IRC_STATE_BEGIN;
+    unsigned initiator_pos = 0;
+    unsigned count = 0;
 };
 
 IrcServiceDetector::IrcServiceDetector(ServiceDiscovery* sd)
@@ -85,26 +88,24 @@ IrcServiceDetector::IrcServiceDetector(ServiceDiscovery* sd)
 
 int IrcServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceIRCData* id;
-    const uint8_t* end;
-    IRCState* state;
-    unsigned* pos;
-    const char** command;
-    const uint8_t* data = args.data;
-
     if (!args.size)
-        goto inprocess;
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    id = (ServiceIRCData*)data_get(args.asd);
+    ServiceIRCData* id = (ServiceIRCData*)data_get(args.asd);
     if (!id)
     {
-        id =  (ServiceIRCData*)snort_calloc(sizeof(ServiceIRCData));
-        data_add(args.asd, id, &snort_free);
-        id->initiator_state = IRC_STATE_BEGIN;
-        id->state = IRC_STATE_BEGIN;
+        id = new ServiceIRCData;
+        data_add(args.asd, id);
     }
 
-    end = (const uint8_t*)(data + args.size);
+    IRCState* state;
+    unsigned* pos;
+    const char** command;
+    const uint8_t* data = args.data;
+    const uint8_t* end = (const uint8_t*)(data + args.size);
 
     if (args.dir == APP_ID_FROM_RESPONDER)
     {
index bb9d5cf2a2054ff2da52af4ec1a6636bb79b4213..921d7403ad92926895f990b905a18162f4bb8bc3 100644 (file)
@@ -52,11 +52,14 @@ enum LPRSubCommand
     LPR_SUBCMD_DATA
 };
 
-struct ServiceLPRData
+class ServiceLPRData : public AppIdFlowData
 {
-    LPRState state;
-    unsigned no_data_count;
-    unsigned count;
+public:
+    ~ServiceLPRData() override = default;
+
+    LPRState state = LPR_STATE_COMMAND;
+    unsigned no_data_count = 0;
+    unsigned count = 0;
 };
 
 LprServiceDetector::LprServiceDetector(ServiceDiscovery* sd)
@@ -82,22 +85,23 @@ LprServiceDetector::LprServiceDetector(ServiceDiscovery* sd)
 
 int LprServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceLPRData* ld;
-    int i;
-    const uint8_t* data = args.data;
-    uint16_t size = args.size;
-
-    if (!size)
-        goto inprocess;
+    if (!args.size)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    ld = (ServiceLPRData*)data_get(args.asd);
+    ServiceLPRData* ld = (ServiceLPRData*)data_get(args.asd);
     if (!ld)
     {
-        ld = (ServiceLPRData*)snort_calloc(sizeof(ServiceLPRData));
-        data_add(args.asd, ld, &snort_free);
-        ld->state = LPR_STATE_COMMAND;
+        ld = new ServiceLPRData;
+        data_add(args.asd, ld);
     }
 
+    int i;
+    const uint8_t* data = args.data;
+    uint16_t size = args.size;
+
     switch (ld->state)
     {
     case LPR_STATE_COMMAND:
index 33ea24b32d20ab57d2d6576c564e69d5224350b4..a7b07b6079cc88373ef8e206206d96c9ce3492ab 100644 (file)
@@ -61,9 +61,12 @@ enum MDNSState
     MDNS_STATE_CONNECTION_ERROR
 };
 
-struct ServiceMDNSData
+class ServiceMDNSData : public AppIdFlowData
 {
-    MDNSState state;
+public:
+    ~ServiceMDNSData() override = default;
+
+    MDNSState state = MDNS_STATE_CONNECTION;
 };
 
 struct MdnsPattern
@@ -118,19 +121,16 @@ void MdnsServiceDetector::do_custom_reload()
 
 int MdnsServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    int ret_val;
-
     ServiceMDNSData* fd = (ServiceMDNSData*)data_get(args.asd);
     if (!fd)
     {
-        fd = (ServiceMDNSData*)snort_calloc(sizeof(ServiceMDNSData));
-        data_add(args.asd, fd, &snort_free);
-        fd->state = MDNS_STATE_CONNECTION;
+        fd = new ServiceMDNSData();
+        data_add(args.asd, fd);
     }
 
     if (args.pkt->ptrs.dp == MDNS_PORT || args.pkt->ptrs.sp == MDNS_PORT )
     {
-        ret_val = validate_reply(args.data, args.size);
+        int ret_val = validate_reply(args.data, args.size);
         if (ret_val == 1)
         {
             if (args.asd.get_odp_ctxt().mdns_user_reporting)
index 1f45008bf6f9f5539ce360adb995c48d4882c6fe..16c47310edeb93baf2b2de89643e4f1a68963d0d 100644 (file)
@@ -430,6 +430,9 @@ int NbnsServiceDetector::validate(AppIdDiscoveryArgs& args)
     if (hdr->QCount)
     {
         count = ntohs(hdr->QCount);
+        // Coverity doesn't realize that nbns_validate_query() checks the packet data for valid values
+        // which validates the count
+        // coverity[tainted_scalar]
         for (i=0; i<count; i++)
         {
             if (nbns_validate_query(&data, begin, end))
@@ -440,6 +443,9 @@ int NbnsServiceDetector::validate(AppIdDiscoveryArgs& args)
     if (hdr->ACount)
     {
         count = ntohs(hdr->ACount);
+        // Coverity doesn't realize that nbns_validate_answer() checks the packet data for valid values
+        // which validates the count
+        // coverity[tainted_scalar]
         for (i=0; i<count; i++)
         {
             if (nbns_validate_answer(&data, begin, end))
@@ -450,6 +456,9 @@ int NbnsServiceDetector::validate(AppIdDiscoveryArgs& args)
     if (hdr->NSCount)
     {
         count = ntohs(hdr->NSCount);
+        // Coverity doesn't realize that nbns_validate_answer() checks the packet data for valid values
+        // which validates the count
+        // coverity[tainted_scalar]
         for (i=0; i<count; i++)
         {
             if (nbns_validate_answer(&data, begin, end))
@@ -460,6 +469,9 @@ int NbnsServiceDetector::validate(AppIdDiscoveryArgs& args)
     if (hdr->ARCount)
     {
         count = ntohs(hdr->ARCount);
+        // Coverity doesn't realize that nbns_validate_answer() checks the packet data for valid values
+        // which validates the count
+        // coverity[tainted_scalar]
         for (i=0; i<count; i++)
         {
             if (nbns_validate_answer(&data, begin, end))
index 88c2ec374ca0db6c3adb5c36c189b9a60ace6168..36cef5d8ceb56d50d503a7e859eb71546fad182b 100644 (file)
@@ -43,11 +43,14 @@ enum NNTPState
 #define NNTP_MID_LINE       0x0002
 #define NNTP_MID_TERM       0x0004
 
-struct ServiceNNTPData
+class ServiceNNTPData : public AppIdFlowData
 {
-    NNTPState state;
-    uint32_t flags;
-    unsigned count;
+public:
+    ~ServiceNNTPData() override = default;
+
+    NNTPState state = NNTP_STATE_CONNECTION;
+    uint32_t flags = 0;
+    unsigned count = 0;
 };
 
 #pragma pack(1)
@@ -262,26 +265,23 @@ static int nntp_validate_data(const uint8_t* data, uint16_t* offset, uint16_t si
 
 int NntpServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceNNTPData* nd;
-    uint16_t offset;
-    int code;
-    const uint8_t* data = args.data;
-    uint16_t size = args.size;
-
-    if (!size)
-        goto inprocess;
-    if (args.dir != APP_ID_FROM_RESPONDER)
-        goto inprocess;
+    if (!args.size || args.dir != APP_ID_FROM_RESPONDER)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    nd = (ServiceNNTPData*)data_get(args.asd);
+    ServiceNNTPData* nd = (ServiceNNTPData*)data_get(args.asd);
     if (!nd)
     {
-        nd = (ServiceNNTPData*)snort_calloc(sizeof(ServiceNNTPData));
-        data_add(args.asd, nd, &snort_free);
-        nd->state = NNTP_STATE_CONNECTION;
+        nd = new ServiceNNTPData();
+        data_add(args.asd, nd);
     }
 
-    offset = 0;
+    int code;
+    const uint8_t* data = args.data;
+    uint16_t size = args.size;
+    uint16_t offset = 0;
     while (offset < size)
     {
         if (nd->state == NNTP_STATE_DATA)
index f88d210666e2458c39fa8165a69843b6ea2a7aa3..652ecdf8546bdf492e34a762f4c8bc7ed888c304 100644 (file)
@@ -40,10 +40,13 @@ enum RADIUSState
     RADIUS_STATE_RESPONSE
 };
 
-struct ServiceRADIUSData
+class ServiceRADIUSData : public AppIdFlowData
 {
-    RADIUSState state;
-    uint8_t id;
+public:
+    ~ServiceRADIUSData() override = default;
+
+    RADIUSState state = RADIUS_STATE_REQUEST;
+    uint8_t id = 0;
 };
 
 #pragma pack(1)
@@ -82,25 +85,28 @@ RadiusServiceDetector::RadiusServiceDetector(ServiceDiscovery* sd)
 
 int RadiusServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceRADIUSData* rd;
-    const RADIUSHeader* hdr = (const RADIUSHeader*)args.data;
-    uint16_t len;
-    int new_dir;
-
     if (!args.size)
-        goto inprocess;
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
     if (args.size < sizeof(RADIUSHeader))
-        goto fail;
+    {
+        fail_service(args.asd, args.pkt, args.dir);
+        return APPID_NOMATCH;
+    }
 
-    rd = (ServiceRADIUSData*)data_get(args.asd);
+    ServiceRADIUSData* rd = (ServiceRADIUSData*)data_get(args.asd);
     if (!rd)
     {
-        rd = (ServiceRADIUSData*)snort_calloc(sizeof(ServiceRADIUSData));
-        data_add(args.asd, rd, &snort_free);
-        rd->state = RADIUS_STATE_REQUEST;
+        rd = new ServiceRADIUSData;
+        data_add(args.asd, rd);
     }
 
-    new_dir = args.dir;
+    const RADIUSHeader* hdr = (const RADIUSHeader*)args.data;
+    uint16_t len;
+    int new_dir = args.dir;
+
     if (rd->state == RADIUS_STATE_REQUEST)
     {
         if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT ||
@@ -203,25 +209,27 @@ RadiusAcctServiceDetector::RadiusAcctServiceDetector(ServiceDiscovery* sd)
 
 int RadiusAcctServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceRADIUSData* rd;
-    const RADIUSHeader* hdr = (const RADIUSHeader*)args.data;
-    uint16_t len;
-    int new_dir;
-
     if (!args.size)
-        goto inprocess;
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
     if (args.size < sizeof(RADIUSHeader))
-        goto fail;
+    {
+        fail_service(args.asd, args.pkt, args.dir);
+        return APPID_NOMATCH;
+    }
 
-    rd = (ServiceRADIUSData*)data_get(args.asd);
+    ServiceRADIUSData* rd = (ServiceRADIUSData*)data_get(args.asd);
     if (!rd)
     {
-        rd = (ServiceRADIUSData*)snort_calloc(sizeof(ServiceRADIUSData));
-        data_add(args.asd, rd, &snort_free);
-        rd->state = RADIUS_STATE_REQUEST;
+        rd = new ServiceRADIUSData;
+        data_add(args.asd, rd);
     }
 
-    new_dir = args.dir;
+    const RADIUSHeader* hdr = (const RADIUSHeader*)args.data;
+    uint16_t len;
+    int new_dir = args.dir;
     if (rd->state == RADIUS_STATE_REQUEST)
     {
         if (hdr->code == RADIUS_CODE_ACCOUNTING_RESPONSE)
index fb2a81f04f9dcb2da0541d5a788b8d9986db5548..b9fa1cd3824ab8ce113620fb00eee4a65fdb4ff9 100644 (file)
@@ -53,11 +53,16 @@ enum REXECState
     REXEC_STATE_STDERR_DONE
 };
 
-struct ServiceREXECData
+class ServiceREXECData : public AppIdFlowData
 {
+public:
+    explicit ServiceREXECData(REXECState state) : state(state)
+    { }
+    ~ServiceREXECData() override;
+
+    ServiceREXECData* parent = nullptr;
+    ServiceREXECData* child = nullptr;
     REXECState state;
-    struct ServiceREXECData* parent;
-    struct ServiceREXECData* child;
 };
 
 static const uint64_t REXEC_EXPECTED_SESSION_FLAGS = APPID_SESSION_CONTINUE |
@@ -85,23 +90,17 @@ RexecServiceDetector::RexecServiceDetector(ServiceDiscovery* sd)
 }
 
 
-static void rexec_free_state(void* data)
+ServiceREXECData::~ServiceREXECData()
 {
-    ServiceREXECData* rd = (ServiceREXECData*)data;
-
-    if (rd)
+    if (parent)
     {
-        if (rd->parent)
-        {
-            rd->parent->child = nullptr;
-            rd->parent->parent = nullptr;
-        }
-        if (rd->child)
-        {
-            rd->child->parent = nullptr;
-            rd->child->child = nullptr;
-        }
-        snort_free(rd);
+        parent->child = nullptr;
+        parent->parent = nullptr;
+    }
+    if (child)
+    {
+        child->parent = nullptr;
+        child->child = nullptr;
     }
 }
 
@@ -119,24 +118,25 @@ void RexecServiceDetector::rexec_bail(ServiceREXECData* rd)
 
 int RexecServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    int i = 0;
-    uint32_t port = 0;
-    const uint8_t* data = args.data;
-    uint16_t size = args.size;
-
     ServiceREXECData* rd = (ServiceREXECData*)data_get(args.asd);
     if (!rd)
     {
-        if (!size)
-            goto inprocess;
-        rd = (ServiceREXECData*)snort_calloc(sizeof(ServiceREXECData));
-        data_add(args.asd, rd, &rexec_free_state);
-        rd->state = REXEC_STATE_PORT;
+        if (!args.size)
+        {
+            service_inprocess(args.asd, args.pkt, args.dir);
+            return APPID_INPROCESS;
+        }
+        rd = new ServiceREXECData(REXEC_STATE_PORT);
+        data_add(args.asd, rd);
     }
-    // cppcheck-suppress nullPointerRedundantCheck
     APPID_LOG(args.pkt, TRACE_DEBUG_LEVEL, "rexec state %d\n", rd->state);
 
-    switch (rd->state) // cppcheck-suppress nullPointerRedundantCheck
+    int i = 0;
+    uint32_t port = 0;
+    const uint8_t* data = args.data;
+    uint16_t size = args.size;
+
+    switch (rd->state)
     {
     case REXEC_STATE_PORT:
         if (args.dir != APP_ID_FROM_INITIATOR)
@@ -168,12 +168,10 @@ int RexecServiceDetector::validate(AppIdDiscoveryArgs& args)
 
             if (pf)
             {
-                ServiceREXECData* tmp_rd = (ServiceREXECData*)snort_calloc(
-                    sizeof(ServiceREXECData));
-                tmp_rd->state = REXEC_STATE_STDERR_CONNECT_SYN;
+                ServiceREXECData* tmp_rd = new ServiceREXECData(REXEC_STATE_STDERR_CONNECT_SYN);
                 tmp_rd->parent = rd;
 
-                data_add(*pf, tmp_rd, &rexec_free_state);
+                data_add(*pf, tmp_rd);
                 if (pf->add_flow_data_id((uint16_t)port, this))
                 {
                     pf->service_disco_state = APPID_DISCO_STATE_FINISHED;
index 32e5313204ae0a6ff81366a6eb54af09ee10f371..44916120e2ec3422323faee609bacf8112042f89 100644 (file)
@@ -25,7 +25,7 @@
 #include "service_detector.h"
 
 class ServiceDiscovery;
-struct ServiceREXECData;
+class ServiceREXECData;
 
 class RexecServiceDetector : public ServiceDetector
 {
index ba39a61167a2ba819c26b11340a3e85faf53d501..4065200212c8196021eb375fdf54f1062dbe935c 100644 (file)
@@ -39,9 +39,12 @@ enum RLOGINState
     RLOGIN_STATE_DONE
 };
 
-struct ServiceRLOGINData
+class ServiceRLOGINData: public AppIdFlowData
 {
-    RLOGINState state;
+public:
+    ~ServiceRLOGINData() override = default;
+
+    RLOGINState state = RLOGIN_STATE_HANDSHAKE;
 };
 
 RloginServiceDetector::RloginServiceDetector(ServiceDiscovery* sd)
@@ -67,22 +70,21 @@ RloginServiceDetector::RloginServiceDetector(ServiceDiscovery* sd)
 
 int RloginServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceRLOGINData* rd;
-    const uint8_t* data = args.data;
-
-    if (!args.size)
-        goto inprocess;
-    if (args.dir != APP_ID_FROM_RESPONDER)
-        goto inprocess;
+    if (!args.size || args.dir != APP_ID_FROM_RESPONDER)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    rd = (ServiceRLOGINData*)data_get(args.asd);
+    ServiceRLOGINData* rd = (ServiceRLOGINData*)data_get(args.asd);
     if (!rd)
     {
-        rd = (ServiceRLOGINData*)snort_calloc(sizeof(ServiceRLOGINData));
-        data_add(args.asd, rd, &snort_free);
-        rd->state = RLOGIN_STATE_HANDSHAKE;
+        rd = new ServiceRLOGINData;
+        data_add(args.asd, rd);
     }
 
+    const uint8_t* data = args.data;
+
     switch (rd->state)
     {
     case RLOGIN_STATE_HANDSHAKE:
@@ -124,7 +126,6 @@ int RloginServiceDetector::validate(AppIdDiscoveryArgs& args)
         goto fail;
     }
 
-inprocess:
     service_inprocess(args.asd, args.pkt, args.dir);
     return APPID_INPROCESS;
 
index c2e6e6ccb7f85e761e120e46f51f48d087f047f7..aae5685b840de812a4f2d62cedc5cdf5b2c34c62 100644 (file)
@@ -163,22 +163,27 @@ struct ServiceRPCReply
 
 #pragma pack()
 
-struct ServiceRPCData
+class ServiceRPCData : public AppIdFlowData
 {
+public:
+    explicit ServiceRPCData(RPCState state): state(state)
+    { }
+    ~ServiceRPCData() override = default;
+
     RPCState state;
-    RPCTCPState tcpstate[APP_ID_APPID_SESSION_DIRECTION_MAX];
-    RPCTCPState tcpfragstate[APP_ID_APPID_SESSION_DIRECTION_MAX];
-    uint32_t program;
-    uint32_t program_version;
-    uint32_t procedure;
-    uint32_t xid;
-    IpProtocol proto;
-    uint32_t tcpsize[APP_ID_APPID_SESSION_DIRECTION_MAX];
-    uint32_t tcpfragpos[APP_ID_APPID_SESSION_DIRECTION_MAX];
-    uint32_t tcpauthsize[APP_ID_APPID_SESSION_DIRECTION_MAX];
-    uint32_t tcppos[APP_ID_APPID_SESSION_DIRECTION_MAX];
-    uint8_t tcpdata[APP_ID_APPID_SESSION_DIRECTION_MAX][RPC_MAX_TCP_PACKET_SIZE];
-    int once;
+    RPCTCPState tcpstate[APP_ID_APPID_SESSION_DIRECTION_MAX] = {};
+    RPCTCPState tcpfragstate[APP_ID_APPID_SESSION_DIRECTION_MAX] = {};
+    uint32_t program = 0;
+    uint32_t program_version = 0;
+    uint32_t procedure = 0;
+    uint32_t xid = 0;
+    IpProtocol proto = {};
+    uint32_t tcpsize[APP_ID_APPID_SESSION_DIRECTION_MAX] = {};
+    uint32_t tcpfragpos[APP_ID_APPID_SESSION_DIRECTION_MAX] = {};
+    uint32_t tcpauthsize[APP_ID_APPID_SESSION_DIRECTION_MAX] = {};
+    uint32_t tcppos[APP_ID_APPID_SESSION_DIRECTION_MAX] = {};
+    uint8_t tcpdata[APP_ID_APPID_SESSION_DIRECTION_MAX][RPC_MAX_TCP_PACKET_SIZE] = {};
+    int once = 0;
 };
 
 #define RPC_PORT_PORTMAPPER 111
@@ -584,9 +589,8 @@ int RpcServiceDetector::rpc_udp_validate(AppIdDiscoveryArgs& args)
     rd = (ServiceRPCData*)data_get(args.asd);
     if (!rd)
     {
-        rd = (ServiceRPCData*)snort_calloc(sizeof(ServiceRPCData));
-        data_add(args.asd, rd, &snort_free);
-        rd->state = (dir == APP_ID_FROM_INITIATOR) ? RPC_STATE_CALL : RPC_STATE_REPLY;
+        rd = new ServiceRPCData((dir == APP_ID_FROM_INITIATOR) ? RPC_STATE_CALL : RPC_STATE_REPLY);
+        data_add(args.asd, rd);
         rd->xid = 0xFFFFFFFF;
     }
 
@@ -670,9 +674,8 @@ int RpcServiceDetector::rpc_tcp_validate(AppIdDiscoveryArgs& args)
     rd = (ServiceRPCData*)data_get(args.asd);
     if (!rd)
     {
-        rd = (ServiceRPCData*)snort_calloc(sizeof(ServiceRPCData));
-        data_add(args.asd, rd, &snort_free);
-        rd->state = RPC_STATE_CALL;
+        rd = new ServiceRPCData(RPC_STATE_CALL);
+        data_add(args.asd, rd);
         for (ret=0; ret<APP_ID_APPID_SESSION_DIRECTION_MAX; ret++)
         {
             rd->tcpstate[ret] = RPC_TCP_STATE_FRAG;
index 9e951d29b2a0cc51fdb63befb45deeffbdda426f..c6dd564d1b5362861ce4443b33f2fe99178774ad 100644 (file)
@@ -26,7 +26,7 @@
 
 class AppIdSession;
 class ServiceDiscovery;
-struct ServiceRPCData;
+class ServiceRPCData;
 
 class RpcServiceDetector : public ServiceDetector
 {
index 37e9754e52648f5dbe1777bc98287dd0948c4611..2b68d2a517f91e43d818d3cd6bfa55f594f3b673 100644 (file)
@@ -53,11 +53,16 @@ enum RSHELLState
     RSHELL_STATE_STDERR_DONE
 };
 
-struct ServiceRSHELLData
+class ServiceRSHELLData : public AppIdFlowData
 {
+public:
+    explicit ServiceRSHELLData(RSHELLState state) : state(state)
+    { }
+    ~ServiceRSHELLData() override;
+
+    ServiceRSHELLData* parent = nullptr;
+    ServiceRSHELLData* child = nullptr;
     RSHELLState state;
-    ServiceRSHELLData* parent;
-    ServiceRSHELLData* child;
 };
 
 RshellServiceDetector::RshellServiceDetector(ServiceDiscovery* sd)
@@ -81,23 +86,17 @@ RshellServiceDetector::RshellServiceDetector(ServiceDiscovery* sd)
 }
 
 
-static void rshell_free_state(void* data)
+ServiceRSHELLData::~ServiceRSHELLData()
 {
-    ServiceRSHELLData* rd = (ServiceRSHELLData*)data;
-
-    if (rd)
+    if (parent)
     {
-        if (rd->parent)
-        {
-            rd->parent->child = nullptr;
-            rd->parent->parent = nullptr;
-        }
-        if (rd->child)
-        {
-            rd->child->parent = nullptr;
-            rd->child->child = nullptr;
-        }
-        snort_free(rd);
+        parent->child = nullptr;
+        parent->parent = nullptr;
+    }
+    if (child)
+    {
+        child->parent = nullptr;
+        child->child = nullptr;
     }
 }
 
@@ -114,25 +113,26 @@ void RshellServiceDetector::rshell_bail(ServiceRSHELLData* rd)
 
 int RshellServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    int i = 0;
-    uint32_t port = 0;
-    const uint8_t* data = args.data;
-    uint16_t size = args.size;
-
     ServiceRSHELLData* rd = (ServiceRSHELLData*)data_get(args.asd);
     if (!rd)
     {
-        if (!size)
-            goto inprocess;
-        rd = (ServiceRSHELLData*)snort_calloc(sizeof(ServiceRSHELLData));
-        data_add(args.asd, rd, &rshell_free_state);
-        rd->state = RSHELL_STATE_PORT;
+        if (!args.size)
+        {
+            service_inprocess(args.asd, args.pkt, args.dir);
+            return APPID_INPROCESS;
+        }
+        rd = new ServiceRSHELLData(RSHELL_STATE_PORT);
+        data_add(args.asd, rd);
     }
 
-    // cppcheck-suppress nullPointerRedundantCheck
     APPID_LOG(args.pkt, TRACE_DEBUG_LEVEL, "RSHELL state %d\n",rd->state);
 
-    switch (rd->state) // cppcheck-suppress nullPointerRedundantCheck
+    int i = 0;
+    uint32_t port = 0;
+    const uint8_t* data = args.data;
+    uint16_t size = args.size;
+
+    switch (rd->state)
     {
     case RSHELL_STATE_PORT:
         if (args.dir != APP_ID_FROM_INITIATOR)
@@ -161,12 +161,10 @@ int RshellServiceDetector::validate(AppIdDiscoveryArgs& args)
 
             if (pf)
             {
-                ServiceRSHELLData* tmp_rd = (ServiceRSHELLData*)snort_calloc(
-                    sizeof(ServiceRSHELLData));
-                tmp_rd->state = RSHELL_STATE_STDERR_CONNECT_SYN;
+                ServiceRSHELLData* tmp_rd = new ServiceRSHELLData(RSHELL_STATE_STDERR_CONNECT_SYN);
                 tmp_rd->parent = rd;
                 pf->client_disco_state = APPID_DISCO_STATE_FINISHED;
-                data_add(*pf, tmp_rd, &rshell_free_state);
+                data_add(*pf, tmp_rd);
                 if (pf->add_flow_data_id((uint16_t)port, this))
                 {
                     pf->service_disco_state = APPID_DISCO_STATE_FINISHED;
index a55837cdcaf7d6b0283c846ec1c38af45481a0a1..90bbd4e3295dbdb2c1febf4c7998af0263669b50 100644 (file)
@@ -25,7 +25,7 @@
 #include "service_detector.h"
 
 class ServiceDiscovery;
-struct ServiceRSHELLData;
+class ServiceRSHELLData;
 
 class RshellServiceDetector : public ServiceDetector
 {
index 1402c7f2f5ffd20b226c2a2a6b0cc18a81fdbcaf..8bc27417a8b95add1d241fc836464c6c79a546c1 100644 (file)
@@ -37,9 +37,12 @@ enum RSYNCState
     RSYNC_STATE_DONE
 };
 
-struct ServiceRSYNCData
+class ServiceRSYNCData : public AppIdFlowData
 {
-    RSYNCState state;
+public:
+    ~ServiceRSYNCData() override = default;
+
+    RSYNCState state = RSYNC_STATE_BANNER;
 };
 
 RsyncServiceDetector::RsyncServiceDetector(ServiceDiscovery* sd)
@@ -70,24 +73,23 @@ RsyncServiceDetector::RsyncServiceDetector(ServiceDiscovery* sd)
 
 int RsyncServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceRSYNCData* rd;
-    int i;
-    const uint8_t* data = args.data;
-    uint16_t size = args.size;
-
-    if (!size)
-        goto inprocess;
-    if (args.dir != APP_ID_FROM_RESPONDER)
-        goto inprocess;
+    if (!args.size || args.dir != APP_ID_FROM_RESPONDER)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    rd = (ServiceRSYNCData*)data_get(args.asd);
+    ServiceRSYNCData* rd = (ServiceRSYNCData*)data_get(args.asd);
     if (!rd)
     {
-        rd = (ServiceRSYNCData*)snort_calloc(sizeof(ServiceRSYNCData));
-        data_add(args.asd, rd, &snort_free);
-        rd->state = RSYNC_STATE_BANNER;
+        rd = new ServiceRSYNCData;
+        data_add(args.asd, rd);
     }
 
+    int i;
+    const uint8_t* data = args.data;
+    uint16_t size = args.size;
+
     switch (rd->state)
     {
     case RSYNC_STATE_BANNER:
@@ -116,7 +118,6 @@ int RsyncServiceDetector::validate(AppIdDiscoveryArgs& args)
         goto fail;
     }
 
-inprocess:
     service_inprocess(args.asd, args.pkt, args.dir);
     return APPID_INPROCESS;
 
index c9e5751f3cab78580cf53d98c8337d1c8b1ad58f..0df64cf1a6b53734fda6f207124402ddf5ddbe85 100644 (file)
@@ -64,14 +64,17 @@ enum RTMPState
                                          server". */
 };
 
-struct ServiceRTMPData
+class ServiceRTMPData : public AppIdFlowData
 {
-    RTMPState client_state;
-    RTMPState server_state;
-    uint16_t client_bytes_left;
-    uint16_t server_bytes_left;
-    char* swfUrl;
-    char* pageUrl;
+public:
+    ~ServiceRTMPData() override;
+
+    char* swfUrl = nullptr;
+    char* pageUrl = nullptr;
+    RTMPState client_state = {};
+    RTMPState server_state = {};
+    uint16_t client_bytes_left = 0;
+    uint16_t server_bytes_left = 0;
 };
 
 RtmpServiceDetector::RtmpServiceDetector(ServiceDiscovery* sd)
@@ -95,12 +98,10 @@ RtmpServiceDetector::RtmpServiceDetector(ServiceDiscovery* sd)
     handler->register_detector(name, this, proto);
 }
 
-static void rtmp_free(void* ss)    /* AppIdFreeFCN */
+ServiceRTMPData::~ServiceRTMPData()
 {
-    ServiceRTMPData* ss_tmp = (ServiceRTMPData*)ss;
-    snort_free(ss_tmp->swfUrl);
-    snort_free(ss_tmp->pageUrl);
-    snort_free(ss_tmp);
+    snort_free(swfUrl);
+    snort_free(pageUrl);
 }
 
 static int parse_rtmp_chunk_basic_header(const uint8_t** data_inout, uint16_t* size_inout,
@@ -414,16 +415,17 @@ parse_rtmp_message_fail:
 
 int RtmpServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceRTMPData* ss;
-
     if (!args.size)
-        goto inprocess;
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    ss = (ServiceRTMPData*)data_get(args.asd);
+    ServiceRTMPData* ss = (ServiceRTMPData*)data_get(args.asd);
     if (!ss)
     {
-        ss = (ServiceRTMPData*)snort_calloc(sizeof(ServiceRTMPData));
-        data_add(args.asd, ss, &rtmp_free);
+        ss = new ServiceRTMPData;
+        data_add(args.asd, ss);
     }
 
     /* Client -> Server */
@@ -618,7 +620,6 @@ int RtmpServiceDetector::validate(AppIdDiscoveryArgs& args)
         goto fail;
     }
 
-inprocess:
     service_inprocess(args.asd, args.pkt, args.dir);
     return APPID_INPROCESS;
 
index 2f189f2c6f1556d3df9e6517c53531a33b516377..5064040da2c6717a9156bfa5ad7c82394cdbcc24 100644 (file)
@@ -57,8 +57,13 @@ enum SNMPState
     SNMP_STATE_ERROR
 };
 
-struct ServiceSNMPData
+class ServiceSNMPData : public AppIdFlowData
 {
+public:
+    explicit ServiceSNMPData(SNMPState state) : state(state)
+    { }
+    ~ServiceSNMPData() override = default;
+
     SNMPState state;
 };
 
@@ -388,25 +393,25 @@ static int snmp_verify_packet(const uint8_t** const data,
 
 int SnmpServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceSNMPData* sd = nullptr;
-    ServiceSNMPData* tmp_sd = nullptr;
+    if (!args.size)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
+
+    ServiceSNMPData* sd = (ServiceSNMPData*)data_get(args.asd);
+    if (!sd)
+    {
+        sd = new ServiceSNMPData(SNMP_STATE_CONNECTION);
+        data_add(args.asd, sd);
+    }
+
     uint8_t pdu = 0;
     uint8_t version = 0;
     const char* version_str = nullptr;
     const uint8_t* data = args.data;
     uint16_t size = args.size;
 
-    if (!size)
-        goto inprocess;
-
-    sd = (ServiceSNMPData*)data_get(args.asd);
-    if (!sd)
-    {
-        sd = (ServiceSNMPData*)snort_calloc(sizeof(ServiceSNMPData));
-        data_add(args.asd, sd, &snort_free);
-        sd->state = SNMP_STATE_CONNECTION;
-    }
-
     if (snmp_verify_packet(&data, data+size, &pdu, &version))
     {
         APPID_LOG(args.pkt, TRACE_DEBUG_LEVEL, "SNMP payload verify failed\n");
@@ -470,9 +475,8 @@ int SnmpServiceDetector::validate(AppIdDiscoveryArgs& args)
 
         if (pf)
         {
-            tmp_sd = (ServiceSNMPData*)snort_calloc(sizeof(ServiceSNMPData));
-            tmp_sd->state = SNMP_STATE_RESPONSE;
-            data_add(*pf, tmp_sd, &snort_free);
+            ServiceSNMPData* tmp_sd = new ServiceSNMPData(SNMP_STATE_RESPONSE);
+            data_add(*pf, tmp_sd);
             if (pf->add_flow_data_id(args.pkt->ptrs.dp, this))
             {
                 pf->set_session_flags(APPID_SESSION_SERVICE_DETECTED);
@@ -534,7 +538,6 @@ int SnmpServiceDetector::validate(AppIdDiscoveryArgs& args)
             goto bail;
     }
 
-inprocess:
     service_inprocess(args.asd, args.pkt, args.dir);
     return APPID_INPROCESS;
 
index 8f2b227a892aff4b0c99252d778820a5aa1a896e..266c29116090196754ed2439fb963430da9c9793 100644 (file)
@@ -51,20 +51,23 @@ enum SSLState
     SSL_STATE_HEADER,
 };
 
-struct ServiceSSLData
+class ServiceSSLData : public AppIdFlowData
 {
-    SSLState state;
-    int pos;
-    int length;
-    int tot_length;
+public:
+    ~ServiceSSLData() override;
+
+    SSLState state = SSL_STATE_INITIATE;
+    int pos = 0;
+    int length = 0;
+    int tot_length = 0;
     /* From client: */
     SSLV3ClientHelloData client_hello;
     /* From server: */
-    SSLV3ServerCertData server_cert;
-    int in_certs;         // Currently collecting certificates?
-    int certs_curr_len;   // Current amount of collected certificate data.
-    uint8_t* cached_data;
-    uint16_t cached_len;
+    SSLV3ServerCertData server_cert = {};
+    int in_certs = 0;         // Currently collecting certificates?
+    int certs_curr_len = 0;   // Current amount of collected certificate data.
+    uint8_t* cached_data = nullptr;
+    uint16_t cached_len = 0;
 };
 
 #pragma pack(1)
@@ -184,13 +187,11 @@ static void ssl_cache_free(uint8_t*& ssl_cache, uint16_t& len)
     len = 0;
 }
 
-static void ssl_free(void* ss)
+ServiceSSLData::~ServiceSSLData()
 {
-    ServiceSSLData* ss_tmp = (ServiceSSLData*)ss;
-    ss_tmp->client_hello.clear();
-    ss_tmp->server_cert.clear();
-    ssl_cache_free(ss_tmp->cached_data, ss_tmp->cached_len);
-    snort_free(ss_tmp);
+    client_hello.clear();
+    server_cert.clear();
+    ssl_cache_free(cached_data, cached_len);
 }
 
 static void parse_client_initiation(const uint8_t* data, uint16_t size, ServiceSSLData* ss)
@@ -223,7 +224,19 @@ static void save_ssl_cache(ServiceSSLData* ss, uint16_t size, const uint8_t* dat
 
 int SslServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceSSLData* ss;
+    if (!args.size)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
+
+    ServiceSSLData* ss = (ServiceSSLData*)data_get(args.asd);
+    if (!ss)
+    {
+        ss = new ServiceSSLData;
+        data_add(args.asd, ss);
+    }
+
     const ServiceSSLPCTHdr* pct;
     const ServiceSSLV2Hdr* hdr2;
     const ServiceSSLV3Hdr* hdr3;
@@ -234,19 +247,6 @@ int SslServiceDetector::validate(AppIdDiscoveryArgs& args)
     uint16_t size = args.size;
     uint8_t* reallocated_data = nullptr;
 
-    if (!size)
-        goto inprocess;
-
-    ss = (ServiceSSLData*)data_get(args.asd);
-    if (!ss)
-    {
-        ss = (ServiceSSLData*)snort_calloc(sizeof(ServiceSSLData));
-        data_add(args.asd, ss, &ssl_free);
-        ss->state = SSL_STATE_INITIATE;
-        ss->cached_data = nullptr;
-        ss->cached_len = 0;
-    }
-
     if (ss->cached_len and ss->cached_data and (args.dir == APP_ID_FROM_RESPONDER))
     {
         reallocated_data = (uint8_t*)snort_calloc(ss->cached_len + size, sizeof(uint8_t));
index bd1ad5e6b6423254b26011a4efbc8cd35388a343..13e58707999ff7a34fa102a718f44784113414e2 100644 (file)
@@ -66,9 +66,12 @@ enum TELNET_COMMAND_VALUE
     TELNET_CMD_IAC
 };
 
-struct ServiceTelnetData
+class ServiceTelnetData : public AppIdFlowData
 {
-    unsigned count;
+public:
+    ~ServiceTelnetData() override = default;
+
+    unsigned count = 0;
 };
 
 TelnetServiceDetector::TelnetServiceDetector(ServiceDiscovery* sd)
@@ -95,23 +98,23 @@ TelnetServiceDetector::TelnetServiceDetector(ServiceDiscovery* sd)
 
 int TelnetServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceTelnetData* td;
-    const uint8_t* end;
-    const uint8_t* data = args.data;
-    uint16_t size = args.size;
-
-    if (!size)
-        goto inprocess;
-    if (args.dir != APP_ID_FROM_RESPONDER)
-        goto inprocess;
+    if (!args.size || args.dir != APP_ID_FROM_RESPONDER)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    td = (ServiceTelnetData*)data_get(args.asd);
+    ServiceTelnetData* td = (ServiceTelnetData*)data_get(args.asd);
     if (!td)
     {
-        td = (ServiceTelnetData*)snort_calloc(sizeof(ServiceTelnetData));
-        data_add(args.asd, td, &snort_free);
+        td = new ServiceTelnetData;
+        data_add(args.asd, td);
     }
 
+    const uint8_t* end;
+    const uint8_t* data = args.data;
+    uint16_t size = args.size;
+
     for (end=(data+size); data<end; data++)
     {
         /* Currently we only look for the first packet to contain
@@ -138,7 +141,7 @@ int TelnetServiceDetector::validate(AppIdDiscoveryArgs& args)
             goto fail;
         }
     }
-inprocess:
+
     service_inprocess(args.asd, args.pkt, args.dir);
     return APPID_INPROCESS;
 
index 5d508cbd0d73eb60e783d9b25fbb59f7bbca1577..c8c8f9b9bf88c7904610ecc57481c9020e5a1473 100644 (file)
@@ -47,12 +47,17 @@ enum TFTPState
     TFTP_STATE_ERROR
 };
 
-struct ServiceTFTPData
+class ServiceTFTPData : public AppIdFlowData
 {
+public:
+    explicit ServiceTFTPData(TFTPState state) : state(state)
+    { }
+    ~ServiceTFTPData() override = default;
+
     TFTPState state;
-    unsigned count;
-    int last;
-    uint16_t block;
+    unsigned count = 0;
+    int last = 0;
+    uint16_t block= 0;
 };
 
 #pragma pack(1)
@@ -123,8 +128,20 @@ static int tftp_verify_header(const uint8_t* data, uint16_t size,
 
 int TftpServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceTFTPData* td = nullptr;
-    ServiceTFTPData* tmp_td = nullptr;
+    if (!args.size)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
+
+    ServiceTFTPData* td = (ServiceTFTPData*)data_get(args.asd);
+    if (!td)
+    {
+        td = new ServiceTFTPData(TFTP_STATE_CONNECTION);
+        data_add(args.asd, td);
+    }
+    APPID_LOG(args.pkt, TRACE_DEBUG_LEVEL, "TFTP state %d\n", td->state);
+
     int mode = 0;
     uint16_t block = 0;
     uint16_t tmp = 0;
@@ -134,18 +151,6 @@ int TftpServiceDetector::validate(AppIdDiscoveryArgs& args)
     const uint8_t* data = args.data;
     uint16_t size = args.size;
 
-    if (!size)
-        goto inprocess;
-
-    td = (ServiceTFTPData*)data_get(args.asd);
-    if (!td)
-    {
-        td = (ServiceTFTPData*)snort_calloc(sizeof(ServiceTFTPData));
-        data_add(args.asd, td, &snort_free);
-        td->state = TFTP_STATE_CONNECTION;
-    }
-    APPID_LOG(args.pkt, TRACE_DEBUG_LEVEL, "TFTP state %d\n", td->state);
-
     if (td->state == TFTP_STATE_CONNECTION && args.dir == APP_ID_FROM_RESPONDER)
         goto fail;
     if ((td->state == TFTP_STATE_TRANSFER || td->state == TFTP_STATE_DATA) &&
@@ -181,35 +186,35 @@ int TftpServiceDetector::validate(AppIdDiscoveryArgs& args)
         if (strcasecmp((const char*)data, "netascii") && strcasecmp((const char*)data, "octet"))
             goto bail;
 
-
-        tmp_td = (ServiceTFTPData*)snort_calloc(sizeof(ServiceTFTPData));
-        tmp_td->state = TFTP_STATE_TRANSFER;
-        dip = args.pkt->ptrs.ip_api.get_dst();
-        sip = args.pkt->ptrs.ip_api.get_src();
-        pf = AppIdSession::create_future_session(args.pkt,
-            dip, 0, sip, args.pkt->ptrs.sp, args.asd.protocol,
-            args.asd.config.snort_proto_ids[PROTO_INDEX_TFTP], args.asd.get_odp_ctxt());
-
-        if (pf)
         {
-            data_add(*pf, tmp_td, &snort_free);
-            if (pf->add_flow_data_id(args.pkt->ptrs.dp, this))
+            ServiceTFTPData* tmp_td = new ServiceTFTPData(TFTP_STATE_TRANSFER);
+            dip = args.pkt->ptrs.ip_api.get_dst();
+            sip = args.pkt->ptrs.ip_api.get_src();
+            pf = AppIdSession::create_future_session(args.pkt,
+                dip, 0, sip, args.pkt->ptrs.sp, args.asd.protocol,
+                args.asd.config.snort_proto_ids[PROTO_INDEX_TFTP], args.asd.get_odp_ctxt());
+
+            if (pf)
             {
-                pf->set_session_flags(APPID_SESSION_SERVICE_DETECTED);
-                pf->clear_session_flags(APPID_SESSION_CONTINUE);
-                tmp_td->state = TFTP_STATE_ERROR;
-                return APPID_ENOMEM;
+                data_add(*pf, tmp_td);
+                if (pf->add_flow_data_id(args.pkt->ptrs.dp, this))
+                {
+                    pf->set_session_flags(APPID_SESSION_SERVICE_DETECTED);
+                    pf->clear_session_flags(APPID_SESSION_CONTINUE);
+                    tmp_td->state = TFTP_STATE_ERROR;
+                    return APPID_ENOMEM;
+                }
+                args.asd.initialize_future_session(*pf, APPID_SESSION_EXPECTED_EVALUATE);
+                pf->set_initiator_ip(*sip);
+                pf->service_disco_state = APPID_DISCO_STATE_STATEFUL;
+                pf->scan_flags |= SCAN_HOST_PORT_FLAG;
+            }
+            else
+            {
+                delete tmp_td;
+                goto inprocess;   /* Assume that the flow already exists
+                                    as in a retransmit situation */
             }
-            args.asd.initialize_future_session(*pf, APPID_SESSION_EXPECTED_EVALUATE);
-            pf->set_initiator_ip(*sip);
-            pf->service_disco_state = APPID_DISCO_STATE_STATEFUL;
-            pf->scan_flags |= SCAN_HOST_PORT_FLAG;
-        }
-        else
-        {
-            snort_free(tmp_td);
-            goto inprocess;   /* Assume that the flow already exists
-                                 as in a retransmit situation */
         }
         break;
     case TFTP_STATE_TRANSFER:
index a7db5844f3db16e5b557d6063173aa34cb2c3d7e..273ab2e381d7c21755d9bb64a080b18050297fbc 100644 (file)
@@ -43,11 +43,14 @@ enum TIMBUKTUState
 };
 }
 
-struct ServiceTIMBUKTUData
+class ServiceTIMBUKTUData : public AppIdFlowData
 {
-    TIMBUKTUState state;
-    unsigned stringlen;
-    unsigned pos;
+public:
+    ~ServiceTIMBUKTUData() override = default;
+
+    TIMBUKTUState state = TIMBUKTU_STATE_BANNER;
+    unsigned stringlen = 0;
+    unsigned pos = 0;
 };
 
 #pragma pack(1)
@@ -88,24 +91,21 @@ TimbuktuServiceDetector::TimbuktuServiceDetector(ServiceDiscovery* sd)
 
 int TimbuktuServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceTIMBUKTUData* ss;
-    const uint8_t* data = args.data;
-    uint16_t offset=0;
-
-    if (!args.size)
-        goto inprocess;
-    if (args.dir != APP_ID_FROM_RESPONDER)
-        goto inprocess;
+    if (!args.size || args.dir != APP_ID_FROM_RESPONDER)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    ss = (ServiceTIMBUKTUData*)data_get(args.asd);
+    ServiceTIMBUKTUData* ss = (ServiceTIMBUKTUData*)data_get(args.asd);
     if (!ss)
     {
-        ss = (ServiceTIMBUKTUData*)snort_calloc(sizeof(ServiceTIMBUKTUData));
-        data_add(args.asd, ss, &snort_free);
-        ss->state = TIMBUKTU_STATE_BANNER;
+        ss = new ServiceTIMBUKTUData;
+        data_add(args.asd, ss);
     }
 
-    offset = 0;
+    const uint8_t* data = args.data;
+    uint16_t offset = 0;
     while (offset < args.size)
     {
         switch (ss->state)
@@ -152,7 +152,6 @@ int TimbuktuServiceDetector::validate(AppIdDiscoveryArgs& args)
         offset++;
     }
 
-inprocess:
     service_inprocess(args.asd, args.pkt, args.dir);
     return APPID_INPROCESS;
 
index a57440d3c3d40a94769b8b9ee471b217d59fcf1c..e7ee5dc901460939fea39ae83fbda159739b5591 100644 (file)
@@ -48,33 +48,33 @@ static const uint8_t TNS_BANNER[]  = "\000\000";
 #define TNS_TYPE_CONTROL 14
 #define TNS_TYPE_MAX 19
 
-namespace
+enum TNSSvcState
 {
-enum TNSState
-{
-    TNS_STATE_MESSAGE_LEN,
-    TNS_STATE_MESSAGE_CHECKSUM,
-    TNS_STATE_MESSAGE,
-    TNS_STATE_MESSAGE_RES,
-    TNS_STATE_MESSAGE_HD_CHECKSUM,
-    TNS_STATE_MESSAGE_ACCEPT,
-    TNS_STATE_MESSAGE_DATA
+    SVC_MSG_LEN = 0,
+    SVC_MSG_CHECKSUM,
+    SVC_MSG,
+    SVC_MSG_RES,
+    SVC_MSG_HD_CHECKSUM,
+    SVC_MSG_ACCEPT,
+    SVC_MSG_DATA
 };
-}
 
 #define ACCEPT_VERSION_OFFSET   8
-struct ServiceTNSData
+class ServiceTNSData : public AppIdFlowData
 {
-    TNSState state;
-    unsigned stringlen;
-    unsigned pos;
-    unsigned message;
+public:
+    ~ServiceTNSData() override = default;
+
+    const char* version = nullptr;
+    TNSSvcState state = SVC_MSG_LEN;
+    unsigned stringlen = 0;
+    unsigned pos = 0;
+    unsigned message = 0;
     union
     {
         uint16_t len;
         uint8_t raw_len[2];
-    } l;
-    const char* version;
+    } l = {};
 };
 
 #pragma pack(1)
@@ -117,30 +117,30 @@ TnsServiceDetector::TnsServiceDetector(ServiceDiscovery* sd)
 
 int TnsServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    ServiceTNSData* ss;
-    uint16_t offset;
-    const uint8_t* data = args.data;
-    uint16_t size = args.size;
-
-    if (!size)
-        goto inprocess;
-    if (args.dir != APP_ID_FROM_RESPONDER)
-        goto inprocess;
+    if (!args.size || args.dir != APP_ID_FROM_RESPONDER)
+    {
+        service_inprocess(args.asd, args.pkt, args.dir);
+        return APPID_INPROCESS;
+    }
 
-    ss = (ServiceTNSData*)data_get(args.asd);
+    ServiceTNSData* ss = (ServiceTNSData*)data_get(args.asd);
     if (!ss)
     {
-        ss = (ServiceTNSData*)snort_calloc(sizeof(ServiceTNSData));
-        data_add(args.asd, ss, &snort_free);
-        ss->state = TNS_STATE_MESSAGE_LEN;
+        ss = new ServiceTNSData();
+        data_add(args.asd, ss);
     }
 
-    offset = 0;
+    const uint8_t* data = args.data;
+    uint16_t size = args.size;
+    uint16_t offset = 0;
     while (offset < size)
     {
+        // For some reason, coverity cannot follow the state machine. It does state transitions that are not possible
+        // This makes the coverity overrun exceptions necessary
         switch (ss->state)
         {
-        case TNS_STATE_MESSAGE_LEN:
+        case SVC_MSG_LEN:
+            // coverity[overrun]
             ss->l.raw_len[ss->pos++] = data[offset];
             if (ss->pos >= offsetof(ServiceTNSMsg, checksum))
             {
@@ -153,44 +153,39 @@ int TnsServiceDetector::validate(AppIdDiscoveryArgs& args)
                 }
                 else if (ss->stringlen < 2)
                     goto fail;
-                else
-                {
-                    ss->state = TNS_STATE_MESSAGE_CHECKSUM;
-                }
+                ss->state = SVC_MSG_CHECKSUM;
             }
             break;
 
-        case TNS_STATE_MESSAGE_CHECKSUM:
+        case SVC_MSG_CHECKSUM:
             if (data[offset] != 0)
                 goto fail;
             ss->pos++;
             if (ss->pos >= offsetof(ServiceTNSMsg, msg))
-            {
-                ss->state = TNS_STATE_MESSAGE;
-            }
+                ss->state = SVC_MSG;
             break;
 
-        case TNS_STATE_MESSAGE:
+        case SVC_MSG:
             ss->message = data[offset];
             if (ss->message < TNS_TYPE_CONNECT || ss->message > TNS_TYPE_MAX)
                 goto fail;
             ss->pos++;
-            ss->state = TNS_STATE_MESSAGE_RES;
+            ss->state = SVC_MSG_RES;
             break;
 
-        case TNS_STATE_MESSAGE_RES:
+        case SVC_MSG_RES:
             ss->pos++;
-            ss->state = TNS_STATE_MESSAGE_HD_CHECKSUM;
+            ss->state = SVC_MSG_HD_CHECKSUM;
             break;
 
-        case TNS_STATE_MESSAGE_HD_CHECKSUM:
+        case SVC_MSG_HD_CHECKSUM:
             ss->pos++;
             if (ss->pos >= offsetof(ServiceTNSMsg, data))
             {
                 switch (ss->message)
                 {
                 case TNS_TYPE_ACCEPT:
-                    ss->state = TNS_STATE_MESSAGE_ACCEPT;
+                    ss->state = SVC_MSG_ACCEPT;
                     break;
                 case TNS_TYPE_ACK:
                 case TNS_TYPE_REFUSE:
@@ -208,14 +203,14 @@ int TnsServiceDetector::validate(AppIdDiscoveryArgs& args)
                         else
                             goto fail;
                     }
-                    ss->state = TNS_STATE_MESSAGE_DATA;
+                    ss->state = SVC_MSG_DATA;
                     break;
                 case TNS_TYPE_RESEND:
                     if (ss->pos == ss->stringlen)
                     {
                         if (offset == (size - 1))
                         {
-                            ss->state = TNS_STATE_MESSAGE_LEN;
+                            ss->state = SVC_MSG_LEN;
                             ss->pos = 0;
                             goto inprocess;
                         }
@@ -230,9 +225,8 @@ int TnsServiceDetector::validate(AppIdDiscoveryArgs& args)
             }
             break;
 
-        case TNS_STATE_MESSAGE_ACCEPT:
-            if (ss->pos >= (ACCEPT_VERSION_OFFSET + 2))
-                break;
+        case SVC_MSG_ACCEPT:
+            // coverity[overrun]
             ss->l.raw_len[ss->pos - ACCEPT_VERSION_OFFSET] = data[offset];
             ss->pos++;
             if (ss->pos == (ACCEPT_VERSION_OFFSET + 2))
@@ -257,10 +251,10 @@ int TnsServiceDetector::validate(AppIdDiscoveryArgs& args)
                 default:
                     break;
                 }
-                ss->state = TNS_STATE_MESSAGE_DATA;
+                ss->state = SVC_MSG_DATA;
             }
             break;
-        case TNS_STATE_MESSAGE_DATA:
+        case SVC_MSG_DATA:
             ss->pos++;
             if (ss->pos == ss->stringlen)
             {
index 9f3fe362b3a4c845bc5f6b43fe6cbfcdfd020074..17b9950611959d90056a74c72f716c103aa32ca6 100644 (file)
@@ -95,8 +95,8 @@ void ClientDiscovery::reload() {}
 FpSMBData* smb_data = nullptr;
 
 int AppIdDetector::initialize(AppIdInspector&){return 0;}
-int AppIdDetector::data_add(AppIdSession&, void*, AppIdFreeFCN){return 0;}
-void* AppIdDetector::data_get(const AppIdSession&) {return nullptr;}
+int AppIdDetector::data_add(AppIdSession&, AppIdFlowData*){return 0;}
+AppIdFlowData* AppIdDetector::data_get(const AppIdSession&) {return nullptr;}
 void AppIdDetector::add_user(AppIdSession&, const char*, AppId, bool, AppidChangeBits&){}
 void AppIdDetector::add_payload(AppIdSession&, AppId){}
 void AppIdDetector::add_app(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppId, const char*, AppidChangeBits&){}
@@ -112,7 +112,7 @@ void AppIdDiscovery::register_udp_pattern(AppIdDetector*, const uint8_t* const,
     int, unsigned){}
 int AppIdDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort&){return 0;}
 void ApplicationDescriptor::set_id(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&){}
-int AppIdSession::add_flow_data(void*, unsigned, AppIdFreeFCN) { return 0; }
+int AppIdSession::add_flow_data(void*, unsigned) { return 0; }
 int dcerpc_validate(const uint8_t*, int){return 0; }
 AppIdDiscovery::~AppIdDiscovery() { }
 void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { }
index 3d71c9136dbbca6827db28a2846a8cc972866288..9ec2591a3658f0ca2deb6bfae872b58113cf3da3 100644 (file)
@@ -296,7 +296,7 @@ HostPortVal* HostPortCache::find(const SfIp*, uint16_t, IpProtocol, const OdpCon
     return nullptr;
 }
 
-HostAppIdsVal* HostPortCache::find_on_first_pkt(const SfIp*, uint16_t, IpProtocol, const OdpContext&)
+const HostAppIdsVal* HostPortCache::find_on_first_pkt(const SfIp*, uint16_t, IpProtocol, const OdpContext&)
 {
     return nullptr;
 }
index 2556cf3704f584b0e05f9591825efda7a3648639..be3b12d2b1fc9949b8f92c1711c83f268e8f3469 100644 (file)
@@ -50,7 +50,7 @@ int Flow::set_flow_data(FlowData* fd)
     return 0;
 }
 
-FlowStash::~FlowStash() = default;
+bool FlowStash::get(const std::string &, StashGenericObject*&) { return false; }
 
 #endif
 
index a05e949b4c6b5b1bd0b89747d23c2741646cb574..1382aeac3fdd0cf201065224122a3cf68e7f0313 100644 (file)
@@ -128,12 +128,12 @@ AppIdSession::~AppIdSession()
     delete tsession;
 }
 
-void* AppIdSession::get_flow_data(unsigned) const
+AppIdFlowData* AppIdSession::get_flow_data(unsigned) const
 {
     return nullptr;
 }
 
-int AppIdSession::add_flow_data(void*, unsigned, AppIdFreeFCN)
+int AppIdSession::add_flow_data(AppIdFlowData*, unsigned)
 {
     return 0;
 }
index 7f791f0b6cd15f63bddffb81411bed3ec1e31a00..0ee30f24ac58313b3ed3cd8cbc292abcc99202fd 100644 (file)
@@ -288,13 +288,15 @@ TEST(service_state_tests, service_cache)
 
     // The cache should now be  ip6:3007, ip4:3008, ip6:3009.
     // Check that the order in the cache is correct.
-    Queue_t::iterator it = ServiceCache.newest();
-    std::vector<ServiceDiscoveryState*>::iterator vit = --ssvec.end();
-    for( size_t i=0; i<max_entries; i++, --it, --vit )
+    auto it = ServiceCache.end();
+    auto vit = ssvec.cend();
+    do
     {
-        Map_t::iterator mit = *it;
-        CHECK_TRUE( mit->second == *vit );
-    }
+        --it;
+        --vit;
+        CHECK_TRUE( vit != ssvec.begin() );
+        CHECK_TRUE( (*it)->second == *vit );
+    } while( it != ServiceCache.oldest() );
 
     // Now get e.g. the oldest from the cache and check that it got touched:
     it = ServiceCache.oldest();