Regarding the specific implementation:
http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/User.php?r1…
comparePasswords() will treat future methods as Old-Style. I think it
would be preferable to determine as old-style only if $type[0] != ':'
and let hooks be able to handle unknown cases failing to "don't know
this codification" if noone is able to detect it.
I don't like that comparePasswords and crypt are doing the same thing
(knowing the intrinsecs of the hashing formats).
Same with oldCrypt, which should be a special case of crypt.
Expressed into code, it could be something like this:
static function cryptPassword( $password, $salt = false, $method = null,
$showMethod = true) {
$hash = "";
if ($method === null)
$efectiveMethod = $wgPasswordSalt ? "B" : "A";
else
$efectiveMethod = $method;
switch ($efectiveMethod) {
case "A":
$salt = false;
$hash = md5( $password );
break;
case "B":
if ( $salt === false )
$salt = substr( wfGenerateToken(), 0, 8 );
$hash = md5( $salt.'-'.md5( $password ) );
break;
default: if (wfRunHooks('cryptPassword', array(&$hash, $password,
$salt, $method)))
throw new MWException("I have no idea how to handle password
method $efectiveMethod!");
}
if ($showMethod) {
if ($salt !== false)
$hash = "$salt:$hash";
$hash = ":$efectiveMethod:$hash";
}
return $hash;
}
static function comparePasswords( $hash, $password, $userId = false ) {
$A = explode( ':', $hash, 4 );
if (count(A) < 4)
return cryptPassword($password, $userId, null, false) == $A[0];
else
return cryptPassword($password, $A[2], $A[1]) == $A[3];
}
Opinions?