Authentication: add a "time-loop" around authentication for failed attempts, closes https://github.com/opnsense/core/issues/8031

This commit adds a wrapper in base for the authenticate() method, which calls the protected _authenticate() method for a timed auth sequence.
When authentication is fully handled elsewhere (LDAP, RADIUS), we trust the provider for proper constraints, for local cases we move our implementations to _authenticate() in this commit.
This commit is contained in:
Ad Schellevis 2024-11-02 15:37:48 +01:00
parent d67f9b4ab8
commit 4cb1f6d57d
5 changed files with 38 additions and 4 deletions

View File

@ -134,7 +134,7 @@ class API extends Base implements IAuthConnector
* @param string $password user password
* @return bool authentication status
*/
public function authenticate($username, $password)
public function _authenticate($username, $password)
{
// reset auth properties
$this->lastAuthProperties = array();

View File

@ -251,4 +251,38 @@ abstract class Base
{
return $this->lastAuthErrors;
}
/**
* authenticate user, implementation when using this base classes authenticate()
* @param string $username username to authenticate
* @param string $password user password
* @return bool
*/
protected function _authenticate($username, $password)
{
return false;
}
/**
* authenticate user, when failed, make sure we always spend the same time for the sequence.
* This also adds a penalty for failed attempts.
* @param string $username username to authenticate
* @param string $password user password
* @return bool
*/
public function authenticate($username, $password)
{
$tstart = microtime(true);
$expected_time = 2000000; /* failed login, aim at 2 seconds total time */
$result = $this->_authenticate($username, $password);
$timeleft = $expected_time - ((microtime(true) - $tstart) * 1000000);
if (!$result && $timeleft > 0) {
usleep($timeleft);
}
return $result;
}
}

View File

@ -149,7 +149,7 @@ class Local extends Base implements IAuthConnector
* @param string $password user password
* @return bool authentication status
*/
public function authenticate($username, $password)
protected function _authenticate($username, $password)
{
$userObject = $this->getUser($username);
if ($userObject != null) {

View File

@ -140,7 +140,7 @@ trait TOTP
* @param string $password user password
* @return bool authentication status
*/
public function authenticate($username, $password)
protected function _authenticate($username, $password)
{
$userObject = $this->getUser($username);
if ($userObject != null && !empty($userObject->otp_seed)) {

View File

@ -371,7 +371,7 @@ class Voucher extends Base implements IAuthConnector
* @param string $password user password
* @return bool authentication status
*/
public function authenticate($username, $password)
protected function _authenticate($username, $password)
{
$stmt = $this->dbHandle->prepare('
select username, password, validity, expirytime, starttime