diff options
Diffstat (limited to 'inc/auth.php')
-rw-r--r-- | inc/auth.php | 167 |
1 files changed, 101 insertions, 66 deletions
diff --git a/inc/auth.php b/inc/auth.php index 9164522bf..6e3b543de 100644 --- a/inc/auth.php +++ b/inc/auth.php @@ -846,6 +846,7 @@ function isvalidemail($email){ * The following methods are understood: * * smd5 - Salted MD5 hashing + * apr1 - Apache salted MD5 hashing * md5 - Simple MD5 hashing * sha1 - SHA1 hashing * ssha - Salted SHA1 hashing @@ -856,44 +857,75 @@ function isvalidemail($email){ * @author Andreas Gohr <andi@splitbrain.org> * @return string The crypted password */ -function auth_cryptPassword($clear,$method='',$salt=''){ - global $conf; - if(empty($method)) $method = $conf['passcrypt']; - - //prepare a salt - if(empty($salt)) $salt = md5(uniqid(rand(), true)); - - switch(strtolower($method)){ - case 'smd5': - return crypt($clear,'$1$'.substr($salt,0,8).'$'); - case 'md5': - return md5($clear); - case 'sha1': - return sha1($clear); - case 'ssha': - $salt=substr($salt,0,4); - return '{SSHA}'.base64_encode(pack("H*", sha1($clear.$salt)).$salt); - case 'crypt': - return crypt($clear,substr($salt,0,2)); - case 'mysql': - //from http://www.php.net/mysql comment by <soren at byu dot edu> - $nr=0x50305735; - $nr2=0x12345671; - $add=7; - $charArr = preg_split("//", $clear); - foreach ($charArr as $char) { - if (($char == '') || ($char == ' ') || ($char == '\t')) continue; - $charVal = ord($char); - $nr ^= ((($nr & 63) + $add) * $charVal) + ($nr << 8); - $nr2 += ($nr2 << 8) ^ $nr; - $add += $charVal; - } - return sprintf("%08x%08x", ($nr & 0x7fffffff), ($nr2 & 0x7fffffff)); - case 'my411': - return '*'.sha1(pack("H*", sha1($clear))); - default: - msg("Unsupported crypt method $method",-1); - } +function auth_cryptPassword($clear,$method='',$salt=null){ + global $conf; + if(empty($method)) $method = $conf['passcrypt']; + + //prepare a salt + if(is_null($salt)) $salt = md5(uniqid(rand(), true)); + + switch(strtolower($method)){ + case 'smd5': + if(defined('CRYPT_MD5')) return crypt($clear,'$1$'.substr($salt,0,8).'$'); + // when crypt can't handle SMD5, falls through to pure PHP implementation + $magic = '1'; + case 'apr1': + //from http://de.php.net/manual/en/function.crypt.php#73619 comment by <mikey_nich at hotmail dot com> + if(!$magic) $magic = 'apr1'; + $salt = substr($salt,0,8); + $len = strlen($clear); + $text = $clear.'$'.$magic.'$'.$salt; + $bin = pack("H32", md5($clear.$salt.$clear)); + for($i = $len; $i > 0; $i -= 16) { $text .= substr($bin, 0, min(16, $i)); } + for($i = $len; $i > 0; $i >>= 1) { $text .= ($i & 1) ? chr(0) : $clear{0}; } + $bin = pack("H32", md5($text)); + for($i = 0; $i < 1000; $i++) { + $new = ($i & 1) ? $clear : $bin; + if ($i % 3) $new .= $salt; + if ($i % 7) $new .= $clear; + $new .= ($i & 1) ? $bin : $clear; + $bin = pack("H32", md5($new)); + } + $tmp = ''; + for ($i = 0; $i < 5; $i++) { + $k = $i + 6; + $j = $i + 12; + if ($j == 16) $j = 5; + $tmp = $bin[$i].$bin[$k].$bin[$j].$tmp; + } + $tmp = chr(0).chr(0).$bin[11].$tmp; + $tmp = strtr(strrev(substr(base64_encode($tmp), 2)), + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + return '$'.$magic.'$'.$salt.'$'.$tmp; + case 'md5': + return md5($clear); + case 'sha1': + return sha1($clear); + case 'ssha': + $salt=substr($salt,0,4); + return '{SSHA}'.base64_encode(pack("H*", sha1($clear.$salt)).$salt); + case 'crypt': + return crypt($clear,substr($salt,0,2)); + case 'mysql': + //from http://www.php.net/mysql comment by <soren at byu dot edu> + $nr=0x50305735; + $nr2=0x12345671; + $add=7; + $charArr = preg_split("//", $clear); + foreach ($charArr as $char) { + if (($char == '') || ($char == ' ') || ($char == '\t')) continue; + $charVal = ord($char); + $nr ^= ((($nr & 63) + $add) * $charVal) + ($nr << 8); + $nr2 += ($nr2 << 8) ^ $nr; + $add += $charVal; + } + return sprintf("%08x%08x", ($nr & 0x7fffffff), ($nr2 & 0x7fffffff)); + case 'my411': + return '*'.sha1(pack("H*", sha1($clear))); + default: + msg("Unsupported crypt method $method",-1); + } } /** @@ -907,35 +939,38 @@ function auth_cryptPassword($clear,$method='',$salt=''){ * @return bool */ function auth_verifyPassword($clear,$crypt){ - $method=''; - $salt=''; - - //determine the used method and salt - $len = strlen($crypt); - if(substr($crypt,0,3) == '$1$'){ - $method = 'smd5'; - $salt = substr($crypt,3,8); - }elseif(substr($crypt,0,6) == '{SSHA}'){ - $method = 'ssha'; - $salt = substr(base64_decode(substr($crypt, 6)),20); - }elseif($len == 32){ - $method = 'md5'; - }elseif($len == 40){ - $method = 'sha1'; - }elseif($len == 16){ - $method = 'mysql'; - }elseif($len == 41 && $crypt[0] == '*'){ - $method = 'my411'; - }else{ - $method = 'crypt'; - $salt = substr($crypt,0,2); - } + $method=''; + $salt=''; + + //determine the used method and salt + $len = strlen($crypt); + if(preg_match('/^\$1\$([^\$]{0,8})\$/',$crypt,$m)){ + $method = 'smd5'; + $salt = $m[1]; + }elseif(preg_match('/^\$apr1\$([^\$]{0,8})\$/',$crypt,$m)){ + $method = 'apr1'; + $salt = $m[1]; + }elseif(substr($crypt,0,6) == '{SSHA}'){ + $method = 'ssha'; + $salt = substr(base64_decode(substr($crypt, 6)),20); + }elseif($len == 32){ + $method = 'md5'; + }elseif($len == 40){ + $method = 'sha1'; + }elseif($len == 16){ + $method = 'mysql'; + }elseif($len == 41 && $crypt[0] == '*'){ + $method = 'my411'; + }else{ + $method = 'crypt'; + $salt = substr($crypt,0,2); + } - //crypt and compare - if(auth_cryptPassword($clear,$method,$salt) === $crypt){ - return true; - } - return false; + //crypt and compare + if(auth_cryptPassword($clear,$method,$salt) === $crypt){ + return true; + } + return false; } //Setup VIM: ex: et ts=2 enc=utf-8 : |