diff --git a/MANIFEST b/MANIFEST index 5cbad48..28ac182 100644 --- a/MANIFEST +++ b/MANIFEST @@ -39,6 +39,7 @@ lib/Danga/TimeoutSocket.pm lib/Qpsmtpd.pm lib/Qpsmtpd/Address.pm lib/Qpsmtpd/Auth.pm +lib/Qpsmtpd/Base.pm lib/Qpsmtpd/Command.pm lib/Qpsmtpd/ConfigServer.pm lib/Qpsmtpd/Connection.pm @@ -55,7 +56,6 @@ lib/Qpsmtpd/SMTP/Prefork.pm lib/Qpsmtpd/TcpServer.pm lib/Qpsmtpd/TcpServer/Prefork.pm lib/Qpsmtpd/Transaction.pm -lib/Qpsmtpd/Utils.pm LICENSE log/log2sql log/log2sql.sql diff --git a/lib/Qpsmtpd.pm b/lib/Qpsmtpd.pm index fa52a58..bbefb1d 100644 --- a/lib/Qpsmtpd.pm +++ b/lib/Qpsmtpd.pm @@ -1,14 +1,16 @@ package Qpsmtpd; use strict; - #use warnings; + +our $VERSION = "0.95"; use vars qw($TraceLevel $Spool_dir $Size_threshold); use Sys::Hostname; -use Qpsmtpd::Constants; -use Qpsmtpd::Address; -our $VERSION = "0.95"; +use lib 'lib'; +use base 'Qpsmtpd::Base'; +use Qpsmtpd::Address; +use Qpsmtpd::Constants; my $git; @@ -592,8 +594,7 @@ sub spool_dir { unless ($Spool_dir) { # first time through $self->log(LOGDEBUG, "Initializing spool_dir"); - $Spool_dir = $self->config('spool_dir') - || Qpsmtpd::Utils->tildeexp('~/tmp/'); + $Spool_dir = $self->config('spool_dir') || $self->tildeexp('~/tmp/'); $Spool_dir .= "/" unless ($Spool_dir =~ m!/$!); @@ -627,8 +628,8 @@ sub temp_file { } sub temp_dir { - my $self = shift; - my $mask = shift || 0700; + my ($self, $mask) = @_; + $mask ||= '0700'; my $dirname = $self->temp_file(); -d $dirname or mkdir($dirname, $mask) @@ -638,10 +639,10 @@ sub temp_dir { sub size_threshold { my $self = shift; - unless (defined $Size_threshold) { - $Size_threshold = $self->config('size_threshold') || 0; - $self->log(LOGDEBUG, "size_threshold set to $Size_threshold"); - } + return $Size_threshold if defined $Size_threshold; + + $Size_threshold = $self->config('size_threshold') || 0; + $self->log(LOGDEBUG, "size_threshold set to $Size_threshold"); return $Size_threshold; } diff --git a/lib/Qpsmtpd/Utils.pm b/lib/Qpsmtpd/Base.pm similarity index 96% rename from lib/Qpsmtpd/Utils.pm rename to lib/Qpsmtpd/Base.pm index 2aa3c0b..871fda1 100644 --- a/lib/Qpsmtpd/Utils.pm +++ b/lib/Qpsmtpd/Base.pm @@ -1,4 +1,4 @@ -package Qpsmtpd::Utils; +package Qpsmtpd::Base; use strict; use Net::IP; diff --git a/lib/Qpsmtpd/Transaction.pm b/lib/Qpsmtpd/Transaction.pm index 294fcd0..65307c4 100644 --- a/lib/Qpsmtpd/Transaction.pm +++ b/lib/Qpsmtpd/Transaction.pm @@ -4,7 +4,7 @@ use Qpsmtpd; use strict; use warnings; -use Qpsmtpd::Utils; +use Qpsmtpd::Base; use Qpsmtpd::Constants; use IO::File qw(O_RDWR O_CREAT); diff --git a/plugins/fcrdns b/plugins/fcrdns index e9f224a..26af74e 100644 --- a/plugins/fcrdns +++ b/plugins/fcrdns @@ -166,7 +166,7 @@ sub connect_handler { sub is_valid_localhost { my ($self) = @_; - if (Qpsmtpd::Utils->is_localhost($self->qp->connection->remote_ip)) { + if (Qpsmtpd::Base->is_localhost($self->qp->connection->remote_ip)) { $self->adjust_karma(1); $self->log(LOGDEBUG, "pass, is localhost"); return 1; diff --git a/plugins/helo b/plugins/helo index 92ac3eb..49088bb 100644 --- a/plugins/helo +++ b/plugins/helo @@ -229,8 +229,8 @@ use warnings; use Net::IP; +use Qpsmtpd::Base; use Qpsmtpd::Constants; -use Qpsmtpd::Utils; sub register { my ($self, $qp) = (shift, shift); @@ -342,7 +342,7 @@ sub is_regex_match { sub invalid_localhost { my ($self, $host) = @_; - if (Qpsmtpd::Utils->is_localhost($self->qp->connection->remote_ip)) { + if (Qpsmtpd::Base->is_localhost($self->qp->connection->remote_ip)) { $self->log(LOGDEBUG, "pass, is localhost"); return; } @@ -357,7 +357,7 @@ sub invalid_localhost { sub is_plain_ip { my ($self, $host) = @_; - return if !Qpsmtpd::Utils->is_valid_ip($host); + return if !Qpsmtpd::Base->is_valid_ip($host); $self->log(LOGDEBUG, "fail, plain IP"); return ("Plain IP is invalid HELO hostname (RFC 2821)", "plain IP"); @@ -369,7 +369,7 @@ sub is_address_literal { my ($ip) = $host =~ /^\[(.*)\]/; # strip off any brackets return if !$ip; # no brackets, not a literal - return if !Qpsmtpd::Utils->is_valid_ip($ip); + return if !Qpsmtpd::Base->is_valid_ip($ip); $self->log(LOGDEBUG, "fail, bracketed IP"); return ("RFC 2821 allows an address literal, but we do not", @@ -378,7 +378,7 @@ sub is_address_literal { sub is_forged_literal { my ($self, $host) = @_; - return if !Qpsmtpd::Utils->is_valid_ip($host); + return if !Qpsmtpd::Base->is_valid_ip($host); # should we add exceptions for reserved internal IP space? (192.168,10., etc) $host = substr $host, 1, -1; diff --git a/t/qpsmtpd-utils.t b/t/qpsmtpd-base.t similarity index 88% rename from t/qpsmtpd-utils.t rename to t/qpsmtpd-base.t index 920c271..24cdc9f 100644 --- a/t/qpsmtpd-utils.t +++ b/t/qpsmtpd-base.t @@ -4,11 +4,11 @@ use warnings; use Test::More; -use lib 'lib'; # test lib/Qpsmtpd/Utils (vs site_perl) +use lib 'lib'; # test lib/Qpsmtpd/Base (vs site_perl) -BEGIN { use_ok('Qpsmtpd::Utils'); } +BEGIN { use_ok('Qpsmtpd::Base'); } -my $utils = bless {}, 'Qpsmtpd::Utils'; +my $utils = bless {}, 'Qpsmtpd::Base'; __tildeexp(); __is_localhost(); diff --git a/t/qpsmtpd.t b/t/qpsmtpd.t index 65e2203..c84b39f 100644 --- a/t/qpsmtpd.t +++ b/t/qpsmtpd.t @@ -3,6 +3,7 @@ use strict; use warnings; use Data::Dumper; +use File::Path; use Test::More; use lib 'lib'; # test lib/Qpsmtpd (vs site_perl) @@ -20,12 +21,18 @@ my $qp = bless {}, 'Qpsmtpd'; ok($qp->version(), "version, " . $qp->version()); is_deeply(Qpsmtpd::hooks(), {}, 'hooks, empty'); +__temp_dir(); +__size_threshold(); __authenticated(); +__auth_user(); +__auth_mechanism(); + +__log(); +__load_logging(); + __config_dir(); __get_qmail_config(); __config(); -__log(); -__load_logging(); done_testing(); @@ -75,17 +82,6 @@ sub __load_logging { $Qpsmtpd::hooks->{logging} = undef; # restore } -sub __authenticated { - - ok(!$qp->authenticated(), "authenticated, undef"); - - $qp->{_auth} = 1; - ok($qp->authenticated(), "authenticated, true"); - - $qp->{_auth} = 0; - ok(!$qp->authenticated(), "authenticated, false"); -} - sub __config { my @r = $qp->config('badhelo'); ok($r[0], "config, badhelo, @r"); @@ -187,11 +183,60 @@ sub __config { } } +sub __temp_dir { + my $r = $qp->temp_dir(); + ok( $r, "temp_dir, $r"); + + $r = $qp->temp_dir('0775'); + ok( $r, "temp_dir with mask, $r"); + + if ($r && -d $r) { File::Path::rmtree $r; } +} + +sub __size_threshold { + ok( ! $qp->size_threshold(), "size_threshold is undefined") + or warn "size_threshold: " . $qp->size_threshold; + + $Qpsmtpd::Size_threshold = 5; + cmp_ok( 5, '==', $qp->size_threshold(), "size_threshold equals 5"); + + $Qpsmtpd::Size_threshold = undef; +} + +sub __authenticated { + ok( ! $qp->authenticated(), "authenticated is undefined"); + + $qp->{_auth} = 1; + ok($qp->authenticated(), "authenticated is true"); + + $qp->{_auth} = 0; + ok(! $qp->authenticated(), "authenticated is false"); +} + +sub __auth_user { + ok( ! $qp->auth_user(), "auth_user is undefined"); + + $qp->{_auth_user} = 'matt'; + cmp_ok('matt', 'eq', $qp->auth_user(), "auth_user set"); + + $qp->{_auth_user} = undef; +} + +sub __auth_mechanism { + ok( ! $qp->auth_mechanism(), "auth_mechanism is undefined"); + + $qp->{_auth_mechanism} = 'MD5'; + cmp_ok('MD5', 'eq', $qp->auth_mechanism(), "auth_mechanism set"); + + $qp->{_auth_mechanism} = undef; +} + + package FakeAddress; sub new { - shift; - return bless {@_}; + my $class = shift; + return bless {@_}, $class; } sub address { } # pass the can('address') conditional