]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2684 in SNORT/snort3 from ~ARMANDAV/snort3:rnafilter to master
authorMasud Hasan (mashasan) <mashasan@cisco.com>
Thu, 7 Jan 2021 20:23:36 +0000 (20:23 +0000)
committerMasud Hasan (mashasan) <mashasan@cisco.com>
Thu, 7 Jan 2021 20:23:36 +0000 (20:23 +0000)
Squashed commit of the following:

commit f4e3ff89854a11ff6d1cf3acd9bb7f99c2445314
Author: Arun Mandava <armandav@cisco.com>
Date:   Tue Dec 22 15:49:13 2020 -0500

    rna: Perform appropriate filter check based on the event type

src/helpers/discovery_filter.cc
src/helpers/discovery_filter.h
src/network_inspectors/rna/rna_app_discovery.cc
src/network_inspectors/rna/rna_app_discovery.h

index a3e3a3602748239f7521b41791a2f578bb18ad6c..b8230ae0f42dd53fde77962141d809f01bb03817 100644 (file)
@@ -203,11 +203,12 @@ bool DiscoveryFilter::is_app_monitored(const Packet* p, uint8_t* flag)
     return is_monitored(p, DF_APP, *flag, DF_APP_CHECKED, DF_APP_MONITORED);
 }
 
-bool DiscoveryFilter::is_host_monitored(const Packet* p, uint8_t* flag, const SfIp* ip)
+bool DiscoveryFilter::is_host_monitored(const Packet* p, uint8_t* flag, const SfIp* ip,
+    FlowCheckDirection flowdir)
 {
     if ( flag == nullptr )
-        return is_monitored(p, DF_HOST, ip);
-    return is_monitored(p, DF_HOST, *flag, DF_HOST_CHECKED, DF_HOST_MONITORED, ip);
+        return is_monitored(p, DF_HOST, ip, flowdir);
+    return is_monitored(p, DF_HOST, *flag, DF_HOST_CHECKED, DF_HOST_MONITORED, ip, flowdir);
 }
 
 bool DiscoveryFilter::is_user_monitored(const Packet* p, uint8_t* flag)
