Allow updating the token on session regeneration

Sometimes when we force a session regeneration we want to update the
current token for this session.

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
Roeland Jago Douma 2018-06-11 10:45:19 +02:00
parent 479e31997f
commit 8c47a632e0
No known key found for this signature in database
GPG Key ID: F941078878347C0C
6 changed files with 42 additions and 7 deletions

View File

@ -217,7 +217,7 @@ class ShareController extends Controller {
private function linkShareAuth(\OCP\Share\IShare $share, $password = null) { private function linkShareAuth(\OCP\Share\IShare $share, $password = null) {
if ($password !== null) { if ($password !== null) {
if ($this->shareManager->checkPassword($share, $password)) { if ($this->shareManager->checkPassword($share, $password)) {
$this->session->regenerateId(); $this->session->regenerateId(true, true);
$this->session->set('public_link_authenticated', (string)$share->getId()); $this->session->set('public_link_authenticated', (string)$share->getId());
} else { } else {
$this->emitAccessShareHook($share, 403, 'Wrong password'); $this->emitAccessShareHook($share, 403, 'Wrong password');

View File

@ -150,10 +150,11 @@ class CryptoSessionData implements \ArrayAccess, ISession {
* Wrapper around session_regenerate_id * Wrapper around session_regenerate_id
* *
* @param bool $deleteOldSession Whether to delete the old associated session file or not. * @param bool $deleteOldSession Whether to delete the old associated session file or not.
* @param bool $updateToken Wheater to update the associated auth token
* @return void * @return void
*/ */
public function regenerateId(bool $deleteOldSession = true) { public function regenerateId(bool $deleteOldSession = true, bool $updateToken = false) {
$this->session->regenerateId($deleteOldSession); $this->session->regenerateId($deleteOldSession, $updateToken);
} }
/** /**

View File

@ -30,6 +30,10 @@ declare(strict_types=1);
namespace OC\Session; namespace OC\Session;
use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Token\IProvider;
use OC\SystemConfig;
use OCP\IConfig;
use OCP\Session\Exceptions\SessionNotAvailableException; use OCP\Session\Exceptions\SessionNotAvailableException;
/** /**
@ -111,14 +115,41 @@ class Internal extends Session {
* Wrapper around session_regenerate_id * Wrapper around session_regenerate_id
* *
* @param bool $deleteOldSession Whether to delete the old associated session file or not. * @param bool $deleteOldSession Whether to delete the old associated session file or not.
* @param bool $updateToken Wheater to update the associated auth token
* @return void * @return void
*/ */
public function regenerateId(bool $deleteOldSession = true) { public function regenerateId(bool $deleteOldSession = true, bool $updateToken = false) {
$oldId = null;
if ($updateToken) {
// Get the old id to update the token
try {
$oldId = $this->getId();
} catch (SessionNotAvailableException $e) {
// We can't update a token if there is no previous id
$updateToken = false;
}
}
try { try {
@session_regenerate_id($deleteOldSession); @session_regenerate_id($deleteOldSession);
} catch (\Error $e) { } catch (\Error $e) {
$this->trapError($e->getCode(), $e->getMessage()); $this->trapError($e->getCode(), $e->getMessage());
} }
if ($updateToken) {
// Get the new id to update the token
$newId = $this->getId();
/** @var IProvider $tokenProvider */
$tokenProvider = \OC::$server->query(IProvider::class);
try {
$tokenProvider->renewSessionToken($oldId, $newId);
} catch (InvalidTokenException $e) {
// Just ignore
}
}
} }
/** /**

View File

@ -91,7 +91,7 @@ class Memory extends Session {
* *
* @param bool $deleteOldSession * @param bool $deleteOldSession
*/ */
public function regenerateId(bool $deleteOldSession = true) {} public function regenerateId(bool $deleteOldSession = true, bool $updateToken = false) {}
/** /**
* Wrapper around session_id * Wrapper around session_id

View File

@ -626,6 +626,8 @@ class Session implements IUserSession, Emitter {
try { try {
$sessionId = $this->session->getId(); $sessionId = $this->session->getId();
$pwd = $this->getPassword($password); $pwd = $this->getPassword($password);
// Make sure the current sessionId has no leftover tokens
$this->tokenProvider->invalidateToken($sessionId);
$this->tokenProvider->generateToken($sessionId, $uid, $loginName, $pwd, $name, IToken::TEMPORARY_TOKEN, $remember); $this->tokenProvider->generateToken($sessionId, $uid, $loginName, $pwd, $name, IToken::TEMPORARY_TOKEN, $remember);
return true; return true;
} catch (SessionNotAvailableException $ex) { } catch (SessionNotAvailableException $ex) {

View File

@ -96,10 +96,11 @@ interface ISession {
* Wrapper around session_regenerate_id * Wrapper around session_regenerate_id
* *
* @param bool $deleteOldSession Whether to delete the old associated session file or not. * @param bool $deleteOldSession Whether to delete the old associated session file or not.
* @param bool $updateToken Wheater to update the associated auth token
* @return void * @return void
* @since 9.0.0 * @since 9.0.0, $updateToken added in 14.0.0
*/ */
public function regenerateId(bool $deleteOldSession = true); public function regenerateId(bool $deleteOldSession = true, bool $updateToken = false);
/** /**
* Wrapper around session_id * Wrapper around session_id