NAME
Haver::Spec::Auth - The authentication extension.
DESCRIPTION
This document describes the authentication extension to Haver::Spec.
BEGIN YOUR FEAR
The auth extension provides a login authentication system. A related extension, Haver::Spec::Reg provides a way of registering under this auth system.
The client must advertize it understands the auth extension. It does this by mentioning 'auth' in the second arg of C:HAVER, like so:
C: HAVER CoolClient/1.10 auth
If the client does not advertize, the server will assume it does not understand any AUTH: commands. If the client requests a name that is registered and does not advertize it supports auth, the server will fail it with auth.impossible. Otherwise:
C: IDENT vadim
S: AUTH:TYPES AUTH:BASIC GPG:AUTH
C: AUTH:TYPE AUTH:BASIC
S: AUTH:BASIC $nonce sha1 md5
C: AUTH:BASIC $digest $response
If the authentication is successful, the server will send HELLO as per normal. If not, the server will fail the client with auth.fail.
$digest is one of the parameters after the first parameter of S:AUTH:BASIC. $response is the result of hashing the concatenation of $nonce and the user's passcode using the hash function named in $digest. The $response is always base64 encoded.
See also "PASSCODES" for instructions on creating a passcode.
Thus, $response can be generated with the following perl function:
use Digest::MD5 'md5_base64';
use Digest::SHA1 'sha1_base64';
sub response {
my ($digest, $nonce, $passcode) = @_;
if ($digest eq 'sha1') {
return sha1_base64($nonce . $passcode);
} elsif ($digest eq 'md5') {
return md5_base64($nonce . $passcode);
}
}
YOU FAIL
This extension introduces a few new errors.
auth.impossible
Raised when the client does not understand the auth extension. Always associated with IDENT.
auth.fail
Raised when authentication did not work because the passcode or whatever was wrong. This happens when the client understands authentication and after AUTH:* commands have been sent.
unknown.digest
Raised when the hashing (digest) algorithm requested by the client is unknown to the server.
PASSCODES
First, the problem: The server admin can't be trusted knowing the user's password. They might use it else where, for example. So the first idea that comes to mind is to hash it. Bingo, the server admin does not know the password now. But the server admin knows the hash! So they can still login to other haver servers that the user has accounts on.
So, we hash the concatenation of the user's password and the hostname of the server. Now the hash is specific to the server, the admin can't figure out the hash for the user on other servers.
But, the admin, being very evil, can find out what users have the same password. To prevent this, we hash the user's password, the user's name, and the hostname of the server.
This is something the client does, of course. It is very important the clients hash things in the same way. Thus all clients must use the sha1() hash function, and base64 encode its results.
Also, both the hostname and username need to be lower-cased, as both are case insensitive.
Thus, to generate passcodes in perl, the following function is used.
use Digest::SHA1 'sha1_base64';
sub passcode {
my ($user, $password, $host) = @_;
sha1_base64($password . lc("$host$user"));
}
AUTHOR
Dylan William Hardison, <dylan@haverdev.org>, with many thanks to muffin and bdonlan. Lots of ideas floated around, I just cherry-picked them to create this scheme.
SEE ALSO
COPYRIGHT and LICENSE
Copyright (C) 2005 by Dylan William Hardison. All Rights Reserved.
This module is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This module is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this module; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA