Skip to content

Instantly share code, notes, and snippets.

@mizzy
Created March 9, 2009 08:46
Show Gist options
  • Save mizzy/76168 to your computer and use it in GitHub Desktop.
Save mizzy/76168 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl -w
use strict;
sub register {
my ( $self, $qp ) = @_;
$self->register_hook("connect", "connect");
$self->register_hook("auth-plain", "authsql" );
$self->register_hook("auth-login", "authsql" );
$self->register_hook("auth-cram-md5", "authsql");
}
sub connect {
my $self = shift;
warn 'connect auth_mysql';
delete $self->{_qp}->{_auth};
}
sub authsql {
use DBI;
use Qpsmtpd::Constants;
use Digest::HMAC_MD5 qw( hmac_md5_hex );
use Digest::MD5 qw( md5_hex );
# $DB::single = 1;
my $connect = "dbi:mysql:dbname=postfix";
my $dbuser = "postfix";
my $dbpasswd = "postfix";
my $dbh = DBI->connect( $connect, $dbuser, $dbpasswd );
$dbh->{ShowErrorStatement} = 1;
my ( $self, $transaction, $method, $user, $passClear, $passHash, $ticket ) =
@_;
$self->log(LOGINFO,
"Authentication to vpopmail via mysql: $user");
my $sth = $dbh->prepare(<<SQL);
select *
from users
where mail = ?
SQL
$sth->execute( $user );
my $passwd_hash = $sth->fetchrow_hashref;
$sth->finish;
$dbh->disconnect;
# if vpopmail was not built with '--enable-clear-passwd=y'
# then pw_clear_passwd may not even exist
my $clear_password = exists $passwd_hash->{'clear_password'}
? $passwd_hash->{'clear_password'}
: undef;
my $md5_password = $passwd_hash->{'md5_password'}; # this is always present
if ( # clear_passwd isn't defined so we cannot support CRAM-MD5
( $method =~ /CRAM-MD5/i and not defined $clear_password )
or
# user doesn't exist in this domain
( not defined $md5_password )
) {
return ( DECLINED, "authsql/$method" );
}
# at this point we can assume the user name matched
if (
( defined $passClear and
(
($clear_password eq $passClear)
or ($md5_password eq md5_hex( $passClear ) )
)
)
or ( defined $passHash
and $passHash eq hmac_md5_hex( $ticket, $clear_password ) )
)
{
return ( OK, "authsql/$method" );
}
else {
return ( DENY, "authsql/$method - wrong password" );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment