qpsmtpd/plugins/auth/auth_flat_file
Matt Simerson 35e1ce9883 consolidate auth logic into Qpsmtpd::Auth
These 3 auth plugins all have a data store they fetch the reference
password or hash from. They then match the attemped password or hash
against the reference. This consolidates the latter portion (validating
the password/hash) into Auth.pm.

* less duplicated code in the plugins.
* Pass validation consistently handled for these 3 plugins.
* less work to create new auth plugins

Also caches the CRAM-MD5 ticket. It could also cache user/pass info if
this was desirable.
2012-05-20 23:37:06 -07:00

84 lines
2.1 KiB
Perl

#!perl -w
=head1 NAME
auth_flat_file - simple CRAM MD5 auth plugin using a flat password file
=head1 SYNOPSIS
in config/plugins:
auth/auth_flat_file
in config/flat_auth_pw
username1:password1
username2:password2
...
=head1 DESCRIPTION
This plugin implements a very simple authentication plugin using a flat password
file containing username and password separated by colons.
Note that this plugin enforces the use of a full email address (including
@domain) as the username. There's no particular reason for this so feel free
to modify the code to suit your setup.
The password is stored on disk unencrypted, however authentication uses a HMAC
algorithm so no password is transfered in the clear.
=cut
use strict;
use warnings;
use Qpsmtpd::Auth;
use Qpsmtpd::Constants;
sub register {
my ( $self, $qp ) = @_;
$self->register_hook('auth-plain', 'auth_flat_file');
$self->register_hook('auth-login', 'auth_flat_file');
$self->register_hook('auth-cram-md5', 'auth_flat_file');
}
sub auth_flat_file {
my ( $self, $transaction, $method, $user, $passClear, $passHash, $ticket ) =
@_;
if ( ! defined $passClear && ! defined $passHash ) {
$self->log(LOGINFO, "fail: missing password");
return ( DENY, "authflat - missing password" );
}
my ( $pw_name, $pw_domain ) = split '@', lc($user);
unless ( defined $pw_domain ) {
$self->log(LOGINFO, "fail: missing domain");
return DECLINED;
}
my ($auth_line) = grep {/^$pw_name\@$pw_domain:/} $self->qp->config('flat_auth_pw');
if ( ! defined $auth_line) {
$self->log(LOGINFO, "fail: no such user: $user");
return DECLINED;
}
my ($auth_user, $auth_pass) = split(/:/, $auth_line, 2);
# at this point we can assume the user name matched
return Qpsmtpd::Auth::validate_password( $self,
src_clear => $auth_pass,
src_crypt => undef,
attempt_clear => $passClear,
attempt_hash => $passHash,
method => $method,
ticket => $ticket,
deny => DENY,
);
}