]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2657 in SNORT/snort3 from ~SATHIRKA/snort3:dhcp_fp_unified to...
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Thu, 10 Dec 2020 20:39:29 +0000 (20:39 +0000)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Thu, 10 Dec 2020 20:39:29 +0000 (20:39 +0000)
Squashed commit of the following:

commit d37742db24cf3a3aae8e30d0df0a310347911d97
Author: Sreeja Athirkandathil Narayanan <sathirka@cisco.com>
Date:   Thu Dec 3 12:58:16 2020 -0500

    rna: Use service ip and port provided by appid for DHCP discovery events

12 files changed:
src/network_inspectors/appid/appid_app_descriptor.h
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/appid_session_api.cc
src/network_inspectors/appid/appid_session_api.h
src/network_inspectors/appid/service_plugins/service_detector.cc
src/network_inspectors/appid/service_plugins/service_discovery.cc
src/network_inspectors/appid/test/appid_mock_session.h
src/network_inspectors/appid/tp_appid_utils.cc
src/network_inspectors/rna/rna_app_discovery.cc
src/network_inspectors/rna/rna_app_discovery.h

index 89b5d2701b5a5787235c616843dbf227c1f61cbf..3124435cef52e92739c9b1b9f9f5afd603772fee 100644 (file)
@@ -103,7 +103,11 @@ struct AppIdServiceSubtype
 class ServiceAppDescriptor : public ApplicationDescriptor
 {
 public:
-    ServiceAppDescriptor() = default;
+    ServiceAppDescriptor()
+    {
+        service_ip.clear();
+    }
+
     ~ServiceAppDescriptor() override
     {
         AppIdServiceSubtype* tmp_subtype = subtype;
@@ -130,6 +134,9 @@ public:
             delete tmp_subtype;
             tmp_subtype = subtype;
         }
+        service_ip.clear();
+        service_port = 0;
+        service_group = DAQ_PKTHDR_UNKNOWN;
     }
 
     void update_stats(AppId id, bool increment = true) override;
@@ -175,12 +182,50 @@ public:
         return subtype;
     }
 
+    void set_service_ip(const snort::SfIp& ip)
+    {
+        service_ip = ip;
+    }
+
+    const snort::SfIp& get_service_ip() const
+    {
+        return service_ip;
+    }
+
+    bool is_service_ip_set() const
+    {
+        return service_ip.is_set();
+    }
+
+    void set_service_port(uint16_t port)
+    {
+        service_port = port;
+    }
+
+    uint16_t get_service_port() const
+    {
+        return service_port;
+    }
+
+    void set_service_group(int16_t group)
+    {
+        service_group = group;
+    }
+
+    int16_t get_service_group() const
+    {
+        return service_group;
+    }
+
 private:
     AppId port_service_id = APP_ID_NONE;
     bool deferred = false;
     using ApplicationDescriptor::set_id;
     std::string my_vendor;
     AppIdServiceSubtype* subtype = nullptr;
+    snort::SfIp service_ip;
+    uint16_t service_port = 0;
+    int16_t service_group = DAQ_PKTHDR_UNKNOWN;
 };
 
 class ClientAppDescriptor : public ApplicationDescriptor
index b6c4caef0ebd452fdc56537957cd743b7c982da8..0a53fc23d917a75268a4eb8e823506571da5f39a 100644 (file)
@@ -501,7 +501,7 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession*& asd, AppIdInspec
 
                 asd->set_session_flags(APPID_SESSION_SYN_RST);
                 if (asd->is_service_ip_set())
