diff --git a/NEWS b/NEWS index 6d0bb2a7e5..9da01925d1 100644 --- a/NEWS +++ b/NEWS @@ -90,6 +90,9 @@ Changed Functionality (where the "mime_type" field is just a shortcut for the strongest match). +- dns_TXT_reply() now supports more than one string entry by receiving + a vector of strings. + Bro 2.2 ======= diff --git a/scripts/base/protocols/dns/main.bro b/scripts/base/protocols/dns/main.bro index d7280602e6..83c9682e8c 100644 --- a/scripts/base/protocols/dns/main.bro +++ b/scripts/base/protocols/dns/main.bro @@ -382,9 +382,19 @@ event dns_A_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr) &priori hook DNS::do_reply(c, msg, ans, fmt("%s", a)); } -event dns_TXT_reply(c: connection, msg: dns_msg, ans: dns_answer, str: string) &priority=5 +event dns_TXT_reply(c: connection, msg: dns_msg, ans: dns_answer, strs: string_vec) &priority=5 { - hook DNS::do_reply(c, msg, ans, str); + local txt_strings: string = ""; + + for ( i in strs ) + { + if ( i > 0 ) + txt_strings += " "; + + txt_strings += fmt("TXT %d %s", |strs[i]|, strs[i]); + } + + hook DNS::do_reply(c, msg, ans, txt_strings); } event dns_AAAA_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr) &priority=5 diff --git a/src/analyzer/protocol/dns/DNS.cc b/src/analyzer/protocol/dns/DNS.cc index a97c7b8632..649237c75a 100644 --- a/src/analyzer/protocol/dns/DNS.cc +++ b/src/analyzer/protocol/dns/DNS.cc @@ -835,34 +835,61 @@ int DNS_Interpreter::ParseRR_HINFO(DNS_MsgInfo* msg, return 1; } +static StringVal* extract_char_string(analyzer::Analyzer* analyzer, + const u_char*& data, int& len, int& rdlen) + { + if ( rdlen <= 0 ) + return 0; + + uint8 str_size = data[0]; + + --rdlen; + --len; + ++data; + + if ( str_size > rdlen ) + { + analyzer->Weird("DNS_TXT_char_str_past_rdlen"); + return 0; + } + + StringVal* rval = new StringVal(str_size, + reinterpret_cast(data)); + + rdlen -= str_size; + len -= str_size; + data += str_size; + + return rval; + } + int DNS_Interpreter::ParseRR_TXT(DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start) { - int name_len = data[0]; - - char* name = new char[name_len]; - - memcpy(name, data+1, name_len); - - data += rdlength; - len -= rdlength; - - if ( dns_TXT_reply && ! msg->skip_event ) + if ( ! dns_TXT_reply || msg->skip_event ) { - val_list* vl = new val_list; - - vl->append(analyzer->BuildConnVal()); - vl->append(msg->BuildHdrVal()); - vl->append(msg->BuildAnswerVal()); - vl->append(new StringVal(name_len, name)); - - analyzer->ConnectionEvent(dns_TXT_reply, vl); + data += rdlength; + len -= rdlength; + return 1; } - delete [] name; + VectorVal* char_strings = new VectorVal(string_vec); + StringVal* char_string; - return 1; + while ( (char_string = extract_char_string(analyzer, data, len, rdlength)) ) + char_strings->Assign(char_strings->Size(), char_string); + + val_list* vl = new val_list; + + vl->append(analyzer->BuildConnVal()); + vl->append(msg->BuildHdrVal()); + vl->append(msg->BuildAnswerVal()); + vl->append(char_strings); + + analyzer->ConnectionEvent(dns_TXT_reply, vl); + + return rdlength == 0; } void DNS_Interpreter::SendReplyOrRejectEvent(DNS_MsgInfo* msg, diff --git a/src/analyzer/protocol/dns/events.bif b/src/analyzer/protocol/dns/events.bif index 520e32fe6d..efa0807fd1 100644 --- a/src/analyzer/protocol/dns/events.bif +++ b/src/analyzer/protocol/dns/events.bif @@ -376,7 +376,7 @@ event dns_MX_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string, ## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply ## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout ## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, str: string%); +event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, strs: string_vec%); ## Generated for DNS replies of type *SRV*. For replies with multiple answers, ## an individual event of the corresponding type is raised for each. diff --git a/testing/btest/Baseline/core.ipv6-frag/dns.log b/testing/btest/Baseline/core.ipv6-frag/dns.log index 69aec7e222..5eede0a0e4 100644 --- a/testing/btest/Baseline/core.ipv6-frag/dns.log +++ b/testing/btest/Baseline/core.ipv6-frag/dns.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path dns -#open 2013-08-26-19-02-10 +#open 2014-04-24-20-25-19 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs rejected #types time string addr port addr port enum count string count string count string count string bool bool bool bool count vector[string] vector[interval] bool -1331084278.438444 CXWv6p3arKYeMETxOg 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51850 2607:f740:b::f93 53 udp 3903 txtpadding_323.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 This TXT record should be ignored 1.000000 F -1331084293.592245 CjhGID4nQcgTWjvg4c 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 This TXT record should be ignored 1.000000 F +1331084278.438444 CXWv6p3arKYeMETxOg 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51850 2607:f740:b::f93 53 udp 3903 txtpadding_323.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 TXT 33 This TXT record should be ignored TXT 21 As it is just padding TXT 136 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1.000000 F +1331084293.592245 CjhGID4nQcgTWjvg4c 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 TXT 33 This TXT record should be ignored TXT 21 As it is just padding TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 192 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1.000000 F 1331084298.593081 CjhGID4nQcgTWjvg4c 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT - - F F T F 0 - - F -#close 2013-08-26-19-02-10 +#close 2014-04-24-20-25-20 diff --git a/testing/btest/Baseline/scripts.base.protocols.dns.multiple-txt-strings/dns.log b/testing/btest/Baseline/scripts.base.protocols.dns.multiple-txt-strings/dns.log new file mode 100644 index 0000000000..ba73d16c82 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.dns.multiple-txt-strings/dns.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path dns +#open 2014-04-24-23-33-57 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs rejected +#types time string addr port addr port enum count string count string count string count string bool bool bool bool count vector[string] vector[interval] bool +1398382067.286885 CXWv6p3arKYeMETxOg 192.150.187.50 51946 68.142.255.16 53 udp 28079 - - - - - 0 NOERROR T F F F 0 fa14._domainkey.flickr.com,fa14._domainkey.yahoo.com,TXT 127 k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPdPfyJM2R2GqMyZM1flTzFeDIU+e7KmiKRw5yz3Xht+cgEIiHmm5lIGBuWCc5rtiy0CcxePpqccPKjn TXT 98 HSrDI23PU+HOuqJ6ergE1IOsL6LOEgG6YT53vMb8Z6UiBSsYPlrDEC+8CUIkTLMLXJauRK5bNRKV1ATGzGFpf3TjZtWwIDAQAB 900.000000,900.000000,7200.000000 F +#close 2014-04-24-23-33-57 diff --git a/testing/btest/Traces/dns-txt-multiple.trace b/testing/btest/Traces/dns-txt-multiple.trace new file mode 100644 index 0000000000..ef02181e75 Binary files /dev/null and b/testing/btest/Traces/dns-txt-multiple.trace differ diff --git a/testing/btest/scripts/base/protocols/dns/multiple-txt-strings.bro b/testing/btest/scripts/base/protocols/dns/multiple-txt-strings.bro new file mode 100644 index 0000000000..4a15792702 --- /dev/null +++ b/testing/btest/scripts/base/protocols/dns/multiple-txt-strings.bro @@ -0,0 +1,4 @@ +# This tests the case where the DNS server responded with zero RRs. +# +# @TEST-EXEC: bro -r $TRACES/dns-txt-multiple.trace +# @TEST-EXEC: btest-diff dns.log