]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2364 in SNORT/snort3 from ~SHRARANG/snort3:appid_dns_event to...
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Fri, 31 Jul 2020 17:35:48 +0000 (17:35 +0000)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Fri, 31 Jul 2020 17:35:48 +0000 (17:35 +0000)
Squashed commit of the following:

commit 70f3556fd38a9414e77ae2c752284ab25b174eec
Author: Shravan Rangaraju <shrarang@cisco.com>
Date:   Thu Jul 30 15:06:55 2020 -0400

    appid: generate event notification when dns host is set

src/network_inspectors/appid/appid_dns_session.h
src/network_inspectors/appid/detector_plugins/detector_dns.cc
src/network_inspectors/appid/detector_plugins/detector_dns.h
src/network_inspectors/appid/test/appid_api_test.cc
src/network_inspectors/appid/test/appid_discovery_test.cc
src/pub_sub/appid_events.h

index 7a3646867f3cf430d0b6c7c6a3c10d5be13c5584..a0375664b47c5ca035a7f82550afca943c347da1 100644 (file)
@@ -23,6 +23,7 @@
 #define APPID_DNS_SESSION_H
 
 #include <string>
+#include "pub_sub/appid_events.h"
 
 #define DNS_GOT_QUERY    0x01
 #define DNS_GOT_RESPONSE 0x02
@@ -76,8 +77,11 @@ public:
     const char* get_host() const
     { return host.c_str(); }
 
-    void set_host(char* host)
-    { this->host = host; }
+    void set_host(char* host, AppidChangeBits& change_bits)
+    {
+        this->host = host;
+        change_bits.set(APPID_DNS_HOST_BIT);
+    }
 
     uint32_t get_host_len() const
     { return host.size(); }
