qpsmtpd Wiki

[[plugins:auth:authcheckpassword]]

You are here: start » plugins » auth » authcheckpassword

Login

You are currently not logged in! Enter your authentication credentials below to log in. You need to have cookies enabled to log in.

Login

You don't have an account yet? Just get one: Register

Forgotten your password? Get a new one: Set new password

Plug-in Summary

Plug-in name: authcheckpassword
Info: An authentication plugin to interface with djb's checkpassword interface
Author: mattsim
Email: Won't say
Compatibility: all
Download: here

authcheckpassword

An SMTP AUTH plug-in to interface with djb's checkpassword interface.

NAME

auth_checkpassword - Authenticate against a DJB style checkpassword program

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.

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.

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:

vchkpw.pl
#!/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.

Plugin Source

auth_checkpassword
#!/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;
}