summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--_test/cases/inc/auth_password.test.php7
-rw-r--r--inc/auth.php47
2 files changed, 54 insertions, 0 deletions
diff --git a/_test/cases/inc/auth_password.test.php b/_test/cases/inc/auth_password.test.php
index 77ee9eed3..140c7c23e 100644
--- a/_test/cases/inc/auth_password.test.php
+++ b/_test/cases/inc/auth_password.test.php
@@ -16,6 +16,8 @@ class auth_password_test extends UnitTestCase {
'mysql' => '4a1fa3780bd6fd55',
'my411' => '*e5929347e25f82e19e4ebe92f1dc6b6e7c2dbd29',
'kmd5' => 'a579299436d7969791189acadd86fcb716',
+ 'pmd5' => '$P$abcdefgh1RC6Fd32heUzl7EYCG9uGw.',
+ 'hmd5' => '$H$abcdefgh1ZbJodHxmeXVAhEzTG7IAp.',
);
@@ -39,6 +41,11 @@ class auth_password_test extends UnitTestCase {
$this->assertTrue(auth_verifyPassword('foo','$1$$n1rTiFE0nRifwV/43bVon/'));
}
+ function test_verifyPassword_fixedpmd5(){
+ $this->assertTrue(auth_verifyPassword('test12345','$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0'));
+ $this->assertTrue(auth_verifyPassword('test12345','$H$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0'));
+ }
+
}
//Setup VIM: ex: et ts=4 :
diff --git a/inc/auth.php b/inc/auth.php
index 83d1d4159..5cdcec830 100644
--- a/inc/auth.php
+++ b/inc/auth.php
@@ -937,6 +937,8 @@ function act_resendpwd(){
* mysql - MySQL password (old method)
* my411 - MySQL 4.1.1 password
* kmd5 - Salted MD5 hashing as used by UNB
+ * pmd5 - Salted multi iteration MD5 as used by Wordpress
+ * hmd5 - Same as pmd5 but PhpBB3 flavour
*
* @author Andreas Gohr <andi@splitbrain.org>
* @return string The crypted password
@@ -1016,6 +1018,45 @@ function auth_cryptPassword($clear,$method='',$salt=null){
$hash1 = strtolower(md5($key . md5($clear)));
$hash2 = substr($hash1, 0, 16) . $key . substr($hash1, 16);
return $hash2;
+ case 'hmd5':
+ $key = 'H';
+ // hmd5 is exactly the same as pmd5, but uses an H as identifier
+ // PhpBB3 uses it that way, so we just fall through here
+ case 'pmd5':
+ if(!$key) $key = 'P';
+ $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+ $iterc = $salt[0]; // pos 0 of salt is iteration count
+ $iter = strpos($itoa64,$iterc);
+ $iter = 1 << $iter;
+ $salt = substr($salt,1,8);
+
+ // iterate
+ $hash = md5($salt . $clear, true);
+ do {
+ $hash = md5($hash . $clear, true);
+ } while (--$iter);
+
+ // encode
+ $output = '';
+ $count = 16;
+ $i = 0;
+ do {
+ $value = ord($hash[$i++]);
+ $output .= $itoa64[$value & 0x3f];
+ if ($i < $count)
+ $value |= ord($hash[$i]) << 8;
+ $output .= $itoa64[($value >> 6) & 0x3f];
+ if ($i++ >= $count)
+ break;
+ if ($i < $count)
+ $value |= ord($hash[$i]) << 16;
+ $output .= $itoa64[($value >> 12) & 0x3f];
+ if ($i++ >= $count)
+ break;
+ $output .= $itoa64[($value >> 18) & 0x3f];
+ } while ($i < $count);
+
+ return '$'.$key.'$'.$iterc.$salt.$output;
default:
msg("Unsupported crypt method $method",-1);
}
@@ -1043,6 +1084,12 @@ function auth_verifyPassword($clear,$crypt){
}elseif(preg_match('/^\$apr1\$([^\$]{0,8})\$/',$crypt,$m)){
$method = 'apr1';
$salt = $m[1];
+ }elseif(preg_match('/^\$P\$(.{31})$/',$crypt,$m)){
+ $method = 'pmd5';
+ $salt = $m[1];
+ }elseif(preg_match('/^\$H\$(.{31})$/',$crypt,$m)){
+ $method = 'hmd5';
+ $salt = $m[1];
}elseif(substr($crypt,0,6) == '{SSHA}'){
$method = 'ssha';
$salt = substr(base64_decode(substr($crypt, 6)),20);