-                    std::tie(ip, port, group) = asd->get_service_info();
+                    std::tie(ip, port, group) = asd->get_server_info();
                 else
                 {
                     ip = p->ptrs.ip_api.get_src();
index bd1c4561e3c8a3eec02d1395a81bfd7297924dd6..ba1b793c0ea375663259c908e595cca91bd28f04 100644 (file)
@@ -101,8 +101,6 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t port,
         odp_ctxt_version(odp_ctxt.get_version()),
         tp_appid_ctxt(pkt_thread_tp_appid_ctxt)
 {
-    service_ip.clear();
-
     appid_stats.total_sessions++;
 }
 
@@ -118,12 +116,13 @@ AppIdSession::~AppIdSession()
             APPID_SESSION_UDP_REVERSED | APPID_SESSION_MID |
             APPID_SESSION_OOO) and flow)
         {
+            const SfIp& svc_ip = api.service.get_service_ip();
             ServiceDiscoveryState* sds =
-                AppIdServiceState::get(&service_ip, protocol, service_port, service_group,
-                    asid, is_decrypted());
+                AppIdServiceState::get(&svc_ip, protocol, api.service.get_service_port(),
+                    api.service.get_service_group(), asid, is_decrypted());
             if (sds)
             {
-                if (flow->server_ip.fast_eq6(service_ip))
+                if (flow->server_ip.fast_eq6(svc_ip))
                     sds->set_service_id_failed(*this, &flow->client_ip,
                         STATE_ID_INCONCLUSIVE_SERVICE_WEIGHT);
                 else
@@ -281,8 +280,6 @@ void AppIdSession::reinit_session_data(AppidChangeBits& change_bits,
     {
         api.service.reset();
         tp_app_id = APP_ID_NONE;
-        service_ip.clear();
-        service_port = 0;
         service_disco_state = APPID_DISCO_STATE_NONE;
         service_detector = nullptr;
         service_search_state = SESSION_SERVICE_SEARCH_STATE::START;
@@ -420,8 +417,6 @@ void AppIdSession::check_tunnel_detection_restart()
         api.service.set_id(APP_ID_NONE, odp_ctxt);
     api.service.set_port_service_id(APP_ID_NONE);
     api.service.reset();
-    service_ip.clear();
-    service_port = 0;
     service_disco_state = APPID_DISCO_STATE_NONE;
     service_detector = nullptr;
     free_flow_data_by_mask(APPID_SESSION_DATA_SERVICE_MODSTATE_BIT);
@@ -720,7 +715,7 @@ int AppIdSession::add_flow_data_id(uint16_t port, ServiceDetector* service)
     if (service_detector)
         return -1;
     service_detector = service;
-    service_port = port;
+    set_service_port(port);
     return 0;
 }
 
@@ -728,13 +723,13 @@ void AppIdSession::stop_service_inspection(Packet* p, AppidSessionDirection dire
 {
     if (direction == APP_ID_FROM_INITIATOR)
     {
-        service_ip = *p->ptrs.ip_api.get_dst();
-        service_port = p->ptrs.dp;
+        set_service_ip(*p->ptrs.ip_api.get_dst());
+        set_service_port(p->ptrs.dp);
     }
     else
     {
-        service_ip = *p->ptrs.ip_api.get_src();
-        service_port = p->ptrs.sp;
+        set_service_ip(*p->ptrs.ip_api.get_src());
+        set_service_port(p->ptrs.sp);
     }
 
     service_disco_state = APPID_DISCO_STATE_FINISHED;
index f55d6f134f7fef9c8104b5d0a562cc320154da05..4e4fd53445b29f4b9170242e457c8ec8e33b4d91 100644 (file)
@@ -546,6 +546,16 @@ public:
         api.initiator_ip = ip;
     }
 
+    void set_service_ip(const snort::SfIp& ip)
+    {
+        api.service.set_service_ip(ip);
+    }
+
+    void set_service_port(uint16_t port)
+    {
+        api.service.set_service_port(port);
+    }
+
     void set_tls_host(const AppidChangeBits& change_bits)
     {
         if (tsession and change_bits[APPID_TLSHOST_BIT])
@@ -567,26 +577,27 @@ public:
         return tp_appid_ctxt;
     }
 
-    void set_service_info(const snort::SfIp& ip, uint16_t port, int16_t group = DAQ_PKTHDR_UNKNOWN)
+    void set_server_info(const snort::SfIp& ip, uint16_t port, int16_t group = DAQ_PKTHDR_UNKNOWN)
     {
-        service_ip = ip;
-        service_port = port;
-        service_group = group;
+        api.service.set_service_ip(ip);
+        api.service.set_service_port(port);
+        api.service.set_service_group(group);
     }
 
-    std::tuple<const snort::SfIp*, uint16_t, int16_t>  get_service_info() const
+    std::tuple<const snort::SfIp*, uint16_t, int16_t>  get_server_info() const
     {
-        return std::make_tuple(&service_ip, service_port, service_group);
+        return std::make_tuple(&api.service.get_service_ip(), api.service.get_service_port(),
+            api.service.get_service_group());
     }
 
     uint16_t get_service_port() const
     {
-        return service_port;
+        return api.service.get_service_port();
     }
 
     bool is_service_ip_set() const
     {
-        return service_ip.is_set();
+        return api.service.is_service_ip_set();
     }
 
     void set_user_logged_in()
@@ -612,10 +623,6 @@ private:
     AppId tp_app_id = APP_ID_NONE;
     AppId tp_payload_app_id = APP_ID_NONE;
 
-    snort::SfIp service_ip;
-    uint16_t service_port = 0;
-    int16_t service_group = DAQ_PKTHDR_UNKNOWN;
-
     uint16_t my_inferred_svcs_ver = 0;
     snort::AppIdSessionApi& api;
     static uint16_t inferred_svcs_ver;
index bf3593d14e32b9b8ee414355662fef1fb1b034af..aed49b8888b0a5e80b505f40dfaaf092a9cfade8 100644 (file)
@@ -280,6 +280,16 @@ const SfIp* AppIdSessionApi::get_initiator_ip() const
     return &initiator_ip;
 }
 
+const SfIp& AppIdSessionApi::get_service_ip() const
+{
+    return service.get_service_ip();
+}
+
+uint16_t AppIdSessionApi::get_service_port() const
+{
+    return service.get_service_port();
+}
+
 const AppIdDnsSession* AppIdSessionApi::get_dns_session() const
 {
     return dsession;
index 0e896a6666c6a7d8f47184d429b272ef5b05c8c2..19a800bf420743c05c3488317de911c51b67cb76 100644 (file)
@@ -120,6 +120,8 @@ public:
     const char* get_client_info(uint32_t stream_index = 0) const;
     uint64_t get_appid_session_attribute(uint64_t flag) const;
     const SfIp* get_initiator_ip() const;
+    const SfIp& get_service_ip() const;
+    uint16_t get_service_port() const;
     const AppIdDnsSession* get_dns_session() const;
     const AppIdHttpSession* get_http_session(uint32_t stream_index = 0) const;
     const char* get_tls_host() const;
index b697c8cd8a4d1731bc4a52ce1fc4f126873e48b0..547c9efcf00eae1e65229586f0e02f86fdaf6bd9 100644 (file)
@@ -73,7 +73,7 @@ int ServiceDetector::service_inprocess(AppIdSession& asd, const Packet* pkt, App
     if (!asd.is_service_ip_set())
     {
         uint16_t port = asd.get_service_port();
-        asd.set_service_info(*(pkt->ptrs.ip_api.get_src()),
+        asd.set_server_info(*(pkt->ptrs.ip_api.get_src()),
             port ? port : pkt->ptrs.sp, pkt->get_ingress_group());
     }
     return APPID_SUCCESS;
@@ -131,7 +131,7 @@ int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt,
         }
     }
 
-    asd.set_service_info(*ip, port, group);
+    asd.set_server_info(*ip, port, group);
 
     ServiceDiscoveryState* sds = AppIdServiceState::add(ip, asd.protocol, port,
         group, asd.asid, asd.is_decrypted());
index 8a8030a71e4d84cfcabe87d2a1742f2450ecdaf6..d8f10d1181ed6c721186e52e284505b8c1ef644a 100644 (file)
@@ -403,7 +403,7 @@ int ServiceDiscovery::identify_service(AppIdSession& asd, Packet* p,
     /* Get packet info. */
     auto proto = asd.protocol;
     if ( asd.is_service_ip_set() )
-        std::tie(ip, port, group) = asd.get_service_info();
+        std::tie(ip, port, group) = asd.get_server_info();
     else
     {
         if ( dir == APP_ID_FROM_RESPONDER )
@@ -418,7 +418,7 @@ int ServiceDiscovery::identify_service(AppIdSession& asd, Packet* p,
             port = p->ptrs.dp;
             group = p->get_egress_group();
         }
-        asd.set_service_info(*ip, port, group);
+        asd.set_server_info(*ip, port, group);
     }
 
     if ( asd.service_search_state == SESSION_SERVICE_SEARCH_STATE::START )
@@ -766,7 +766,7 @@ int ServiceDiscovery::incompatible_data(AppIdSession& asd, const Packet* pkt, Ap
     sds->set_service(service);
     sds->set_reset_time(0);
     if ( !asd.is_service_ip_set() )
-        asd.set_service_info(*ip, port, group);
+        asd.set_server_info(*ip, port, group);
 
     return APPID_SUCCESS;
 }
@@ -808,7 +808,7 @@ int ServiceDiscovery::fail_service(AppIdSession& asd, const Packet* pkt, AppidSe
         port = pkt->ptrs.sp;
 
     if (!asd.is_service_ip_set())
-        asd.set_service_info(*ip, port, group);
+        asd.set_server_info(*ip, port, group);
 
     if ( !sds )
     {
index f2be49fb9d62a90cbcb31ed0d1cd820148ca3f14..b5cdc4076c3b508573778afe160442b2d0a395b4 100644 (file)
@@ -84,7 +84,7 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t, AppIdInsp
     protocol(proto), api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt)
 {
     odp_ctxt_version = odp_ctxt.get_version();
-    service_port = APPID_UT_SERVICE_PORT;
+    set_service_port(APPID_UT_SERVICE_PORT);
     AppidChangeBits change_bits;
 
     set_client_user(APPID_UT_ID, APPID_UT_USERNAME, change_bits);
@@ -96,7 +96,9 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t, AppIdInsp
 
     tsession = new TlsSession;
 
-    service_ip.pton(AF_INET, APPID_UT_SERVICE_IP_ADDR);
+    SfIp svc_ip;
+    svc_ip.pton(AF_INET, APPID_UT_SERVICE_IP_ADDR);
+    set_service_ip(svc_ip);
     api.initiator_ip.pton(AF_INET, APPID_UT_INITIATOR_IP_ADDR);
 
     netbios_name = snort_strdup(APPID_UT_NETBIOS_NAME);
index 3b13cb2d1161444caeb7f3eda72094834e6000c2..8640ca3687fb770fef5ee4f0188230a211319aa3 100644 (file)
@@ -754,10 +754,10 @@ bool do_tp_discovery(ThirdPartyAppIdContext& tp_appid_ctxt, AppIdSession& asd, I
                     APPID_SESSION_SERVICE_DETECTED);
                 asd.clear_session_flags(APPID_SESSION_CONTINUE);
                 if (direction == APP_ID_FROM_INITIATOR)
-                    asd.set_service_info(*(p->ptrs.ip_api.get_dst()), p->ptrs.dp,
+                    asd.set_server_info(*(p->ptrs.ip_api.get_dst()), p->ptrs.dp,
                         p->get_egress_group());
                 else
-                    asd.set_service_info(*(p->ptrs.ip_api.get_src()), p->ptrs.sp,
+                    asd.set_server_info(*(p->ptrs.ip_api.get_src()), p->ptrs.sp,
                         p->get_ingress_group());
             }
         }
index 7a72a6b53c57b3d25d30ec40945d35af5e9847b0..70e55160e3301ccf2cc24e07d3060d7456ff1166 100644 (file)
@@ -70,6 +70,8 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
     const auto& appid_session_api = appid_event->get_appid_session_api();
     AppId service = appid_session_api.get_service_app_id();
     bool newservice = false;
+    bool is_client = false;
+    uint16_t port = p->flow->server_port;
 
     if ( appid_change_bits[APPID_SERVICE_BIT] or appid_change_bits[APPID_CLIENT_BIT] or
         appid_change_bits[APPID_PAYLOAD_BIT] )
@@ -78,8 +80,17 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
         appid_session_api.get_app_id(nullptr, &client, &payload, nullptr, nullptr);
 
         if ( appid_change_bits[APPID_SERVICE_BIT] and service > APP_ID_NONE )
+        {
+            if (service == APP_ID_DHCP)
+            {
+                const SfIp& service_ip = appid_session_api.get_service_ip();
+                if (p->flow->client_ip.fast_eq6(service_ip))
+                    is_client = true;
+                port = appid_session_api.get_service_port();
+            }
             newservice = discover_service(p, rna_flow, proto, conf, logger,
-                p->flow->server_port, service);
+                port, service, is_client);
+        }
 
         if ( appid_change_bits[APPID_CLIENT_BIT] and client > APP_ID_NONE
             and service > APP_ID_NONE )
@@ -101,12 +112,12 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
         const char* version;
         const AppIdServiceSubtype* subtype;
         appid_session_api.get_service_info(vendor, version, subtype);
-        update_service_info(p, rna_flow, proto, vendor, version, logger, conf, service);
+        update_service_info(p, rna_flow, proto, port, vendor, version, logger, conf, service, is_client);
     }
     else if ( newservice and appid_change_bits[APPID_SERVICE_BIT]
         and service > APP_ID_NONE )
     {
-        update_service_info(p, rna_flow, proto, nullptr, nullptr, logger, conf, service);
+        update_service_info(p, rna_flow, proto, port, nullptr, nullptr, logger, conf, service, is_client);
     }
 
     if ( conf->enable_banner_grab and p->is_from_server() and
@@ -150,9 +161,17 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
 }
 
 bool RnaAppDiscovery::discover_service(const Packet* p, RNAFlow* rna_flow, IpProtocol proto,
-    RnaConfig* conf, RnaLogger& logger, uint16_t port, AppId service)
+    RnaConfig* conf, RnaLogger& logger, uint16_t port, AppId service, bool is_client)
 {
-    RnaTracker htp = get_server_rna_tracker(p, rna_flow);
+    RnaTracker htp;
+    SfIp ip = p->flow->server_ip;
+    if (!is_client)
+        htp = get_server_rna_tracker(p, rna_flow);
+    else
+    {
+        htp = get_client_rna_tracker(p, rna_flow);
+        ip = p->flow->client_ip;
+    }
 
     if ( !htp or !htp->is_visible() )
         return false;
@@ -170,12 +189,10 @@ bool RnaAppDiscovery::discover_service(const Packet* p, RNAFlow* rna_flow, IpPro
     {
         if ( proto == IpProtocol::TCP )
             logger.log(RNA_EVENT_NEW, NEW_TCP_SERVICE, p, &htp,
-                (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(),
-                htp->get_last_seen_mac(), &ha);
+                (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
         else
             logger.log(RNA_EVENT_NEW, NEW_UDP_SERVICE, p, &htp,
-                (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(),
-                htp->get_last_seen_mac(), &ha);
+                (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
 
         ha.hits = 0; // hit count is reset after logs are written
         htp->update_service(ha);
@@ -239,16 +256,25 @@ void RnaAppDiscovery::discover_payload(const Packet* p, RNAFlow* rna_flow, IpPro
             crt->get_last_seen_mac(), &hc);
 }
 
-void RnaAppDiscovery::update_service_info(const Packet* p, RNAFlow* rna_flow, IpProtocol proto,
-    const char* vendor, const char* version, RnaLogger& logger, RnaConfig* conf, AppId service)
+void RnaAppDiscovery::update_service_info(const Packet* p, RNAFlow* rna_flow, IpProtocol proto, uint16_t port,
+    const char* vendor, const char* version, RnaLogger& logger, RnaConfig* conf, AppId service, bool is_client)
 {
-    RnaTracker htp = get_server_rna_tracker(p, rna_flow);
+    RnaTracker htp;
+    SfIp ip = p->flow->server_ip;
+    if (!is_client)
+        htp = get_server_rna_tracker(p, rna_flow);
+    else
+    {
+        htp = get_client_rna_tracker(p, rna_flow);
+        ip = p->flow->client_ip;
+    }
+
     if ( !htp or !htp->is_visible() )
         return;
 
     htp->update_last_seen();
 
-    HostApplication ha(p->flow->server_port, proto, service, false);
+    HostApplication ha(port, proto, service, false);
     if ( !htp->update_service_info(ha, vendor, version, conf->max_host_service_info) )
         return;
 
@@ -257,12 +283,10 @@ void RnaAppDiscovery::update_service_info(const Packet* p, RNAFlow* rna_flow, Ip
 
     if ( proto == IpProtocol::TCP )
         logger.log(RNA_EVENT_CHANGE, CHANGE_TCP_SERVICE_INFO, p, &htp,
-            (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), htp->get_last_seen_mac(),
-            &ha);
+            (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
     else
         logger.log(RNA_EVENT_CHANGE, CHANGE_UDP_SERVICE_INFO, p, &htp,
-            (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), htp->get_last_seen_mac(),
-            &ha);
+            (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
 
     ha.hits = 0;
     htp->update_service(ha);
index 7ae0dc9fc84ac96ad99556ef3009939b7ace895e..b9b18e4d108cecb673f8d7992dfdb3ff0dad08e4 100644 (file)
@@ -29,7 +29,7 @@ public:
     static void process(AppidEvent*, DiscoveryFilter&, RnaConfig*, RnaLogger&);
 
     static bool discover_service(const snort::Packet*, RNAFlow*, IpProtocol, RnaConfig*,
-        RnaLogger&, uint16_t, AppId service = APP_ID_NONE);
+        RnaLogger&, uint16_t, AppId service = APP_ID_NONE, bool is_client = false);
 
     static void discover_payload(const snort::Packet*, RNAFlow*, IpProtocol, RnaConfig*,
         RnaLogger&, AppId service, AppId payload, AppId client);
@@ -42,8 +42,8 @@ public:
 
     static void discover_banner(const snort::Packet*, RNAFlow*, IpProtocol, RnaLogger&, AppId);
 private:
-    static void update_service_info(const snort::Packet*, RNAFlow*, IpProtocol,
-        const char* vendor, const char* version, RnaLogger&, RnaConfig*, AppId service);
+    static void update_service_info(const snort::Packet*, RNAFlow*, IpProtocol, uint16_t,
+        const char* vendor, const char* version, RnaLogger&, RnaConfig*, AppId service, bool is_client = false);
 
     static void analyze_user_agent_fingerprint(const snort::Packet*, RNAFlow*, const char* host,
         const char* uagent, RnaLogger&, snort::UaFpProcessor&);