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 2012/12/21 19:21:45 UTC
svn commit: r1425068 - in /spamassassin/trunk: lib/Mail/SpamAssassin/Dns.pm
lib/Mail/SpamAssassin/DnsResolver.pm lib/Mail/SpamAssassin/Plugin/AskDNS.pm
lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm sa-update.raw
Author: mmartinec
Date: Fri Dec 21 18:21:45 2012
New Revision: 1425068
URL: http://svn.apache.org/viewvc?rev=1425068&view=rev
Log:
Bug 6872 - replace $rr->rdatastr with $rr->txtdata where appropriate
Modified:
spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm
spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/AskDNS.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm
spamassassin/trunk/sa-update.raw
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm?rev=1425068&r1=1425067&r2=1425068&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm Fri Dec 21 18:21:45 2012
@@ -185,9 +185,11 @@ sub dnsbl_hit {
if (substr($rule, 0, 2) eq "__") {
# don't bother with meta rules
} elsif ($answer->type eq 'TXT') {
+ # txtdata returns a non- zone-file-format encoded result, unlike rdatastr;
+ # avoid space-separated RDATA <character-string> fields if possible,
+ # txtdata provides a list of strings in a list context since Net::DNS 0.69
+ $log = join('',$answer->txtdata);
local $1;
- $log = $answer->rdatastr;
- $log =~ s/^"(.*)"\z/$1/s;
$log =~ s{ (?<! [<(\[] ) (https? : // \S+)}{<$1>}xgi;
} else { # assuming $answer->type eq 'A'
local($1,$2,$3,$4,$5);
@@ -226,8 +228,13 @@ sub dnsbl_uri {
my ($self, $question, $answer) = @_;
my $qname = $question->qname;
- my $rdatastr = $answer->rdatastr;
+ # txtdata returns a non- zone-file-format encoded result, unlike rdatastr;
+ # avoid space-separated RDATA <character-string> fields if possible,
+ # txtdata provides a list of strings in a list context since Net::DNS 0.69
+ #
+ my $rdatastr = $answer->UNIVERSAL::can('txtdata') ? join('',$answer->txtdata)
+ : $answer->rdatastr;
if (defined $qname && defined $rdatastr) {
my $qclass = $question->qclass;
my $qtype = $question->qtype;
@@ -289,7 +296,13 @@ sub process_dnsbl_result {
sub process_dnsbl_set {
my ($self, $set, $question, $answer) = @_;
- my $rdatastr = $answer->rdatastr;
+ # txtdata returns a non- zone-file-format encoded result, unlike rdatastr;
+ # avoid space-separated RDATA <character-string> fields if possible,
+ # txtdata provides a list of strings in a list context since Net::DNS 0.69
+ #
+ my $rdatastr = $answer->UNIVERSAL::can('txtdata') ? join('',$answer->txtdata)
+ : $answer->rdatastr;
+
while (my ($subtest, $rule) = each %{ $self->{dnspost}->{$set} }) {
next if $self->{tests_already_hit}->{$rule};
@@ -305,8 +318,7 @@ sub process_dnsbl_set {
next;
}
- $rdatastr =~ s/^"?\d+-//;
- $rdatastr =~ s/"$//;
+ $rdatastr =~ s/^\d+-//;
my %sb = ($rdatastr =~ m/(?:^|\|)(\d+)=([^|]+)/g);
my $undef = 0;
while ($subtest =~ m/\bS(\d+)\b/g) {
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm?rev=1425068&r1=1425067&r2=1425068&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm Fri Dec 21 18:21:45 2012
@@ -596,7 +596,7 @@ sub _packet_id {
# Net::DNS::Packet::dn_expand and Net::DNS::wire2presentation in turn.
# Let's undo the effect of the wire2presentation routine here to make
# sure the query section of an answer packet matches the query section
- # in our packet formed by new_dns_packet():
+ # 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;
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/AskDNS.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/AskDNS.pm?rev=1425068&r1=1425067&r2=1425068&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/AskDNS.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/AskDNS.pm Fri Dec 21 18:21:45 2012
@@ -192,7 +192,7 @@ use Mail::SpamAssassin::Plugin;
use Mail::SpamAssassin::Util;
use Mail::SpamAssassin::Logger;
-use vars qw(@ISA %rcode_value);
+use vars qw(@ISA %rcode_value $txtdata_can_provide_a_list);
@ISA = qw(Mail::SpamAssassin::Plugin);
%rcode_value = ( # http://www.iana.org/assignments/dns-parameters, RFC 6195
@@ -211,6 +211,8 @@ sub new {
$self->set_config($sa_main->{conf});
+ $txtdata_can_provide_a_list = Net::DNS->VERSION >= 0.69;
+
return $self;
}
@@ -534,20 +536,40 @@ sub process_response_packet {
# evaluate also rules which only care for rcode status
@answer = ( undef );
}
+
+ # NOTE: $rr->rdatastr returns the result encoded in a DNS zone file
+ # format, i.e. enclosed in double quotes if a result contains whitespace
+ # (or other funny characters), and may use \DDD encoding or \X quoting as
+ # per RFC 1035. Using $rr->txtdata instead avoids this unnecessary encoding
+ # step and a need for decoding by a caller, returning an unmodified string.
+ # Caveat: in case of multiple RDATA <character-string> fields contained
+ # in a resource record (TXT, SPF, HINFO), starting with Net::DNS 0.69
+ # the $rr->txtdata in a list context returns these strings as a list.
+ # The $rr->txtdata in a scalar context always returns a single string
+ # with <character-string> fields joined by a single space character as
+ # a separator. The $rr->txtdata in Net::DNS 0.68 and older returned
+ # such joined space-separated string even in a list context.
+
+ # RFC 5518: If the RDATA in the TXT record contains multiple
+ # character-strings (as defined in Section 3.3 of [RFC1035]),
+ # the code handling that reply from DNS MUST assemble all of these
+ # marshaled text blocks into a single one before any syntactical
+ # verification takes place.
+ # The same goes for RFC 4408 (SPF), RFC 4871 (DKIM), RFC 5617 (ADSP) ...
+
for my $rr (@answer) {
my($rr_rdatastr, $rdatanum, $rr_type);
if (!$rr) {
# special case, no answer records, only rcode can be tested
} else {
$rr_type = uc $rr->type;
- if ($rr_type eq 'TXT' || $rr_type eq 'SPF') {
- # RFC 5518: If the RDATA in the TXT record contains multiple
- # character-strings (as defined in Section 3.3 of [RFC1035]),
- # the code handling that reply from DNS MUST assemble all of these
- # marshaled text blocks into a single one before any syntactical
- # verification takes place.
- # The same goes for RFC 4408 (SPF), RFC 4871 (DKIM), RFC 5617 (ADSP) ...
- $rr_rdatastr = join('', $rr->char_str_list); # as per RFC 5518
+ if ($rr->UNIVERSAL::can('txtdata')) { # TXT, SPF
+ # join with no intervening spaces, as per RFC 5518
+ if ($txtdata_can_provide_a_list || $rr_type ne 'TXT') {
+ $rr_rdatastr = join('', $rr->txtdata); # txtdata() in list context!
+ } else { # char_str_list() is only available for TXT records
+ $rr_rdatastr = join('', $rr->char_str_list); # historical
+ }
} else {
$rr_rdatastr = $rr->rdatastr;
if ($rr_type eq 'A' &&
@@ -555,9 +577,6 @@ sub process_response_packet {
$rdatanum = Mail::SpamAssassin::Util::my_inet_aton($rr_rdatastr);
}
}
- # decode DNS presentation format as returned by Net::DNS
- local $1;
- $rr_rdatastr =~ s/\\([0-9]{3}|.)/length($1)==1 ? $1 : chr($1)/gse;
# dbg("askdns: received rr type %s, data: %s", $rr_type, $rr_rdatastr);
}
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm?rev=1425068&r1=1425067&r2=1425068&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm Fri Dec 21 18:21:45 2012
@@ -1075,7 +1075,13 @@ sub complete_dnsbl_lookup {
next if ($rr->type ne 'A' && $rr->type ne 'TXT');
my $dom = $ent->{obj}->{dom};
- my $rdatastr = $rr->rdatastr;
+
+ # txtdata returns a non- zone-file-format encoded result, unlike rdatastr;
+ # avoid space-separated RDATA <character-string> fields if possible,
+ # txtdata provides a list of strings in a list context since Net::DNS 0.69
+ #
+ my $rdatastr = $rr->type eq 'TXT' ? join('',$rr->txtdata) : $rr->rdatastr;
+
my $rdatanum;
if ($rdatastr =~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
$rdatanum = Mail::SpamAssassin::Util::my_inet_aton($rdatastr);
Modified: spamassassin/trunk/sa-update.raw
URL: http://svn.apache.org/viewvc/spamassassin/trunk/sa-update.raw?rev=1425068&r1=1425067&r2=1425068&view=diff
==============================================================================
--- spamassassin/trunk/sa-update.raw (original)
+++ spamassassin/trunk/sa-update.raw Fri Dec 21 18:21:45 2012
@@ -1243,16 +1243,32 @@ sub do_dns_query {
my $RR = $res->query($query, $rr_type);
my @result;
+ # NOTE: $rr->rdatastr returns the result encoded in a DNS zone file
+ # format, i.e. enclosed in double quotes if a result contains whitespace
+ # (or other funny characters), and may use \DDD encoding or \X quoting as
+ # per RFC 1035. Using $rr->txtdata instead avoids this unnecessary encoding
+ # step and a need for decoding by a caller, returning an unmodified string.
+ # Caveat: in case of multiple RDATA <character-string> fields contained
+ # in a resource record (TXT, SPF, HINFO), starting with Net::DNS 0.69
+ # the $rr->txtdata in a list context returns these strings as a list.
+ # The $rr->txtdata in a scalar context always returns a single string
+ # with <character-string> fields joined by a single space character as
+ # a separator. The $rr->txtdata in Net::DNS 0.68 and older returned
+ # such joined space-separated string even in a list context.
+ #
+ # From Net::DNS maintainers (Willem Toorop, NLnet Labs):
+ # I encourage you to use txtdata for getting the values of
+ # <version>.updates.spamassassin.org and mirros.updates.spamassassin.org.
+ # As those records have only a single rdata field, txtdata would return
+ # the same value since Net::DNS 0.34.
+ #
if ($RR) {
foreach my $rr ($RR->answer) {
next if !$rr; # no answer records, only rcode
next if $rr->type ne $rr_type;
- my $text = $rr->rdatastr;
- if (defined $text && $text ne '') {
- local($1);
- $text =~ s/^"(.*)"\z/$1/s;
- push(@result,$text);
- }
+ # scalar context!
+ my $text = $rr->UNIVERSAL::can('txtdata') ? $rr->txtdata : $rr->rdatastr;
+ push(@result,$text) if defined $text && $text ne '';
}
printf("DNS %s query: %s -> %s\n", $rr_type, $query, join(", ",@result))
if $opt{'verbose'} && $opt{'verbose'} > 1;