Skip to content

Commit

Permalink
create remember-me cookies only if checkbox is checked and 2fa solved
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Wurst <[email protected]>
  • Loading branch information
ChristophWurst committed Oct 24, 2016
1 parent 45e88a5 commit d382a67
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 25 deletions.
15 changes: 7 additions & 8 deletions core/Controller/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,10 @@ private function generateRedirect($redirectUrl) {
* @param string $user
* @param string $password
* @param string $redirect_url
* @param boolean $remember_login
* @return RedirectResponse
*/
public function tryLogin($user, $password, $redirect_url) {
public function tryLogin($user, $password, $redirect_url, $remember_login) {
$currentDelay = $this->throttler->getDelay($this->request->getRemoteAddress());
$this->throttler->sleepDelay($this->request->getRemoteAddress());

Expand Down Expand Up @@ -238,17 +239,11 @@ public function tryLogin($user, $password, $redirect_url) {
$this->userSession->login($user, $password);
$this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password);

if (true) {
$token = \OC::$server->getSecureRandom()->generate(32);
$this->config->setUserValue($originalUser, 'login_token', $token, time());
$this->userSession->setMagicInCookie($originalUser, $token);
}

// User has successfully logged in, now remove the password reset link, when it is available
$this->config->deleteUserValue($loginResult->getUID(), 'core', 'lostpassword');

if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) {
$this->twoFactorManager->prepareTwoFactorLogin($loginResult);
$this->twoFactorManager->prepareTwoFactorLogin($loginResult, $remember_login);

$providers = $this->twoFactorManager->getProviders($loginResult);
if (count($providers) === 1) {
Expand All @@ -271,6 +266,10 @@ public function tryLogin($user, $password, $redirect_url) {
return new RedirectResponse($this->urlGenerator->linkToRoute($url, $urlParams));
}

if ($remember_login) {
$this->userSession->createRememberMeToken($loginResult);
}

return $this->generateRedirect($redirect_url);
}

Expand Down
9 changes: 5 additions & 4 deletions core/Controller/TwoFactorChallengeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
namespace OC\Core\Controller;

use OC\Authentication\TwoFactorAuth\Manager;
use OC\User\Session;
use OC_User;
use OC_Util;
use OCP\AppFramework\Controller;
Expand All @@ -32,14 +33,14 @@
use OCP\IRequest;
use OCP\ISession;
use OCP\IURLGenerator;
use OCP\IUserSession;
use OCP\IUserSession as UserSession;

class TwoFactorChallengeController extends Controller {

/** @var Manager */
private $twoFactorManager;

/** @var IUserSession */
/** @var UserSession */
private $userSession;

/** @var ISession */
Expand All @@ -53,10 +54,10 @@ class TwoFactorChallengeController extends Controller {
* @param IRequest $request
* @param Manager $twoFactorManager
* @param IUserSession $userSession
* @param ISession $session
* @param UserSession $session
* @param IURLGenerator $urlGenerator
*/
public function __construct($appName, IRequest $request, Manager $twoFactorManager, IUserSession $userSession,
public function __construct($appName, IRequest $request, Manager $twoFactorManager, UserSession $userSession,
ISession $session, IURLGenerator $urlGenerator) {
parent::__construct($appName, $request);
$this->twoFactorManager = $twoFactorManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ public function __construct($appName, $urlParams = array()){
$this->registerService('OCP\\IUserSession', function($c) {
return $this->getServer()->getUserSession();
});
$this->registerAlias(\OC\User\Session::class, \OCP\IUserSession::class);

$this->registerService('OCP\\ISession', function($c) {
return $this->getServer()->getSession();
Expand Down
19 changes: 14 additions & 5 deletions lib/private/Authentication/TwoFactorAuth/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Manager {
const SESSION_UID_KEY = 'two_factor_auth_uid';
const BACKUP_CODES_APP_ID = 'twofactor_backupcodes';
const BACKUP_CODES_PROVIDER_ID = 'backup_codes';
const REMEBER_LOGIN = 'two_factor_remember_login';

/** @var AppManager */
private $appManager;
Expand All @@ -51,6 +52,7 @@ class Manager {
* @param AppManager $appManager
* @param ISession $session
* @param IConfig $config
* @param Session $userSession
*/
public function __construct(AppManager $appManager, ISession $session, IConfig $config) {
$this->appManager = $appManager;
Expand Down Expand Up @@ -171,11 +173,16 @@ public function verifyChallenge($providerId, IUser $user, $challenge) {
return false;
}

$result = $provider->verifyChallenge($user, $challenge);
if ($result) {
$passed = $provider->verifyChallenge($user, $challenge);
if ($passed) {
if ($this->session->get(self::REMEBER_LOGIN) === true) {
// TODO: resolve cyclic dependency and use DI
\OC::$server->getUserSession()->createRememberMeToken($user);
}
$this->session->remove(self::SESSION_UID_KEY);
$this->session->remove(self::REMEBER_LOGIN);
}
return $result;
return $passed;
}

/**
Expand All @@ -202,12 +209,14 @@ public function needsSecondFactor(IUser $user = null) {
}

/**
* Prepare the 2FA login (set session value)
* Prepare the 2FA login
*
* @param IUser $user
* @param boolean $rememberMe
*/
public function prepareTwoFactorLogin(IUser $user) {
public function prepareTwoFactorLogin(IUser $user, $rememberMe) {
$this->session->set(self::SESSION_UID_KEY, $user->getUID());
$this->session->set(self::REMEBER_LOGIN, $rememberMe);
}

}
2 changes: 1 addition & 1 deletion lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ public function __construct($webRoot, \OC\Config $config) {
return $userSession;
});

$this->registerService('\OC\Authentication\TwoFactorAuth\Manager', function (Server $c) {
$this->registerService(\OC\Authentication\TwoFactorAuth\Manager::class, function (Server $c) {
return new \OC\Authentication\TwoFactorAuth\Manager($c->getAppManager(), $c->getSession(), $c->getConfig());
});

Expand Down
25 changes: 18 additions & 7 deletions lib/private/User/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,15 @@ public function loginWithCookie($uid, $currentToken, $oldSessionId) {
return true;
}

/**
* @param IUser $user
*/
public function createRememberMeToken(IUser $user) {
$token = OC::$server->getSecureRandom()->generate(32);
$this->config->setUserValue($user->getUID(), 'login_token', $token, time());
$this->setMagicInCookie($user->getUID(), $token);
}

/**
* logout the user from the session
*/
Expand Down Expand Up @@ -745,15 +754,19 @@ public function logout() {
*/
public function setMagicInCookie($username, $token) {
$secureCookie = OC::$server->getRequest()->getServerProtocol() === 'https';
$webRoot = \OC::$WEBROOT;
if ($webRoot === '') {
$webRoot = '/';
}

$expires = $this->timeFacory->getTime() + OC::$server->getConfig()->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
setcookie('nc_username', $username, $expires, OC::$WEBROOT, '', $secureCookie, true);
setcookie('nc_token', $token, $expires, OC::$WEBROOT, '', $secureCookie, true);
setcookie('nc_username', $username, $expires, $webRoot, '', $secureCookie, true);
setcookie('nc_token', $token, $expires, $webRoot, '', $secureCookie, true);
try {
setcookie('nc_session_id', $this->session->getId(), $expires, OC::$WEBROOT, '', $secureCookie, true);
setcookie('nc_session_id', $this->session->getId(), $expires, $webRoot, '', $secureCookie, true);
} catch (SessionNotAvailableException $ex) {
// ignore
}
setcookie('nc_remember_login', '1', $expires, OC::$WEBROOT, '', $secureCookie, true);
}

/**
Expand All @@ -766,16 +779,14 @@ public function unsetMagicInCookie() {
unset($_COOKIE['nc_username']); //TODO: DI
unset($_COOKIE['nc_token']);
unset($_COOKIE['nc_session_id']);
unset($_COOKIE['nc_remember_login']);
setcookie('nc_username', '', time() - 3600, OC::$WEBROOT, '', $secureCookie, true);
setcookie('nc_token', '', time() - 3600, OC::$WEBROOT, '', $secureCookie, true);
setcookie('nc_remember_login', '', time() - 3600, OC::$WEBROOT, '', $secureCookie, true);
setcookie('nc_session_id', '', time() - 3600, OC::$WEBROOT, '', $secureCookie, true);
// old cookies might be stored under /webroot/ instead of /webroot
// and Firefox doesn't like it!
setcookie('nc_username', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true);
setcookie('nc_token', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true);
setcookie('nc_session_id', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true);
setcookie('nc_remember_login', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true);
}

/**
Expand Down

0 comments on commit d382a67

Please sign in to comment.