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