otp failure limit revoke threshold

This commit is contained in:
Paweł Suwiński
2020-11-17 12:17:53 +01:00
parent a06447c270
commit 4b0e41dbf3
4 changed files with 42 additions and 4 deletions

View File

@@ -79,9 +79,11 @@ class auth_plugin_emailotp extends auth_plugin_base {
// OTP already generated and base credentials matches. // OTP already generated and base credentials matches.
if (isset($_SESSION[self::COMPONENT_NAME]) && if (isset($_SESSION[self::COMPONENT_NAME]) &&
$_SESSION[self::COMPONENT_NAME]['credentials'] === static::get_credentials($username)) { $_SESSION[self::COMPONENT_NAME]['credentials'] === static::get_credentials($username)) {
return empty($password) if (empty($password)) {
? (bool) $this->redirect($username, notification::NOTIFY_INFO) return (bool) $this->redirect($username, notification::NOTIFY_INFO);
: password_verify($password, $_SESSION[self::COMPONENT_NAME]['password']); } else if (password_verify($password, $_SESSION[self::COMPONENT_NAME]['password'])) {
return true;
}
} }
// OTP request - do not proceed on preventaccountcreation when user not exits. // OTP request - do not proceed on preventaccountcreation when user not exits.
if (!isset($_SESSION[self::COMPONENT_NAME]) && empty($password) && ( if (!isset($_SESSION[self::COMPONENT_NAME]) && empty($password) && (
@@ -96,6 +98,18 @@ class auth_plugin_emailotp extends auth_plugin_base {
: notification::NOTIFY_ERROR : notification::NOTIFY_ERROR
); );
} }
// OTP exits but validation failed - reset if revoke threshold is set.
if (isset($_SESSION[self::COMPONENT_NAME])) {
$_SESSION[self::COMPONENT_NAME]['login_failed_count']++;
if (!empty($this->config->revokethreshold) &&
$_SESSION[self::COMPONENT_NAME]['login_failed_count'] >= $this->config->revokethreshold) {
unset($_SESSION[self::COMPONENT_NAME]);
\core\notification::add(
(string)new lang_string('otpinvalidated', self::COMPONENT_NAME, null, $CFG->lang),
notification::NOTIFY_WARNING
);
}
}
return false; return false;
} }
@@ -181,6 +195,7 @@ class auth_plugin_emailotp extends auth_plugin_base {
$_SESSION[self::COMPONENT_NAME] = array( $_SESSION[self::COMPONENT_NAME] = array(
'credentials' => static::get_credentials($username), 'credentials' => static::get_credentials($username),
'password' => password_hash($newpassword, PASSWORD_DEFAULT), 'password' => password_hash($newpassword, PASSWORD_DEFAULT),
'login_failed_count' => 0,
); );
$a = (object)array( $a = (object)array(
'username' => $username, 'username' => $username,

View File

@@ -28,6 +28,12 @@ $string['otpgeneratedtext'] = 'One-time password for current session: {$a->passw
$string['otpsentsuccess'] = 'One-time password was sent to given email.'; $string['otpsentsuccess'] = 'One-time password was sent to given email.';
$string['otpsenterror'] = 'An error occurred while sending one-time password.'; $string['otpsenterror'] = 'An error occurred while sending one-time password.';
$string['otpsentinfo'] = 'One-time password for current session was already generated and sent to email.'; $string['otpsentinfo'] = 'One-time password for current session was already generated and sent to email.';
$string['otpinvalidated'] = 'Previously generated password has been revoked due to exceeding the login failure threshold.';
$string['optperioderror'] = 'Minim period after which another password can be generated not preserved. Try again later.';
$string['revokethreshold'] = 'Revoke threshold';
$string['revokethreshold_help'] = 'Login failures limit causing revoke of the generated password (0 - unlimited).';
$string['minrequestperiod'] = 'Minium period';
$string['minrequestperiod_help'] = 'A time in seconds after which another password can be generated.';
$string['fieldsmapping'] = 'User profile fields mapping'; $string['fieldsmapping'] = 'User profile fields mapping';
$string['fieldsmapping_pattern'] = 'Pattern'; $string['fieldsmapping_pattern'] = 'Pattern';
$string['fieldsmapping_pattern_help'] = 'Capturing groups PCRE patttern.'; $string['fieldsmapping_pattern_help'] = 'Capturing groups PCRE patttern.';

View File

@@ -27,7 +27,13 @@ $string['otpgeneratedsubj'] = 'Hasło jednorazowe';
$string['otpgeneratedtext'] = 'Hasło jednorazowe dla bieżącej sesji: {$a->password}'; $string['otpgeneratedtext'] = 'Hasło jednorazowe dla bieżącej sesji: {$a->password}';
$string['otpsentsuccess'] = 'Hasło jednorazowe zostało wysłane na podany adres email.'; $string['otpsentsuccess'] = 'Hasło jednorazowe zostało wysłane na podany adres email.';
$string['otpsenterror'] = 'Wystąpił błąd podczas wysyłania hasła jednorazowego.'; $string['otpsenterror'] = 'Wystąpił błąd podczas wysyłania hasła jednorazowego.';
$string['otpsentinfo'] = 'Hasło jednorazowe dla bieżącej sesji już zostało wygenerowane i wyłane.'; $string['otpsentinfo'] = 'Hasło jednorazowe dla bieżącej sesji już zostało wygenerowane i wysłane.';
$string['otpinvalidated'] = 'Poprzednio wygenerowane hasło zostało unieważnione z powodu przekroczenia limitu niepoprawnych logowań.';
$string['optperioderror'] = 'Nie zachowany minimalny odstęp, po którym kolejne hasło może być wygenerowane. Spróbuj ponownie później.';
$string['revokethreshold'] = 'Próg nieważnienia';
$string['revokethreshold_help'] = 'Limit nieudanych logowań unieważniających wygenerowane hasło (0 - bez limitu).';
$string['minrequestperiod'] = 'Minimalny odstęp';
$string['minrequestperiod_help'] = 'Czas w sekundach, po którym kolejne hasło może być wygenerowane.';
$string['fieldsmapping'] = 'Mapowanie pól profilu użytkownika'; $string['fieldsmapping'] = 'Mapowanie pól profilu użytkownika';
$string['fieldsmapping_pattern'] = 'Wzorzec'; $string['fieldsmapping_pattern'] = 'Wzorzec';
$string['fieldsmapping_pattern_help'] = 'Grupujące wyrażenie regularne PCRE.'; $string['fieldsmapping_pattern_help'] = 'Grupujące wyrażenie regularne PCRE.';

View File

@@ -52,6 +52,17 @@ if ($ADMIN->fulltree) {
get_string('fieldsmapping_mapping', 'auth_emailotp'), get_string('fieldsmapping_mapping', 'auth_emailotp'),
get_string('fieldsmapping_mapping_help', 'auth_emailotp'), '', PARAM_RAW_TRIMMED)); get_string('fieldsmapping_mapping_help', 'auth_emailotp'), '', PARAM_RAW_TRIMMED));
$settings->add(new admin_setting_heading('auth_emailotp/security',
new lang_string('security', 'admin'), ''));
$settings->add(new admin_setting_configtext('auth_emailotp/revokethreshold',
get_string('revokethreshold', 'auth_emailotp'),
get_string('revokethreshold_help', 'auth_emailotp'), 3, PARAM_INT));
$settings->add(new admin_setting_configtext('auth_emailotp/minrequestperiod',
get_string('minrequestperiod', 'auth_emailotp'),
get_string('minrequestperiod_help', 'auth_emailotp'), 120, PARAM_INT));
// Display locking / mapping of profile fields. // Display locking / mapping of profile fields.
$authplugin = get_auth_plugin('emailotp'); $authplugin = get_auth_plugin('emailotp');
display_auth_lock_options($settings, $authplugin->authtype, $authplugin->userfields, display_auth_lock_options($settings, $authplugin->authtype, $authplugin->userfields,