You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by he...@apache.org on 2019/04/15 06:45:15 UTC

svn commit: r1857549 - in /spamassassin: branches/3.4/ branches/3.4/lib/Mail/SpamAssassin/Plugin/ branches/3.4/t/ trunk/ trunk/lib/Mail/SpamAssassin/Plugin/ trunk/rules/ trunk/t/

Author: hege
Date: Mon Apr 15 06:45:15 2019
New Revision: 1857549

URL: http://svn.apache.org/viewvc?rev=1857549&view=rev
Log:
Bug 7211 - Support IPv6 ASN lookups with asn_lookup_ipv6

Modified:
    spamassassin/branches/3.4/UPGRADE
    spamassassin/branches/3.4/lib/Mail/SpamAssassin/Plugin/ASN.pm
    spamassassin/branches/3.4/t/cross_user_config_leak.t
    spamassassin/trunk/UPGRADE
    spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/ASN.pm
    spamassassin/trunk/rules/25_asn.cf
    spamassassin/trunk/t/cross_user_config_leak.t

Modified: spamassassin/branches/3.4/UPGRADE
URL: http://svn.apache.org/viewvc/spamassassin/branches/3.4/UPGRADE?rev=1857549&r1=1857548&r2=1857549&view=diff
==============================================================================
--- spamassassin/branches/3.4/UPGRADE (original)
+++ spamassassin/branches/3.4/UPGRADE Mon Apr 15 06:45:15 2019
@@ -20,11 +20,12 @@ Note for Users Upgrading to SpamAssassin
   Old hardcoded list is now removed and RB will print "no tlds defined, need
   to run sa-update" unless it can find list from config files.
 
-
 - Deprecated functions: Parser::is_delimited_regexp_valid(),
   Parser::is_regexp_valid(), Util::regexp_remove_delimiters(),
   Util::make_qr().  These all are combined into new Util::compile_regexp().
 
+- ASN: Support IPv6 with asn_lookup_ipv6 (Bug 7211)
+
 
 Note for Users Upgrading to SpamAssassin 3.4.2
 ----------------------------------------------

Modified: spamassassin/branches/3.4/lib/Mail/SpamAssassin/Plugin/ASN.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/3.4/lib/Mail/SpamAssassin/Plugin/ASN.pm?rev=1857549&r1=1857548&r2=1857549&view=diff
==============================================================================
--- spamassassin/branches/3.4/lib/Mail/SpamAssassin/Plugin/ASN.pm (original)
+++ spamassassin/branches/3.4/lib/Mail/SpamAssassin/Plugin/ASN.pm Mon Apr 15 06:45:15 2019
@@ -39,7 +39,7 @@
 # (e.g. from cymru.com). This form of a response is handled as well.
 #
 # Some zones also support IPv6 lookups, for example:
-#   asn_lookup origin6.asn.cymru.com [_ASN_ _ASNCIDR_]
+#   asn_lookup_ipv6 origin6.asn.cymru.com [_ASN_ _ASNCIDR_]
 
 =head1 NAME
 
@@ -51,6 +51,8 @@ Autonomous System Number (ASN) of the co
  loadplugin Mail::SpamAssassin::Plugin::ASN
 
  asn_lookup asn.routeviews.org _ASN_ _ASNCIDR_
+ 
+ asn_lookup_ipv6 origin6.asn.cymru.com _ASN_ _ASNCIDR_
 
  add_header all ASN _ASN_ _ASNCIDR_
 
@@ -115,14 +117,19 @@ package Mail::SpamAssassin::Plugin::ASN;
 use strict;
 use warnings;
 use re 'taint';
-use Mail::SpamAssassin;
+
 use Mail::SpamAssassin::Plugin;
 use Mail::SpamAssassin::Logger;
 use Mail::SpamAssassin::Util qw(reverse_ip_address);
 use Mail::SpamAssassin::Dns;
+use Mail::SpamAssassin::Constants qw(:ip);
 
 our @ISA = qw(Mail::SpamAssassin::Plugin);
 
