Merge pull request #31 from visit1985/persistentcookies
reresubmit: improved persistent cookies :)
This commit is contained in:
commit
59404b5675
3 changed files with 70 additions and 14 deletions
|
@ -92,6 +92,9 @@ $CONFIG = array(
|
|||
/* Loglevel to start logging at. 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR (default is WARN) */
|
||||
"loglevel" => "",
|
||||
|
||||
/* Lifetime of the remember login cookie, default is 15 days */
|
||||
"remember_login_cookie_lifetime" => 60*60*24*15,
|
||||
|
||||
/* The directory where the user data is stored, default to data in the owncloud
|
||||
* directory. The sqlite database is also stored here, when sqlite is used.
|
||||
*/
|
||||
|
@ -110,4 +113,4 @@ $CONFIG = array(
|
|||
'writable' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
|
|
70
lib/base.php
70
lib/base.php
|
@ -264,8 +264,30 @@ class OC{
|
|||
}
|
||||
|
||||
public static function initSession() {
|
||||
// prevents javascript from accessing php session cookies
|
||||
ini_set('session.cookie_httponly', '1;');
|
||||
|
||||
// (re)-initialize session
|
||||
session_start();
|
||||
|
||||
// regenerate session id periodically to avoid session fixation
|
||||
if (!isset($_SESSION['SID_CREATED'])) {
|
||||
$_SESSION['SID_CREATED'] = time();
|
||||
} else if (time() - $_SESSION['SID_CREATED'] > 900) {
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['SID_CREATED'] = time();
|
||||
}
|
||||
|
||||
// session timeout
|
||||
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 3600)) {
|
||||
if (isset($_COOKIE[session_name()])) {
|
||||
setcookie(session_name(), '', time() - 42000, '/');
|
||||
}
|
||||
session_unset();
|
||||
session_destroy();
|
||||
session_start();
|
||||
}
|
||||
$_SESSION['LAST_ACTIVITY'] = time();
|
||||
}
|
||||
|
||||
public static function init() {
|
||||
|
@ -453,6 +475,7 @@ class OC{
|
|||
OC_App::loadApps();
|
||||
OC_User::setupBackends();
|
||||
if(isset($_GET["logout"]) and ($_GET["logout"])) {
|
||||
OC_Preferences::deleteKey(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']);
|
||||
OC_User::logout();
|
||||
header("Location: ".OC::$WEBROOT.'/');
|
||||
}else{
|
||||
|
@ -514,6 +537,17 @@ class OC{
|
|||
OC_Util::displayLoginPage(array_unique($error));
|
||||
}
|
||||
|
||||
protected static function cleanupLoginTokens($user) {
|
||||
$cutoff = time() - OC_Config::getValue('remember_login_cookie_lifetime', 60*60*24*15);
|
||||
$tokens = OC_Preferences::getKeys($user, 'login_token');
|
||||
foreach($tokens as $token) {
|
||||
$time = OC_Preferences::getValue($user, 'login_token', $token);
|
||||
if ($time < $cutoff) {
|
||||
OC_Preferences::deleteKey($user, 'login_token', $token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static function tryRememberLogin() {
|
||||
if(!isset($_COOKIE["oc_remember_login"])
|
||||
|| !isset($_COOKIE["oc_token"])
|
||||
|
@ -527,15 +561,30 @@ class OC{
|
|||
OC_Log::write('core', 'Trying to login from cookie', OC_Log::DEBUG);
|
||||
}
|
||||
// confirm credentials in cookie
|
||||
if(isset($_COOKIE['oc_token']) && OC_User::userExists($_COOKIE['oc_username']) &&
|
||||
OC_Preferences::getValue($_COOKIE['oc_username'], "login", "token") === $_COOKIE['oc_token'])
|
||||
{
|
||||
OC_User::setUserId($_COOKIE['oc_username']);
|
||||
OC_Util::redirectToDefaultPage();
|
||||
}
|
||||
else {
|
||||
OC_User::unsetMagicInCookie();
|
||||
if(isset($_COOKIE['oc_token']) && OC_User::userExists($_COOKIE['oc_username'])) {
|
||||
// delete outdated cookies
|
||||
self::cleanupLoginTokens($_COOKIE['oc_username']);
|
||||
// get stored tokens
|
||||
$tokens = OC_Preferences::getKeys($_COOKIE['oc_username'], 'login_token');
|
||||
// test cookies token against stored tokens
|
||||
if (in_array($_COOKIE['oc_token'], $tokens, true)) {
|
||||
// replace successfully used token with a new one
|
||||
OC_Preferences::deleteKey($_COOKIE['oc_username'], 'login_token', $_COOKIE['oc_token']);
|
||||
$token = OC_Util::generate_random_bytes(32);
|
||||
OC_Preferences::setValue($_COOKIE['oc_username'], 'login_token', $token, time());
|
||||
OC_User::setMagicInCookie($_COOKIE['oc_username'], $token);
|
||||
// login
|
||||
OC_User::setUserId($_COOKIE['oc_username']);
|
||||
OC_Util::redirectToDefaultPage();
|
||||
// doesn't return
|
||||
}
|
||||
// if you reach this point you have changed your password
|
||||
// or you are an attacker
|
||||
// we can not delete tokens here because users may reach
|
||||
// this point multiple times after a password change
|
||||
OC_Log::write('core', 'Authentication cookie rejected for user '.$_COOKIE['oc_username'], OC_Log::WARN);
|
||||
}
|
||||
OC_User::unsetMagicInCookie();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -550,12 +599,13 @@ class OC{
|
|||
OC_User::setupBackends();
|
||||
|
||||
if(OC_User::login($_POST["user"], $_POST["password"])) {
|
||||
self::cleanupLoginTokens($_POST['user']);
|
||||
if(!empty($_POST["remember_login"])) {
|
||||
if(defined("DEBUG") && DEBUG) {
|
||||
OC_Log::write('core', 'Setting remember login to cookie', OC_Log::DEBUG);
|
||||
}
|
||||
$token = md5($_POST["user"].time().$_POST['password']);
|
||||
OC_Preferences::setValue($_POST['user'], 'login', 'token', $token);
|
||||
$token = OC_Util::generate_random_bytes(32);
|
||||
OC_Preferences::setValue($_POST['user'], 'login_token', $token, time());
|
||||
OC_User::setMagicInCookie($_POST["user"], $token);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -329,6 +329,8 @@ class OC_User {
|
|||
}
|
||||
}
|
||||
}
|
||||
// invalidate all login cookies
|
||||
OC_Preferences::deleteApp($uid, 'login_token');
|
||||
OC_Hook::emit( "OC_User", "post_setPassword", array( "uid" => $uid, "password" => $password ));
|
||||
return $success;
|
||||
}
|
||||
|
@ -472,9 +474,10 @@ class OC_User {
|
|||
*/
|
||||
public static function setMagicInCookie($username, $token) {
|
||||
$secure_cookie = OC_Config::getValue("forcessl", false);
|
||||
setcookie("oc_username", $username, time()+60*60*24*15, '', '', $secure_cookie);
|
||||
setcookie("oc_token", $token, time()+60*60*24*15, '', '', $secure_cookie);
|
||||
setcookie("oc_remember_login", true, time()+60*60*24*15, '', '', $secure_cookie);
|
||||
$expires = time() + OC_Config::getValue('remember_login_cookie_lifetime', 60*60*24*15);
|
||||
setcookie("oc_username", $username, $expires, '', '', $secure_cookie);
|
||||
setcookie("oc_token", $token, $expires, '', '', $secure_cookie);
|
||||
setcookie("oc_remember_login", true, $expires, '', '', $secure_cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue