summaryrefslogtreecommitdiff
path: root/inc/auth.php
diff options
context:
space:
mode:
Diffstat (limited to 'inc/auth.php')
-rw-r--r--inc/auth.php190
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();