added auth_checkpassword plugin
New and improved! With POD! (because JP said so: http://www.nntp.perl.org/group/perl.qpsmtpd/2005/06/msg3145.html) Includes usage notes and a perl script useful for diagnosing a checkpassword program. Signed-off-by: Robert <rspier@pobox.com>
This commit is contained in:
parent
3939c7bc51
commit
fbbf43ad15
1
MANIFEST
1
MANIFEST
@ -62,6 +62,7 @@ plugins/async/queue/smtp-forward
|
||||
plugins/async/require_resolvable_fromhost
|
||||
plugins/async/rhsbl
|
||||
plugins/async/uribl
|
||||
plugins/auth/auth_checkpassword
|
||||
plugins/auth/auth_cvm_unix_local
|
||||
plugins/auth/auth_flat_file
|
||||
plugins/auth/auth_ldap_bind
|
||||
|
145
plugins/auth/auth_checkpassword
Normal file
145
plugins/auth/auth_checkpassword
Normal file
@ -0,0 +1,145 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
=head1 NAME
|
||||
|
||||
auth_checkpassword - Authenticate against a DJB style checkpassword program
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This plugin authenticates users against a DJB style checkpassword
|
||||
program. Unlike previous checkpassword implementations, this plugin
|
||||
expects qpsmtpd to be running as the qpsmtpd user. Privilege
|
||||
escalation can be attained by running the checkpassword binary setuid
|
||||
or with sudo.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
Configure the path to your checkpassword binary:
|
||||
|
||||
echo "/usr/local/vpopmail/bin/vchkpw /usr/bin/true" > ~qpsmtpd/config/smtpauth-checkpassword
|
||||
|
||||
vchkpw is the checkpassword program provided by vpopmail. Substitute
|
||||
your own checkpassword app as appropriate.
|
||||
|
||||
If you are using vchkpw and this plugin is being executed by a user ID
|
||||
other than 89 or 0 (as is the default), and the vchkpw binary is not
|
||||
setuid (as is the default), this plugin will automatically prepend the
|
||||
vchkpw command with sudo. If that is the case, you must configure sudo
|
||||
by adding these two lines to your sudoers file:
|
||||
|
||||
Defaults:qpsmtpd closefrom_override
|
||||
qpsmtpd ALL = (ALL) NOPASSWD: /usr/local/vpopmail/bin/vchkpw
|
||||
|
||||
The closefrom_override option is necessary because, by default, sudo
|
||||
appropriates the first 3 file descriptors. Those descriptors are
|
||||
necessary to communicate with the checkpassword program. If you run
|
||||
qpsmtpd as some other user, adjust the sudo lines approriately.
|
||||
|
||||
Using sudo is preferable to enabling setuid on the vchkpw binary. If
|
||||
you reinstall vpopmail and the setuid bit is lost, this plugin will be
|
||||
broken.
|
||||
|
||||
=head1 DIAGNOSTICS
|
||||
|
||||
Is the path in the config/smtpauth-checkpassword correct?
|
||||
|
||||
Is the path to true in config/smtpauth-checkpassword correct?
|
||||
|
||||
Is qpsmtpd running as the qpsmtpd user? If not, did you adjust the
|
||||
sudo configuration appropriately?
|
||||
|
||||
If you are not using sudo, did you remember to make the vchkpw binary
|
||||
setuid (chmod 4711 ~vpopmail/bin/vchkpw)?
|
||||
|
||||
While writing this plugin, I first wrote myself a little test script,
|
||||
which helped me identify the sudo closefrom_override issue. Here is
|
||||
that script:
|
||||
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
my $sudo = "/usr/local/bin/sudo";
|
||||
$sudo .= " -C4 -u vpopmail";
|
||||
my $vchkpw = "/usr/local/vpopmail/bin/vchkpw";
|
||||
my $true = "/usr/bin/true";
|
||||
|
||||
open(CPW,"|$sudo $vchkpw $true 3<&0");
|
||||
printf(CPW "%s\0%s\0Y123456\0",'user@example.com','pa55word');
|
||||
close(CPW);
|
||||
|
||||
my $status = $?;
|
||||
print "FAIL\n" and exit if ( $status != 0 );
|
||||
print "OK\n";
|
||||
|
||||
Save that script to vchkpw.pl and then run it as the same user that
|
||||
qpsmtpd runs as:
|
||||
|
||||
setuidgid qpsmtpd perl vchkpw.pl
|
||||
|
||||
If you aren't using sudo, then remove $sudo from the open line.
|
||||
|
||||
=head1 ACKNOWLEDGEMENTS
|
||||
|
||||
based upon authcheckpassword by Michael Holzt
|
||||
and adapted by Johan Almqvist 2006-01-18
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Matt Simerson <msimerson@cpan.org>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (c) 2010 Matt Simerson
|
||||
|
||||
This plugin is licensed under the same terms as the qpsmtpd package itself.
|
||||
Please see the LICENSE file included with qpsmtpd for details.
|
||||
|
||||
=cut
|
||||
|
||||
sub register {
|
||||
my ($self, $qp) = @_;
|
||||
|
||||
$self->register_hook("auth-plain", "auth_checkpassword");
|
||||
$self->register_hook("auth-login", "auth_checkpassword");
|
||||
}
|
||||
|
||||
sub auth_checkpassword {
|
||||
my ($self, $transaction, $method, $user, $passClear, $passHash, $ticket) =
|
||||
@_;
|
||||
|
||||
my $command = $self->qp->config("smtpauth-checkpassword")
|
||||
or return (DECLINED);
|
||||
my ($binary, $params) = $command =~ /^(\S+)(.*)$/;
|
||||
|
||||
return (DECLINED) if (!-x $binary);
|
||||
my $sudo = get_sudo($binary);
|
||||
|
||||
open(CPW, "|$sudo $binary $params 3<&0");
|
||||
printf(CPW "%s\0%s\0Y123456\0", $user, $passClear);
|
||||
close(CPW);
|
||||
|
||||
my $status = $?;
|
||||
|
||||
return (DECLINED) if ($status != 0);
|
||||
|
||||
$self->connection->notes('authuser', $user);
|
||||
return (OK, "auth_checkpassword");
|
||||
}
|
||||
|
||||
sub get_sudo {
|
||||
my $binary = shift;
|
||||
|
||||
return '' if $> == 0; # running as root
|
||||
return '' if $> == 89 && $binary =~ /vchkpw/; # running as vpopmail
|
||||
|
||||
my $mode = (stat($binary))[2];
|
||||
$mode = sprintf "%lo", $mode & 07777;
|
||||
return '' if $mode eq '4711'; # $binary is setuid
|
||||
|
||||
my $sudo = `which sudo` || '/usr/local/bin/sudo';
|
||||
return '' if !-x $sudo;
|
||||
$sudo .= ' -C4'; # prevent sudo from clobber file descriptor 3
|
||||
|
||||
return "$sudo -u vpopmail" if $binary =~ /vchkpw/;
|
||||
return $sudo;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user