You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by jm...@apache.org on 2004/05/01 04:11:41 UTC

svn commit: rev 10468 - in incubator/spamassassin/trunk: . lib/Mail/SpamAssassin lib/Mail/SpamAssassin/Plugin lib/Mail/SpamAssassin/Util t

Author: jm
Date: Fri Apr 30 19:11:41 2004
New Revision: 10468

Added:
   incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Util/
   incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Util/RegistrarBoundaries.pm
Modified:
   incubator/spamassassin/trunk/MANIFEST
   incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/SPF.pm
   incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Received.pm
   incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm
   incubator/spamassassin/trunk/t/ip_addrs.t
Log:
more comprehensive handling of the (sick, sick, sick) rules for TLD delegation -- now deals with 3 and 4 level TLDs correctly

Modified: incubator/spamassassin/trunk/MANIFEST
==============================================================================
--- incubator/spamassassin/trunk/MANIFEST	(original)
+++ incubator/spamassassin/trunk/MANIFEST	Fri Apr 30 19:11:41 2004
@@ -343,3 +343,4 @@
 t/body_mod.t
 t/bayesdbm_flock.t
 t/spamc_E.t
+lib/Mail/SpamAssassin/Util/RegistrarBoundaries.pm

Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/SPF.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/SPF.pm	(original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/SPF.pm	Fri Apr 30 19:11:41 2004
@@ -143,7 +143,12 @@
 
   if ($ishelo) {
     dbg ("SPF: checking HELO (helo=$helo, ip=$ip)");
-    $helo = Mail::SpamAssassin::Util::trim_domain_to_registrar_boundary ($helo);
+
+    if ($helo !~ /^\d+\.\d+\.\d+\.\d+$/) {
+      # get rid of hostname part of domain, understanding delegation
+      $helo = Mail::SpamAssassin::Util::RegistrarBoundaries::trim_domain ($helo);
+    }
+
     dbg ("SPF: trimmed HELO down to '$helo'");
 
   } else {

Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Received.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Received.pm	(original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Received.pm	Fri Apr 30 19:11:41 2004
@@ -47,6 +47,7 @@
 
 use Mail::SpamAssassin::Dns;
 use Mail::SpamAssassin::PerMsgStatus;
+use Mail::SpamAssassin::Util::RegistrarBoundaries;
 use Mail::SpamAssassin::Constants qw(:ip);
 
 use vars qw{
@@ -325,22 +326,17 @@
 sub mx_of_helo_near_ip {
   my ($self, $helo, $ip) = @_;
 
-  my $helodomain = $helo;
+  my $helodom = $helo;
 
   # TODO: should we just traverse down the chain instead of this;
   # e.g. "foo.bar.baz.co.uk" would be "bar.baz.co.uk", "baz.co.uk",
   # instead of just "baz.co.uk" straight away?
-  if (Mail::SpamAssassin::Util::is_in_subdelegated_cctld ($helo)) {
-    if ($helo =~ /\.([^\.]+\.[^\.]+\.[^\.]+)$/) {
-      $helodomain = $1;
-    }
-  } else {
-    if ($helo =~ /\.([^\.]+\.[^\.]+)$/) {
-      $helodomain = $1;
-    }
+  
+  if ($helo !~ /^\d+\.\d+\.\d+\.\d+$/) {
+    $helodom = Mail::SpamAssassin::Util::RegistrarBoundaries::trim_domain ($helo);
   }
 
-  my $mxes = $self->lookup_mx ($helodomain);
+  my $mxes = $self->lookup_mx ($helodom);
   my @mxips = ();
   foreach my $mx (@$mxes) {
     push (@mxips, $self->lookup_all_ips ($mx));
@@ -348,7 +344,7 @@
   if ($mxes && Mail::SpamAssassin::Util::ips_match_in_24_mask ([ $ip ], [ @mxips ]))
   {
     dbg ("IP address $ip is near to an MX (".join (', ', @mxips).
-					") for ".$helodomain);
+					") for ".$helodom);
     return 1;
   }
   return 0;

Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm	(original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm	Fri Apr 30 19:11:41 2004
@@ -34,6 +34,7 @@
 @EXPORT = qw(local_tz base64_decode);
 
 use Mail::SpamAssassin;
+use Mail::SpamAssassin::Util::RegistrarBoundaries;
 
 use Config;
 use File::Spec;
@@ -749,31 +750,13 @@
   # keep IPs intact
   if ($uri !~ /^\d+\.\d+\.\d+\.\d+$/) { 
     # get rid of hostname part of domain, understanding delegation
-    if (Mail::SpamAssassin::Util::is_in_subdelegated_cctld($uri)) {
-      $uri = $1 if $uri =~ /\.([^\.]+\.[^\.]+\.[^\.]+)$/;
-    }
-    else {
-      $uri = $1 if $uri =~ /\.([^\.]+\.[^\.]+)$/;
-    }
+    $uri = Mail::SpamAssassin::Util::RegistrarBoundaries::trim_domain ($uri);
   }
   
   # $uri is now the domain only
   return $uri;
 }
 
-sub is_in_subdelegated_cctld {
-  my ($domain) = @_;
-
-  # http://www.bestregistrar.com/help/ccTLD.htm lists these
-  return ($domain =~ /\.
-	  (?:ac| ae| ar| at| au| az| bb| bm| br| bs| ca| cn| co|
-	  cr| cu| cy| do| ec| eg| fj| ge| gg| gu| hk| hu| id| il| im|
-	  in| je| jo| jp| kh| kr| la| lb| lc| lv| ly| mm| mo| mt| mx| my|
-	  na| nc| ni| np| nz| pa| pe| ph| pl| py| ru| sg| sh| sv| sy| th|
-	  tn| tr| tw| ua| ug| uk| uy| ve| vi| yu| za)
-	$/ixo);
-}
-
 sub uri_list_canonify {
   my(@uris) = @_;
 
@@ -817,41 +800,6 @@
   my %uris = map { $_ => 1 } @uris, @nuris;
 
   return keys %uris;
-}
-
-###########################################################################
-
-sub trim_domain_to_registrar_boundary {
-  my ($domain) = @_;
-
-  # drop any hostname parts, if we can.
-  my @domparts = split (/\./, $domain);
-  my $numparts = scalar @domparts;
-
-  # for the HELO variant, drop the first bit of the HELO (ie. turn
-  # "host.dom.ain" into "dom.ain".)
-  if ($numparts > 0) {
-    my $partsreqd = 2;
-
-    # the "Demon case"; Demon Internet registers domains for
-    # its customers, ie. "foo.demon.co.uk".
-    if ($domain =~ /\. (?:
-		      demon\.co\.uk
-		      )$/ix)
-    {
-      $partsreqd = 4;
-    }
-    # Subdelegated CCTLD
-    elsif (is_in_subdelegated_cctld ($domain)) {
-      $partsreqd = 3;
-    }
-
-    while ($numparts > $partsreqd) {
-      $domain =~ s/^[^\.]+\.//;
-      $numparts--;
-    }
-  }
-  $domain;
 }
 
 ###########################################################################

Added: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Util/RegistrarBoundaries.pm
==============================================================================
--- (empty file)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Util/RegistrarBoundaries.pm	Fri Apr 30 19:11:41 2004
@@ -0,0 +1,631 @@
+# The (extremely complex) rules for domain delegation.
+
+# <@LICENSE>
+# Copyright 2004 Apache Software Foundation
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# </...@LICENSE>
+
+package Mail::SpamAssassin::Util::RegistrarBoundaries;
+
+use strict;
+use bytes;
+
+use vars qw (
+  @ISA $TWO_LEVEL_DOMAINS $THREE_LEVEL_DOMAINS $US_STATES $FOUR_LEVEL_DOMAINS
+);
+
+# This is required because the .us domain is nuts. See $THREE_LEVEL_DOMAINS
+# and $FOUR_LEVEL_DOMAINS below.
+#
+$US_STATES = qr{ (?:
+  ak|al|ar|az|ca|co|ct|dc|de|fl|ga|gu|hi|ia|id|il|in|ks|ky|la|ma|md|me|mi|
+  mn|mo|ms|mt|nc|nd|ne|nh|nj|nm|nv|ny|oh|ok|or|pa|pr|ri|sc|sd|tn|tx|ut|va|vi|
+  vt|wa|wi|wv|wy )
+}ix;
+
+# updated: 2004-04-30: first rev
+#
+$THREE_LEVEL_DOMAINS = qr( (?:
+  demon\.co\.uk |
+
+  # http://www.neustar.us/policies/docs/rfc_1480.txt
+  [^\.]+\.${US_STATES}\.us )
+)ix;
+
+$FOUR_LEVEL_DOMAINS = qr( (?:
+  # http://www.neustar.us/policies/docs/rfc_1480.txt
+  # "Fire-Dept.CI.Los-Angeles.CA.US"
+  # "<school-name>.PVT.K12.<state>.US"
+
+  pvt\.k12\.${US_STATES}\.us
+  c[io]\.[^\.]+\.${US_STATES}\.us
+)
+)ix;
+
+# updated: 2004-04-30: first rev
+$TWO_LEVEL_DOMAINS = qr{ (?:
+
+  # http://www.neustar.us/policies/docs/rfc_1480.txt
+
+  fed\.us |
+  dni\.us |
+
+  # data from http://spamcheck.freeapp.net/two-level-tlds , in turn from
+  # http://www.bestregistrar.com/help/ccTLD.htm
+
+  com\.ac |
+  edu\.ac |
+  gov\.ac |
+  net\.ac |
+  mil\.ac |
+  org\.ac |
+  com\.ae |
+  net\.ae |
+  org\.ae |
+  com\.ar |
+  net\.ar |
+  org\.ar |
+  co\.at |
+  ac\.at |
+  com\.au |
+  org\.au |
+  gov\.au |
+  org\.au |
+  edu\.au |
+  id\.au |
+  oz\.au |
+  info\.au |
+  net\.au |
+  asn\.au |
+  csiro\.au |
+  telememo\.au |
+  conf\.au |
+  com\.az |
+  net\.az |
+  org\.az |
+  com\.bb |
+  net\.bb |
+  org\.bb |
+  ac\.be |
+  belgie\.be |
+  dns\.be |
+  fgov\.be |
+  com\.bm |
+  edu\.bm |
+  gov\.bm |
+  org\.bm |
+  net\.bm |
+  art\.br |
+  sp\.br |
+  com\.br |
+  etc\.br |
+  g12\.br |
+  gov\.br |
+  ind\.br |
+  inf\.br |
+  mil\.br |
+  net\.br |
+  org\.br |
+  psi\.br |
+  rec\.br |
+  tmp\.br |
+  com\.bs |
+  net\.bs |
+  org\.bs |
+  ab\.ca |
+  bc\.ca |
+  mb\.ca |
+  nb\.ca |
+  nf\.ca |
+  ns\.ca |
+  nt\.ca |
+  nu\.ca |
+  on\.ca |
+  pe\.ca |
+  qc\.ca |
+  sk\.ca |
+  yk\.ca |
+  co\.ck |
+  com\.cn |
+  edu\.cn |
+  gov\.cn |
+  net\.cn |
+  org\.cn |
+  ac\.cn |
+  ah\.cn |
+  bj\.cn |
+  cq\.cn |
+  gd\.cn |
+  gs\.cn |
+  gx\.cn |
+  gz\.cn |
+  hb\.cn |
+  he\.cn |
+  hi\.cn |
+  hk\.cn |
+  hl\.cn |
+  hn\.cn |
+  jl\.cn |
+  js\.cn |
+  ln\.cn |
+  mo\.cn |
+  nm\.cn |
+  nx\.cn |
+  qh\.cn |
+  sc\.cn |
+  sn\.cn |
+  sh\.cn |
+  sx\.cn |
+  tj\.cn |
+  tw\.cn |
+  xj\.cn |
+  xz\.cn |
+  yn\.cn |
+  zj\.cn |
+  arts\.co |
+  com\.co |
+  edu\.co |
+  firm\.co |
+  gov\.co |
+  info\.co |
+  int\.co |
+  nom\.co |
+  mil\.co |
+  org\.co |
+  rec\.co |
+  store\.co |
+  web\.co |
+  ac\.cr |
+  co\.cr |
+  ed\.cr |
+  fi\.cr |
+  go\.cr |
+  or\.cr |
+  sa\.cr |
+  com\.cu |
+  net\.cu |
+  org\.cu |
+  ac\.cy |
+  com\.cy |
+  gov\.cy |
+  net\.cy |
+  org\.cy |
+  art\.do |
+  com\.do |
+  edu\.do |
+  gov\.do |
+  org\.do |
+  mil\.do |
+  net\.do |
+  web\.do |
+  com\.ec |
+  k12\.ec |
+  edu\.ec |
+  fin\.ec |
+  med\.ec |
+  gov\.ec |
+  mil\.ec |
+  org\.ec |
+  net\.ec |
+  com\.eg |
+  edu\.eg |
+  eun\.eg |
+  gov\.eg |
+  net\.eg |
+  org\.eg |
+  sci\.eg |
+  ac\.fj |
+  com\.fj |
+  gov\.fj |
+  id\.fj |
+  org\.fj |
+  school\.fj |
+  asso\.fr |
+  nom\.fr |
+  barreau\.fr |
+  com\.fr  |
+  prd\.fr  |
+  presse\.fr  |
+  tm\.fr  |
+  aeroport\.fr |
+  assedic\.fr |
+  avocat\.fr |
+  avoues\.fr |
+  cci\.fr |
+  chambagri\.fr |
+  chirurgiens-dentistes\.fr |
+  experts-comptables\.fr |
+  geometre-expert\.fr |
+  gouv\.fr |
+  greta\.fr |
+  huissier-justice\.fr |
+  medecin\.fr |
+  notaires\.fr |
+  pharmacien\.fr |
+  port\.fr |
+  veterinaire\.fr |
+  notaires\.fr |
+  com\.ge |
+  edu\.ge |
+  gov\.ge |
+  mil\.ge |
+  net\.ge |
+  org\.ge |
+  pvt\.ge |
+  co\.gg |
+  org\.gg |
+  sch\.gg |
+  ac\.gg |
+  gov\.gg |
+  ltd\.gg |
+  ind\.gg |
+  net\.gg |
+  alderney\.gg |
+  guernsey\.gg |
+  sark\.gg |
+  com\.gu |
+  edu\.gu |
+  net\.gu |
+  org\.gu |
+  gov\.gu |
+  mil\.gu |
+  com\.hk |
+  net\.hk |
+  org\.hk |
+  co\.hu |
+  org\.hu |
+  info\.hu |
+  nui\.hu |
+  priv\.hu |
+  tm\.hu |
+  ac\.id |
+  co\.id |
+  go\.id |
+  mil\.id |
+  net\.id |
+  or\.id |
+  co\.il |
+  net\.il |
+  org\.il |
+  ac\.il |
+  gov\.il |
+  k12\.il |
+  muni\.il |
+  co\.im |
+  net\.im |
+  org\.im |
+  ac\.im |
+  lkd\.co\.im |
+  gov\.im |
+  nic\.im |
+  plc\.co\.im |
+  co\.in |
+  net\.in |
+  ac\.in |
+  ernet\.in |
+  gov\.in |
+  nic\.in |
+  res\.in |
+  co\.je |
+  net\.je |
+  org\.je |
+  ac\.je |
+  gov\.je |
+  ind\.je |
+  jersey\.je |
+  ltd\.je |
+  sch\.je |
+  com\.jo |
+  net\.jo |
+  gov\.jo |
+  edu\.jo |
+  ad\.jp |
+  ac\.jp |
+  co\.jp |
+  net\.jp |
+  org\.jp |
+  gov\.jp |
+  com\.kh |
+  net\.kh |
+  org\.kh |
+  ac\.kr |
+  co\.kr |
+  go\.kr |
+  nm\.kr |
+  or\.kr |
+  pe\.kr |
+  re\.kr |
+  com\.la |
+  net\.la |
+  org\.la |
+  com\.lb |
+  org\.lb |
+  net\.lb |
+  gov\.lb |
+  mil\.lb |
+  com\.lc |
+  edu\.lc |
+  gov\.lc |
+  net\.lc |
+  org\.lc |
+  com\.lv |
+  net\.lv |
+  org\.lv |
+  edu\.lv |
+  gov\.lv |
+  mil\.lv |
+  id\.lv |
+  asn\.lv |
+  conf\.lv |
+  com\.ly |
+  net\.ly |
+  org\.ly |
+  com\.mm |
+  net\.mm |
+  org\.mm |
+  edu\.mm |
+  gov\.mm |
+  com\.mo |
+  net\.mo |
+  org\.mo |
+  edu\.mo |
+  gov\.mo |
+  com\.mt |
+  net\.mt |
+  org\.mt |
+  com\.mx |
+  net\.mx |
+  org\.mx |
+  com\.my |
+  org\.my |
+  gov\.my |
+  edu\.my |
+  net\.my |
+  com\.na |
+  org\.na |
+  net\.na |
+  com\.nc |
+  net\.nc |
+  org\.nc |
+  gov\.ng |
+  com\.ni |
+  com\.np |
+  net\.np |
+  org\.np |
+  gov\.np |
+  ac\.nz |
+  co\.nz |
+  cri\.nz |
+  gen\.nz |
+  geek\.nz |
+  govt\.nz |
+  iwi\.nz |
+  maori\.nz |
+  mil\.nz |
+  net\.nz |
+  org\.nz |
+  school\.nz |
+  com\.pa |
+  net\.pa |
+  org\.pa |
+  edu\.pa |
+  ac\.pa |
+  gob\.pa |
+  sld\.pa |
+  com\.pe |
+  net\.pe |
+  org\.pe |
+  ac\.pa |
+  com\.ph |
+  net\.ph |
+  org\.ph |
+  mil\.ph |
+  ngo\.ph |
+  com\.pl |
+  net\.pl |
+  org\.pl |
+  com\.py |
+  net\.py |
+  org\.py |
+  edu\.py |
+  asso\.re |
+  com\.re |
+  nom\.re |
+  com\.ru |
+  net\.ru |
+  org\.ru |
+  pp\.ru |
+  com\.sg |
+  net\.sg |
+  org\.sg |
+  edu\.sg |
+  gov\.sg |
+  com\.sh |
+  net\.sh |
+  org\.sh |
+  edu\.sh |
+  gov\.sh |
+  mil\.sh |
+  co\.sv |
+  com\.sy |
+  net\.sy |
+  org\.sy |
+  ac\.th |
+  co\.th |
+  go\.th |
+  net\.th |
+  or\.th |
+  com\.tn |
+  net\.tn |
+  org\.tn |
+  edunet\.tn |
+  gov\.tn |
+  ens\.tn |
+  fin\.tn |
+  nat\.tn |
+  ind\.tn |
+  info\.tn |
+  intl\.tn |
+  rnrt\.tn |
+  rnu\.tn |
+  rns\.tn |
+  tourism\.tn |
+  com\.tr |
+  net\.tr |
+  org\.tr |
+  edu\.tr |
+  gov\.tr |
+  mil\.tr |
+  bbs\.tr |
+  k12\.tr |
+  co\.tv |
+  com\.tw |
+  net\.tw |
+  org\.tw |
+  edu\.tw |
+  idv\.tw |
+  gove\.tw |
+  com\.ua |
+  net\.ua |
+  gov\.ua |
+  ac\.ug |
+  co\.ug |
+  or\.ug |
+  go\.ug |
+  co\.uk |
+  net\.uk |
+  org\.uk |
+  ltd\.uk |
+  plc\.uk |
+  sch\.uk |
+  ac\.uk |
+  gov\.uk |
+  nhs\.uk |
+  police\.uk |
+  mod\.uk |
+  com\.uy |
+  edu\.uy |
+  net\.uy |
+  org\.uy |
+  com\.ve |
+  net\.ve |
+  org\.ve |
+  co\.ve |
+  edu\.ve |
+  gov\.ve |
+  mil\.ve |
+  arts\.ve |
+  bib\.ve |
+  firm\.ve |
+  info\.ve |
+  int\.ve |
+  nom\.ve |
+  rec\.ve |
+  store\.ve |
+  tec\.ve |
+  web\.ve |
+  co\.vi |
+  net\.vi |
+  org\.vi |
+  ac\.yu |
+  co\.yu |
+  edu\.yu |
+  org\.yu |
+  ac\.za |
+  alt\.za |
+  bourse\.za |
+  city\.za |
+  co\.za |
+  edu\.za |
+  gov\.za |
+  law\.za |
+  mil\.za |
+  net\.za |
+  ngo\.za |
+  nom\.za |
+  org\.za |
+  school\.za |
+  tm\.za |
+  web\.za |
+  gov\.zw |
+  eu\.org |
+  au\.com |
+  e164\.arpa )
+}ix;
+
+###########################################################################
+
+=item ($hostname, $domain) = split_domain ($fqdn)
+
+Cut a fully-qualified hostname into the hostname part and the domain
+part, splitting at the DNS registrar boundary.
+
+Examples:
+
+    "www.foo.com" => ( "www", "foo.com" )
+    "www.foo.co.uk" => ( "www", "foo.co.uk" )
+
+=cut
+
+sub split_domain {
+  my ($domain) = @_;
+
+  # drop any hostname parts, if we can.
+  my @domparts = split (/\./, $domain);
+  my $numparts = scalar @domparts;
+
+  # turn "host.dom.ain" into "dom.ain".
+  my $chopped = '';
+  if ($numparts > 0) {
+    my $partsreqd;
+
+    if ($domain =~ /${FOUR_LEVEL_DOMAINS}/io)     # Fire-Dept.CI.Los-Angeles.CA.US
+    { $partsreqd = 5; }
+    elsif ($domain =~ /${THREE_LEVEL_DOMAINS}/io) # demon.co.uk
+    { $partsreqd = 4; }
+    elsif ($domain =~ /${TWO_LEVEL_DOMAINS}/io)   # co.uk
+    { $partsreqd = 3; }
+    else                                          # com
+    { $partsreqd = 2; }
+
+    while ($numparts > $partsreqd) {
+      $domain =~ s/^([^\.]+\.)//;
+      $chopped .= $1;
+      $numparts--;
+    }
+  }
+
+  $chopped =~ s/\.$//;
+  ($chopped, $domain);
+}
+
+=item $domain = trim_domain ($fqdn)
+
+Cut a fully-qualified hostname into the hostname part and the domain
+part, returning just the domain.
+
+Examples:
+
+    "www.foo.com" => "foo.com" 
+    "www.foo.co.uk" => "foo.co.uk" 
+
+=cut
+
+sub trim_domain {
+  my ($domain) = @_;
+  my ($host, $dom) = split_domain ($domain);
+  return $dom;
+}
+
+1;

Modified: incubator/spamassassin/trunk/t/ip_addrs.t
==============================================================================
--- incubator/spamassassin/trunk/t/ip_addrs.t	(original)
+++ incubator/spamassassin/trunk/t/ip_addrs.t	Fri Apr 30 19:11:41 2004
@@ -26,7 +26,7 @@
     rules_filename => "$prefix/rules",
 });
 
-plan tests => 66;
+plan tests => 67;
 
 sub tryone {
   my ($pat, $testip) = @_;
@@ -95,7 +95,7 @@
 sub tsttrim {
   my $dom = shift;
   my $want = shift;
-  my $got = Mail::SpamAssassin::Util::trim_domain_to_registrar_boundary ($dom);
+  my $got = Mail::SpamAssassin::Util::RegistrarBoundaries::trim_domain ($dom);
   if ($got eq $want) {
     return 1;
   } else {
@@ -111,5 +111,6 @@
 ok (tsttrim ("jmason.org", "jmason.org"));
 ok (tsttrim ("localhost.jmason.org", "jmason.org"));
 ok (tsttrim ("localhost.jmason.edu.au", "jmason.edu.au"));
+ok (tsttrim ("localhost.jmason.hacked.au", "hacked.au"));
 ok (tsttrim ("localhost.jmason.edu.net", "edu.net"));