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 2010/03/09 19:51:59 UTC

svn commit: r921052 - in /spamassassin/trunk: MANIFEST lib/Mail/SpamAssassin/Conf.pm lib/Mail/SpamAssassin/Dns.pm lib/Mail/SpamAssassin/DnsResolver.pm lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm t/dnsbl_subtests.t

Author: mmartinec
Date: Tue Mar  9 18:51:58 2010
New Revision: 921052

URL: http://svn.apache.org/viewvc?rev=921052&view=rev
Log:
Bug 6362: Change urirhssub mask syntax:
- provided a supporting test t/dnsbl_subtests.t;
- provided config directives dns_server and clear_dns_servers,
  offering means to specify a list of DNS servers with
  optional port numbers, needed by dnsbl_subtests.t, which
  is running its own test DNS server in a subprocess

Added:
    spamassassin/trunk/t/dnsbl_subtests.t   (with props)
Modified:
    spamassassin/trunk/MANIFEST
    spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm

Modified: spamassassin/trunk/MANIFEST
URL: http://svn.apache.org/viewvc/spamassassin/trunk/MANIFEST?rev=921052&r1=921051&r2=921052&view=diff
==============================================================================
--- spamassassin/trunk/MANIFEST (original)
+++ spamassassin/trunk/MANIFEST Tue Mar  9 18:51:58 2010
@@ -537,3 +537,4 @@ t/uribl_domains_only.t
 t/data/spam/dnsbl_ipsonly.eml
 t/uribl_all_types.t
 t/uribl_ips_only.t
+t/dnsbl_subtests.t

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm?rev=921052&r1=921051&r2=921052&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm Tue Mar  9 18:51:58 2010
@@ -84,7 +84,7 @@ use re 'taint';
 
 use Mail::SpamAssassin::Util;
 use Mail::SpamAssassin::NetSet;
-use Mail::SpamAssassin::Constants qw(:sa);
+use Mail::SpamAssassin::Constants qw(:sa :ip);
 use Mail::SpamAssassin::Conf::Parser;
 use Mail::SpamAssassin::Logger;
 use Mail::SpamAssassin::Util::TieOneStringHash;
@@ -1314,6 +1314,74 @@ Please note, the DNS test queries for NS
     }
   });
 
