diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/API.php b/src/opnsense/mvc/app/library/OPNsense/Auth/API.php index a1e3b73af..4cebd9463 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Auth/API.php +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/API.php @@ -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(); diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/Base.php b/src/opnsense/mvc/app/library/OPNsense/Auth/Base.php index ebd8ef0c0..d491ba9f0 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Auth/Base.php +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/Base.php @@ -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; + } + } diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/Local.php b/src/opnsense/mvc/app/library/OPNsense/Auth/Local.php index e0cef7e78..334aa9385 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Auth/Local.php +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/Local.php @@ -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) { diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/TOTP.php b/src/opnsense/mvc/app/library/OPNsense/Auth/TOTP.php index 1c21a2230..96cb993a2 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Auth/TOTP.php +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/TOTP.php @@ -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)) { diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/Voucher.php b/src/opnsense/mvc/app/library/OPNsense/Auth/Voucher.php index a514aa420..dbb55d290 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Auth/Voucher.php +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/Voucher.php @@ -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