You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by mm...@apache.org on 2013/01/25 20:53:04 UTC

svn commit: r1438670 - in /spamassassin/trunk/lib/Mail/SpamAssassin: AsyncLoop.pm DnsResolver.pm Plugin/AskDNS.pm Util.pm

Author: mmartinec
Date: Fri Jan 25 19:53:04 2013
New Revision: 1438670

URL: http://svn.apache.org/viewvc?rev=1438670&view=rev
Log:
Bug 6896: encode/decode a DNS query according to RFC 1035 zone file format as expected by Net::DNS API (what a terrible idea!), turn warning into info() for unmatching DNS responses

Modified:
    spamassassin/trunk/lib/Mail/SpamAssassin/AsyncLoop.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/AskDNS.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/AsyncLoop.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/AsyncLoop.pm?rev=1438670&r1=1438669&r2=1438670&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/AsyncLoop.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/AsyncLoop.pm Fri Jan 25 19:53:04 2013
@@ -295,7 +295,7 @@ sub bgsend_and_start_lookup {
     return if !defined $id;  # presumably blocked, or other fatal failure
     my $id_tail = $id; $id_tail =~ s{^\d+/IN/}{};
     lc($id_tail) eq lc($dnskey)
-      or warn "async: unmatched id $id, key=$dnskey\n";
+      or info("async: unmatched id %s, key=%s", $id, $dnskey);
     my $pkt = $dns_query_info->{pkt};
     if (!$pkt) {  # DNS query underway, still waiting for results
       # just add our query to the existing one

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm?rev=1438670&r1=1438669&r2=1438670&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm Fri Jan 25 19:53:04 2013
@@ -43,7 +43,7 @@ use re 'taint';
 use Mail::SpamAssassin;
 use Mail::SpamAssassin::Logger;
 use Mail::SpamAssassin::Constants qw(:ip);
-use Mail::SpamAssassin::Util qw(untaint_var);
+use Mail::SpamAssassin::Util qw(untaint_var fmt_dns_question_entry);
 
 use Socket;
 use Errno qw(EADDRINUSE EACCES);
@@ -552,6 +552,8 @@ sub new_dns_packet {
     if ($self->{conf}->{dns_options}->{dns0x20}) {
       $domain = dnsext_dns0x20($domain);
     }
+    # Net::DNS expects RFC 1035 zone format encoding even in its API, silly!
+    $domain =~ s{\\}{\\\\}gs;
     $packet = Net::DNS::Packet->new($domain, $type, $class);
 
     # a bit noisy, so commented by default...
@@ -596,9 +598,8 @@ sub _packet_id {
   my $header = $packet->header;
   my $id = $header->id;
   my @questions = $packet->question;
-  my $ques = $questions[0];
 
-  if (defined $ques) {
+  if ($questions[0]) {
     # Bug 6232: Net::DNS::Packet::new is not consistent in keeping data in
     # sections of a packet either as original bytes or presentation-encoded:
     # creating a query packet as above in new_dns_packet() keeps label in
@@ -609,10 +610,8 @@ sub _packet_id {
     # sure the query section of an answer packet matches the query section
     # in our packet as formed by new_dns_packet():
     #
-    my $qname = $ques->qname;
-    $qname =~ s/\\([0-9]{3}|.)/length($1)==1 ? $1 : chr($1)/gse;
-    $qname = lc $qname  if !$self->{conf}->{dns_options}->{dns0x20};
-    return join '/', $id, $ques->qclass, $ques->qtype, $qname;
+       # $qname = lc $qname  if !$self->{conf}->{dns_options}->{dns0x20};
+    return join('/', $id, fmt_dns_question_entry($questions[0]));
 
   } else {
     # odd.  this should not happen, but clearly some DNS servers
@@ -746,10 +745,10 @@ sub poll_responses {
         my $packet_id = $header->id;
         if ($rcode ne 'NOERROR') {
           # some failure, e.g. NXDOMAIN, SERVFAIL, FORMERR, REFUSED, ...
+          # NOTE: qname is encoded in RFC 1035 zone format, decode it
           dbg("dns: dns response %s, %s, %s", $packet_id, $rcode,
-              join(', ', map { my $qn = $_->qname;
-                $qn =~ s/\\([0-9]{3}|.)/length($1)==1 ? $1 : chr($1)/gse;
-                $qn.'/'.$_->qtype .'/'.$_->qclass} $packet->question));
+              join(', ', map(join('/', fmt_dns_question_entry($_)),
+                             $packet->question)));
         } else {
           # NOERROR, may or may not have answer records
           dbg("dns: dns response %s is OK, %d answer records",

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/AskDNS.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/AskDNS.pm?rev=1438670&r1=1438669&r2=1438670&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/AskDNS.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/AskDNS.pm Fri Jan 25 19:53:04 2013
@@ -189,7 +189,7 @@ use warnings;
 use re 'taint';
 
 use Mail::SpamAssassin::Plugin;
-use Mail::SpamAssassin::Util;
+use Mail::SpamAssassin::Util qw(fmt_dns_question_entry);
 use Mail::SpamAssassin::Logger;
 
 use vars qw(@ISA %rcode_value $txtdata_can_provide_a_list);
@@ -507,10 +507,14 @@ sub process_response_packet {
     $header = $pkt->header;
     @question = $pkt->question;
     $qtype = uc $question[0]->qtype  if @question;
-    my $query_str = join(', ',map($_->qtype.' '.$_->qname, @question));
     $rcode = uc $header->rcode  if $header;  # 'NOERROR', 'NXDOMAIN', ...
+
+    # NOTE: qname is encoded in RFC 1035 zone format, decode it
     dbg("askdns: answer received, rcode %s, query %s, answer has %d records",
-        $rcode, $query_str, scalar @answer);
+        $rcode,
+        join(', ', map(join('/', fmt_dns_question_entry($_)), @question)),
+        scalar @answer);
+
     if (defined $rcode && exists $rcode_value{$rcode}) {
       # Net::DNS return a rcode name for codes it knows about,
       # and returns a number for the rest; we deal with numbers from here on

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm?rev=1438670&r1=1438669&r2=1438670&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm Fri Jan 25 19:53:04 2013
@@ -59,7 +59,8 @@ BEGIN {
   @EXPORT = ();
   @EXPORT_OK = qw(&local_tz &base64_decode &untaint_var &untaint_file_path
                   &exit_status_str &proc_status_ok &am_running_on_windows
-                  &reverse_ip_address &secure_tmpfile &secure_tmpdir);
+                  &reverse_ip_address &fmt_dns_question_entry
+                  &secure_tmpfile &secure_tmpdir);
 }
 
 use Mail::SpamAssassin;
@@ -914,6 +915,21 @@ sub my_inet_aton { unpack("N", pack("C4"
 
 ###########################################################################
 
+sub fmt_dns_question_entry {
+  # converts a @{Net::DNS::Packet->question} entry to a presentable format,
+  # returning a triple: class, type, label
+  #
+  my $q = $_[0];
+  my $qname = $q->qname;
+  local $1;
+  # Net::DNS provides a query in encoded RFC 1035 zone file format, decode it!
+  $qname =~ s{ \\ ( [0-9]{3} | [^0-9] ) }
+             { length($1)==1 ? $1 : $1 <= 255 ? chr($1) : "\\$1" }xgse;
+  return ($q->qclass, $q->qtype, $qname);
+}
+
+###########################################################################
+
 sub parse_content_type {
   # This routine is typically called by passing a
   # get_header("content-type") which passes all content-type headers