Skip to content

Commit 2f26acc

Browse files
kesselbmiaulalala
authored andcommitted
chore: use local variable for remote address
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
1 parent 9681be3 commit 2f26acc

2 files changed

Lines changed: 111 additions & 1 deletion

File tree

lib/private/User/Session.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
use OCP\IUser;
6161
use OCP\IUserSession;
6262
use OCP\Lockdown\ILockdownManager;
63+
use OC\Security\Bruteforce\Throttler;
6364
use OCP\Security\ISecureRandom;
6465
use OCP\Session\Exceptions\SessionNotAvailableException;
6566
use OCP\User\Events\PostLoginEvent;
@@ -437,7 +438,8 @@ public function logClientIn($user,
437438
$password,
438439
IRequest $request,
439440
OC\Security\Bruteforce\Throttler $throttler) {
440-
$currentDelay = $throttler->sleepDelay($request->getRemoteAddress(), 'login');
441+
$remoteAddress = $request->getRemoteAddress();
442+
$currentDelay = $throttler->sleepDelay($remoteAddress, 'login');
441443

442444
if ($this->manager instanceof PublicEmitter) {
443445
$this->manager->emit('\OC\User', 'preLogin', [$user, $password]);
@@ -462,6 +464,7 @@ public function logClientIn($user,
462464

463465
// Failed, maybe the user used their email address
464466
if (!filter_var($user, FILTER_VALIDATE_EMAIL)) {
467+
$this->handleLoginFailed($throttler, $currentDelay, $remoteAddress, $user, $password);
465468
return false;
466469
}
467470
$users = $this->manager->getByEmail($user);
@@ -489,6 +492,17 @@ public function logClientIn($user,
489492
return true;
490493
}
491494

495+
private function handleLoginFailed(Throttler $throttler, int $currentDelay, string $remoteAddress, string $user, ?string $password) {
496+
$this->logger->warning("Login failed: '" . $user . "' (Remote IP: '" . $remoteAddress . "')", ['app' => 'core']);
497+
498+
$throttler->registerAttempt('login', $remoteAddress, ['user' => $user]);
499+
$this->dispatcher->dispatchTyped(new OC\Authentication\Events\LoginFailed($user, $password));
500+
501+
if ($currentDelay === 0) {
502+
$throttler->sleepDelay($remoteAddress, 'login');
503+
}
504+
}
505+
492506
protected function supportsCookies(IRequest $request) {
493507
if (!is_null($request->getCookie('cookie_test'))) {
494508
return true;

tests/lib/User/SessionTest.php

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,4 +1472,100 @@ public function testUpdateTokens() {
14721472

14731473
$this->userSession->updateTokens('uid', 'pass');
14741474
}
1475+
1476+
public function testLogClientInThrottlerUsername() {
1477+
$manager = $this->createMock(Manager::class);
1478+
$session = $this->createMock(ISession::class);
1479+
$request = $this->createMock(IRequest::class);
1480+
1481+
/** @var Session $userSession */
1482+
$userSession = $this->getMockBuilder(Session::class)
1483+
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
1484+
->setMethods(['isTokenPassword', 'login', 'supportsCookies', 'createSessionToken', 'getUser'])
1485+
->getMock();
1486+
1487+
$userSession->expects($this->once())
1488+
->method('isTokenPassword')
1489+
->willReturn(true);
1490+
$userSession->expects($this->once())
1491+
->method('login')
1492+
->with('john', 'I-AM-AN-PASSWORD')
1493+
->willReturn(false);
1494+
1495+
$session->expects($this->never())
1496+
->method('set');
1497+
$request
1498+
->method('getRemoteAddress')
1499+
->willReturn('192.168.0.1');
1500+
$this->throttler
1501+
->expects($this->exactly(2))
1502+
->method('sleepDelay')
1503+
->with('192.168.0.1');
1504+
$this->throttler
1505+
->expects($this->any())
1506+
->method('getDelay')
1507+
->with('192.168.0.1')
1508+
->willReturn(0);
1509+
1510+
$this->throttler
1511+
->expects($this->once())
1512+
->method('registerAttempt')
1513+
->with('login', '192.168.0.1', ['user' => 'john']);
1514+
$this->dispatcher
1515+
->expects($this->once())
1516+
->method('dispatchTyped')
1517+
->with(new LoginFailed('john', 'I-AM-AN-PASSWORD'));
1518+
1519+
$this->assertFalse($userSession->logClientIn('john', 'I-AM-AN-PASSWORD', $request, $this->throttler));
1520+
}
1521+
1522+
public function testLogClientInThrottlerEmail() {
1523+
$manager = $this->createMock(Manager::class);
1524+
$session = $this->createMock(ISession::class);
1525+
$request = $this->createMock(IRequest::class);
1526+
1527+
/** @var Session $userSession */
1528+
$userSession = $this->getMockBuilder(Session::class)
1529+
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
1530+
->setMethods(['isTokenPassword', 'login', 'supportsCookies', 'createSessionToken', 'getUser'])
1531+
->getMock();
1532+
1533+
$userSession->expects($this->once())
1534+
->method('isTokenPassword')
1535+
->willReturn(true);
1536+
$userSession->expects($this->once())
1537+
->method('login')
1538+
->with('john@foo.bar', 'I-AM-AN-PASSWORD')
1539+
->willReturn(false);
1540+
$manager
1541+
->method('getByEmail')
1542+
->with('john@foo.bar')
1543+
->willReturn([]);
1544+
1545+
$session->expects($this->never())
1546+
->method('set');
1547+
$request
1548+
->method('getRemoteAddress')
1549+
->willReturn('192.168.0.1');
1550+
$this->throttler
1551+
->expects($this->exactly(2))
1552+
->method('sleepDelay')
1553+
->with('192.168.0.1');
1554+
$this->throttler
1555+
->expects($this->any())
1556+
->method('getDelay')
1557+
->with('192.168.0.1')
1558+
->willReturn(0);
1559+
1560+
$this->throttler
1561+
->expects($this->once())
1562+
->method('registerAttempt')
1563+
->with('login', '192.168.0.1', ['user' => 'john@foo.bar']);
1564+
$this->dispatcher
1565+
->expects($this->once())
1566+
->method('dispatchTyped')
1567+
->with(new LoginFailed('john@foo.bar', 'I-AM-AN-PASSWORD'));
1568+
1569+
$this->assertFalse($userSession->logClientIn('john@foo.bar', 'I-AM-AN-PASSWORD', $request, $this->throttler));
1570+
}
14751571
}

0 commit comments

Comments
 (0)