diff --git a/Makefile.PL b/Makefile.PL index f7062fe6..41daaae9 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -30,10 +30,11 @@ WriteMakefile( # 'DBIx::Simple' => 0, # log2sql # modules that cause Travis build tests to fail # 'Mail::SpamAssassin' => 0, -# 'GeoIP2' => 2, + 'GeoIP2' => 2, # 'Geo::IP' => 1, 'Math::Complex' => 0, # geodesic distance in Geo::IP 'PerlIO::gzip' => 0, # gunzip GeoIP databases + 'Redis' => 2, 'Mail::SPF' => 0, }, ABSTRACT => 'Flexible smtpd daemon written in Perl', diff --git a/plugins/ident/geoip b/plugins/ident/geoip index f5dfa145..1ab6cd00 100644 --- a/plugins/ident/geoip +++ b/plugins/ident/geoip @@ -162,10 +162,10 @@ sub load_geoip1 { $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. + # 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->init_my_country_code(); $self->register_hook('connect', 'geoip_lookup'); diff --git a/t/plugin_tests/dmarc b/t/plugin_tests/dmarc deleted file mode 100644 index 58c09098..00000000 --- a/t/plugin_tests/dmarc +++ /dev/null @@ -1,46 +0,0 @@ -#!perl -w - -use strict; -use English qw/-no_match_vars/; -use POSIX qw(strftime); - -use Qpsmtpd::Address; -use Qpsmtpd::Constants; - -my $remote_ip = '66.128.51.165'; -my $test_email = 'matt@tnpi.net'; - -sub register_tests { - my $self = shift; - - eval 'use Mail::DMARC'; - if ($EVAL_ERROR) { - warn 'unable to load Mail::DMARC'; - return; - } - - $self->register_test('_check_dmarc'); -} - -sub _check_dmarc { - my $self = shift; - - $self->qp->connection->remote_ip($remote_ip); - my $t = $self->qp->transaction; - $t->header(Mail::Header->new(Modify => 0, MailFrom => "COERCE")); - $t->sender(Qpsmtpd::Address->new( "<$test_email>" )); - $t->header->add('Date', strftime "%a %b %e %H:%M:%S %Y", localtime time); - $t->body_write( "test message body " ); - - # no From header, reject as invalid message - my ($rc, $msg) = $self->check_dmarc($t); - cmp_ok($rc, '==', DENY, "no From header, $msg"); - - - $t->header->add('From', "<$test_email>"); - ($rc, $msg) = $self->check_dmarc($t); - cmp_ok($rc, '==', DENY, "$msg"); - cmp_ok($msg, 'eq', 'failed DMARC policy', 'check_dmarc, no SPF'); - - #warn $self->qp->connection->notes('authentication_results'); -} \ No newline at end of file diff --git a/t/plugin_tests/helo b/t/plugin_tests/helo index f144ab36..7aa4bcbd 100644 --- a/t/plugin_tests/helo +++ b/t/plugin_tests/helo @@ -53,9 +53,9 @@ sub test_invalid_localhost { my $self = shift; my ($err, $why); - foreach my $ip ( undef, '', '192.0.99.5' ) { + foreach my $ip ( '', '192.0.99.5' ) { $self->qp->connection->remote_ip(undef); - ($err, $why) = $self->invalid_localhost('localhost' ); + ($err, $why) = $self->invalid_localhost('localhost'); ok($err, "host: localhost, remote ip ($ip)"); $self->qp->connection->remote_ip(undef); diff --git a/t/plugin_tests/ident/geoip b/t/plugin_tests/ident/geoip index 54368664..7c46b025 100644 --- a/t/plugin_tests/ident/geoip +++ b/t/plugin_tests/ident/geoip @@ -13,19 +13,6 @@ sub register_tests { if ( !$@ ) { $self->register_test('test_geoip2_lookup'); } - - eval 'use Geo::IP'; - if ( !$@ ) { - $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'); - $self->register_test('test_add_headers'); - } } sub test_geoip2_lookup { @@ -41,7 +28,7 @@ sub test_geoip2_lookup { 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"); + cmp_ok( $self->connection->notes('geoip_city'), 'eq', 'Syracuse', "24.24.24.24 is in city of Syracuse"); } sub test_add_headers { @@ -68,173 +55,3 @@ sub all_headers { return join " | ", map { chomp $_; $_ } $self->transaction->header->get($tag); } -sub test_geoip_lookup { - my $self = shift; - - $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', "24.24.24.24 is in the US"); -} - -sub test_geoip_load_db { - my $self = shift; - - $self->open_geoip_db(); - - if ( $self->{_geoip_city} ) { - ok( ref $self->{_geoip_city}, "loaded GeoIP city db" ); - } - else { - ok( "no GeoIP city db" ); - } - - if ( $self->{_geoip} ) { - ok( ref $self->{_geoip}, "loaded GeoIP db" ); - } - else { - ok( "no GeoIP db" ); - } -} - -sub test_geoip_init_cc { - my $self = shift; - - $self->{_my_country_code} = undef; - ok( ! $self->{_my_country_code}, "undefined"); - - my $test_ip = '208.175.177.10'; - $self->{_args}{distance} = $test_ip; - $self->init_my_country_code( $test_ip ); - cmp_ok( $self->{_my_country_code}, 'eq', 'US', "country set and matches"); -} - -sub test_set_country_code { - my $self = shift; - - $self->qp->connection->remote_ip(''); - my $cc = $self->set_country_code(); - ok( ! $cc, "undef"); - - $self->qp->connection->remote_ip('24.24.24.24'); - $self->clear_geoip_data; - $cc = $self->set_country_code(); - ok( ! $cc, "set_country_code() returns nothing for no geoip data"); - $self->restore_geoip_data; - $cc = $self->set_country_code(); - cmp_ok( $cc, 'eq', 'US', "set_country_code result is $cc"); - - my $note = $self->connection->notes('geoip_country'); - cmp_ok( $note, 'eq', 'US', "set_country_code set note to $cc"); -} - -sub test_set_country_name { - my $self = shift; - - $self->{_geoip_record} = undef; - $self->qp->connection->remote_ip(''); - $self->set_country_code(); - my $cn = $self->set_country_name(); - ok( ! $cn, "undef") or warn "$cn\n"; - - $self->qp->connection->remote_ip('24.24.24.24'); - $self->clear_geoip_data; - $self->set_country_code(); - $cn = $self->set_country_name(); - ok( ! $cn, "set_country_name() returns nothing for no geoip data"); - $self->restore_geoip_data; - $self->set_country_code(); - $cn = $self->set_country_name(); - cmp_ok( $cn, 'eq', 'United States', "$cn"); - - my $note = $self->connection->notes('geoip_country_name'); - cmp_ok( $note, 'eq', 'United States', "note has: $cn"); -} - -sub test_set_continent { - my $self = shift; - - $self->{_geoip_record} = undef; - $self->qp->connection->remote_ip(''); - $self->set_country_code(); - my $cn = $self->set_continent(); - ok( ! $cn, "undef") or warn "$cn\n"; - - $self->qp->connection->remote_ip('24.24.24.24'); - $self->clear_geoip_data; - $self->set_country_code(); - $cn = $self->set_continent('US'); - ok( ! $cn, 'set_continent() returns nothing for no geoip data'); - $self->restore_geoip_data; - $self->set_country_code(); - $cn = $self->set_continent() || ''; - my $note = $self->connection->notes('geoip_continent'); - if ( $cn ) { - cmp_ok( $cn, 'eq', 'NA', "$cn"); - cmp_ok( $note, 'eq', 'NA', "note has: $cn"); - } - else { - ok(1, "no continent data" ); - ok(1, "no continent data" ); - } -} - -sub test_set_distance { - my $self = shift; - - $self->{_geoip_record} = undef; - $self->qp->connection->remote_ip(''); - $self->set_country_code(); - my $cn = $self->set_distance_gc(); - ok( ! $cn, "undef") or warn "$cn\n"; - - $self->qp->connection->remote_ip('24.24.24.24'); - $self->set_country_code(); - $cn = $self->set_distance_gc(); - if ( $cn ) { - ok( $cn, "$cn km"); - - my $note = $self->connection->notes('geoip_distance'); - ok( $note, "note has: $cn"); - } - else { - ok( 1, "no distance data"); - ok( 1, "no distance data"); - } -} - -sub test_set_asn { - my $self = shift; - - return if !$self->{GeoIPASNum}; - - $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'); - $self->clear_geoip_data; - $asn = $self->set_asn(); - ok( ! $asn, 'set_asn() returns nothing for no ASN data' ); - $self->restore_geoip_data; - $asn = $self->set_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') =~ /^7819/, "note has: $asn"); -} - -my $geoip_data_bak; -my @geoip_keys = qw( _geoip _geoip_city GeoIPASNum ); -sub clear_geoip_data { - my ( $self ) = @_; - $geoip_data_bak->{$_} = delete $self->{$_} for @geoip_keys; -} - -sub restore_geoip_data { - my ( $self ) = @_; - $self->{$_} = delete $geoip_data_bak->{$_} for @geoip_keys; -}