diff options
Diffstat (limited to 'inc/auth.php')
-rw-r--r-- | inc/auth.php | 190 |
1 files changed, 41 insertions, 149 deletions
diff --git a/inc/auth.php b/inc/auth.php index 834b63ec3..eff984b36 100644 --- a/inc/auth.php +++ b/inc/auth.php @@ -70,6 +70,12 @@ function auth_setup(){ $_REQUEST['http_credentials'] = false; if (!$conf['rememberme']) $_REQUEST['r'] = false; + // handle renamed HTTP_AUTHORIZATION variable (can happen when a fix like + // the one presented at + // http://www.besthostratings.com/articles/http-auth-php-cgi.html is used + // for enabling HTTP authentication with CGI/SuExec) + if(isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) + $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; // streamline HTTP auth credentials (IIS/rewrite -> mod_php) if(isset($_SERVER['HTTP_AUTHORIZATION'])){ list($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']) = @@ -183,7 +189,8 @@ function auth_login($user,$pass,$sticky=false,$silent=false){ if ($auth->checkPass($user,$pass)){ // make logininfo globally available $_SERVER['REMOTE_USER'] = $user; - auth_setCookie($user,PMA_blowfish_encrypt($pass,auth_cookiesalt()),$sticky); + $secret = auth_cookiesalt(!$sticky); //bind non-sticky to session + auth_setCookie($user,PMA_blowfish_encrypt($pass,$secret),$sticky); return true; }else{ //invalid credentials - log off @@ -194,23 +201,26 @@ function auth_login($user,$pass,$sticky=false,$silent=false){ }else{ // read cookie information list($user,$sticky,$pass) = auth_getCookie(); - // get session info - $session = $_SESSION[DOKU_COOKIE]['auth']; if($user && $pass){ // we got a cookie - see if we can trust it + + // get session info + $session = $_SESSION[DOKU_COOKIE]['auth']; if(isset($session) && $auth->useSessionCache($user) && ($session['time'] >= time()-$conf['auth_security_timeout']) && ($session['user'] == $user) && - ($session['pass'] == $pass) && //still crypted + ($session['pass'] == sha1($pass)) && //still crypted ($session['buid'] == auth_browseruid()) ){ + // he has session, cookie and browser right - let him in $_SERVER['REMOTE_USER'] = $user; $USERINFO = $session['info']; //FIXME move all references to session return true; } // no we don't trust it yet - recheck pass but silent - $pass = PMA_blowfish_decrypt($pass,auth_cookiesalt()); + $secret = auth_cookiesalt(!$sticky); //bind non-sticky to session + $pass = PMA_blowfish_decrypt($pass,$secret); return auth_login($user,$pass,$sticky,true); } } @@ -291,10 +301,10 @@ function auth_browseruid(){ * and stored in this file. * * @author Andreas Gohr <andi@splitbrain.org> - * + * @param bool $addsession if true, the sessionid is added to the salt * @return string */ -function auth_cookiesalt(){ +function auth_cookiesalt($addsession=false){ global $conf; $file = $conf['metadir'].'/_htcookiesalt'; $salt = io_readFile($file); @@ -302,6 +312,9 @@ function auth_cookiesalt(){ $salt = uniqid(rand(),true); io_saveFile($file,$salt); } + if($addsession){ + $salt .= session_id(); + } return $salt; } @@ -416,7 +429,7 @@ function auth_isMember($memberlist,$user,array $groups){ if (!$auth) return false; // clean user and groups - if($auth->isCaseSensitive()){ + if(!$auth->isCaseSensitive()){ $user = utf8_strtolower($user); $groups = array_map('utf8_strtolower',$groups); } @@ -431,7 +444,7 @@ function auth_isMember($memberlist,$user,array $groups){ // compare cleaned values foreach($members as $member){ - if($auth->isCaseSensitive()) $member = utf8_strtolower($member); + if(!$auth->isCaseSensitive()) $member = utf8_strtolower($member); if($member[0] == '@'){ $member = $auth->cleanGroup(substr($member,1)); if(in_array($member, $groups)) return true; @@ -680,9 +693,8 @@ function register(){ global $conf; global $auth; - if (!$auth) return false; if(!$_POST['save']) return false; - if(!$auth->canDo('addUser')) return false; + if(!actionOK('register')) return false; //clean username $_POST['login'] = trim($auth->cleanUser($_POST['login'])); @@ -758,12 +770,10 @@ function updateprofile() { global $lang; global $auth; - if (!$auth) return false; if(empty($_POST['save'])) return false; if(!checkSecurityToken()) return false; - // should not be able to get here without Profile being possible... - if(!$auth->canDo('Profile')) { + if(!actionOK('profile')) { msg($lang['profna'],-1); return false; } @@ -806,11 +816,11 @@ function updateprofile() { if ($result = $auth->triggerUserMod('modify', array($_SERVER['REMOTE_USER'], $changes))) { // update cookie and session with the changed data - $cookie = base64_decode($_COOKIE[DOKU_COOKIE]); - list($user,$sticky,$pass) = explode('|',$cookie,3); - if ($changes['pass']) $pass = PMA_blowfish_encrypt($changes['pass'],auth_cookiesalt()); - - auth_setCookie($_SERVER['REMOTE_USER'],$pass,(bool)$sticky); + if ($changes['pass']){ + list($user,$sticky,$pass) = auth_getCookie(); + $pass = PMA_blowfish_encrypt($changes['pass'],auth_cookiesalt(!$sticky)); + auth_setCookie($_SERVER['REMOTE_USER'],$pass,(bool)$sticky); + } return true; } } @@ -834,11 +844,7 @@ function act_resendpwd(){ global $conf; global $auth; - if(!actionOK('resendpwd')) return false; - if (!$auth) return false; - - // should not be able to get here without modPass being possible... - if(!$auth->canDo('modPass')) { + if(!actionOK('resendpwd')) { msg($lang['resendna'],-1); return false; } @@ -926,18 +932,6 @@ function act_resendpwd(){ * If the selected method needs a salt and none was given, a random one * is chosen. * - * 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 - * crypt - Unix crypt - * mysql - MySQL password (old method) - * my411 - MySQL 4.1.1 password - * kmd5 - Salted MD5 hashing as used by UNB - * * @author Andreas Gohr <andi@splitbrain.org> * @return string The crypted password */ @@ -945,128 +939,26 @@ 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') && 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(!isset($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))); - case 'kmd5': - $key = substr($salt, 16, 2); - $hash1 = strtolower(md5($key . md5($clear))); - $hash2 = substr($hash1, 0, 16) . $key . substr($hash1, 16); - return $hash2; - default: - msg("Unsupported crypt method $method",-1); + $pass = new PassHash(); + $call = 'hash_'.$method; + + if(!method_exists($pass,$call)){ + msg("Unsupported crypt method $method",-1); + return false; } + + return $pass->$call($clear,$salt); } /** * Verifies a cleartext password against a crypted hash * - * The method and salt used for the crypted hash is determined automatically - * then the clear text password is crypted using the same method. If both hashs - * match true is is returned else false - * * @author Andreas Gohr <andi@splitbrain.org> * @return bool */ function auth_verifyPassword($clear,$crypt){ - $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'; - }elseif($len == 34){ - $method = 'kmd5'; - $salt = $crypt; - }else{ - $method = 'crypt'; - $salt = substr($crypt,0,2); - } - - //crypt and compare - if(auth_cryptPassword($clear,$method,$salt) === $crypt){ - return true; - } - return false; + $pass = new PassHash(); + return $pass->verify_hash($clear,$crypt); } /** @@ -1095,7 +987,7 @@ function auth_setCookie($user,$pass,$sticky) { } // set session $_SESSION[DOKU_COOKIE]['auth']['user'] = $user; - $_SESSION[DOKU_COOKIE]['auth']['pass'] = $pass; + $_SESSION[DOKU_COOKIE]['auth']['pass'] = sha1($pass); $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid(); $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; $_SESSION[DOKU_COOKIE]['auth']['time'] = time(); |