> 3. Client sends one line:
> AUTH LOGIN Passhash\0Username\0Password
Forget this, i was wrong, and qpsmtpd is also wrong (and is also wrong
in AUTH PLAIN).
AUTH LOGIN is not specified by any RFC. However it is used with two
parameters (also called responsed in the nomenclature of SMTP AUTH):
1. Username and 2. Password. The initial (first) reponse to a SMTP
AUTH command can be specified optionally with the SMTP AUTH command
regarding to RFC2554.
So there are only two ways to do AUTH LOGIN:
1.
Client: AUTH LOGIN
Server: "Username:" (in base64)
Client: Username (in base64)
Server: "Password:" (in base64)
Client: Password (in base64)
2.
Client: AUTH LOGIN Username (in base64)
Server: "Password:" (in base64)
Client: Password (in base64)
A syntax with a \0-Byte is nowhere documented. I believe qpsmtpd is
wrong here and the split should be thrown away.
AUTH PLAIN is also wrongly implemented. AUTH PLAIN is specified in
RFC2595. It takes only one response, and the response has the syntax
"Authorization ID\0Authentication ID\0Password". So the first token
is _not_ a password hash as suggested by the qpsmtpd code but the
userid to login as.
This is a bit complicated: The server will check the Authentication
ID (second token) with the password. If the password is correct _and_
the user is allowed to login as the Authorization ID (first token),
the authentication will complete successful. The idea here is, that
one username+password pair might allow to login into different
accounts.
One possible use might be logging in into Subfolders of your
account. Imagine a login with 'user\0user\0pw' vs.
'user/outbox\0user\0pw'. But usually the Authentication ID is equal
to the Authorization ID and can then be left blank. However qpsmtpd
should check this.
I suggest the following modification to Auth.pm to both fix AUTH
LOGIN as well as AUTH PLAIN:
diff -Naur old/Auth.pm new/Auth.pm
--- old/Auth.pm 2006-02-26 13:22:16.000000000 +0100
+++ new/Auth.pm 2006-04-22 00:20:48.000000000 +0200
@@ -230,7 +230,7 @@
# $DB::single = 1;
my ( $session, $mechanism, $prekey ) = @_;
- my ( $user, $passClear, $passHash, $ticket );
+ my ( $user, $passClear, $passHash, $ticket, $loginas );
$mechanism = lc($mechanism);
if ( $mechanism eq "plain" ) {
@@ -238,17 +238,23 @@
$session->respond( 334, "Please continue" );
$prekey= <STDIN>;
}
- ( $passHash, $user, $passClear ) = split /\x0/,
+ ( $loginas, $user, $passClear ) = split /\x0/,
decode_base64($prekey);
+ # Authorization ID might not be different from
+ # Authentication ID
+ if ( $loginas ne '' && $loginas != $user )
+ {
+ $session->respond(535, "Authentication invalid");
+ return DECLINED;
+ }
}
elsif ($mechanism eq "login") {
if ( $prekey ) {
- ($passHash, $user, $passClear) = split /\x0/, decode_base64($prekey);
+ $user = decode_base64($prekey);
}
else {
-
$session->respond(334, e64("Username:"));
$user = decode_base64(<STDIN>);
#warn("Debug: User: '$user'");
@@ -256,15 +262,15 @@
$session->respond(501, "Authentification canceled");
return DECLINED;
}
+ }
- $session->respond(334, e64("Password:"));
- $passClear = <STDIN>;
- $passClear = decode_base64($passClear);
- #warn("Debug: Pass: '$pass'");
- if ($passClear eq '*') {
- $session->respond(501, "Authentification canceled");
- return DECLINED;
- }
+ $session->respond(334, e64("Password:"));
+ $passClear = <STDIN>;
+ $passClear = decode_base64($passClear);
+ #warn("Debug: Pass: '$pass'");
+ if ($passClear eq '*') {
+ $session->respond(501, "Authentification canceled");
+ return DECLINED;
}
}
elsif ( $mechanism eq "cram-md5" ) {
Gruss
Michael
--
It's an insane world, but i'm proud to be a part of it. -- Bill Hicks