@@ -218,14 +219,14 @@ bool DiscoveryFilter::is_user_monitored(const Packet* p, uint8_t* flag)
 }
 
 bool DiscoveryFilter::is_monitored(const Packet* p, FilterType type, uint8_t& flag,
-    uint8_t checked, uint8_t monitored, const SfIp* ip)
+    uint8_t checked, uint8_t monitored, const SfIp* ip, FlowCheckDirection flowdir)
 {
     if ( flag & checked )
         return flag & monitored;
 
     flag |= checked;
 
-    if ( is_monitored(p, type, ip) )
+    if ( is_monitored(p, type, ip, flowdir) )
     {
         flag |= monitored;
         return true;
@@ -235,7 +236,8 @@ bool DiscoveryFilter::is_monitored(const Packet* p, FilterType type, uint8_t& fl
     return false;
 }
 
-bool DiscoveryFilter::is_monitored(const Packet* p, FilterType type, const SfIp* ip)
+bool DiscoveryFilter::is_monitored(const Packet* p, FilterType type, const SfIp* ip,
+    FlowCheckDirection flowdir)
 {
     if ( !vartable )
         return true; // when not configured, 'any' ip/port/interface are monitored by default
@@ -245,20 +247,39 @@ bool DiscoveryFilter::is_monitored(const Packet* p, FilterType type, const SfIp*
         return false;
 
     // check interface
-    if (intf_ip_list[type].empty())
+    if ( intf_ip_list[type].empty() )
         return false; // the configuration did not have this type of rule
 
-    auto intf = (int32_t)p->pkth->ingress_index;
+    int32_t intf;
+    const SfIp* host_ip;
+    if ( flowdir == FlowCheckDirection::DF_SERVER )
+    {
+        intf = (int32_t)p->flow->server_intf;
+        host_ip = &p->flow->server_ip;
+    }
+    else if ( flowdir == FlowCheckDirection::DF_CLIENT )
+    {
+        intf = (int32_t)p->flow->client_intf;
+        host_ip = &p->flow->client_ip;
+    }
+    else
+    {
+        intf = (int32_t)p->pkth->ingress_index;
+        host_ip = p->ptrs.ip_api.get_src();
+    }
+
     if ( intf == DAQ_PKTHDR_UNKNOWN or intf < 0 )
         intf = DF_ANY_INTF;
+    if ( ip )
+        host_ip = ip;
+
     auto varip = get_list(type, intf, true);
-    if (!varip and intf != DF_ANY_INTF)
+    if ( !varip and intf != DF_ANY_INTF )
         varip = get_list(type, DF_ANY_INTF, true);
 
-    if (!p->ptrs.ip_api.get_src() and !ip)
+    if ( !host_ip )
         return true; // Don't check for non-IP, non ARP
 
-    const SfIp* host_ip = (ip) ? ip : p->ptrs.ip_api.get_src();
     return sfvar_ip_in(varip, host_ip);
 }
 
index 0c1c2e9f0d6df7d2afb4993259121d9f12d22b6d..0652d1d4af197265fe2e57987a74aa9d1d15de06 100644 (file)
@@ -28,6 +28,7 @@
 #include "sfip/sf_vartable.h"
 
 enum FilterType { DF_APP, DF_HOST, DF_USER, DF_MAX };
+enum FlowCheckDirection { DF_NONE, DF_CLIENT, DF_SERVER };
 
 typedef int32_t IntfType; // matching daq header
 #define DF_ANY_INTF INT32_MAX
@@ -42,7 +43,7 @@ public:
     // If flag is provided (preferable), results are stored in flag to avoid future lookups
     bool is_app_monitored(const snort::Packet* p, uint8_t* flag = nullptr);
     bool is_host_monitored(const snort::Packet* p, uint8_t* flag = nullptr,
-        const snort::SfIp* ip = nullptr);
+        const snort::SfIp* ip = nullptr, FlowCheckDirection flowdir = FlowCheckDirection::DF_NONE);
     bool is_user_monitored(const snort::Packet* p, uint8_t* flag = nullptr);
 
 private:
@@ -50,8 +51,10 @@ private:
     enum Direction { CLIENT, SERVER, NUM_DIRECTIONS };
 
     bool is_monitored(const snort::Packet* p, FilterType type, uint8_t& flag,
-        uint8_t checked, uint8_t monitored, const snort::SfIp* ip = nullptr);
-    bool is_monitored(const snort::Packet* p, FilterType type, const snort::SfIp* ip = nullptr);
+        uint8_t checked, uint8_t monitored, const snort::SfIp* ip = nullptr,
+        FlowCheckDirection flowdir = FlowCheckDirection::DF_NONE);
+    bool is_monitored(const snort::Packet* p, FilterType type, const snort::SfIp* ip = nullptr,
+        FlowCheckDirection flowdir = FlowCheckDirection::DF_NONE);
     void add_ip(FilterType type, IntfType intf, std::string& ip);
     sfip_var_t* get_list(FilterType type, IntfType intf, bool exclude_empty = false);
 
index e59949a7d8b6a6f6b693fad5cfd0016a2dbf47a8..18151a49d0815729ae500b601d6fd385d2826ea5 100644 (file)
@@ -41,13 +41,13 @@ RnaTracker RnaAppDiscovery::get_client_rna_tracker(const Packet* p, RNAFlow*)
     return host_cache.find(p->flow->client_ip);
 }
 
-void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
-    RnaConfig* conf, RnaLogger& logger)
+void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, RnaConfig* conf,
+    RnaLogger& logger)
 {
     const Packet* p = DetectionEngine::get_current_packet();
 
     // Published appid events may be on rebuilt packets
-    if ( !p->flow or !filter.is_host_monitored(p) )
+    if ( !p->flow )
         return;
 
     IpProtocol proto;
@@ -77,14 +77,14 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
 
         if ( appid_change_bits[APPID_SERVICE_BIT] and service > APP_ID_NONE )
         {
-            if (service == APP_ID_DHCP)
+            if ( service == APP_ID_DHCP )
             {
                 const SfIp& service_ip = appid_session_api.get_service_ip();
-                if (p->flow->client_ip.fast_eq6(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,
+            newservice = discover_service(p, filter, rna_flow, proto, conf, logger,
                 port, service, is_client);
         }
 
@@ -92,13 +92,13 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
             and service > APP_ID_NONE )
         {
             const char* version = appid_session_api.get_client_info();
-            discover_client(p, rna_flow, conf, logger, version, client, service);
+            discover_client(p, filter, rna_flow, conf, logger, version, client, service);
         }
 
         if ( appid_change_bits[APPID_PAYLOAD_BIT] and payload > APP_ID_NONE
              and service > APP_ID_NONE )
         {
-            discover_payload(p, rna_flow, proto, conf, logger, service, payload, client);
+            discover_payload(p, filter, rna_flow, proto, conf, logger, service, payload, client);
         }
     }
 
@@ -108,12 +108,14 @@ 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, port, vendor, version, logger, conf, service, is_client);
+        update_service_info(p, filter, 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, port, nullptr, nullptr, logger, conf, service, is_client);
+        update_service_info(p, filter, rna_flow, proto, port, nullptr, nullptr, logger, conf,
+            service, is_client);
     }
 
     if ( conf->enable_banner_grab and p->is_from_server() and
@@ -121,7 +123,7 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
         appid_change_bits[APPID_SERVICE_INFO_BIT] or
         appid_change_bits[APPID_SERVICE_BIT]) )
     {
-        discover_banner(p, rna_flow, proto, logger, service);
+        discover_banner(p, filter, rna_flow, proto, logger, service);
     }
 
     // Appid supports login success/failure events, but not logoff event.
