From 9862cdc042ac8028e1c119c8ed39b49f116c9344 Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Tue, 4 Nov 2014 14:43:54 -0800 Subject: [PATCH 1/7] geoip: simplify the get/set data bits --- plugins/ident/geoip | 81 +++++++++++++++++++++++--------------- t/plugin_tests/ident/geoip | 3 +- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/plugins/ident/geoip b/plugins/ident/geoip index ccb8ab6..c24e113 100644 --- a/plugins/ident/geoip +++ b/plugins/ident/geoip @@ -6,8 +6,8 @@ geoip - provide geographic information about mail senders. =head1 SYNOPSIS -Use MaxMind's GeoIP databases and the Geo::IP perl module to report geographic -information about incoming connections. +Use MaxMind's GeoIP databases and the GeoIP2 or Geo::IP perl modules to report +geographic information about incoming connections. =head1 DESCRIPTION @@ -110,9 +110,11 @@ http://smartech.gatech.edu/bitstream/handle/1853/25135/GT-CSE-08-02.pdf use strict; use warnings; +use lib 'lib'; use Qpsmtpd::Constants; -#use Geo::IP; # eval'ed in register() +#use GeoIP2; # eval'ed in register() +#use Geo::IP; # eval loaded if GeoIP2 doesn't #use Math::Trig; # eval'ed in set_distance_gc sub register { @@ -122,11 +124,19 @@ sub register { $self->{_args} = {@args}; $self->{_args}{db_dir} ||= '/usr/local/share/GeoIP'; - eval 'use Geo::IP'; + my $loaded = 0; + + eval 'use GeoIP2'; if ($@) { - warn "could not load Geo::IP"; - $self->log(LOGERROR, "could not load Geo::IP"); - return; + warn "could not load GeoIP2"; + $self->log(LOGERROR, "could not load GeoIP2"); + + eval 'use Geo::IP'; + if ($@) { + warn "could not load Geo::IP"; + $self->log(LOGERROR, "could not load Geo::IP"); + return; + } } # Note that opening the GeoIP DB only in register has caused problems before: @@ -137,10 +147,10 @@ sub register { $self->init_my_country_code(); - $self->register_hook('connect', 'connect_handler'); + $self->register_hook('connect', 'geoip_lookup'); } -sub connect_handler { +sub geoip_lookup { my $self = shift; # reopen the DB if Geo::IP failed due to DB update @@ -150,7 +160,6 @@ sub connect_handler { $self->log(LOGINFO, "skip, no results"); return DECLINED; }; - $self->qp->connection->notes('geoip_country', $c_code); my $c_name = $self->set_country_name(); my ($city, $continent_code, $distance) = ''; @@ -162,8 +171,9 @@ sub connect_handler { } my @msg_parts; - push @msg_parts, $continent_code - if $continent_code && $continent_code ne '--'; + if ($continent_code && $continent_code ne '--') { + push @msg_parts, $continent_code; + }; push @msg_parts, $c_code if $c_code; #push @msg_parts, $c_name if $c_name; @@ -211,9 +221,13 @@ sub init_my_country_code { sub set_country_code { my $self = shift; - return $self->get_country_code_gc() if $self->{_geoip_city}; my $remote_ip = $self->qp->connection->remote_ip; - my $code = $self->get_country_code(); + + my $code = $self->{_geoip_city} + ? $self->get_country_code_gc($remote_ip) + : $self->get_country_code($remote_ip); + + return if ! $code; $self->qp->connection->notes('geoip_country', $code); return $code; } @@ -221,7 +235,9 @@ sub set_country_code { sub get_country_code { my $self = shift; my $ip = shift || $self->qp->connection->remote_ip; - return $self->get_country_code_gc($ip) if $self->{_geoip_city}; + if ($self->{_geoip_city}) { + return $self->get_country_code_gc($ip); + }; return $self->{_geoip}->country_code_by_addr($ip); } @@ -235,44 +251,45 @@ sub get_country_code_gc { sub set_country_name { my $self = shift; - return $self->set_country_name_gc() if $self->{_geoip_city}; my $remote_ip = $self->qp->connection->remote_ip; - my $name = $self->{_geoip}->country_name_by_addr($remote_ip) or return; + + my $name = $self->{_geoip_city} + ? $self->get_country_name_gc($remote_ip) + : $self->{_geoip}->country_name_by_addr($remote_ip); + + return if ! $name; $self->qp->connection->notes('geoip_country_name', $name); return $name; } -sub set_country_name_gc { +sub get_country_name_gc { my $self = shift; return if !$self->{_geoip_record}; - my $remote_ip = $self->qp->connection->remote_ip; - my $name = $self->{_geoip_record}->country_name() or return; - $self->qp->connection->notes('geoip_country_name', $name); - return $name; + return $self->{_geoip_record}->country_name(); } sub set_continent { - my $self = shift; - return $self->set_continent_gc() if $self->{_geoip_city}; - my $c_code = shift or return; - my $continent = $self->{_geoip}->continent_code_by_country_code($c_code) - or return; + my ($self, $country_code) = @_; + $country_code or return; + + my $continent = $self->{_geoip_city} + ? $self->get_continent_gc() + : $self->{_geoip}->continent_code_by_country_code($country_code); + + $continent or return; $self->qp->connection->notes('geoip_continent', $continent); return $continent; } -sub set_continent_gc { +sub get_continent_gc { my $self = shift; return if !$self->{_geoip_record}; - my $continent = $self->{_geoip_record}->continent_code() or return; - $self->qp->connection->notes('geoip_continent', $continent); - return $continent; + return $self->{_geoip_record}->continent_code(); } sub set_city_gc { my $self = shift; return if !$self->{_geoip_record}; - my $remote_ip = $self->qp->connection->remote_ip; my $city = $self->{_geoip_record}->city() or return; $self->qp->connection->notes('geoip_city', $city); return $city; diff --git a/t/plugin_tests/ident/geoip b/t/plugin_tests/ident/geoip index 3d503e7..5541c61 100644 --- a/t/plugin_tests/ident/geoip +++ b/t/plugin_tests/ident/geoip @@ -3,6 +3,7 @@ use strict; use warnings; +use lib 'lib'; use Qpsmtpd::Constants; sub register_tests { @@ -27,7 +28,7 @@ sub test_geoip_lookup { my $self = shift; $self->qp->connection->remote_ip('24.24.24.24'); - cmp_ok( $self->connect_handler(), '==', DECLINED, "exit code"); + cmp_ok( $self->geoip_lookup(), '==', DECLINED, "exit code"); cmp_ok( $self->connection->notes('geoip_country'), 'eq', 'US', "note"); }; From c61dbb5734631b11e5f3fd51d8abda9ae63bdb4b Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Wed, 5 Nov 2014 00:23:31 -0800 Subject: [PATCH 2/7] added GeoIP2 support, partial ASN support --- Makefile.PL | 5 +- plugins/ident/geoip | 104 +++++++++++++++++++++++++++++++------ t/plugin_tests/ident/geoip | 27 ++++++++-- 3 files changed, 114 insertions(+), 22 deletions(-) diff --git a/Makefile.PL b/Makefile.PL index 481c5cb..b30ea54 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -30,8 +30,9 @@ WriteMakefile( # 'DBIx::Simple' => 0, # log2sql # modules that cause Travis build tests to fail # 'Mail::SpamAssassin' => 0, -# 'Geo::IP' => 0, -# 'Math::Complex' => 0, # geodesic distance in Geo::IP +# 'GeoIP2' => 2, +# 'Geo::IP' => 1, +# 'Math::Complex' => 0, # geodesic distance in geoip # 'Mail::SPF' => 0, }, ABSTRACT => 'Flexible smtpd daemon written in Perl', diff --git a/plugins/ident/geoip b/plugins/ident/geoip index c24e113..fb9b8be 100644 --- a/plugins/ident/geoip +++ b/plugins/ident/geoip @@ -85,6 +85,8 @@ This plugin does not update the GeoIP databases. You may want to. =head1 CHANGES +2014-06 - Matt Simerson - added GeoIP2 support + 2012-06 - Matt Simerson - added GeoIP City support, continent, distance 2012-05 - Matt Simerson - added geoip_country_name note, added tests @@ -126,30 +128,75 @@ sub register { my $loaded = 0; - eval 'use GeoIP2'; - if ($@) { - warn "could not load GeoIP2"; - $self->log(LOGERROR, "could not load GeoIP2"); + eval 'use GeoIP2::Database::Reader'; + if (!$@) { + warn "using GeoIP2"; + $self->log(LOGINFO, "using GeoIP2"); - eval 'use Geo::IP'; - if ($@) { - warn "could not load Geo::IP"; - $self->log(LOGERROR, "could not load Geo::IP"); - return; - } + eval { + $self->{_geoip2_city} = GeoIP2::Database::Reader->new( + file => $self->{_args}{db_dir} . '/GeoLite2-City.mmdb', + ); + }; + eval { + $self->{_geoip2_country} = GeoIP2::Database::Reader->new( + file => $self->{_args}{db_dir} . '/GeoLite2-Country.mmdb', + ); + }; + $self->register_hook('connect', 'geoip2_lookup'); + return; } + warn "could not load GeoIP2"; + $self->log(LOGERROR, "could not load GeoIP2"); + + eval 'use Geo::IP'; + if ($@) { + warn "could not load Geo::IP"; + $self->log(LOGERROR, "could not load Geo::IP"); + return; + } + + $self->open_geoip_db(); + # Note that opening the GeoIP DB only in register has caused problems before: # https://github.com/smtpd/qpsmtpd/commit/29ea9516806e9a8ca6519fcf987dbd684793ebdd#plugins/ident/geoip # Opening the DB anew for every connection is horribly inefficient. # Instead, attempt to reopen upon connect if the DB connection fails. - $self->open_geoip_db(); - $self->init_my_country_code(); $self->register_hook('connect', 'geoip_lookup'); } +sub geoip2_lookup { + my $self = shift; + + my $ip = $self->qp->connection->remote_ip; + + if ($self->{_geoip2_city}) { + my $city_rec = $self->{_geoip2_city}->city(ip => $ip); + if ($city_rec) { + $self->qp->connection->notes('geoip_country', $city_rec->country->iso_code()); + $self->qp->connection->notes('geoip_country_name', $city_rec->country->name()); + $self->qp->connection->notes('geoip_continent', $city_rec->continent->code()); + $self->qp->connection->notes('geoip_city', $city_rec->city->name()); + $self->qp->connection->notes('geoip_asn', $city_rec->traits->autonomous_system_number()); + return DECLINED; + } + } + + if ($self->{_geoip2_country}) { + my $country_rec = $self->{_geoip2_country}->country(ip => $ip); + if ($country_rec) { + $self->qp->connection->notes('geoip_country', $country_rec->country->iso_code()); + $self->qp->connection->notes('geoip_country_name', $country_rec->country->name()); + $self->qp->connection->notes('geoip_continent', $country_rec->continent->code()); + }; + } + + return DECLINED; +} + sub geoip_lookup { my $self = shift; @@ -200,10 +247,15 @@ sub open_geoip_db { # save the handles in different locations my $db_dir = $self->{_args}{db_dir}; foreach my $db (qw/ GeoIPCity GeoLiteCity /) { - if (-f "$db_dir/$db.dat") { - $self->log(LOGDEBUG, "using db $db"); - $self->{_geoip_city} = Geo::IP->open("$db_dir/$db.dat"); - } + next if !-f "$db_dir/$db.dat"; + $self->log(LOGDEBUG, "using db $db"); + $self->{_geoip_city} = Geo::IP->open("$db_dir/$db.dat"); + } + + foreach my $db (qw/ GeoIPASNum GeoIPASNumv6 /) { + next if !-f "$db_dir/$db.dat"; + $self->log(LOGDEBUG, "using db $db"); + $self->{$db} = Geo::IP->open("$db_dir/$db.dat"); } # can't think of a good reason to load country if city data is present @@ -287,6 +339,26 @@ sub get_continent_gc { return $self->{_geoip_record}->continent_code(); } +sub set_asn { + my ($self) = @_; + my $remote_ip = $self->qp->connection->remote_ip; + return if ! $self->{GeoIPASNum}; + + my $asn = $self->{GeoIPASNum} + ? $self->get_asn_gc($remote_ip) + : $self->{_geoip}->asn_by_addr($remote_ip); + + $asn or return; + $self->qp->connection->notes('geoip_asn', $asn); + return $asn; +} + +sub get_asn_gc { + my $self = shift; + return if !$self->{GeoIPASNum}; + return $self->{GeoIPASNum}->asn_by_addr(); +} + sub set_city_gc { my $self = shift; return if !$self->{_geoip_record}; diff --git a/t/plugin_tests/ident/geoip b/t/plugin_tests/ident/geoip index 5541c61..58c234a 100644 --- a/t/plugin_tests/ident/geoip +++ b/t/plugin_tests/ident/geoip @@ -9,6 +9,13 @@ use Qpsmtpd::Constants; sub register_tests { my $self = shift; + eval 'use GeoIP2::Database::Reader'; + if ( !$@ ) { + warn "using GeoIP2\n"; + $self->register_test('test_geoip2_lookup'); + return; + } + eval 'use Geo::IP'; if ( $@ ) { warn "could not load Geo::IP\n"; @@ -22,6 +29,19 @@ sub register_tests { $self->register_test('test_set_country_name'); $self->register_test('test_set_continent'); $self->register_test('test_set_distance'); + $self->register_test('test_set_isp'); +}; + +sub test_geoip2_lookup { + my $self = shift; + + $self->qp->connection->remote_ip('24.24.24.24'); + cmp_ok( $self->geoip2_lookup(), '==', DECLINED, "exit code"); + + cmp_ok( $self->connection->notes('geoip_country'), 'eq', 'US', "24.24.24.24 is in the US"); + cmp_ok( $self->connection->notes('geoip_country_name'), 'eq', 'United States', "24.24.24.24 is in the United States"); + cmp_ok( $self->connection->notes('geoip_continent'), 'eq', 'NA', "24.24.24.24 is in NA"); + cmp_ok( $self->connection->notes('geoip_city'), 'eq', 'Deer Park', "24.24.24.24 is in Deer Park"); }; sub test_geoip_lookup { @@ -30,7 +50,7 @@ sub test_geoip_lookup { $self->qp->connection->remote_ip('24.24.24.24'); cmp_ok( $self->geoip_lookup(), '==', DECLINED, "exit code"); - cmp_ok( $self->connection->notes('geoip_country'), 'eq', 'US', "note"); + cmp_ok( $self->connection->notes('geoip_country'), 'eq', 'US', "24.24.24.24 is in the US"); }; sub test_geoip_load_db { @@ -74,10 +94,10 @@ sub test_set_country_code { $self->qp->connection->remote_ip('24.24.24.24'); $cc = $self->set_country_code(); - cmp_ok( $cc, 'eq', 'US', "$cc"); + cmp_ok( $cc, 'eq', 'US', "set_country_code result is $cc"); my $note = $self->connection->notes('geoip_country'); - cmp_ok( $note, 'eq', 'US', "note has: $cc"); + cmp_ok( $note, 'eq', 'US', "set_country_code set note to $cc"); }; sub test_set_country_name { @@ -144,4 +164,3 @@ sub test_set_distance { ok( 1, "no distance data"); } }; - From 4eba2a39bc07607cf3bd15737a73dfcde757194f Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Wed, 5 Nov 2014 00:27:05 -0800 Subject: [PATCH 3/7] remove unused var --- plugins/ident/geoip | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/ident/geoip b/plugins/ident/geoip index fb9b8be..881f9e0 100644 --- a/plugins/ident/geoip +++ b/plugins/ident/geoip @@ -126,8 +126,6 @@ sub register { $self->{_args} = {@args}; $self->{_args}{db_dir} ||= '/usr/local/share/GeoIP'; - my $loaded = 0; - eval 'use GeoIP2::Database::Reader'; if (!$@) { warn "using GeoIP2"; From f2eda74074f906c496b73e31f8c550ce9c9c1879 Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Wed, 5 Nov 2014 13:50:19 -0800 Subject: [PATCH 4/7] ASN lookups now work --- lib/Qpsmtpd/Base.pm | 7 +++ plugins/ident/geoip | 105 ++++++++++++++++++++++++------------- t/plugin_tests/ident/geoip | 55 ++++++++++++------- 3 files changed, 113 insertions(+), 54 deletions(-) diff --git a/lib/Qpsmtpd/Base.pm b/lib/Qpsmtpd/Base.pm index b07835b..1d2f4d4 100644 --- a/lib/Qpsmtpd/Base.pm +++ b/lib/Qpsmtpd/Base.pm @@ -39,4 +39,11 @@ sub is_valid_ip { return; } +sub is_ipv6 { + my ($self, $ip) = @_; + return if !$ip; + return 1 if Net::IP::ip_is_ipv6($ip); + return; +}; + 1; diff --git a/plugins/ident/geoip b/plugins/ident/geoip index 881f9e0..b33d1d4 100644 --- a/plugins/ident/geoip +++ b/plugins/ident/geoip @@ -102,6 +102,8 @@ data source: http://software77.net/geo-ip/ =head1 ACKNOWLEDGEMENTS +MaxMind - the packager and distributor of the free GeoIP data + Stevan Bajic, the DSPAM author, who suggested SNARE, which describes using geodesic distance to determine spam probability. The research paper on SNARE can be found here: @@ -126,27 +128,12 @@ sub register { $self->{_args} = {@args}; $self->{_args}{db_dir} ||= '/usr/local/share/GeoIP'; - eval 'use GeoIP2::Database::Reader'; - if (!$@) { - warn "using GeoIP2"; - $self->log(LOGINFO, "using GeoIP2"); + $self->load_geoip2() and return; + $self->load_geoip1(); +} - eval { - $self->{_geoip2_city} = GeoIP2::Database::Reader->new( - file => $self->{_args}{db_dir} . '/GeoLite2-City.mmdb', - ); - }; - eval { - $self->{_geoip2_country} = GeoIP2::Database::Reader->new( - file => $self->{_args}{db_dir} . '/GeoLite2-Country.mmdb', - ); - }; - $self->register_hook('connect', 'geoip2_lookup'); - return; - } - - warn "could not load GeoIP2"; - $self->log(LOGERROR, "could not load GeoIP2"); +sub load_geoip1 { + my $self = shift; eval 'use Geo::IP'; if ($@) { @@ -166,6 +153,43 @@ sub register { $self->register_hook('connect', 'geoip_lookup'); } +sub load_geoip2 { + my $self = shift; + + eval 'use GeoIP2::Database::Reader'; + if ($@) { + $self->log(LOGERROR, "could not load GeoIP2"); + return; + } + + $self->log(LOGINFO, "GeoIP2 loaded"); + + eval { + $self->{_geoip2_city} = GeoIP2::Database::Reader->new( + file => $self->{_args}{db_dir} . '/GeoLite2-City.mmdb', + ); + }; + if ($@) { + $self->log(LOGERROR, "unable to load GeoLite2-City.mmdb"); + } + + eval { + $self->{_geoip2_country} = GeoIP2::Database::Reader->new( + file => $self->{_args}{db_dir} . '/GeoLite2-Country.mmdb', + ); + }; + if ($@) { + $self->log(LOGERROR, "unable to load GeoLite2-Country.mmdb"); + } + + if ($self->{_geoip2_city} || $self->{_geoip2_country}) { + $self->register_hook('connect', 'geoip2_lookup'); + return 1; + } + + return; +} + sub geoip2_lookup { my $self = shift; @@ -246,14 +270,18 @@ sub open_geoip_db { my $db_dir = $self->{_args}{db_dir}; foreach my $db (qw/ GeoIPCity GeoLiteCity /) { next if !-f "$db_dir/$db.dat"; - $self->log(LOGDEBUG, "using db $db"); + $self->log(LOGINFO, "using db $db"); $self->{_geoip_city} = Geo::IP->open("$db_dir/$db.dat"); } - foreach my $db (qw/ GeoIPASNum GeoIPASNumv6 /) { - next if !-f "$db_dir/$db.dat"; - $self->log(LOGDEBUG, "using db $db"); - $self->{$db} = Geo::IP->open("$db_dir/$db.dat"); + if (-f "$db_dir/GeoIPASNum.dat") { + $self->log(LOGINFO, "using GeoIPASNum"); + $self->{GeoIPASNum} = Geo::IP->open("$db_dir/GeoIPASNum.dat"); + } + + if (-f "$db_dir/GeoIPASNumv6.dat") { + $self->log(LOGINFO, "using GeoIPASNumv6"); + $self->{GeoIPASNumv6} = Geo::IP->open("$db_dir/GeoIPASNumv6.dat"); } # can't think of a good reason to load country if city data is present @@ -338,23 +366,28 @@ sub get_continent_gc { } sub set_asn { - my ($self) = @_; - my $remote_ip = $self->qp->connection->remote_ip; + my ($self, $ip) = @_; + $ip ||= $self->qp->connection->remote_ip; + + if (Qpsmtpd::Base->is_ipv6($ip)) { + return $self->set_asn_ipv6($ip); + } return if ! $self->{GeoIPASNum}; - my $asn = $self->{GeoIPASNum} - ? $self->get_asn_gc($remote_ip) - : $self->{_geoip}->asn_by_addr($remote_ip); - - $asn or return; + my $asn = $self->{GeoIPASNum}->name_by_addr($ip) or return; $self->qp->connection->notes('geoip_asn', $asn); return $asn; } -sub get_asn_gc { - my $self = shift; - return if !$self->{GeoIPASNum}; - return $self->{GeoIPASNum}->asn_by_addr(); +sub set_asn_ipv6 { + my ($self, $ip) = @_; + $ip ||= $self->qp->connection->remote_ip; + + return if ! $self->{GeoIPASNumv6}; + + my $asn = $self->{GeoIPASNumv6}->name_by_addr_v6($ip) or return; + $self->qp->connection->notes('geoip_asn', $asn); + return $asn; } sub set_city_gc { diff --git a/t/plugin_tests/ident/geoip b/t/plugin_tests/ident/geoip index 58c234a..2610894 100644 --- a/t/plugin_tests/ident/geoip +++ b/t/plugin_tests/ident/geoip @@ -13,35 +13,37 @@ sub register_tests { if ( !$@ ) { warn "using GeoIP2\n"; $self->register_test('test_geoip2_lookup'); - return; } eval 'use Geo::IP'; - if ( $@ ) { - warn "could not load Geo::IP\n"; - return; - }; + if ( !$@ ) { + warn "loaded Geo::IP\n"; - $self->register_test('test_geoip_lookup'); - $self->register_test('test_geoip_load_db'); - $self->register_test('test_geoip_init_cc'); - $self->register_test('test_set_country_code'); - $self->register_test('test_set_country_name'); - $self->register_test('test_set_continent'); - $self->register_test('test_set_distance'); - $self->register_test('test_set_isp'); + $self->register_test('test_geoip_lookup'); + $self->register_test('test_geoip_load_db'); + $self->register_test('test_geoip_init_cc'); + $self->register_test('test_set_country_code'); + $self->register_test('test_set_country_name'); + $self->register_test('test_set_continent'); + $self->register_test('test_set_distance'); + $self->register_test('test_set_asn'); + }; }; sub test_geoip2_lookup { my $self = shift; $self->qp->connection->remote_ip('24.24.24.24'); - cmp_ok( $self->geoip2_lookup(), '==', DECLINED, "exit code"); + cmp_ok( $self->geoip2_lookup(), '==', DECLINED, "exit code DECLINED"); - cmp_ok( $self->connection->notes('geoip_country'), 'eq', 'US', "24.24.24.24 is in the US"); - cmp_ok( $self->connection->notes('geoip_country_name'), 'eq', 'United States', "24.24.24.24 is in the United States"); - cmp_ok( $self->connection->notes('geoip_continent'), 'eq', 'NA', "24.24.24.24 is in NA"); - cmp_ok( $self->connection->notes('geoip_city'), 'eq', 'Deer Park', "24.24.24.24 is in Deer Park"); + if (!$self->load_geoip2()) { + warn "failed to load GeoIP2\n"; + } + + cmp_ok( $self->connection->notes('geoip_country'), 'eq', 'US', "24.24.24.24 is in country US"); + cmp_ok( $self->connection->notes('geoip_country_name'), 'eq', 'United States', "24.24.24.24 is in country United States"); + cmp_ok( $self->connection->notes('geoip_continent'), 'eq', 'NA', "24.24.24.24 is in continent NA"); + cmp_ok( $self->connection->notes('geoip_city'), 'eq', 'Deer Park', "24.24.24.24 is in city of Deer Park"); }; sub test_geoip_lookup { @@ -164,3 +166,20 @@ sub test_set_distance { ok( 1, "no distance data"); } }; +sub test_set_asn { + my $self = shift; + + $self->qp->connection->remote_ip(''); + $self->set_asn(); + my $asn = $self->set_asn(); + ok( ! $asn, "undef") or warn "$asn\n"; + + $self->qp->connection->remote_ip('24.24.24.24'); + $asn = $self->set_asn(); + ok( $self->connection->notes('geoip_asn') =~ /^AS11351/, "note has: $asn"); + + $self->qp->connection->remote_ip('66.128.51.163'); + $asn = $self->set_asn(); + + ok( $self->connection->notes('geoip_asn') =~ /^AS7819/, "note has: $asn"); +}; From 54abd602396102e869021767f4dc5ea410b887b6 Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Wed, 5 Nov 2014 13:52:21 -0800 Subject: [PATCH 5/7] strip off AS prefix --- plugins/ident/geoip | 3 +++ t/plugin_tests/ident/geoip | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/ident/geoip b/plugins/ident/geoip index b33d1d4..6961ed6 100644 --- a/plugins/ident/geoip +++ b/plugins/ident/geoip @@ -375,6 +375,9 @@ sub set_asn { return if ! $self->{GeoIPASNum}; my $asn = $self->{GeoIPASNum}->name_by_addr($ip) or return; + if ('AS' eq substr($asn, 0, 2)) { + $asn = substr($asn, 2); + } $self->qp->connection->notes('geoip_asn', $asn); return $asn; } diff --git a/t/plugin_tests/ident/geoip b/t/plugin_tests/ident/geoip index 2610894..43392fd 100644 --- a/t/plugin_tests/ident/geoip +++ b/t/plugin_tests/ident/geoip @@ -176,10 +176,10 @@ sub test_set_asn { $self->qp->connection->remote_ip('24.24.24.24'); $asn = $self->set_asn(); - ok( $self->connection->notes('geoip_asn') =~ /^AS11351/, "note has: $asn"); + ok( $self->connection->notes('geoip_asn') =~ /^11351/, "note has: $asn"); $self->qp->connection->remote_ip('66.128.51.163'); $asn = $self->set_asn(); - ok( $self->connection->notes('geoip_asn') =~ /^AS7819/, "note has: $asn"); + ok( $self->connection->notes('geoip_asn') =~ /^7819/, "note has: $asn"); }; From 954fa45f2d792010e1d684c1dd20dc7b24a2385d Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Wed, 5 Nov 2014 14:23:06 -0800 Subject: [PATCH 6/7] added call to ->set_asn --- plugins/ident/geoip | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/ident/geoip b/plugins/ident/geoip index 6961ed6..0a44eaa 100644 --- a/plugins/ident/geoip +++ b/plugins/ident/geoip @@ -230,6 +230,8 @@ sub geoip_lookup { return DECLINED; }; + $self->set_asn(); + my $c_name = $self->set_country_name(); my ($city, $continent_code, $distance) = ''; From 149063d37f0c0edad6e9d39baa59def885a2bd2a Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Wed, 5 Nov 2014 14:31:44 -0800 Subject: [PATCH 7/7] base: removed redundant code from is_ipv6 --- lib/Qpsmtpd/Base.pm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Qpsmtpd/Base.pm b/lib/Qpsmtpd/Base.pm index 1d2f4d4..cfe88ff 100644 --- a/lib/Qpsmtpd/Base.pm +++ b/lib/Qpsmtpd/Base.pm @@ -42,8 +42,7 @@ sub is_valid_ip { sub is_ipv6 { my ($self, $ip) = @_; return if !$ip; - return 1 if Net::IP::ip_is_ipv6($ip); - return; + return Net::IP::ip_is_ipv6($ip); }; 1;