delete the token in case an exception is thrown when decrypting the password

This commit is contained in:
Christoph Wurst 2016-05-08 19:31:42 +02:00 committed by Thomas Müller
parent af707fba41
commit 69dafd727d
No known key found for this signature in database
GPG Key ID: A943788A3BBEC44C
3 changed files with 50 additions and 6 deletions

View File

@ -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();
}
}
}

View File

@ -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();

View File

@ -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')