diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php index 53ecb562a8..a6641277cf 100644 --- a/lib/private/Authentication/Token/DefaultTokenProvider.php +++ b/lib/private/Authentication/Token/DefaultTokenProvider.php @@ -22,6 +22,7 @@ namespace OC\Authentication\Token; +use Exception; use OC\Authentication\Exceptions\InvalidTokenException; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; @@ -192,7 +193,13 @@ class DefaultTokenProvider implements IProvider { */ private function decryptPassword($password, $token) { $secret = $this->config->getSystemValue('secret'); - return $this->crypto->decrypt($password, $token . $secret); + try { + return $this->crypto->decrypt($password, $token . $secret); + } catch (Exception $ex) { + // Delete the invalid token + $this->invalidateToken($token); + throw new InvalidTokenException(); + } } } diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 0351125b5d..0b0d298db2 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -69,10 +69,10 @@ use OCP\Session\Exceptions\SessionNotAvailableException; * @package OC\User */ class Session implements IUserSession, Emitter { - /* * @var Manager $manager */ + private $manager; /* @@ -107,8 +107,7 @@ class Session implements IUserSession, Emitter { * @param IProvider $tokenProvider * @param IProvider[] $tokenProviders */ - public function __construct(IUserManager $manager, ISession $session, ITimeFactory $timeFacory, $tokenProvider, - array $tokenProviders = []) { + public function __construct(IUserManager $manager, ISession $session, ITimeFactory $timeFacory, $tokenProvider, array $tokenProviders = []) { $this->manager = $manager; $this->session = $session; $this->timeFacory = $timeFacory; @@ -230,7 +229,14 @@ class Session implements IUserSession, Emitter { $lastCheck = $this->session->get('last_login_check') ? : 0; $now = $this->timeFacory->getTime(); if ($lastCheck < ($now - 60 * 5)) { - $pwd = $this->tokenProvider->getPassword($token, $sessionId); + try { + $pwd = $this->tokenProvider->getPassword($token, $sessionId); + } catch (InvalidTokenException $ex) { + // An invalid token password was used -> log user out + $this->logout(); + return; + } + if ($this->manager->checkPassword($user->getUID(), $pwd) === false) { // Password has changed -> log user out $this->logout(); diff --git a/tests/lib/authentication/token/defaulttokenprovidertest.php b/tests/lib/authentication/token/defaulttokenprovidertest.php index 567068ef06..5ee33d0ec1 100644 --- a/tests/lib/authentication/token/defaulttokenprovidertest.php +++ b/tests/lib/authentication/token/defaulttokenprovidertest.php @@ -54,7 +54,8 @@ class DefaultTokenProviderTest extends TestCase { ->method('getTime') ->will($this->returnValue($this->time)); - $this->tokenProvider = new DefaultTokenProvider($this->mapper, $this->crypto, $this->config, $this->logger, $this->timeFactory); + $this->tokenProvider = new DefaultTokenProvider($this->mapper, $this->crypto, $this->config, $this->logger, + $this->timeFactory); } public function testGenerateToken() { @@ -118,6 +119,36 @@ class DefaultTokenProviderTest extends TestCase { $this->assertEquals('passme', $actual); } + /** + * @expectedException \OC\Authentication\Exceptions\InvalidTokenException + */ + public function testGetPasswordDeletesInvalidToken() { + $token = 'token1234'; + $tk = new DefaultToken(); + $tk->setPassword('someencryptedvalue'); + /* @var $tokenProvider DefaultTokenProvider */ + $tokenProvider = $this->getMockBuilder('\OC\Authentication\Token\DefaultTokenProvider') + ->setMethods([ + 'invalidateToken' + ]) + ->setConstructorArgs([$this->mapper, $this->crypto, $this->config, $this->logger, + $this->timeFactory]) + ->getMock(); + $this->config->expects($this->once()) + ->method('getSystemValue') + ->with('secret') + ->will($this->returnValue('1f4h9s')); + $this->crypto->expects($this->once()) + ->method('decrypt') + ->with('someencryptedvalue', $token . '1f4h9s') + ->will($this->throwException(new \Exception('some crypto error occurred'))); + $tokenProvider->expects($this->once()) + ->method('invalidateToken') + ->with($token); + + $tokenProvider->getPassword($tk, $token); + } + public function testInvalidateToken() { $this->mapper->expects($this->once()) ->method('invalidate')