@@ -130,7 +132,8 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
         bool login_success;
         const char* username = appid_session_api.get_user_info(service, login_success);
         if ( service > APP_ID_NONE and username and *username )
-            discover_user(p, rna_flow, logger, username, service, proto, conf, login_success);
+            discover_user(p, filter, rna_flow, logger, username, service, proto, conf,
+                login_success);
     }
     if ( p->is_from_client() and ( appid_change_bits[APPID_HOST_BIT] or
         appid_change_bits[APPID_USERAGENT_BIT] ) )
@@ -150,23 +153,32 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
             {
                 const char* host = hsession->get_cfield(REQ_HOST_FID);
                 const char* uagent = hsession->get_cfield(REQ_AGENT_FID);
-                analyze_user_agent_fingerprint(p, rna_flow, host, uagent, logger, *processor);
+                analyze_user_agent_fingerprint(p, filter, rna_flow, host, uagent, logger,
+                    *processor);
             }
         }
     }
 }
 
-bool RnaAppDiscovery::discover_service(const Packet* p, RNAFlow* rna_flow, IpProtocol proto,
-    RnaConfig* conf, RnaLogger& logger, uint16_t port, AppId service, bool is_client)
+bool RnaAppDiscovery::discover_service(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow,
+    IpProtocol proto, RnaConfig* conf, RnaLogger& logger, uint16_t port, AppId service,
+    bool is_client)
 {
     RnaTracker htp;
     SfIp ip = p->flow->server_ip;
+
     if (!is_client)
+    {
+        if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
+            return false;
         htp = get_server_rna_tracker(p, rna_flow);
+    }
     else
     {
-        htp = get_client_rna_tracker(p, rna_flow);
+        if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) )
+            return false;
         ip = p->flow->client_ip;
+        htp = get_client_rna_tracker(p, rna_flow);
     }
 
     if ( !htp or !htp->is_visible() )
@@ -196,8 +208,9 @@ bool RnaAppDiscovery::discover_service(const Packet* p, RNAFlow* rna_flow, IpPro
     return is_new;
 }
 
-void RnaAppDiscovery::discover_payload(const Packet* p, RNAFlow* rna_flow, IpProtocol proto,
-    RnaConfig* conf, RnaLogger& logger, AppId service, AppId payload, AppId client)
+void RnaAppDiscovery::discover_payload(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow,
+    IpProtocol proto, RnaConfig* conf, RnaLogger& logger, AppId service, AppId payload,
+    AppId client)
 {
     uint16_t lookup_port;
     size_t max_payloads = 0;
@@ -218,6 +231,9 @@ void RnaAppDiscovery::discover_payload(const Packet* p, RNAFlow* rna_flow, IpPro
     // Add server payload
     if ( p->is_from_server() )
     {
+        if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
+            return;
+
         HostApplication local_ha;
         bool new_pld = srt->add_payload(local_ha, lookup_port, proto, payload, service,
             max_payloads);
@@ -236,6 +252,9 @@ void RnaAppDiscovery::discover_payload(const Packet* p, RNAFlow* rna_flow, IpPro
     }
 
     // Add client payloads
+    if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) )
+        return;
+
     RnaTracker crt = get_client_rna_tracker(p, rna_flow);
     if ( !crt or !crt->is_visible() )
         return;
@@ -252,17 +271,24 @@ 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, uint16_t port,
-    const char* vendor, const char* version, RnaLogger& logger, RnaConfig* conf, AppId service, bool is_client)
+void RnaAppDiscovery::update_service_info(const Packet* p, DiscoveryFilter& filter,
+    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;
     SfIp ip = p->flow->server_ip;
     if (!is_client)
+    {
+        if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
+            return;
         htp = get_server_rna_tracker(p, rna_flow);
+    }
     else
     {
-        htp = get_client_rna_tracker(p, rna_flow);
+        if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) )
+            return;
         ip = p->flow->client_ip;
+        htp = get_client_rna_tracker(p, rna_flow);
     }
 
     if ( !htp or !htp->is_visible() )
@@ -288,9 +314,12 @@ void RnaAppDiscovery::update_service_info(const Packet* p, RNAFlow* rna_flow, Ip
     htp->update_service(ha);
 }
 
-void RnaAppDiscovery::discover_banner(const Packet* p, RNAFlow* rna_flow, IpProtocol proto,
-    RnaLogger& logger, AppId service)
+void RnaAppDiscovery::discover_banner(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow,
+    IpProtocol proto, RnaLogger& logger, AppId service)
 {
+    if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
+        return;
+
     RnaTracker rt = get_server_rna_tracker(p, rna_flow);
     if ( !rt or !rt->is_visible() )
         return;
@@ -305,9 +334,12 @@ void RnaAppDiscovery::discover_banner(const Packet* p, RNAFlow* rna_flow, IpProt
         (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), rt->get_last_seen_mac(), &ha);
 }
 
