summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/auth.php167
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 :