+our $txtdata_can_provide_a_list;
+
+my $IPV4_ADDRESS = IPV4_ADDRESS;
+
 sub new {
   my ($class, $mailsa) = @_;
   $class = ref($class) || $class;
@@ -131,6 +138,10 @@ sub new {
 
   $self->set_config($mailsa->{conf});
 
+  #$txtdata_can_provide_a_list = Net::DNS->VERSION >= 0.69;
+  #more robust version check from Damyan Ivanov - Bug 7095
+  $txtdata_can_provide_a_list = version->parse(Net::DNS->VERSION) >= version->parse('0.69');
+
   return $self;
 }
 
@@ -147,7 +158,7 @@ sub set_config {
 =item asn_lookup asn-zone.example.com [ _ASNTAG_ _ASNCIDRTAG_ ]
 
 Use this to lookup the ASN info in the specified zone for the first external
-IP address and add the AS number to the first specified tag and routing info
+IPv4 address and add the AS number to the first specified tag and routing info
 to the second specified tag.
 
 If no tags are specified the AS number will be added to the _ASN_ tag and the
@@ -174,6 +185,12 @@ Examples:
 
 =back
 
+=item asn_lookup_ipv6 asn-zone6.example.com [_ASN_ _ASNCIDR_]
+
+Use specified zone for lookups of IPv6 addresses.  If zone supports both
+IPv4 and IPv6 queries, use both asn_lookup and asn_lookup_ipv6 for the same
+zone.
+
 =over 4
 
 =item clear_asn_lookups
@@ -217,6 +234,26 @@ need not be) enclosed in single or doubl
   });
 
   push (@cmds, {
+    setting => 'asn_lookup_ipv6',
+    is_admin => 1,
+    code => sub {
+      my ($conf, $key, $value, $line) = @_;
+      unless (defined $value && $value !~ /^$/) {
+        return $Mail::SpamAssassin::Conf::MISSING_REQUIRED_VALUE;
+      }
+      local($1,$2,$3);
+      unless ($value =~ /^(\S+?)\.?(?:\s+_(\S+)_\s+_(\S+)_)?$/) {
+        return $Mail::SpamAssassin::Conf::INVALID_VALUE;
+      }
+      my ($zone, $asn_tag, $route_tag) = ($1, $2, $3);
+      $asn_tag   = 'ASN'     if !defined $asn_tag;
+      $route_tag = 'ASNCIDR' if !defined $route_tag;
+      push @{$conf->{asnlookups_ipv6}},
+           { zone=>$zone, asn_tag=>$asn_tag, route_tag=>$route_tag };
+    }
+  });
+
+  push (@cmds, {
     setting => 'clear_asn_lookups',
     is_admin => 1,
     type => $Mail::SpamAssassin::Conf::CONF_TYPE_NOARGS,
@@ -226,6 +263,7 @@ need not be) enclosed in single or doubl
         return $Mail::SpamAssassin::Conf::INVALID_VALUE;
       }
       delete $conf->{asnlookups};
+      delete $conf->{asnlookups_ipv6};
     }
   });
 
