From: Shravan Rangarajuvenkata (shrarang) Date: Fri, 31 Jul 2020 17:35:48 +0000 (+0000) Subject: Merge pull request #2364 in SNORT/snort3 from ~SHRARANG/snort3:appid_dns_event to... X-Git-Tag: 3.0.2-4~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1219d91c15c6d4e805e77ba83bb97a3197519ee;p=thirdparty%2Fsnort3.git Merge pull request #2364 in SNORT/snort3 from ~SHRARANG/snort3:appid_dns_event to master Squashed commit of the following: commit 70f3556fd38a9414e77ae2c752284ab25b174eec Author: Shravan Rangaraju Date: Thu Jul 30 15:06:55 2020 -0400 appid: generate event notification when dns host is set --- diff --git a/src/network_inspectors/appid/appid_dns_session.h b/src/network_inspectors/appid/appid_dns_session.h index 7a3646867..a0375664b 100644 --- a/src/network_inspectors/appid/appid_dns_session.h +++ b/src/network_inspectors/appid/appid_dns_session.h @@ -23,6 +23,7 @@ #define APPID_DNS_SESSION_H #include +#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(); } diff --git a/src/network_inspectors/appid/detector_plugins/detector_dns.cc b/src/network_inspectors/appid/detector_plugins/detector_dns.cc index bba295449..58e84c567 100644 --- a/src/network_inspectors/appid/detector_plugins/detector_dns.cc +++ b/src/network_inspectors/appid/detector_plugins/detector_dns.cc @@ -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; iid), 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; iid), 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; iid), 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; iid), 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; diff --git a/src/network_inspectors/appid/detector_plugins/detector_dns.h b/src/network_inspectors/appid/detector_plugins/detector_dns.h index 8ccecb20b..9bb4d3a15 100644 --- a/src/network_inspectors/appid/detector_plugins/detector_dns.h +++ b/src/network_inspectors/appid/detector_plugins/detector_dns.h @@ -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 diff --git a/src/network_inspectors/appid/test/appid_api_test.cc b/src/network_inspectors/appid/test/appid_api_test.cc index 70000308c..780eafc19 100644 --- a/src/network_inspectors/appid/test/appid_api_test.cc +++ b/src/network_inspectors/appid/test/appid_api_test.cc @@ -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(); } diff --git a/src/network_inspectors/appid/test/appid_discovery_test.cc b/src/network_inspectors/appid/test/appid_discovery_test.cc index 51ac1184c..bf0c3b760 100644 --- a/src/network_inspectors/appid/test/appid_discovery_test.cc +++ b/src/network_inspectors/appid/test/appid_discovery_test.cc @@ -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) diff --git a/src/pub_sub/appid_events.h b/src/pub_sub/appid_events.h index 2f0d7659f..2e76377fa 100644 --- a/src/pub_sub/appid_events.h +++ b/src/pub_sub/appid_events.h @@ -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