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 2012/04/01 12:03:13 UTC
svn commit: r1308059 - in /spamassassin/trunk: INSTALL META.yml Makefile.PL
lib/Mail/SpamAssassin/Plugin/RelayCountry.pm
lib/Mail/SpamAssassin/Util/DependencyInfo.pm rules/init.pre
Author: hege
Date: Sun Apr 1 10:03:12 2012
New Revision: 1308059
URL: http://svn.apache.org/viewvc?rev=1308059&view=rev
Log:
Bug 6599: Add Geo::IP support to RelayCountries
Modified:
spamassassin/trunk/INSTALL
spamassassin/trunk/META.yml
spamassassin/trunk/Makefile.PL
spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/RelayCountry.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Util/DependencyInfo.pm
spamassassin/trunk/rules/init.pre
Modified: spamassassin/trunk/INSTALL
URL: http://svn.apache.org/viewvc/spamassassin/trunk/INSTALL?rev=1308059&r1=1308058&r2=1308059&view=diff
==============================================================================
--- spamassassin/trunk/INSTALL (original)
+++ spamassassin/trunk/INSTALL Sun Apr 1 10:03:12 2012
@@ -363,11 +363,14 @@ version is too low for them to be used.
perl interpreter. NetAddr::IP version 4.007 or later fixes this.
- - IP::Country::Fast (from CPAN)
+ - Geo::IP (from CPAN)
Used by the RelayCountry plugin (not enabled by default) to determine
the domain country codes of each relay in the path of an email.
+ IP::Country::Fast is used as alternative if Geo::IP is not installed.
+ This is not recommended as it's obsolete.
+
- Net::Ident (from CPAN)
Modified: spamassassin/trunk/META.yml
URL: http://svn.apache.org/viewvc/spamassassin/trunk/META.yml?rev=1308059&r1=1308058&r2=1308059&view=diff
==============================================================================
--- spamassassin/trunk/META.yml (original)
+++ spamassassin/trunk/META.yml Sun Apr 1 10:03:12 2012
@@ -49,7 +49,7 @@ recommends:
IO::Socket::INET6: 0
IO::Socket::SSL: 0
IO::Zlib: 1.04
- IP::Country::Fast: 0
+ Geo::IP: 0
LWP::UserAgent: 0
Mail::DKIM: 0.37
Mail::SPF: 0
Modified: spamassassin/trunk/Makefile.PL
URL: http://svn.apache.org/viewvc/spamassassin/trunk/Makefile.PL?rev=1308059&r1=1308058&r2=1308059&view=diff
==============================================================================
--- spamassassin/trunk/Makefile.PL (original)
+++ spamassassin/trunk/Makefile.PL Sun Apr 1 10:03:12 2012
@@ -343,7 +343,7 @@ foreach my $file (@FILES_THAT_MUST_EXIST
'DB_File' => 0,
'Net::SMTP' => 0,
'Mail::SPF' => 0,
- 'IP::Country::Fast' => 0,
+ 'Geo::IP' => 0,
'Razor2::Client::Agent' => 2.61,
'Net::Ident' => 0,
'IO::Socket::INET6' => 0,
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/RelayCountry.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/RelayCountry.pm?rev=1308059&r1=1308058&r2=1308059&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/RelayCountry.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/RelayCountry.pm Sun Apr 1 10:03:12 2012
@@ -32,7 +32,8 @@ the C<_RELAYCOUNTRY_> header markup.
=head1 REQUIREMENT
-This plugin requires the IP::Country module from CPAN.
+This plugin requires the Geo::IP module from CPAN. For backwards
+compatibility IP::Country::Fast is used if Geo::IP is not installed.
=cut
@@ -40,6 +41,7 @@ package Mail::SpamAssassin::Plugin::Rela
use Mail::SpamAssassin::Plugin;
use Mail::SpamAssassin::Logger;
+use Mail::SpamAssassin::Constants qw(:ip);
use strict;
use warnings;
use bytes;
@@ -48,6 +50,52 @@ use re 'taint';
use vars qw(@ISA);
@ISA = qw(Mail::SpamAssassin::Plugin);
+my ($db, $dbv6);
+my $ip_to_cc; # will hold a sub() for the lookup
+my $db_info; # will hold a sub() for database info
+
+# Try to load Geo::IP first
+eval {
+ require Geo::IP;
+ $db = Geo::IP->open_type(Geo::IP->GEOIP_COUNTRY_EDITION, Geo::IP->GEOIP_STANDARD);
+ die "GeoIP.dat not found" unless $db;
+ # IPv6 requires version Geo::IP 1.39+ with GeoIP C API 1.4.7+
+ if (Geo::IP->VERSION >= 1.39 && Geo::IP->api eq 'CAPI') {
+ $dbv6 = Geo::IP->open_type(Geo::IP->GEOIP_COUNTRY_EDITION_V6, Geo::IP->GEOIP_STANDARD);
+ if (!$dbv6) {
+ dbg("metadata: RelayCountry: IPv6 support not enabled, GeoIPv6.dat not found");
+ }
+ } else {
+ dbg("metadata: RelayCountry: IPv6 support not enabled, versions Geo::IP 1.39, GeoIP C API 1.4.7 required");
+ }
+ $ip_to_cc = sub {
+ if ($dbv6 && $_[0] =~ /:/) {
+ return $dbv6->country_code_by_addr_v6($_[0]) || "XX";
+ } else {
+ return $db->country_code_by_addr($_[0]) || "XX";
+ }
+ };
+ $db_info = sub { return "Geo::IP ".$db->database_info; };
+ 1;
+} or do {
+ my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
+ dbg("metadata: RelayCountry: failed to load 'Geo::IP', skipping: $eval_stat");
+ # Try IP::Country::Fast as backup
+ eval {
+ require IP::Country::Fast;
+ $db = IP::Country::Fast->new();
+ $ip_to_cc = sub {
+ return $db->inet_atocc($_[0]) || "XX";
+ };
+ $db_info = sub { return "IP::Country::Fast ".localtime($db->db_time()); };
+ 1;
+ } or do {
+ my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
+ dbg("metadata: RelayCountry: failed to load 'IP::Country::Fast', skipping: $eval_stat");
+ return 1;
+ };
+};
+
# constructor: register the eval rule
sub new {
my $class = shift;
@@ -63,24 +111,17 @@ sub new {
sub extract_metadata {
my ($self, $opts) = @_;
- my $reg;
-
- eval {
- require IP::Country::Fast;
- $reg = IP::Country::Fast->new();
- 1;
- } or do {
- my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
- dbg("metadata: failed to load 'IP::Country::Fast', skipping: $eval_stat");
- return 1;
- };
+ return 1 unless $db;
+ dbg("metadata: RelayCountry: Using database: ".$db_info->());
my $msg = $opts->{msg};
my $countries = '';
+ my $IP_PRIVATE = IP_PRIVATE;
foreach my $relay (@{$msg->{metadata}->{relays_untrusted}}) {
my $ip = $relay->{ip};
- my $cc = $reg->inet_atocc($ip) || "XX";
+ # Private IPs will always be returned as '**'
+ my $cc = $ip =~ /^$IP_PRIVATE$/o ? '**' : $ip_to_cc->($ip);
$countries .= $cc." ";
}
@@ -93,6 +134,9 @@ sub extract_metadata {
sub parsed_metadata {
my ($self, $opts) = @_;
+
+ return 1 unless $db;
+
$opts->{permsgstatus}->set_tag ("RELAYCOUNTRY",
$opts->{permsgstatus}->get_message->get_metadata('X-Relay-Countries'));
return 1;
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Util/DependencyInfo.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Util/DependencyInfo.pm?rev=1308059&r1=1308058&r2=1308059&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Util/DependencyInfo.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Util/DependencyInfo.pm Sun Apr 1 10:03:12 2012
@@ -138,8 +138,7 @@ $have_sha ? {
address forgery and make it easier to identify spams.',
},
{
- module => 'IP::Country::Fast',
- alt_name => 'IP::Country',
+ module => 'Geo::IP',
version => 0,
desc => 'Used by the RelayCountry plugin (not enabled by default) to determine
the domain country codes of each relay in the path of an email.',
Modified: spamassassin/trunk/rules/init.pre
URL: http://svn.apache.org/viewvc/spamassassin/trunk/rules/init.pre?rev=1308059&r1=1308058&r2=1308059&view=diff
==============================================================================
--- spamassassin/trunk/rules/init.pre (original)
+++ spamassassin/trunk/rules/init.pre Sun Apr 1 10:03:12 2012
@@ -17,7 +17,7 @@
# RelayCountry - add metadata for Bayes learning, marking the countries
# a message was relayed through
#
-# Note: This requires the IP::Country::Fast Perl module
+# Note: This requires the Geo::IP Perl module
#
# loadplugin Mail::SpamAssassin::Plugin::RelayCountry