2004-06-29 23:45:35 +02:00
|
|
|
#!/usr/bin/perl -w
|
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
2004-06-30 11:21:40 +02:00
|
|
|
auth_vpopmail_sql - Authenticate to vpopmail via MySQL
|
2004-06-29 23:45:35 +02:00
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
|
|
|
|
This plugin authenticates vpopmail users directly against a standard
|
|
|
|
vpopmail MySQL database. It makes the not-unreasonable assumption that
|
|
|
|
both pw_name and pw_domain are lowercase only (qmail doesn't actually care).
|
Changes by jpeacock@cpan.org (John Peacock)
o plugins/check_badmailfromto
- New plugin in the style of check_badmailfrom, which matches a pair
of FROM/TO and makes it seem like the recipient's address no longer
exists (but only from the matching sender's point of view). Useful
for stalkers and other harassment cases.
o plugins/dns_whitelist_soft
- New plugin to provide a DNS-based whitelist (good for distributed
sites).
o various files
- Replaced tab character with 8 spaces and adjusted line breaks for
better readability.
Changes by mct@toren.net (Michael C. Toren)
o lib/Qpsmtpd/SMTP.pm
- Assumes a MAIL FROM value of "<#@[]>" (utilized by qmail to
indicate a null sender when generating a doublebounce message)
is equivalent to "<>". Previously qpsmtpd complained that the
value could not be parsed.
- Adds LOGIN to the default list of supported auth mechanisms.
The documentation in Auth.pm indicated that auth-login was not
currently supported due to lack of functionality, however I can
confirm that LOGIN appears to work fine as tested by using msmtp
(http://msmtp.sourceforge.net/). Are there any indications that
LOGIN support is actually broken in the current implementation?
- Removes the "X-Qpsmtpd-Auth: True" header appended when a message
has been sent by an authenticated user. One problem with such a
header is that it's impossible to say which SMTP hop added it,
and it provides no information which could be used to backtrack
the transaction. I grepped through my mail archives a bit
looking for how other MTAs handled the problem, and decided it
would be best to place this information in the Received: header:
Received: from remotehost (HELO remotehost) (192.168.42.42)
(smtp-auth username foo, mechanism cram-md5)
by mail.netisland.net (qpsmtpd/0.28) with ESMTP; <date>
o lib/Qpsmtpd/Auth.pm:
- Documentation update for the arguments passed to an auth
handler; previously the $mechanism argument was not mentioned,
which threw off the argument offsets.
- Documentation update for auth-login removing the warning
that auth-login is not currently supported due to lack of
functionality.
- Fix to execute a generic auth hook when a more specific
auth-$mechanism hook does not exist. (Previously posted
to the list last week.)
- Upon authentication, sets $session->{_auth_user} and
$session->{_auth_mechanism} so that SMTP.pm can include them
in the Received: header.
o plugins/queue/qmail-queue
- Added a timestamp and the qmail-queue qp identifier to the
"Queued!" 250 message, for compatibility with qmail-smtpd, which
can be very useful for tracking message delivery from machine to
machine. For example, the new 250 message might be:
250 Queued! 1105927468 qp 3210 <1105927457@netisland.net>
qmail-smtpd returns:
250 ok 1106546213 qp 7129
Additionally, for consistency angle brackets are placed around
the Message-ID displayed in the 250 if they were missing in the
message header.
o plugins/check_badmailfrom:
- Changed the error message from "Mail from $bad not accepted
here" to "sorry, your envelope sender is in my badmailfrom
list", for compatibility with qmail-smtpd. I didn't see any
reason to share with the sender the value of $bad, especially
for situations where the sender was rejected resulting from a
wildcard.
o plugins/check_earlytalker:
o plugins/require_resolvable_fromhost:
- No longer checks for earlytalkers or resolvable senders if the
connection note "whitelistclient" is set, which is nice for
helping backup MX hosts empty their queue faster.
o plugins/count_unrecognized_commands:
- Return code changed from DENY_DISCONNECT, which isn't valid in
an unrecognized_command hook, to DENY, which in this context
drops the connection anyway. (Previously posted to the list
last week.)
git-svn-id: https://svn.perl.org/qpsmtpd/trunk@356 958fd67b-6ff1-0310-b445-bb7760255be9
2005-01-28 04:30:50 +01:00
|
|
|
If you are using CRAM-MD5, it also requires that vpopmail be built with the
|
|
|
|
recommended '--enable-clear-passwd=y' option, because there is no way
|
|
|
|
to compare the crypted password.
|
2004-06-29 23:45:35 +02:00
|
|
|
|
|
|
|
=head1 CONFIGURATION
|
|
|
|
|
|
|
|
Decide which authentication methods you are willing to support and uncomment
|
|
|
|
the lines in the register() sub. See the POD for Qspmtpd::Auth for more
|
|
|
|
details on the ramifications of supporting various authentication methods.
|
|
|
|
Then, change the database information at the top of the authsql() sub so that
|
|
|
|
the module can access the database. This can be a read-only account since
|
|
|
|
the plugin does not update the last accessed time (yet, see below).
|
|
|
|
|
|
|
|
The remote user must login with a fully qualified e-mail address (i.e. both
|
|
|
|
account name and domain), even if they don't normally need to. This is
|
|
|
|
because the vpopmail table has a unique index on pw_name/pw_domain, and this
|
|
|
|
module requires that only a single record be returned from the database.
|
|
|
|
|
|
|
|
=head1 FUTURE DIRECTION
|
|
|
|
|
|
|
|
The default MySQL configuration for vpopmail includes a table to log access,
|
|
|
|
lastauth, which could conceivably be updated upon sucessful authentication.
|
|
|
|
The addition of this feature is left as an exercise for someone who cares. ;)
|
|
|
|
|
|
|
|
=head1 AUTHOR
|
|
|
|
|
|
|
|
John Peacock <jpeacock@cpan.org>
|
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE
|
|
|
|
|
|
|
|
Copyright (c) 2004 John Peacock
|
|
|
|
|
|
|
|
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 ) = @_;
|
|
|
|
|
Changes by jpeacock@cpan.org (John Peacock)
o plugins/check_badmailfromto
- New plugin in the style of check_badmailfrom, which matches a pair
of FROM/TO and makes it seem like the recipient's address no longer
exists (but only from the matching sender's point of view). Useful
for stalkers and other harassment cases.
o plugins/dns_whitelist_soft
- New plugin to provide a DNS-based whitelist (good for distributed
sites).
o various files
- Replaced tab character with 8 spaces and adjusted line breaks for
better readability.
Changes by mct@toren.net (Michael C. Toren)
o lib/Qpsmtpd/SMTP.pm
- Assumes a MAIL FROM value of "<#@[]>" (utilized by qmail to
indicate a null sender when generating a doublebounce message)
is equivalent to "<>". Previously qpsmtpd complained that the
value could not be parsed.
- Adds LOGIN to the default list of supported auth mechanisms.
The documentation in Auth.pm indicated that auth-login was not
currently supported due to lack of functionality, however I can
confirm that LOGIN appears to work fine as tested by using msmtp
(http://msmtp.sourceforge.net/). Are there any indications that
LOGIN support is actually broken in the current implementation?
- Removes the "X-Qpsmtpd-Auth: True" header appended when a message
has been sent by an authenticated user. One problem with such a
header is that it's impossible to say which SMTP hop added it,
and it provides no information which could be used to backtrack
the transaction. I grepped through my mail archives a bit
looking for how other MTAs handled the problem, and decided it
would be best to place this information in the Received: header:
Received: from remotehost (HELO remotehost) (192.168.42.42)
(smtp-auth username foo, mechanism cram-md5)
by mail.netisland.net (qpsmtpd/0.28) with ESMTP; <date>
o lib/Qpsmtpd/Auth.pm:
- Documentation update for the arguments passed to an auth
handler; previously the $mechanism argument was not mentioned,
which threw off the argument offsets.
- Documentation update for auth-login removing the warning
that auth-login is not currently supported due to lack of
functionality.
- Fix to execute a generic auth hook when a more specific
auth-$mechanism hook does not exist. (Previously posted
to the list last week.)
- Upon authentication, sets $session->{_auth_user} and
$session->{_auth_mechanism} so that SMTP.pm can include them
in the Received: header.
o plugins/queue/qmail-queue
- Added a timestamp and the qmail-queue qp identifier to the
"Queued!" 250 message, for compatibility with qmail-smtpd, which
can be very useful for tracking message delivery from machine to
machine. For example, the new 250 message might be:
250 Queued! 1105927468 qp 3210 <1105927457@netisland.net>
qmail-smtpd returns:
250 ok 1106546213 qp 7129
Additionally, for consistency angle brackets are placed around
the Message-ID displayed in the 250 if they were missing in the
message header.
o plugins/check_badmailfrom:
- Changed the error message from "Mail from $bad not accepted
here" to "sorry, your envelope sender is in my badmailfrom
list", for compatibility with qmail-smtpd. I didn't see any
reason to share with the sender the value of $bad, especially
for situations where the sender was rejected resulting from a
wildcard.
o plugins/check_earlytalker:
o plugins/require_resolvable_fromhost:
- No longer checks for earlytalkers or resolvable senders if the
connection note "whitelistclient" is set, which is nice for
helping backup MX hosts empty their queue faster.
o plugins/count_unrecognized_commands:
- Return code changed from DENY_DISCONNECT, which isn't valid in
an unrecognized_command hook, to DENY, which in this context
drops the connection anyway. (Previously posted to the list
last week.)
git-svn-id: https://svn.perl.org/qpsmtpd/trunk@356 958fd67b-6ff1-0310-b445-bb7760255be9
2005-01-28 04:30:50 +01:00
|
|
|
$self->register_hook("auth-plain", "authsql" );
|
|
|
|
$self->register_hook("auth-login", "authsql" );
|
|
|
|
$self->register_hook("auth-cram-md5", "authsql");
|
2004-06-29 23:45:35 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
sub authsql {
|
|
|
|
use DBI;
|
|
|
|
use Qpsmtpd::Constants;
|
|
|
|
use Digest::HMAC_MD5 qw(hmac_md5_hex);
|
2006-01-27 22:13:43 +01:00
|
|
|
my ( $self, $transaction, $method, $user, $passClear, $passHash, $ticket )
|
|
|
|
= @_;
|
2004-06-29 23:45:35 +02:00
|
|
|
# $DB::single = 1;
|
|
|
|
|
|
|
|
my $connect = "dbi:mysql:dbname=vpopmail";
|
|
|
|
my $dbuser = "vpopmailuser";
|
|
|
|
my $dbpasswd = "**********";
|
|
|
|
|
2006-01-27 18:16:13 +01:00
|
|
|
my $dbh = DBI->connect( $connect, $dbuser, $dbpasswd,
|
|
|
|
{ PrintError => 0, } )
|
2006-01-27 22:13:43 +01:00
|
|
|
or (
|
|
|
|
$self->log(LOGERROR, $DBI::errstr)
|
|
|
|
and return DECLINED
|
|
|
|
);
|
2004-06-29 23:45:35 +02:00
|
|
|
|
|
|
|
my ( $pw_name, $pw_domain ) = split "@", lc($user);
|
|
|
|
|
|
|
|
unless ( defined $pw_domain ) {
|
|
|
|
return DECLINED;
|
|
|
|
}
|
|
|
|
|
2004-09-23 20:54:58 +02:00
|
|
|
$self->log(LOGINFO,
|
|
|
|
"Authentication to vpopmail via mysql: $pw_name\@$pw_domain");
|
|
|
|
|
2004-06-29 23:45:35 +02:00
|
|
|
my $sth = $dbh->prepare(<<SQL);
|
2005-01-30 18:24:49 +01:00
|
|
|
select *
|
2004-06-29 23:45:35 +02:00
|
|
|
from vpopmail
|
|
|
|
where pw_name = ? and pw_domain = ?
|
|
|
|
SQL
|
|
|
|
|
|
|
|
$sth->execute( $pw_name, $pw_domain );
|
|
|
|
|
2005-01-30 18:24:49 +01:00
|
|
|
my $passwd_hash = $sth->fetchrow_hashref;
|
2004-06-29 23:45:35 +02:00
|
|
|
|
|
|
|
$sth->finish;
|
|
|
|
$dbh->disconnect;
|
|
|
|
|
2005-02-10 15:33:13 +01:00
|
|
|
# if vpopmail was not built with '--enable-clear-passwd=y'
|
|
|
|
# then pw_clear_passwd may not even exist
|
|
|
|
my $pw_clear_passwd = exists $passwd_hash->{'pw_clear_passwd'}
|
|
|
|
? $passwd_hash->{'pw_clear_passwd'}
|
|
|
|
: undef;
|
|
|
|
my $pw_passwd = $passwd_hash->{'pw_passwd'}; # this is always present
|
2005-01-30 18:24:49 +01:00
|
|
|
|
Changes by jpeacock@cpan.org (John Peacock)
o plugins/check_badmailfromto
- New plugin in the style of check_badmailfrom, which matches a pair
of FROM/TO and makes it seem like the recipient's address no longer
exists (but only from the matching sender's point of view). Useful
for stalkers and other harassment cases.
o plugins/dns_whitelist_soft
- New plugin to provide a DNS-based whitelist (good for distributed
sites).
o various files
- Replaced tab character with 8 spaces and adjusted line breaks for
better readability.
Changes by mct@toren.net (Michael C. Toren)
o lib/Qpsmtpd/SMTP.pm
- Assumes a MAIL FROM value of "<#@[]>" (utilized by qmail to
indicate a null sender when generating a doublebounce message)
is equivalent to "<>". Previously qpsmtpd complained that the
value could not be parsed.
- Adds LOGIN to the default list of supported auth mechanisms.
The documentation in Auth.pm indicated that auth-login was not
currently supported due to lack of functionality, however I can
confirm that LOGIN appears to work fine as tested by using msmtp
(http://msmtp.sourceforge.net/). Are there any indications that
LOGIN support is actually broken in the current implementation?
- Removes the "X-Qpsmtpd-Auth: True" header appended when a message
has been sent by an authenticated user. One problem with such a
header is that it's impossible to say which SMTP hop added it,
and it provides no information which could be used to backtrack
the transaction. I grepped through my mail archives a bit
looking for how other MTAs handled the problem, and decided it
would be best to place this information in the Received: header:
Received: from remotehost (HELO remotehost) (192.168.42.42)
(smtp-auth username foo, mechanism cram-md5)
by mail.netisland.net (qpsmtpd/0.28) with ESMTP; <date>
o lib/Qpsmtpd/Auth.pm:
- Documentation update for the arguments passed to an auth
handler; previously the $mechanism argument was not mentioned,
which threw off the argument offsets.
- Documentation update for auth-login removing the warning
that auth-login is not currently supported due to lack of
functionality.
- Fix to execute a generic auth hook when a more specific
auth-$mechanism hook does not exist. (Previously posted
to the list last week.)
- Upon authentication, sets $session->{_auth_user} and
$session->{_auth_mechanism} so that SMTP.pm can include them
in the Received: header.
o plugins/queue/qmail-queue
- Added a timestamp and the qmail-queue qp identifier to the
"Queued!" 250 message, for compatibility with qmail-smtpd, which
can be very useful for tracking message delivery from machine to
machine. For example, the new 250 message might be:
250 Queued! 1105927468 qp 3210 <1105927457@netisland.net>
qmail-smtpd returns:
250 ok 1106546213 qp 7129
Additionally, for consistency angle brackets are placed around
the Message-ID displayed in the 250 if they were missing in the
message header.
o plugins/check_badmailfrom:
- Changed the error message from "Mail from $bad not accepted
here" to "sorry, your envelope sender is in my badmailfrom
list", for compatibility with qmail-smtpd. I didn't see any
reason to share with the sender the value of $bad, especially
for situations where the sender was rejected resulting from a
wildcard.
o plugins/check_earlytalker:
o plugins/require_resolvable_fromhost:
- No longer checks for earlytalkers or resolvable senders if the
connection note "whitelistclient" is set, which is nice for
helping backup MX hosts empty their queue faster.
o plugins/count_unrecognized_commands:
- Return code changed from DENY_DISCONNECT, which isn't valid in
an unrecognized_command hook, to DENY, which in this context
drops the connection anyway. (Previously posted to the list
last week.)
git-svn-id: https://svn.perl.org/qpsmtpd/trunk@356 958fd67b-6ff1-0310-b445-bb7760255be9
2005-01-28 04:30:50 +01:00
|
|
|
if ( # clear_passwd isn't defined so we cannot support CRAM-MD5
|
|
|
|
( $method =~ /CRAM-MD5/i and not defined $pw_clear_passwd )
|
|
|
|
or
|
|
|
|
# user doesn't exist in this domain
|
|
|
|
( not defined $pw_passwd )
|
|
|
|
) {
|
2004-06-29 23:45:35 +02:00
|
|
|
return ( DECLINED, "authsql/$method" );
|
|
|
|
}
|
|
|
|
|
|
|
|
# at this point we can assume the user name matched
|
|
|
|
if (
|
Changes by jpeacock@cpan.org (John Peacock)
o plugins/check_badmailfromto
- New plugin in the style of check_badmailfrom, which matches a pair
of FROM/TO and makes it seem like the recipient's address no longer
exists (but only from the matching sender's point of view). Useful
for stalkers and other harassment cases.
o plugins/dns_whitelist_soft
- New plugin to provide a DNS-based whitelist (good for distributed
sites).
o various files
- Replaced tab character with 8 spaces and adjusted line breaks for
better readability.
Changes by mct@toren.net (Michael C. Toren)
o lib/Qpsmtpd/SMTP.pm
- Assumes a MAIL FROM value of "<#@[]>" (utilized by qmail to
indicate a null sender when generating a doublebounce message)
is equivalent to "<>". Previously qpsmtpd complained that the
value could not be parsed.
- Adds LOGIN to the default list of supported auth mechanisms.
The documentation in Auth.pm indicated that auth-login was not
currently supported due to lack of functionality, however I can
confirm that LOGIN appears to work fine as tested by using msmtp
(http://msmtp.sourceforge.net/). Are there any indications that
LOGIN support is actually broken in the current implementation?
- Removes the "X-Qpsmtpd-Auth: True" header appended when a message
has been sent by an authenticated user. One problem with such a
header is that it's impossible to say which SMTP hop added it,
and it provides no information which could be used to backtrack
the transaction. I grepped through my mail archives a bit
looking for how other MTAs handled the problem, and decided it
would be best to place this information in the Received: header:
Received: from remotehost (HELO remotehost) (192.168.42.42)
(smtp-auth username foo, mechanism cram-md5)
by mail.netisland.net (qpsmtpd/0.28) with ESMTP; <date>
o lib/Qpsmtpd/Auth.pm:
- Documentation update for the arguments passed to an auth
handler; previously the $mechanism argument was not mentioned,
which threw off the argument offsets.
- Documentation update for auth-login removing the warning
that auth-login is not currently supported due to lack of
functionality.
- Fix to execute a generic auth hook when a more specific
auth-$mechanism hook does not exist. (Previously posted
to the list last week.)
- Upon authentication, sets $session->{_auth_user} and
$session->{_auth_mechanism} so that SMTP.pm can include them
in the Received: header.
o plugins/queue/qmail-queue
- Added a timestamp and the qmail-queue qp identifier to the
"Queued!" 250 message, for compatibility with qmail-smtpd, which
can be very useful for tracking message delivery from machine to
machine. For example, the new 250 message might be:
250 Queued! 1105927468 qp 3210 <1105927457@netisland.net>
qmail-smtpd returns:
250 ok 1106546213 qp 7129
Additionally, for consistency angle brackets are placed around
the Message-ID displayed in the 250 if they were missing in the
message header.
o plugins/check_badmailfrom:
- Changed the error message from "Mail from $bad not accepted
here" to "sorry, your envelope sender is in my badmailfrom
list", for compatibility with qmail-smtpd. I didn't see any
reason to share with the sender the value of $bad, especially
for situations where the sender was rejected resulting from a
wildcard.
o plugins/check_earlytalker:
o plugins/require_resolvable_fromhost:
- No longer checks for earlytalkers or resolvable senders if the
connection note "whitelistclient" is set, which is nice for
helping backup MX hosts empty their queue faster.
o plugins/count_unrecognized_commands:
- Return code changed from DENY_DISCONNECT, which isn't valid in
an unrecognized_command hook, to DENY, which in this context
drops the connection anyway. (Previously posted to the list
last week.)
git-svn-id: https://svn.perl.org/qpsmtpd/trunk@356 958fd67b-6ff1-0310-b445-bb7760255be9
2005-01-28 04:30:50 +01:00
|
|
|
( defined $passClear and
|
|
|
|
(
|
|
|
|
($pw_clear_passwd eq $passClear)
|
|
|
|
or ($pw_passwd eq crypt( $passClear, $pw_passwd ) )
|
|
|
|
)
|
|
|
|
)
|
|
|
|
or ( defined $passHash
|
|
|
|
and $passHash eq hmac_md5_hex( $ticket, $pw_clear_passwd ) )
|
2004-06-29 23:45:35 +02:00
|
|
|
)
|
|
|
|
{
|
|
|
|
|
|
|
|
return ( OK, "authsql/$method" );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return ( DENY, "authsql/$method - wrong password" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|