-void RnaAppDiscovery::discover_client(const Packet* p, RNAFlow* rna_flow, RnaConfig* conf,
-    RnaLogger& logger, const char* version, AppId client, AppId service)
+void RnaAppDiscovery::discover_client(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow,
+    RnaConfig* conf, RnaLogger& logger, const char* version, AppId client, AppId service)
 {
+    if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) )
+        return;
+
     RnaTracker rt = get_client_rna_tracker(p, rna_flow);
     if ( !rt or !rt->is_visible() )
         return;
@@ -340,15 +372,24 @@ void RnaAppDiscovery::discover_client(const Packet* p, RNAFlow* rna_flow, RnaCon
             (const struct in6_addr*) p->flow->client_ip.get_ip6_ptr(), mac, &hc);
 }
 
-void RnaAppDiscovery::discover_user(const Packet* p, RNAFlow* rna_flow, RnaLogger& logger,
-    const char* username, AppId service, IpProtocol proto, RnaConfig* conf, bool login_success)
+void RnaAppDiscovery::discover_user(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow,
+    RnaLogger& logger, const char* username, AppId service, IpProtocol proto, RnaConfig* conf,
+    bool login_success)
 {
     RnaTracker rt;
     if ( p->is_from_server() )
+    {
+        if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
+            return;
         rt = get_server_rna_tracker(p, rna_flow);
+    }
     else
+    {
+        if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) )
+            return;
         rt = get_client_rna_tracker(p, rna_flow);
-    
+    }
+
     if ( !rt or !rt->is_visible() )
         return;
     rt->update_last_seen();
@@ -362,10 +403,12 @@ void RnaAppDiscovery::discover_user(const Packet* p, RNAFlow* rna_flow, RnaLogge
     }
 }
 
-void RnaAppDiscovery::analyze_user_agent_fingerprint(const Packet* p, RNAFlow* rna_flow,
-    const char* host, const char* uagent, RnaLogger& logger, UaFpProcessor& processor)
+void RnaAppDiscovery::analyze_user_agent_fingerprint(const Packet* p, DiscoveryFilter& filter,
+    RNAFlow* rna_flow, const char* host, const char* uagent, RnaLogger& logger,
+    UaFpProcessor& processor)
 {
-    if ( !host or !uagent )
+    if ( !host or !uagent or 
+        !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT))
         return;
 
     RnaTracker rt = get_client_rna_tracker(p, rna_flow);
index b9b18e4d108cecb673f8d7992dfdb3ff0dad08e4..aa9e741395a4fb8bbc5687ab54c49df589602da7 100644 (file)
@@ -28,25 +28,27 @@ class RnaAppDiscovery
 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, bool is_client = false);
+    static bool discover_service(const snort::Packet*, DiscoveryFilter&, RNAFlow*, IpProtocol,
+        RnaConfig*, 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);
+    static void discover_payload(const snort::Packet*, DiscoveryFilter&, RNAFlow*, IpProtocol,
+        RnaConfig*, RnaLogger&, AppId service, AppId payload, AppId client);
 
-    static void discover_client(const snort::Packet*, RNAFlow*, RnaConfig*, RnaLogger&,
-        const char*, AppId client, AppId service);
+    static void discover_client(const snort::Packet*, DiscoveryFilter&, RNAFlow*, RnaConfig*,
+        RnaLogger&, const char*, AppId client, AppId service);
 
-    static void discover_user(const snort::Packet*, RNAFlow*, RnaLogger&, const char*,
-        AppId, IpProtocol, RnaConfig*, bool);
+    static void discover_user(const snort::Packet*, DiscoveryFilter&, RNAFlow*, RnaLogger&,
+        const char*, AppId, IpProtocol, RnaConfig*, bool);
 
-    static void discover_banner(const snort::Packet*, RNAFlow*, IpProtocol, RnaLogger&, AppId);
+    static void discover_banner(const snort::Packet*, DiscoveryFilter&, RNAFlow*, IpProtocol,
+        RnaLogger&, AppId);
 private:
-    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 update_service_info(const snort::Packet*, DiscoveryFilter&, 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&);
+    static void analyze_user_agent_fingerprint(const snort::Packet*, DiscoveryFilter&, RNAFlow*,
+        const char* host, const char* uagent, RnaLogger&, snort::UaFpProcessor&);
 
     static RnaTracker get_server_rna_tracker(const snort::Packet*, RNAFlow*);
     static RnaTracker get_client_rna_tracker(const snort::Packet*, RNAFlow*);