@@ -253,61 +291,83 @@ sub parsed_metadata {
   my $pms = $opts->{permsgstatus};
   my $conf = $self->{main}->{conf};
 
-  unless ($conf->{asnlookups}) {
-    dbg("asn: no asn_lookup configured, skipping ASN lookups");
-    return; # no asn_lookups mean no tags need to be initialized
+  if (!$pms->is_dns_available()) {
+    dbg("asn: DNS is not available, skipping ASN checks");
+    return;
+  }
+
+  if (!$conf->{asnlookups} && !$conf->{asnlookups_ipv6}) {
+    dbg("asn: no asn_lookups configured, skipping ASN lookups");
+    return;
+  }
+
+  # initialize the tag data so that if no result is returned from the DNS
+  # query we won't end up with a missing tag.  Don't use $pms->set_tag()
+  # here to avoid triggering any tag-dependent action unnecessarily
+  if ($conf->{asnlookups}) {
+    foreach my $entry (@{$conf->{asnlookups}}) {
+      $pms->{tag_data}->{$entry->{asn_tag}} ||= '';
+      $pms->{tag_data}->{$entry->{route_tag}} ||= '';
+    }
+  }
+  if ($conf->{asnlookups_ipv6}) {
+    foreach my $entry (@{$conf->{asnlookups_ipv6}}) {
+      $pms->{tag_data}->{$entry->{asn_tag}} ||= '';
+      $pms->{tag_data}->{$entry->{route_tag}} ||= '';
+    }
   }
 
   # get reversed IP address of last external relay to lookup
   # don't return until we've initialized the template tags
-  my($ip,$reversed_ip);
   my $relay = $pms->{relays_external}->[0];
-  $ip = $relay->{ip}  if defined $relay;
-  if (!$pms->is_dns_available()) {
-    dbg("asn: DNS is not available, skipping ASN checks");
-  } elsif (!defined $ip) {
+  if (!defined $relay) {
     dbg("asn: no first external relay IP available, skipping ASN check");
+    return;
   } elsif ($relay->{ip_private}) {
     dbg("asn: first external relay is a private IP, skipping ASN check");
+    return;
+  }
+
+  my $ip = $relay->{ip};
+  my $reversed_ip = reverse_ip_address($ip);
+  if (defined $reversed_ip) {
+    dbg("asn: using first external relay IP for lookups: %s", $ip);
   } else {
-    $reversed_ip = reverse_ip_address($ip);
-    if (defined $reversed_ip) {
-      dbg("asn: using first external relay IP for lookups: %s", $ip);
-    } else {
-      dbg("asn: could not parse first external relay IP: %s, skipping", $ip);
-    }
+    dbg("asn: could not parse first external relay IP: %s, skipping", $ip);
+    return;
   }
 
+  my $lookup_zone;
+  if ($ip =~ /^$IPV4_ADDRESS$/o) {
+    if (!defined $conf->{asnlookups}) {
+      dbg("asn: asn_lookup for IPv4 not defined, skipping");
+      return;
+    }
+    $lookup_zone = "asnlookups";
+  } else {
+    if (!defined $conf->{asnlookups_ipv6}) {
+      dbg("asn: asn_lookup_ipv6 for IPv6 not defined, skipping");
+      return;
+    }
+    $lookup_zone = "asnlookups_ipv6";
+  }
+  
   # we use arrays and array indices rather than hashes and hash keys
   # in case someone wants the same zone added to multiple sets of tags
   my $index = 0;
-  foreach my $entry (@{$conf->{asnlookups}}) {
-    # initialize the tag data so that if no result is returned from the DNS
-    # query we won't end up with a missing tag.  Don't use $pms->set_tag()
-    # here to avoid triggering any tag-dependent action unnecessarily
-    unless (defined $pms->{tag_data}->{$entry->{asn_tag}}) {
-      $pms->{tag_data}->{$entry->{asn_tag}} = '';
-    }
-    unless (defined $pms->{tag_data}->{$entry->{route_tag}}) {
-      $pms->{tag_data}->{$entry->{route_tag}} = '';
-    }
-    next unless $reversed_ip;
-
+  foreach my $entry (@{$conf->{$lookup_zone}}) {
     # do the DNS query, have the callback process the result
     my $zone_index = $index;
     my $zone = $reversed_ip . '.' . $entry->{zone};
-    my $key = "asnlookup-${zone_index}-$entry->{zone}";
-    my $ent = $pms->{async}->bgsend_and_start_lookup(
-        $zone, 'TXT', undef,
-        { key => $key, zone => $zone },
-        sub { my($ent, $pkt) = @_;
-              $self->process_dns_result($pms, $pkt, $zone_index) },
-      master_deadline => $pms->{master_deadline} );
-    if ($ent) {
-      dbg("asn: launched DNS TXT query for %s.%s in background",
-          $reversed_ip, $entry->{zone});
-      $index++;
-    }
+    my $key = "asnlookup-${lookup_zone}-${zone_index}-".$entry->{zone};
+    my $ent = $pms->{async}->bgsend_and_start_lookup($zone, 'TXT', undef,
+      { type => 'ASN', key => $key, zone => $lookup_zone },
+      sub { my($ent, $pkt) = @_;
+            $self->process_dns_result($pms, $pkt, $zone_index, $lookup_zone) },
+      master_deadline => $pms->{master_deadline}
+    );
+    $pms->register_async_rule_start($key) if $ent;
+    $index++;
   }
 }
 
@@ -322,13 +382,13 @@ sub parsed_metadata {
 #       be no CIDR field in that case.
 #
 sub process_dns_result {
-  my ($self, $pms, $pkt, $zone_index) = @_;
+  my ($self, $pms, $pkt, $zone_index, $lookup_zone) = @_;
 
   my $conf = $self->{main}->{conf};
 
-  my $zone = $conf->{asnlookups}[$zone_index]->{zone};
-  my $asn_tag = $conf->{asnlookups}[$zone_index]->{asn_tag};
-  my $route_tag = $conf->{asnlookups}[$zone_index]->{route_tag};
+  my $zone = $conf->{$lookup_zone}[$zone_index]->{zone};
+  my $asn_tag = $conf->{$lookup_zone}[$zone_index]->{asn_tag};
+  my $route_tag = $conf->{$lookup_zone}[$zone_index]->{route_tag};
 
   my($any_asn_updates, $any_route_updates, $tag_value);
 
@@ -355,10 +415,12 @@ sub process_dns_result {
   my @answer = !defined $pkt ? () : $pkt->answer;
 
   foreach my $rr (@answer) {
-    dbg("asn: %s: lookup result packet: %s", $zone, $rr->string);
+    #dbg("asn: %s: lookup result packet: %s", $zone, $rr->string);
     next if $rr->type ne 'TXT';
-    my @strings = $rr->char_str_list;
+    my @strings = $txtdata_can_provide_a_list ? $rr->txtdata :
+      $rr->char_str_list; # historical
     next if !@strings;
+    for (@strings) { utf8::encode($_) if utf8::is_utf8($_) }
 
     my @items;
     if (@strings > 1 && join('',@strings) !~ m{\|}) {
@@ -430,4 +492,7 @@ sub process_dns_result {
   }
 }
 
+# Version features
+sub has_asn_lookup_ipv6 { 1 }
+
 1;

Modified: spamassassin/branches/3.4/t/cross_user_config_leak.t
URL: http://svn.apache.org/viewvc/spamassassin/branches/3.4/t/cross_user_config_leak.t?rev=1857549&r1=1857548&r2=1857549&view=diff
==============================================================================
--- spamassassin/branches/3.4/t/cross_user_config_leak.t (original)
+++ spamassassin/branches/3.4/t/cross_user_config_leak.t Mon Apr 15 06:45:15 2019
@@ -34,7 +34,7 @@ my @ignored_commands = qw(
   version_tag uri_detail uridnssub uridnsbl urirhsbl urirhssub urinsrhsbl
   urinsrhssub urifullnsrhsbl urifullnsrhssub add_header remove_header
   redirector_pattern reuse mimeheader rbl_timeout uridnsbl_timeout
-  util_rb_tld util_rb_2tld util_rb_3tld shortcircuit asn_lookup
+  util_rb_tld util_rb_2tld util_rb_3tld shortcircuit asn_lookup asn_lookup_ipv6
 
 );
 

Modified: spamassassin/trunk/UPGRADE
URL: http://svn.apache.org/viewvc/spamassassin/trunk/UPGRADE?rev=1857549&r1=1857548&r2=1857549&view=diff
==============================================================================
--- spamassassin/trunk/UPGRADE (original)
+++ spamassassin/trunk/UPGRADE Mon Apr 15 06:45:15 2019
@@ -80,6 +80,8 @@ Note for Users Upgrading to SpamAssassin
 
 - Add check_hashbl_bodyre and hashbl_ignore to HashBL.pm
 
+- ASN: Support IPv6 with asn_lookup_ipv6 (Bug 7211)
+
 Note for Users Upgrading to SpamAssassin 3.4.2
 ----------------------------------------------
 

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/ASN.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/ASN.pm?rev=1857549&r1=1857548&r2=1857549&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/ASN.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/ASN.pm Mon Apr 15 06:45:15 2019
@@ -39,7 +39,7 @@
 # (e.g. from cymru.com). This form of a response is handled as well.
 #
 # Some zones also support IPv6 lookups, for example:
-#   asn_lookup origin6.asn.cymru.com [_ASN_ _ASNCIDR_]
+#   asn_lookup_ipv6 origin6.asn.cymru.com [_ASN_ _ASNCIDR_]
 
 =head1 NAME
 
@@ -51,6 +51,8 @@ Autonomous System Number (ASN) of the co
  loadplugin Mail::SpamAssassin::Plugin::ASN
 
  asn_lookup asn.routeviews.org _ASN_ _ASNCIDR_
+ 
+ asn_lookup_ipv6 origin6.asn.cymru.com _ASN_ _ASNCIDR_
 
  add_header all ASN _ASN_ _ASNCIDR_
 
@@ -120,11 +122,14 @@ use Mail::SpamAssassin::Plugin;
 use Mail::SpamAssassin::Logger;
 use Mail::SpamAssassin::Util qw(reverse_ip_address);
 use Mail::SpamAssassin::Dns;
+use Mail::SpamAssassin::Constants qw(:ip);
 
 our @ISA = qw(Mail::SpamAssassin::Plugin);
 
 our $txtdata_can_provide_a_list;
 
+my $IPV4_ADDRESS = IPV4_ADDRESS;
+
 sub new {
   my ($class, $mailsa) = @_;
   $class = ref($class) || $class;
@@ -153,7 +158,7 @@ sub set_config {
 =item asn_lookup asn-zone.example.com [ _ASNTAG_ _ASNCIDRTAG_ ]
 
 Use this to lookup the ASN info in the specified zone for the first external
-IP address and add the AS number to the first specified tag and routing info
+IPv4 address and add the AS number to the first specified tag and routing info
 to the second specified tag.
 
 If no tags are specified the AS number will be added to the _ASN_ tag and the
@@ -180,6 +185,12 @@ Examples:
 
 =back
 
+=item asn_lookup_ipv6 asn-zone6.example.com [_ASN_ _ASNCIDR_]
+
+Use specified zone for lookups of IPv6 addresses.  If zone supports both
+IPv4 and IPv6 queries, use both asn_lookup and asn_lookup_ipv6 for the same
+zone.
+
 =over 4
 
 =item clear_asn_lookups
@@ -223,6 +234,26 @@ need not be) enclosed in single or doubl
   });
 
   push (@cmds, {
+    setting => 'asn_lookup_ipv6',
+    is_admin => 1,
+    code => sub {
+      my ($conf, $key, $value, $line) = @_;
+      unless (defined $value && $value !~ /^$/) {
+        return $Mail::SpamAssassin::Conf::MISSING_REQUIRED_VALUE;
+      }
+      local($1,$2,$3);
+      unless ($value =~ /^(\S+?)\.?(?:\s+_(\S+)_\s+_(\S+)_)?$/) {
+        return $Mail::SpamAssassin::Conf::INVALID_VALUE;
+      }
+      my ($zone, $asn_tag, $route_tag) = ($1, $2, $3);
+      $asn_tag   = 'ASN'     if !defined $asn_tag;
+      $route_tag = 'ASNCIDR' if !defined $route_tag;
+      push @{$conf->{asnlookups_ipv6}},
+           { zone=>$zone, asn_tag=>$asn_tag, route_tag=>$route_tag };
+    }
+  });
+
+  push (@cmds, {
     setting => 'clear_asn_lookups',
     is_admin => 1,
     type => $Mail::SpamAssassin::Conf::CONF_TYPE_NOARGS,
@@ -232,6 +263,7 @@ need not be) enclosed in single or doubl
         return $Mail::SpamAssassin::Conf::INVALID_VALUE;
       }
       delete $conf->{asnlookups};
+      delete $conf->{asnlookups_ipv6};
     }
   });
 
@@ -259,60 +291,81 @@ sub parsed_metadata {
   my $pms = $opts->{permsgstatus};
   my $conf = $self->{main}->{conf};
 
-  unless ($conf->{asnlookups}) {
-    dbg("asn: no asn_lookup configured, skipping ASN lookups");
-    return; # no asn_lookups mean no tags need to be initialized
+  if (!$pms->is_dns_available()) {
+    dbg("asn: DNS is not available, skipping ASN checks");
+    return;
+  }
+
+  if (!$conf->{asnlookups} && !$conf->{asnlookups_ipv6}) {
+    dbg("asn: no asn_lookups configured, skipping ASN lookups");
+    return;
+  }
+
+  # initialize the tag data so that if no result is returned from the DNS
+  # query we won't end up with a missing tag.  Don't use $pms->set_tag()
+  # here to avoid triggering any tag-dependent action unnecessarily
+  if ($conf->{asnlookups}) {
+    foreach my $entry (@{$conf->{asnlookups}}) {
+      $pms->{tag_data}->{$entry->{asn_tag}} ||= '';
+      $pms->{tag_data}->{$entry->{route_tag}} ||= '';
+    }
+  }
+  if ($conf->{asnlookups_ipv6}) {
+    foreach my $entry (@{$conf->{asnlookups_ipv6}}) {
+      $pms->{tag_data}->{$entry->{asn_tag}} ||= '';
+      $pms->{tag_data}->{$entry->{route_tag}} ||= '';
+    }
   }
 
   # get reversed IP address of last external relay to lookup
   # don't return until we've initialized the template tags
-  my($ip,$reversed_ip);
   my $relay = $pms->{relays_external}->[0];
-  $ip = $relay->{ip}  if defined $relay;
-  if (!$pms->is_dns_available()) {
-    dbg("asn: DNS is not available, skipping ASN checks");
-  } elsif (!defined $ip) {
+  if (!defined $relay) {
     dbg("asn: no first external relay IP available, skipping ASN check");
+    return;
   } elsif ($relay->{ip_private}) {
     dbg("asn: first external relay is a private IP, skipping ASN check");
+    return;
+  }
+
+  my $ip = $relay->{ip};
+  my $reversed_ip = reverse_ip_address($ip);
+  if (defined $reversed_ip) {
+    dbg("asn: using first external relay IP for lookups: %s", $ip);
   } else {
-    $reversed_ip = reverse_ip_address($ip);
-    if (defined $reversed_ip) {
-      dbg("asn: using first external relay IP for lookups: %s", $ip);
-    } else {
-      dbg("asn: could not parse first external relay IP: %s, skipping", $ip);
-    }
+    dbg("asn: could not parse first external relay IP: %s, skipping", $ip);
+    return;
   }
 
+  my $lookup_zone;
+  if ($ip =~ /^$IPV4_ADDRESS$/o) {
+    if (!defined $conf->{asnlookups}) {
+      dbg("asn: asn_lookup for IPv4 not defined, skipping");
+      return;
+    }
+    $lookup_zone = "asnlookups";
+  } else {
+    if (!defined $conf->{asnlookups_ipv6}) {
+      dbg("asn: asn_lookup_ipv6 for IPv6 not defined, skipping");
+      return;
+    }
+    $lookup_zone = "asnlookups_ipv6";
+  }
+  
   # we use arrays and array indices rather than hashes and hash keys
   # in case someone wants the same zone added to multiple sets of tags
   my $index = 0;
-  foreach my $entry (@{$conf->{asnlookups}}) {
-    # initialize the tag data so that if no result is returned from the DNS
-    # query we won't end up with a missing tag.  Don't use $pms->set_tag()
-    # here to avoid triggering any tag-dependent action unnecessarily
-    unless (defined $pms->{tag_data}->{$entry->{asn_tag}}) {
-      $pms->{tag_data}->{$entry->{asn_tag}} = '';
-    }
-    unless (defined $pms->{tag_data}->{$entry->{route_tag}}) {
-      $pms->{tag_data}->{$entry->{route_tag}} = '';
-    }
-    next unless $reversed_ip;
-
+  foreach my $entry (@{$conf->{$lookup_zone}}) {
     # do the DNS query, have the callback process the result
     my $zone_index = $index;
     my $zone = $reversed_ip . '.' . $entry->{zone};
-    my $key = "asnlookup-${zone_index}-$entry->{zone}";
-    my $ent = $pms->{async}->bgsend_and_start_lookup($zone, 'TXT', undef,
+    $pms->{async}->bgsend_and_start_lookup($zone, 'TXT', undef,
       { rulename => 'asn_lookup', type => 'ASN' },
       sub { my($ent, $pkt) = @_;
-            $self->process_dns_result($pms, $pkt, $zone_index) },
-      master_deadline => $pms->{master_deadline} );
-    if ($ent) {
-      dbg("asn: launched DNS TXT query for %s.%s in background",
-          $reversed_ip, $entry->{zone});
-      $index++;
-    }
+            $self->process_dns_result($pms, $pkt, $zone_index, $lookup_zone) },
+      master_deadline => $pms->{master_deadline}
+    );
+    $index++;
   }
 }
 
@@ -327,13 +380,13 @@ sub parsed_metadata {
 #       be no CIDR field in that case.
 #
 sub process_dns_result {
-  my ($self, $pms, $pkt, $zone_index) = @_;
+  my ($self, $pms, $pkt, $zone_index, $lookup_zone) = @_;
 
   my $conf = $self->{main}->{conf};
 
-  my $zone = $conf->{asnlookups}[$zone_index]->{zone};
-  my $asn_tag = $conf->{asnlookups}[$zone_index]->{asn_tag};
-  my $route_tag = $conf->{asnlookups}[$zone_index]->{route_tag};
+  my $zone = $conf->{$lookup_zone}[$zone_index]->{zone};
+  my $asn_tag = $conf->{$lookup_zone}[$zone_index]->{asn_tag};
+  my $route_tag = $conf->{$lookup_zone}[$zone_index]->{route_tag};
 
   my($any_asn_updates, $any_route_updates, $tag_value);
 
@@ -360,7 +413,7 @@ sub process_dns_result {
   my @answer = !defined $pkt ? () : $pkt->answer;
 
   foreach my $rr (@answer) {
-    dbg("asn: %s: lookup result packet: %s", $zone, $rr->string);
+    #dbg("asn: %s: lookup result packet: %s", $zone, $rr->string);
     next if $rr->type ne 'TXT';
     my @strings = $txtdata_can_provide_a_list ? $rr->txtdata :
       $rr->char_str_list; # historical
@@ -437,4 +490,7 @@ sub process_dns_result {
   }
 }
 
+# Version features
+sub has_asn_lookup_ipv6 { 1 }
+
 1;

Modified: spamassassin/trunk/rules/25_asn.cf
URL: http://svn.apache.org/viewvc/spamassassin/trunk/rules/25_asn.cf?rev=1857549&r1=1857548&r2=1857549&view=diff
==============================================================================
--- spamassassin/trunk/rules/25_asn.cf (original)
+++ spamassassin/trunk/rules/25_asn.cf Mon Apr 15 06:45:15 2019
@@ -32,4 +32,9 @@
 ifplugin Mail::SpamAssassin::Plugin::ASN
  asn_lookup asn.routeviews.org _ASN_ _ASNCIDR_
  add_header all ASN _ASN_ _ASNCIDR_
+
+ # IPv6 support (Bug 7211)
+ #if can(Mail::SpamAssassin::Plugin::ASN::has_asn_lookup_ipv6)
+ #  asn_lookup origin6.asn.cymru.com _ASN_ _ASNCIDR_
+ #endif
 endif	# Mail::SpamAssassin::Plugin::ASN

Modified: spamassassin/trunk/t/cross_user_config_leak.t
URL: http://svn.apache.org/viewvc/spamassassin/trunk/t/cross_user_config_leak.t?rev=1857549&r1=1857548&r2=1857549&view=diff
==============================================================================
--- spamassassin/trunk/t/cross_user_config_leak.t (original)
+++ spamassassin/trunk/t/cross_user_config_leak.t Mon Apr 15 06:45:15 2019
@@ -34,7 +34,7 @@ my @ignored_commands = qw(
   version_tag uri_detail uridnssub uridnsbl urirhsbl urirhssub urinsrhsbl
   urinsrhssub urifullnsrhsbl urifullnsrhssub add_header remove_header
   redirector_pattern reuse mimeheader rbl_timeout uridnsbl_timeout
-  util_rb_tld util_rb_2tld util_rb_3tld shortcircuit asn_lookup
+  util_rb_tld util_rb_2tld util_rb_3tld shortcircuit asn_lookup asn_lookup_ipv6
 
 );