index bba295449432e05de85aaf77080e545857bdfb16..58e84c567d9b11f3c4a79fbdeacb3be20bce96bb 100644 (file)
@@ -185,7 +185,8 @@ DnsUdpServiceDetector::DnsUdpServiceDetector(ServiceDiscovery* sd)
 
 
 APPID_STATUS_CODE DnsValidator::add_dns_query_info(AppIdSession& asd, uint16_t id,
-    const uint8_t* host, uint8_t host_len, uint16_t host_offset, uint16_t record_type)
+    const uint8_t* host, uint8_t host_len, uint16_t host_offset, uint16_t record_type,
+    AppidChangeBits& change_bits)
 {
     AppIdDnsSession* dsession = asd.get_dns_session();
     if (!dsession)
@@ -207,7 +208,7 @@ APPID_STATUS_CODE DnsValidator::add_dns_query_info(AppIdSession& asd, uint16_t i
             char* new_host = dns_parse_host(host, host_len);
             if (!new_host)
                 return APPID_NOMATCH;
-            dsession->set_host(new_host);
+            dsession->set_host(new_host, change_bits);
             dsession->set_host_offset(host_offset);
             snort_free(new_host);
        }
@@ -217,7 +218,8 @@ APPID_STATUS_CODE DnsValidator::add_dns_query_info(AppIdSession& asd, uint16_t i
 }
 
 APPID_STATUS_CODE DnsValidator::add_dns_response_info(AppIdSession& asd, uint16_t id,
-    const uint8_t* host, uint8_t host_len, uint16_t host_offset, uint8_t response_type, uint32_t ttl)
+    const uint8_t* host, uint8_t host_len, uint16_t host_offset, uint8_t response_type, uint32_t ttl,
+    AppidChangeBits& change_bits)
 {
     AppIdDnsSession* dsession = asd.get_dns_session();
     if (!dsession)
@@ -240,7 +242,7 @@ APPID_STATUS_CODE DnsValidator::add_dns_response_info(AppIdSession& asd, uint16_
             char* new_host = dns_parse_host(host, host_len);
             if (!new_host)
                 return APPID_NOMATCH;
-            dsession->set_host(new_host);
+            dsession->set_host(new_host, change_bits);
             dsession->set_host_offset(host_offset);
             snort_free(new_host);
         }
@@ -316,7 +318,7 @@ APPID_STATUS_CODE DnsValidator::dns_validate_label(const uint8_t* data, uint16_t
 }
 
 int DnsValidator::dns_validate_query(const uint8_t* data, uint16_t* offset, uint16_t size,
-    uint16_t id, bool host_reporting, AppIdSession& asd)
+    uint16_t id, bool host_reporting, AppIdSession& asd, AppidChangeBits& change_bits)
 {
     int ret;
     const uint8_t* host;
@@ -353,10 +355,10 @@ int DnsValidator::dns_validate_query(const uint8_t* data, uint16_t* offset, uint
             case PATTERN_MX_REC:
             case PATTERN_SOA_REC:
             case PATTERN_NS_REC:
-                ret = add_dns_query_info(asd, id, host, host_len, host_offset, record_type);
+                ret = add_dns_query_info(asd, id, host, host_len, host_offset, record_type, change_bits);
                 break;
             case PATTERN_PTR_REC:
-                ret = add_dns_query_info(asd, id, nullptr, 0, 0, record_type);
+                ret = add_dns_query_info(asd, id, nullptr, 0, 0, record_type, change_bits);
                 break;
             default:
                 break;
@@ -367,7 +369,7 @@ int DnsValidator::dns_validate_query(const uint8_t* data, uint16_t* offset, uint
 }
 
 int DnsValidator::dns_validate_answer(const uint8_t* data, uint16_t* offset, uint16_t size,
-    uint16_t id, uint8_t rcode, bool host_reporting, AppIdSession& asd)
+    uint16_t id, uint8_t rcode, bool host_reporting, AppIdSession& asd, AppidChangeBits& change_bits)
 {
     int ret;
     uint8_t host_len;
@@ -399,7 +401,7 @@ int DnsValidator::dns_validate_answer(const uint8_t* data, uint16_t* offset, uin
             case PATTERN_MX_REC:
             case PATTERN_SOA_REC:
             case PATTERN_NS_REC:
-                ret = add_dns_response_info(asd, id, nullptr, 0, 0, rcode, ttl);
+                ret = add_dns_response_info(asd, id, nullptr, 0, 0, rcode, ttl, change_bits);
                 break;
             case PATTERN_PTR_REC:
                 {
@@ -419,7 +421,7 @@ int DnsValidator::dns_validate_answer(const uint8_t* data, uint16_t* offset, uin
                         host_offset = 0;
                     }
                     ret = add_dns_response_info(
-                        asd, id, host, host_len, host_offset, rcode, ttl);
+                        asd, id, host, host_len, host_offset, rcode, ttl, change_bits);
                 }
                 break;
             default:
@@ -430,7 +432,7 @@ int DnsValidator::dns_validate_answer(const uint8_t* data, uint16_t* offset, uin
     return ret;
 }
 
-int DnsValidator::dns_validate_header(const AppidSessionDirection dir, const DNSHeader* hdr,
+int DnsValidator::dns_validate_header(AppidSessionDirection dir, const DNSHeader* hdr,
     bool host_reporting, const AppIdSession& asd)
 {
     if (hdr->Opcode > MAX_OPCODE || hdr->Opcode == INVALID_OPCODE)
@@ -454,7 +456,7 @@ int DnsValidator::dns_validate_header(const AppidSessionDirection dir, const DNS
 }
 
 int DnsValidator::validate_packet(const uint8_t* data, uint16_t size, const int,
-    bool host_reporting, AppIdSession& asd)
+    bool host_reporting, AppIdSession& asd, AppidChangeBits& change_bits)
 {
     uint16_t i;
     uint16_t count;
@@ -471,7 +473,7 @@ int DnsValidator::validate_packet(const uint8_t* data, uint16_t size, const int,
         count = ntohs(hdr->QDCount);
         for (i=0; i<count; i++)
         {
-            if (dns_validate_query(data, &offset, size, ntohs(hdr->id), host_reporting, asd) !=
+            if (dns_validate_query(data, &offset, size, ntohs(hdr->id), host_reporting, asd, change_bits) !=
                 APPID_SUCCESS)
             {
                 return APPID_NOMATCH;
@@ -485,7 +487,7 @@ int DnsValidator::validate_packet(const uint8_t* data, uint16_t size, const int,
         for (i=0; i<count; i++)
         {
             if (dns_validate_answer(data, &offset, size, ntohs(hdr->id), hdr->RCODE,
-                host_reporting, asd) != APPID_SUCCESS)
+                host_reporting, asd, change_bits) != APPID_SUCCESS)
             {
                 return APPID_NOMATCH;
             }
@@ -498,7 +500,7 @@ int DnsValidator::validate_packet(const uint8_t* data, uint16_t size, const int,
         for (i=0; i<count; i++)
         {
             if (dns_validate_answer(data, &offset, size, ntohs(hdr->id), hdr->RCODE,
-                host_reporting, asd) != APPID_SUCCESS)
+                host_reporting, asd, change_bits) != APPID_SUCCESS)
             {
                 return APPID_NOMATCH;
             }
@@ -511,7 +513,7 @@ int DnsValidator::validate_packet(const uint8_t* data, uint16_t size, const int,
         for (i=0; i<count; i++)
         {
             if (dns_validate_answer(data, &offset, size, ntohs(hdr->id), hdr->RCODE,
-                host_reporting, asd) != APPID_SUCCESS)
+                host_reporting, asd, change_bits) != APPID_SUCCESS)
             {
                 return APPID_NOMATCH;
             }
@@ -519,7 +521,7 @@ int DnsValidator::validate_packet(const uint8_t* data, uint16_t size, const int,
     }
 
     if (hdr->QR && (hdr->RCODE != 0))    // error response
-        return add_dns_response_info(asd, ntohs(hdr->id), nullptr, 0, 0, hdr->RCODE, 0);
+        return add_dns_response_info(asd, ntohs(hdr->id), nullptr, 0, 0, hdr->RCODE, 0, change_bits);
 
     return APPID_SUCCESS;
 }
@@ -548,7 +550,7 @@ int DnsUdpServiceDetector::validate(AppIdDiscoveryArgs& args)
                     // To get here, we missed the initial query, got a
                     // response, and now we've got another query.
                     rval = validate_packet(args.data, args.size, args.dir,
-                        args.asd.get_odp_ctxt().dns_host_reporting, args.asd);
+                        args.asd.get_odp_ctxt().dns_host_reporting, args.asd, args.change_bits);
                     if (rval == APPID_SUCCESS)
                         goto inprocess;
                 }
@@ -559,7 +561,7 @@ int DnsUdpServiceDetector::validate(AppIdDiscoveryArgs& args)
                 // To get here, we missed the initial query, but now we've got
                 // a response.
                 rval = validate_packet(args.data, args.size, args.dir,
-                    args.asd.get_odp_ctxt().dns_host_reporting, args.asd);
+                    args.asd.get_odp_ctxt().dns_host_reporting, args.asd, args.change_bits);
                 if (rval == APPID_SUCCESS)
                 {
                     args.asd.set_session_flags(APPID_SESSION_UDP_REVERSED);
@@ -573,7 +575,7 @@ int DnsUdpServiceDetector::validate(AppIdDiscoveryArgs& args)
     }
 
     rval = validate_packet(args.data, args.size, args.dir,
-        args.asd.get_odp_ctxt().dns_host_reporting, args.asd);
+        args.asd.get_odp_ctxt().dns_host_reporting, args.asd, args.change_bits);
     if ((rval == APPID_SUCCESS) && (args.dir == APP_ID_FROM_INITIATOR))
         goto inprocess;
 
@@ -636,7 +638,7 @@ int DnsTcpServiceDetector::validate(AppIdDiscoveryArgs& args)
         if (tmp > size)
             goto not_compatible;
         rval = validate_packet(data, size, args.dir,
-            args.asd.get_odp_ctxt().dns_host_reporting, args.asd);
+            args.asd.get_odp_ctxt().dns_host_reporting, args.asd, args.change_bits);
         if (rval != APPID_SUCCESS)
             goto tcp_done;
 
index 8ccecb20b8c61af36bfcf9e56d06e827485a0d4b..9bb4d3a1532c8e4bd750a233f1dddce33b941909 100644 (file)
@@ -30,21 +30,17 @@ struct DNSHeader;
 
 class DnsValidator
 {
-public:
-    APPID_STATUS_CODE add_dns_query_info(AppIdSession&, uint16_t id, const uint8_t* host,
-        uint8_t host_len, uint16_t host_offset, uint16_t record_type);
-    APPID_STATUS_CODE add_dns_response_info(AppIdSession&, uint16_t id, const uint8_t* host,
-        uint8_t host_len, uint16_t host_offset, uint8_t response_type, uint32_t ttl);
-    APPID_STATUS_CODE dns_validate_label(const uint8_t* data, uint16_t& offset, uint16_t size,
-        uint8_t& len, bool& len_valid);
-    int dns_validate_query(const uint8_t* data, uint16_t* offset, uint16_t size,
-        uint16_t id, bool host_reporting, AppIdSession&);
-    int dns_validate_answer(const uint8_t* data, uint16_t* offset, uint16_t size,
-        uint16_t id, uint8_t rcode, bool host_reporting, AppIdSession&);
-    int dns_validate_header(const AppidSessionDirection dir, const DNSHeader*, bool host_reporting,
-        const AppIdSession&);
-    int validate_packet(const uint8_t* data, uint16_t size, const int,
-        bool host_reporting, AppIdSession&);
+protected:
+    APPID_STATUS_CODE add_dns_query_info(AppIdSession&, uint16_t, const uint8_t*,
+        uint8_t, uint16_t, uint16_t, AppidChangeBits&);
+    APPID_STATUS_CODE add_dns_response_info(AppIdSession&, uint16_t, const uint8_t*,
+        uint8_t, uint16_t, uint8_t, uint32_t, AppidChangeBits&);
+    APPID_STATUS_CODE dns_validate_label(const uint8_t*, uint16_t&, uint16_t, uint8_t&, bool&);
+    int dns_validate_query(const uint8_t*, uint16_t*, uint16_t, uint16_t, bool, AppIdSession&, AppidChangeBits&);
+    int dns_validate_answer(const uint8_t*, uint16_t*, uint16_t,
+        uint16_t, uint8_t, bool, AppIdSession&, AppidChangeBits&);
+    int dns_validate_header(AppidSessionDirection, const DNSHeader*, bool, const AppIdSession&);
+    int validate_packet(const uint8_t*, uint16_t, const int, bool, AppIdSession&, AppidChangeBits&);
 };
 
 class DnsTcpServiceDetector : public ServiceDetector, public DnsValidator
index 70000308cc25e24ff0324116a77431f0eb92d1d8..780eafc19d00437aff8748175055b79fa7d32230 100644 (file)
@@ -304,7 +304,7 @@ TEST(appid_api, ssl_app_group_id_lookup)
     CHECK_EQUAL(service, APPID_UT_ID);
     CHECK_EQUAL(client, APPID_UT_ID);
     CHECK_EQUAL(payload, APPID_UT_ID);
-    STRCMP_EQUAL("Published change_bits == 00000000000000", test_log);
+    STRCMP_EQUAL("Published change_bits == 000000000000000", test_log);
 
     service = APP_ID_NONE;
     client = APP_ID_NONE;
@@ -317,7 +317,7 @@ TEST(appid_api, ssl_app_group_id_lookup)
     STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_first_alt_name(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST);
-    STRCMP_EQUAL("Published change_bits == 00000100011000", test_log);
+    STRCMP_EQUAL("Published change_bits == 000000100011000", test_log);
 
     mock_session->tsession->set_tls_host("www.cisco.com", 13, change_bits);
     mock_session->tsession->set_tls_cname("www.cisco.com", 13, change_bits);
@@ -333,7 +333,7 @@ TEST(appid_api, ssl_app_group_id_lookup)
     STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Cisco");
-    STRCMP_EQUAL("Published change_bits == 00000100011000", test_log);
+    STRCMP_EQUAL("Published change_bits == 000000100011000", test_log);
 
     string host = "";
     val = appid_api.ssl_app_group_id_lookup(flow, (const char*)(host.c_str()), nullptr,
@@ -344,7 +344,7 @@ TEST(appid_api, ssl_app_group_id_lookup)
     STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Google");
-    STRCMP_EQUAL("Published change_bits == 00000100000000", test_log);
+    STRCMP_EQUAL("Published change_bits == 000000100000000", test_log);
     mock().checkExpectations();
 }
 
index 51ac1184cf102db6f7fe5b41963081cfc7f74001..bf0c3b760dac4be9ecfdef29f86beda40fec7b39 100644 (file)
@@ -377,7 +377,7 @@ TEST(appid_discovery_tests, event_published_when_ignoring_flow)
 
     // Detect changes in service, client, payload, and misc appid
     mock().checkExpectations();
-    STRCMP_EQUAL(test_log, "Published change_bits == 00000001111100");
+    STRCMP_EQUAL("Published change_bits == 000000001111100", test_log);
 
     delete &asd->get_api();
     delete asd;
@@ -409,7 +409,7 @@ TEST(appid_discovery_tests, event_published_when_processing_flow)
 
     // Detect changes in service, client, payload, and misc appid
     mock().checkExpectations();
-    STRCMP_EQUAL(test_log, "Published change_bits == 00000001111100");
+    STRCMP_EQUAL("Published change_bits == 000000001111100", test_log);
     delete &asd->get_api();
     delete asd;
     delete flow;
@@ -504,10 +504,10 @@ TEST(appid_discovery_tests, change_bits_to_string)
     change_bits.set();
     change_bits_to_string(change_bits, str);
     STRCMP_EQUAL(str.c_str(), "created, reset, service, client, payload, misc, referred, host,"
-        " tls-host, url, user-agent, response, referrer, version");
+        " tls-host, url, user-agent, response, referrer, dns-host, version");
 
     // Failure of this test is a reminder that enum is changed, hence translator needs update
-    CHECK_EQUAL(APPID_MAX_BIT, 14);
+    CHECK_EQUAL(APPID_MAX_BIT, 15);
 }
 
 int main(int argc, char** argv)
index 2f0d7659fe508988b326f5ac583caa8fcfb824d8..2e76377fa808fcb774cf79ffe704c5b1b5f9d61c 100644 (file)
@@ -55,6 +55,9 @@ enum AppidChangeBit
     APPID_RESPONSE_BIT,
     APPID_REFERER_BIT,
 
+    // dns
+    APPID_DNS_HOST_BIT,
+
     // other
     APPID_VERSION_BIT,
 
@@ -93,6 +96,8 @@ inline void change_bits_to_string(AppidChangeBits& change_bits, std::string& str
         --n? str.append("response, ") : str.append("response");
     if (change_bits.test(APPID_REFERER_BIT))
         --n? str.append("referrer, ") : str.append("referrer");
+    if (change_bits.test(APPID_DNS_HOST_BIT))
+        --n? str.append("dns-host, ") : str.append("dns-host");
     if (change_bits.test(APPID_VERSION_BIT))
         --n? str.append("version, ") : str.append("version");
     if (n != 0) // make sure all bits from AppidChangeBit enum get translated