+=item dns_server ip-addr-port  (default: first entry provided by Net::DNS)
+
+Specifies an IP address of a DNS server, and optionally its port number.
+The I<dns_server> directive may be specified multiple times, each entry
+adding to a list of available resolving name servers. The I<ip-addr-port>
+argument can either be an IPv4 or IPv6 address, optionally enclosed in
+brackets, and optionally followed by a colon and a port number. In absence
+of a port number a standard port number 53 is assumed. When an IPv6 address
+is specified along with a port number, the address B<must> be enclosed in
+brackets to avoid parsing ambiguity regarding a colon separator,
+
+Examples :
+ dns_server 127.0.0.1
+ dns_server 127.0.0.1:53
+ dns_server [127.0.0.1]:53
+ dns_server [::1]:53
+
+In absence of I<dns_server> directives, the list of name servers is provided
+by Net::DNS module, which typically obtains the list from /etc/resolv.conf,
+but this may be platform dependent. Please consult Net::DNS documentation
+for details.
+
+=cut
+
+  push (@cmds, {
+    setting => 'dns_server',
+    type => $CONF_TYPE_STRING,
+    code => sub {
+      no warnings 'uninitialized';
+      my ($self, $key, $value, $line) = @_;
+      my($address,$port); local($1,$2,$3);
+      if ($value =~ /^(?: \[ ([^\]]*) \] | ([^:]*) ) : (\d+) \z/sx) {
+        ($address, $port) = ($1.$2, $3);
+      } elsif ($value =~ /^(?: \[ ([^\]]*) \] | ([0-9a-fA-F.:]+) ) \z/sx) {
+        ($address, $port) = ($1.$2, '53');
+      } else {
+        return $INVALID_VALUE;
+      }
+      my $IP_ADDRESS = IP_ADDRESS;
+      if ($address =~ /$IP_ADDRESS/ && $port >= 1 && $port <= 65535) {
+        $self->{dns_server} = []  if !$self->{dns_server};
+        # checked, untainted, stored in a normalized form
+        push(@{$self->{dns_servers}}, untaint_var("[$address]:$port"));
+      } else {
+        return $INVALID_VALUE;
+      }
+    }
+  });
+
+=item clear_dns_servers
+
+Empty the list of explicitly configured DNS servers through a I<dns_server>
+directive, falling back to Net::DNS -supplied defaults.
+
+=cut
+
+  push (@cmds, {
+    setting => 'clear_dns_servers',
+    type => $CONF_TYPE_NOARGS,
+    code => sub {
+      my ($self, $key, $value, $line) = @_;
+      unless (!defined $value || $value eq '') {
+        return $INVALID_VALUE;
+      }
+      undef $self->{dns_servers};
+    }
+  });
+
 =item dns_test_interval n   (default: 600 seconds)
 
 If dns_available is set to 'test' (which is the default), the dns_test_interval

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm?rev=921052&r1=921051&r2=921052&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm Tue Mar  9 18:51:58 2010
@@ -688,7 +688,7 @@ sub is_dns_available {
   while( $ns  = shift(@nameservers)) {
     for(my $retry = 3; $retry > 0 and $#domains>-1; $retry--) {
       my $domain = splice(@domains, rand(@domains), 1);
-      dbg("dns: trying ($retry) $domain...");
+      dbg("dns: trying ($retry) $domain, server $ns ...");
       my $result = $self->lookup_ns($domain);
       if(defined $result) {
         if (scalar @$result > 0) {

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm?rev=921052&r1=921051&r2=921052&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/DnsResolver.pm Tue Mar  9 18:51:58 2010
@@ -158,15 +158,31 @@ sub get_resolver {
 
 =item $res->nameservers()
 
-Wrapper for Net::DNS::Resolver->nameservers to get or set list of nameservers
+Get or set a list of nameservers
 
 =cut
 
 sub nameservers {
   my $self = shift;
-  my $res = $self->{res};
+
+  if (@_) {
+    $self->{available_dns_servers} = [@_];
+    dbg("dns: servers set by a caller to: %s",
+         join(', ',@{$self->{available_dns_servers}}));
+  } elsif (!$self->{available_dns_servers}) {
+    my $res = $self->{res};
+    my @ns_addr_port;  # list of name servers: [addr]:port entries
+    if ($self->{conf}->{dns_servers}) {  # specified in a config file
+      @ns_addr_port = @{$self->{conf}->{dns_servers}};
+      dbg("dns: servers set by config to: %s", join(', ',@ns_addr_port));
+    } elsif ($res) {  # default as provided by Net::DNS, e.g. /etc/resolv.conf
+      @ns_addr_port = map { "[$_]:" . $res->{port} } @{$res->{nameservers}};
+      dbg("dns: servers obtained from Net::DNS : %s", join(', ',@ns_addr_port));
+    }
+    $self->{available_dns_servers} = \@ns_addr_port;
+  }
   $self->connect_sock_if_reqd();
-  return $res->nameservers(@_) if $res;
+  return @{$self->{available_dns_servers}};
 }
 
 =item $res->connect_sock()
@@ -187,24 +203,29 @@ sub connect_sock {
   my $sock;
   my $errno;
 
+  # list of name servers: [addr]:port entries
+  my @ns_addr_port = @{$self->{available_dns_servers}};
+  # use the first name server in a list
+  my($ns_addr,$ns_port); local($1,$2);
+  ($ns_addr,$ns_port) = ($1,$2)  if $ns_addr_port[0] =~ /^\[(.*)\]:(\d+)\z/;
+
   # IO::Socket::INET6 may choose wrong LocalAddr if family is unspecified,
   # causing EINVAL failure when automatically assigned local IP address
   # and remote address do not belong to the same address family:
   use Mail::SpamAssassin::Constants qw(:ip);
   my $ip64 = IP_ADDRESS;
   my $ip4 = IPV4_ADDRESS;
-  my $ns = $self->{res}->{nameservers}[0];
   my $ipv6opt = !($self->{force_ipv4});
 
   # ensure families of src and dest addresses match (bug 4412 comment 29)
   my $srcaddr;
-  if ($ipv6opt && $ns=~/^${ip64}$/o && $ns!~/^${ip4}$/o) {
+  if ($ipv6opt && $ns_addr =~ /^${ip64}$/o && $ns_addr !~ /^${ip4}$/o) {
     $srcaddr = "::";
   } else {
     $srcaddr = "0.0.0.0";
   }
-
-  dbg("dns: name server: %s, LocalAddr: %s", $ns,$srcaddr);
+  dbg("dns: LocalAddr: %s, name server(s): %s",
+      $srcaddr, join(', ',@ns_addr_port));
 
   # find next available unprivileged port (1024 - 65535)
   # starting at a random value to spread out use of ports
@@ -213,8 +234,8 @@ sub connect_sock {
     my $lport = 1024 + (($port_offset + $i) % 64511);
 
     my %args = (
-        PeerAddr => $ns,
-        PeerPort => $self->{res}->{port},
+        PeerAddr => $ns_addr,
+        PeerPort => $ns_port,
         Proto => 'udp',
         LocalPort => $lport,
         Type => SOCK_DGRAM,

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm?rev=921052&r1=921051&r2=921052&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm Tue Mar  9 18:51:58 2010
@@ -312,6 +312,7 @@ sub parsed_metadata {
 
     my $rulecf = $scanner->{conf}->{uridnsbls}->{$rulename};
     my $tflags = $scanner->{conf}->{tflags}->{$rulename};
+    $tflags = ''  if !defined $tflags;
 
     if ($rulecf->{is_rhsbl} && $tflags =~ /\b ips_only \b/x) {
       $scanner->{uridnsbl_active_rules_rhsbl_ipsonly}->{$rulename} = 1;
@@ -985,6 +986,8 @@ sub complete_dnsbl_lookup {
           $match = 1;
         } elsif ($subtest =~ m{^ (\d+) (?: ([/-]) (\d+) )? \z}x) {
           my($n1,$delim,$n2) = ($1,$2,$3);
+        # dbg("uridnsbl: %s/%s, %s, %s", $rulename, $dom, $rdatanum,
+        #     !defined $n2 ? $n1 : "$n1 $delim $n2");
           $match =
             !defined $n2  ? $rdatanum & $n1                       # mask only
           : $delim eq '-' ? $rdatanum >= $n1 && $rdatanum <= $n2  # range

Added: spamassassin/trunk/t/dnsbl_subtests.t
URL: http://svn.apache.org/viewvc/spamassassin/trunk/t/dnsbl_subtests.t?rev=921052&view=auto
==============================================================================
--- spamassassin/trunk/t/dnsbl_subtests.t (added)
+++ spamassassin/trunk/t/dnsbl_subtests.t Tue Mar  9 18:51:58 2010
@@ -0,0 +1,269 @@
+#!/usr/bin/perl
+
+# supporting tests for: Bug 6362 - Change urirhssub mask syntax
+
+use strict;
+use warnings;
+use re 'taint';
+use lib '.'; use lib 't';
+
+use SATest; sa_t_init("dnsbl_subtests");
+use Test;
+
+use vars qw(%patterns %anti_patterns);
+use constant num_tests => 30;
+use constant DO_RUN => 1;
+
+BEGIN {
+  plan tests => (DO_RUN ? num_tests : 0);
+};
+
+exit unless DO_RUN;
+
+my $prefix = '.';
+if (-e 'test_dir') {            # running from test directory, not ..
+  $prefix = '..';
+}
+
+# Bug 5761 (no 127.0.0.1 in jail, use SPAMD_LOCALHOST if specified)
+my $dns_server_localaddr = $ENV{'SPAMD_LOCALHOST'};
+$dns_server_localaddr = '127.0.0.1'  if !$dns_server_localaddr;
+$dns_server_localaddr = '::1'        if !$dns_server_localaddr;
+
+my $dns_server_localport = '5353';  # some port (mdns), hopefully free
+
+# test zone
+my $z = 'sa-dbl-test.spamassassin.org';
+
+my $local_conf = <<"EOD";
+  use_bayes 0
+  use_razor2 0
+  use_pyzor 0
+# use_auto_whitelist 0
+# use_dcc 0
+  score NO_RELAYS 0
+  score NO_RECEIVED 0
+  score TVD_SPACE_RATIO 0
+
+  rbl_timeout 5
+  dns_available yes
+  clear_dns_servers
+  dns_server [$dns_server_localaddr]:$dns_server_localport
+
+  urirhssub  X_URIBL_Y_2A   $z  A  127.0.1.2
+  body       X_URIBL_Y_2A   eval:check_uridnsbl('X_URIBL_Y_2A')
+
+  urirhssub  X_URIBL_Y_2B   $z  A  127.0.1.2-127.0.1.2
+  body       X_URIBL_Y_2B   eval:check_uridnsbl('X_URIBL_Y_2B')
+
+  urirhssub  X_URIBL_Y_2C   $z  A  127.0.1.2/0xffffffff
+  body       X_URIBL_Y_2C   eval:check_uridnsbl('X_URIBL_Y_2C')
+
+  urirhssub  X_URIBL_Y_2D   $z  A  127.0.1.2/255.255.255.255
+  body       X_URIBL_Y_2D   eval:check_uridnsbl('X_URIBL_Y_2D')
+
+  urirhssub  X_URIBL_Y_2E   $z  A  127.0.1.2/127.0.1.2
+  body       X_URIBL_Y_2E   eval:check_uridnsbl('X_URIBL_Y_2E')
+
+  urirhssub  X_URIBL_Y_2F   $z  A  0/128.255.254.253
+  body       X_URIBL_Y_2F   eval:check_uridnsbl('X_URIBL_Y_2F')
+
+  urirhssub  X_URIBL_Y_2G   $z  A  2
+  body       X_URIBL_Y_2G   eval:check_uridnsbl('X_URIBL_Y_2G')
+
+  urirhssub  X_URIBL_N_2G   $z  A  5
+  body       X_URIBL_N_2G   eval:check_uridnsbl('X_URIBL_N_2G')
+
+  urirhssub  X_URIBL_Y_ANY  $z  A  127.0.1.1-127.0.1.254
+  body       X_URIBL_Y_ANY  eval:check_uridnsbl('X_URIBL_Y_ANY')
+
+  urirhssub  X_URIBL_Y_3    $z  A  127.0.1.3-127.0.1.19
+  body       X_URIBL_Y_3    eval:check_uridnsbl('X_URIBL_Y_3')
+
+  urirhssub  X_URIBL_N_3    $z  A  127.0.1.4-127.0.1.18
+  body       X_URIBL_N_3    eval:check_uridnsbl('X_URIBL_Y_3')
+
+  urirhssub  X_URIBL_N_0A   $z  A  127.0.0.0
+  body       X_URIBL_N_0A   eval:check_uridnsbl('X_URIBL_N_0A')
+
+  urirhssub  X_URIBL_N_0B   $z  A  127.0.1.0
+  body       X_URIBL_N_0B   eval:check_uridnsbl('X_URIBL_N_0B')
+
+  urirhssub  X_URIBL_N_255A $z  A  127.0.1.255
+  body       X_URIBL_N_255A eval:check_uridnsbl('X_URIBL_N_255A')
+
+  urirhssub  X_URIBL_N_255B $z  A  0.0.0.255/0.0.0.255
+  body       X_URIBL_N_255B eval:check_uridnsbl('X_URIBL_N_255B')
+EOD
+
+my(@testzone) = map { chomp; s/[ \t]+//; $_ } split(/^/, <<"EOD");
+  $z               3600 IN SOA  ns.$z hostmaster.$z (1 10800 1800 2419200 3600)
+  $z               3600 IN NS   ns.$z
+  $z               3600 IN MX 0 .
+  ns.$z            3600 IN A    127.0.0.1
+  ns.$z            3600 IN AAAA ::1
+  foo.$z           3600 IN A    10.1.2.3
+  foo.$z           3600 IN A    10.1.2.4
+  dbltest.com.$z   3600 IN A    127.0.1.2
+  dbltest.com.$z   3600 IN TXT  "test answer on dbltest.com"
+  dbltest03.com.$z 3600 IN A    127.0.1.3
+  dbltest19.com.$z 3600 IN A    127.0.1.19
+  dbltest20.com.$z 3600 IN A    127.0.1.20
+  dbltest21.com.$z 3600 IN A    127.0.1.21
+  dbltest39.com.$z 3600 IN A    127.0.1.39
+  dbltest40.com.$z 3600 IN A    127.0.1.40
+  dbltest50.com.$z 3600 IN A    127.0.1.50
+  dbltest59.com.$z 3600 IN A    127.0.1.59
+  dbltest99.com.$z 3600 IN A    127.0.1.99
+  dbltestER.com.$z 3600 IN A    127.0.1.255
+  dbltestER.com.$z 3600 IN TXT  "No IP queries allowed"
+  10.1.2.3.$z      3600 IN A    127.0.1.255
+  10.1.2.3.$z      3600 IN TXT  "No IP queries allowed"
+EOD
+
+# ---------------------------------------------------------------------------
+
+use Net::DNS::Nameserver;
+
+sub reply_handler {
+  my($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_;
+  my($rcode, @ans, @auth, @add);
+  my $qclass_uc = uc $qclass;
+  my $qtype_uc  = uc $qtype;
+# print "Received query from $peerhost to ". $conn->{"sockhost"}. "\n";
+# $query->print;
+  $rcode = "NXDOMAIN";
+  for my $rec_str (@testzone) {
+    my($rrname,$rrttl,$rrclass,$rrtype,$rrdata) = split(' ',$rec_str,5);
+    if ($qclass_uc eq uc($rrclass) && lc($rrname) eq lc($qname)) {
+      $rcode = 'NOERROR';
+      if ($qtype_uc eq uc($rrtype) || $qtype_uc eq 'ANY') {
+        push(@ans, Net::DNS::RR->new(
+                     join(' ', $qname, $rrttl, $qclass, $rrtype, $rrdata)));
+      }
+    }
+  }
+  # special DBL test case - numerical IP query handling
+  if ($qclass_uc eq 'IN' && $qname =~ /^[0-9.]+\.\Q$z\E\z/is) {
+    $rcode = 'NOERROR';
+    if ($qtype_uc eq 'A' || $qtype_uc eq 'ANY') {
+      push(@ans, Net::DNS::RR->new(join(' ',
+                 $qname, '3600', $qclass, 'A', '127.0.1.255')));
+    }
+    if ($qtype_uc eq 'TXT' || $qtype_uc eq 'ANY') {
+      push(@ans, Net::DNS::RR->new(join(' ',
+                 $qname, '3600', $qclass, 'TXT', '"No IP queries allowed"')));
+    }
+  }
+  return ($rcode, \@ans, \@auth, \@add);
+}
+
+sub dns_server($$) {
+  my($local_addr, $local_port) = @_;
+  my $ns = Net::DNS::Nameserver->new(
+    LocalAddr => $local_addr, LocalPort => $local_port,
+    ReplyHandler => \&reply_handler, Verbose => 0);
+  $ns  or die "Cannot create a nameserver object";
+  $ns->main_loop;
+}
+
+# ---------------------------------------------------------------------------
+
+use Mail::SpamAssassin;
+my $spamassassin_obj;
+
+sub process_sample_urls(@) {
+  my(@url_list) = @_;
+  my($mail_obj, $per_msg_status, $spam_report);
+  $spamassassin_obj->timer_reset;
+
+  my $msg = <<'EOD';
+From: "DNSBL Testing" <ab...@example.org>
+To: someone@example.org
+Subject: test
+Date: Mon, 8 Mar 2010 15:10:44 +0100
+Message-Id: <te...@example.org>
+
+EOD
+  $msg .= $_."\n" for @url_list;
+
+  $mail_obj = $spamassassin_obj->parse($msg,0);
+  if ($mail_obj) {
+    local($1,$2,$3,$4,$5,$6);  # avoid Perl 5.8.x bug, $1 can get tainted
+    $per_msg_status = $spamassassin_obj->check($mail_obj);
+  }
+  if ($per_msg_status) {
+    $spam_report = $per_msg_status->get_tag('REPORT');
+    $per_msg_status->finish;
+  }
+  if ($mail_obj) {
+    $mail_obj->finish;
+  }
+  $spam_report =~ s/\A(\s*\n)+//s;
+# print "\t$spam_report\n";
+  return $spam_report;
+}
+
+sub test_samples($$) {
+  my($patt_antipatt_list,$url_list_ref) = @_;
+  my $el = $patt_antipatt_list->[0];
+  shift @$patt_antipatt_list  if @$patt_antipatt_list > 1;  # last autorepeats
+  my($patt,$anti) = split(m{\s* / \s*}x, $el, 2);
+  %patterns      = map { (" $_ ", $_) } split(' ',$patt);
+  %anti_patterns = map { (" $_ ", $_) } split(' ',$anti);
+  my $spam_report = process_sample_urls(@$url_list_ref);
+  clear_pattern_counters();
+  patterns_run_cb($spam_report);
+  my $status = ok_all_patterns();
+  printf("\nTest on %s failed:\n%s\n",
+         join(', ',@$url_list_ref), $spam_report)  if !$status;
+}
+
+# detach a DNS server process
+my $pid = fork();
+defined $pid or die "Cannot fork: $!";
+if (!$pid) {  # child
+  dns_server($dns_server_localaddr, $dns_server_localport);
+  exit;
+}
+
+# parent
+# print STDERR "Forked a DNS server process [$pid]\n";
+sleep 1;
+
+$spamassassin_obj = Mail::SpamAssassin->new({
+# rules_filename      => "$prefix/t/log/test_rules_copy",
+# require_rules       => 1,
+  rules_filename      => "/dev/null",
+  site_rules_filename => "$prefix/t/log/localrules.tmp",
+  userprefs_filename  => "$prefix/masses/spamassassin/user_prefs",
+  post_config_text    => $local_conf,
+  dont_copy_prefs     => 1,
+# debug               => 'dns,async,uridnsbl',
+});
+ok($spamassassin_obj);
+$spamassassin_obj->compile_now;  # try to preloaded most modules
+
+test_samples(
+  [q{ X_URIBL_Y_2A X_URIBL_Y_2B X_URIBL_Y_2C X_URIBL_Y_2D X_URIBL_Y_2E
+      X_URIBL_Y_2F X_URIBL_Y_2G X_URIBL_Y_ANY / X_URIBL_N_2E X_URIBL_N_2G
+      X_URIBL_N_3 X_URIBL_N_0A X_URIBL_N_0B X_URIBL_N_255A X_URIBL_N_255B }],
+  [qw( http://dbltest.com/ )]);
+
+test_samples(
+  [q{ X_URIBL_Y_2A X_URIBL_Y_2B X_URIBL_Y_2C X_URIBL_Y_2D X_URIBL_Y_2E
+      X_URIBL_Y_2F X_URIBL_Y_2G X_URIBL_Y_ANY X_URIBL_Y_3 / X_URIBL_N_3
+      X_URIBL_N_0A X_URIBL_N_0B X_URIBL_N_255A X_URIBL_N_255B }],
+  [qw( http://dbltest.com/ http://dbltest03.com/ http://dbltest19.com/
+       http://10.11.22.33/ )]);
+
+if ($pid) {
+  kill('TERM',$pid) or die "Cannot stop a DNS server [$pid]: $!";
+  waitpid($pid,0);
+  undef $pid;
+}
+
+END {
+  $spamassassin_obj->finish  if $spamassassin_obj;
+  kill('KILL',$pid)  if $pid;  # ignoring status
+}

Propchange: spamassassin/trunk/t/dnsbl_subtests.t
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: spamassassin/trunk/t/dnsbl_subtests.t
------------------------------------------------------------------------------
    svn:executable = *