2004-09-08 18:26:33 +02:00
|
|
|
package Test::Qpsmtpd::Plugin;
|
2014-09-16 08:41:31 +02:00
|
|
|
use strict;
|
2004-09-08 18:26:33 +02:00
|
|
|
1;
|
|
|
|
|
|
|
|
# Additional plugin methods used during testing
|
|
|
|
package Qpsmtpd::Plugin;
|
|
|
|
|
|
|
|
use strict;
|
2012-05-22 00:17:34 +02:00
|
|
|
use warnings;
|
|
|
|
|
|
|
|
use Test::More;
|
2014-09-17 08:16:53 +02:00
|
|
|
use Qpsmtpd::Constants;
|
2004-09-08 18:26:33 +02:00
|
|
|
|
|
|
|
sub register_tests {
|
2013-04-21 06:08:43 +02:00
|
|
|
|
2004-09-08 18:26:33 +02:00
|
|
|
# Virtual base method - implement in plugin
|
|
|
|
}
|
|
|
|
|
|
|
|
sub register_test {
|
2014-09-17 08:16:53 +02:00
|
|
|
my ($plugin, $test) = @_;
|
2013-04-21 06:08:43 +02:00
|
|
|
|
2004-09-08 18:26:33 +02:00
|
|
|
# print STDERR "Registering test $test ($num_tests)\n";
|
2014-09-17 08:16:53 +02:00
|
|
|
push @{$plugin->{_tests}}, {name => $test};
|
2004-09-08 18:26:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub run_tests {
|
2004-09-08 23:48:27 +02:00
|
|
|
my ($plugin, $qp) = @_;
|
2004-09-08 18:26:33 +02:00
|
|
|
foreach my $t (@{$plugin->{_tests}}) {
|
|
|
|
my $method = $t->{name};
|
2014-09-17 08:16:53 +02:00
|
|
|
print "# " . $plugin->plugin_name . "\t $method\n";
|
2004-09-08 23:48:27 +02:00
|
|
|
local $plugin->{_qp} = $qp;
|
2004-09-08 18:26:33 +02:00
|
|
|
$plugin->$method();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-02 21:09:21 +02:00
|
|
|
sub validate_password {
|
2013-04-21 06:08:43 +02:00
|
|
|
my ($self, %a) = @_;
|
2012-06-02 21:09:21 +02:00
|
|
|
|
|
|
|
my ($pkg, $file, $line) = caller();
|
|
|
|
|
|
|
|
my $src_clear = $a{src_clear};
|
|
|
|
my $src_crypt = $a{src_crypt};
|
|
|
|
my $attempt_clear = $a{attempt_clear};
|
|
|
|
my $attempt_hash = $a{attempt_hash};
|
|
|
|
my $method = $a{method} or die "missing method";
|
|
|
|
my $ticket = $a{ticket};
|
|
|
|
my $deny = $a{deny} || DENY;
|
|
|
|
|
2013-04-21 06:08:43 +02:00
|
|
|
if (!$src_crypt && !$src_clear) {
|
2012-06-02 21:09:21 +02:00
|
|
|
$self->log(LOGINFO, "fail: missing password");
|
2014-09-18 03:28:51 +02:00
|
|
|
return $deny, "$file - no such user";
|
2013-04-21 06:08:43 +02:00
|
|
|
}
|
2012-06-02 21:09:21 +02:00
|
|
|
|
2013-04-21 06:08:43 +02:00
|
|
|
if (!$src_clear && $method =~ /CRAM-MD5/i) {
|
2012-06-02 21:09:21 +02:00
|
|
|
$self->log(LOGINFO, "skip: cram-md5 not supported w/o clear pass");
|
2014-09-18 03:28:51 +02:00
|
|
|
return DECLINED, $file;
|
2012-06-02 21:09:21 +02:00
|
|
|
}
|
|
|
|
|
2013-04-21 06:08:43 +02:00
|
|
|
if (defined $attempt_clear) {
|
|
|
|
if ($src_clear && $src_clear eq $attempt_clear) {
|
2012-06-02 21:09:21 +02:00
|
|
|
$self->log(LOGINFO, "pass: clear match");
|
2014-09-18 03:28:51 +02:00
|
|
|
return OK, $file;
|
2013-04-21 06:08:43 +02:00
|
|
|
}
|
2012-06-02 21:09:21 +02:00
|
|
|
|
2013-04-21 06:08:43 +02:00
|
|
|
if ($src_crypt && $src_crypt eq crypt($attempt_clear, $src_crypt)) {
|
2012-06-02 21:09:21 +02:00
|
|
|
$self->log(LOGINFO, "pass: crypt match");
|
2014-09-18 03:28:51 +02:00
|
|
|
return OK, $file;
|
2012-06-02 21:09:21 +02:00
|
|
|
}
|
2013-04-21 06:08:43 +02:00
|
|
|
}
|
2012-06-02 21:09:21 +02:00
|
|
|
|
2013-04-21 06:08:43 +02:00
|
|
|
if (defined $attempt_hash && $src_clear) {
|
|
|
|
if (!$ticket) {
|
2012-06-02 21:09:21 +02:00
|
|
|
$self->log(LOGERROR, "skip: missing ticket");
|
2014-09-18 03:28:51 +02:00
|
|
|
return DECLINED, $file;
|
2013-04-21 06:08:43 +02:00
|
|
|
}
|
2012-06-02 21:09:21 +02:00
|
|
|
|
2013-04-21 06:08:43 +02:00
|
|
|
if ($attempt_hash eq hmac_md5_hex($ticket, $src_clear)) {
|
2012-06-02 21:09:21 +02:00
|
|
|
$self->log(LOGINFO, "pass: hash match");
|
2014-09-18 03:28:51 +02:00
|
|
|
return OK, $file;
|
2013-04-21 06:08:43 +02:00
|
|
|
}
|
|
|
|
}
|
2012-06-02 21:09:21 +02:00
|
|
|
|
|
|
|
$self->log(LOGINFO, "fail: wrong password");
|
2014-09-18 03:28:51 +02:00
|
|
|
return $deny, "$file - wrong password";
|
2013-04-21 06:08:43 +02:00
|
|
|
}
|
2012-06-02 21:09:21 +02:00
|
|
|
|
2004-09-08 18:26:33 +02:00
|
|
|
1;
|