From 18820c71911b9ef71ce1b25e94da9d395bceacd2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20G=C3=BCnther?=
Date: Mon, 26 Feb 2024 14:47:51 +0100
Subject: [PATCH] Protection of WordPress logins
---
assets/password.js | 43 +++
assets/security.css | 12 +
bdp-kompass.php | 12 +
includes/action_caller.php | 23 ++
includes/frontend-functions.php | 34 ++-
includes/pre_requires.php | 1 +
includes/setup.php | 12 +-
includes/spl.php | 32 ++
.../Controllers/LoginHandler.php | 282 ++++++++++++++++++
.../Controllers/OptionsPage.php | 130 ++++++++
.../Views/checkbox-option.php | 29 ++
.../LimitLoginAttempts/Views/radio-option.php | 35 +++
.../LimitLoginAttempts/Views/tab-control.php | 18 ++
.../LimitLoginAttempts/Views/text-element.php | 7 +
.../includes/block-and-allow-list-form.php | 56 ++++
.../includes/gui_elements.php | 116 +++++++
.../includes/validators.php | 64 ++++
.../includes/password_strength_rules.php | 10 +
18 files changed, 903 insertions(+), 13 deletions(-)
create mode 100644 assets/password.js
create mode 100644 includes/action_caller.php
create mode 100644 includes/spl.php
create mode 100644 modules/LimitLoginAttempts/Controllers/LoginHandler.php
create mode 100644 modules/LimitLoginAttempts/Controllers/OptionsPage.php
create mode 100644 modules/LimitLoginAttempts/Views/checkbox-option.php
create mode 100644 modules/LimitLoginAttempts/Views/radio-option.php
create mode 100644 modules/LimitLoginAttempts/Views/tab-control.php
create mode 100644 modules/LimitLoginAttempts/Views/text-element.php
create mode 100644 modules/LimitLoginAttempts/includes/block-and-allow-list-form.php
create mode 100644 modules/LimitLoginAttempts/includes/gui_elements.php
create mode 100644 modules/LimitLoginAttempts/includes/validators.php
create mode 100644 modules/PasswordStrength/includes/password_strength_rules.php
diff --git a/assets/password.js b/assets/password.js
new file mode 100644
index 0000000..8796982
--- /dev/null
+++ b/assets/password.js
@@ -0,0 +1,43 @@
+jQuery(document).ready(function($) {
+ $( "" ).insertBefore( ".submit" );
+
+ $("#password_too_short").css('display', 'none');
+
+ $(document).on('DOMSubtreeModified', '#pass-strength-result', function() {
+ var strengthMeter = $(this).attr('class');
+ var allowedStrengths = php_vars.allowed_strengths;
+
+ $( "[name='pw_weak']" ).css('visibility', 'hidden');
+ $( '.pw-weak' ).css('visibility', 'hidden');
+ $( '#pw-weak-text-label' ).css('visibility', 'hidden');
+
+ if (strengthMeter !== '') {
+ if (allowedStrengths.includes(strengthMeter)) {
+ $("[name='pw_weak']").prop("checked", true);
+ $("[name='submit']").css('display', 'inline');
+ $('#createusersub').css('display', 'inline');
+ $('submit').onclick = function() {
+ $('your-profile').submit();
+ };
+ $("#createusersub").onclick = function() {
+ $('createuser').submit();
+ };
+
+ $("#password_too_short").css('display', 'none');
+ } else {
+ $("#createusersub").css('display', 'none');
+ $("[name='submit']").prop("disabled", true);
+ $("[name='pw_weak']").prop("checked", false);
+ $("[name='submit']").css('display', 'none');
+ $('submit').onclick = function() {
+ return false;
+ };
+ $("#createusersub").onclick = function() {
+ return false;
+ };
+ $("#password_too_short").css('display', 'inline');
+ }
+ }
+ });
+});
\ No newline at end of file
diff --git a/assets/security.css b/assets/security.css
index 5e213a9..46884dd 100644
--- a/assets/security.css
+++ b/assets/security.css
@@ -50,4 +50,16 @@
.long_text {
width: 80%;
+}
+
+.protect-login-no-blocked-ips
+{
+ padding: 5px 10px;
+ width: 90%;
+ background-color: #ffffff;
+ border-style: solid;
+ border-color: #00a32a;
+ border-width: 1px;
+ font-weight: bold;
+ font-size: 12pt;
}
\ No newline at end of file
diff --git a/bdp-kompass.php b/bdp-kompass.php
index 1089ef6..fd253ce 100644
--- a/bdp-kompass.php
+++ b/bdp-kompass.php
@@ -12,6 +12,7 @@
* Text Domain: bdp-kompass
*/
+use Bdp\Modules\LimitLoginAttempts\Controllers\OptionsPage as OptionsPageAlias;
use Bdp\Modules\Security\Security;
use Bdp\Modules\Seo\Seo;
@@ -36,6 +37,9 @@ function bdp_plugin_init() {
}
}
+add_action('admin_menu', function () {
+ new OptionsPageAlias();
+});
function register_custom_theme_directory() {
@@ -47,4 +51,12 @@ function register_custom_theme_directory() {
switch_theme('buena');
}
+function enqueue_custom_password_js() {
+ wp_enqueue_script( 'custom-password-js', BDP_LV_PLUGIN_URL . 'assets/password.js');
+ wp_localize_script( 'custom-password-js', 'php_vars', [
+ 'allowed_strengths' => kompass_get_minimal_password_strength(),
+ 'password_too_short_text' => 'Dass Passwort entspricht nicht den Anforderungen.'
+ ]);
+}
+
#add_action( 'after_setup_theme', 'register_custom_theme_directory' );
diff --git a/includes/action_caller.php b/includes/action_caller.php
new file mode 100644
index 0000000..9913ef1
--- /dev/null
+++ b/includes/action_caller.php
@@ -0,0 +1,23 @@
+handleCookies();
+ add_action('auth_cookie_bad_username', [$loginHandler, 'checkFailedCookies']);
+ add_action('auth_cookie_valid', [$loginHandler, 'onValidCookie'], 10, 2);
+}
+
+if (isset($_POST['save_kompass_balist_list_type'])) {
+ updateBlockOrAllowList($_POST);
+}
+
+
diff --git a/includes/frontend-functions.php b/includes/frontend-functions.php
index a3b79df..e44b540 100644
--- a/includes/frontend-functions.php
+++ b/includes/frontend-functions.php
@@ -16,17 +16,13 @@ function bdp_update_dashboard_style() {
function bdp_add_menu_security() {
+
$moduleLoad = get_admin_url() . 'admin.php?page=' . BDP_LV_PLUGIN_SLUG . '/modules/index.php&loadmodule=';
- add_menu_page(
- 'Sicherheit',
- 'Webseiten-Sicherheit',
- 'manage_options',
- 'site-health.php',
- '',
- 'dashicons-admin-network',
- 5
- );
+
+
+
+
}
function bdp_add_menu_contents() {
@@ -69,7 +65,7 @@ function bdp_add_menu_mein_lv() {
$moduleLoad = get_admin_url() . 'admin.php?page=' . BDP_LV_PLUGIN_SLUG . '/modules/index.php&loadmodule=';
add_menu_page(
- 'Mein BDP',
+ 'Mein BdP',
'BdP',
'manage_options',
$mainSlug,
@@ -113,7 +109,7 @@ function bdp_add_menu_setup() {
add_submenu_page('users.php',
'Design-Einstellungen',
- 'Design',
+ 'Template bearbeiten',
'manage_options',
'customize.php?return=/wp-admin/'
);
@@ -132,6 +128,22 @@ function bdp_add_menu_setup() {
'manage_options',
'themes.php'
);
+
+ add_submenu_page('users.php',
+ 'Sicherheit',
+ 'Webseiten-Sicherheit',
+ 'manage_options',
+ 'site-health.php'
+ );
+
+ $loginOption = new \Bdp\Modules\LimitLoginAttempts\Controllers\OptionsPage();
+ add_submenu_page('users.php',
+ 'Login-Sicherheit',
+ 'Login-Sicherheit',
+ 'manage_options',
+ BDP_LV_PLUGIN_SLUG . '-limit-login-attempts',
+ [$loginOption, 'limit_login_option_page']
+ );
}
function bdp_cleanup_menu()
diff --git a/includes/pre_requires.php b/includes/pre_requires.php
index 1436eff..12dc003 100644
--- a/includes/pre_requires.php
+++ b/includes/pre_requires.php
@@ -3,3 +3,4 @@ require_once (ABSPATH . '/wp-admin/includes/plugin.php');
require_once (ABSPATH . '/wp-admin/includes/class-wp-filesystem-base.php');
require_once (ABSPATH . '/wp-admin/includes/class-wp-filesystem-direct.php');
require_once (ABSPATH . '/wp-includes/pluggable.php');
+require_once (ABSPATH . '/wp-admin/includes/template.php');
\ No newline at end of file
diff --git a/includes/setup.php b/includes/setup.php
index f8b5e8d..ca1e6a2 100644
--- a/includes/setup.php
+++ b/includes/setup.php
@@ -3,9 +3,12 @@ if ( ! defined( 'WP_PLUGIN_DIR' ) ) { // Abspath to wp-content/plu
define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' ); // Full path, no trailing slash.
}
+use Bdp\Modules\LimitLoginAttempts\Controllers\LoginHandler;
+
+
require_once dirname(__FILE__) . '/pre_requires.php';
require_once dirname(__FILE__) . '/environment.php';
-
+require_once dirname(__FILE__) . '/spl.php';
require_once dirname(__FILE__) . '/update.class.php';
require_once BDP_LV_PLUGIN_DIR . 'includes/FileAccess.class.php';
@@ -20,6 +23,10 @@ require_once (BDP_LV_PLUGIN_DIR . '/includes/frontend-functions.php');
require_once (BDP_LV_PLUGIN_DIR . '/modules/security/security.php');
+function admin_init()
+{
+ kompass_settings_validators();
+}
bdp_create_menu_structure();
@@ -31,6 +38,7 @@ function bdp_kompass_load_plugin_textdomain() {
-#$class =
+$loginHandler = new LoginHandler();
new BdpVersionChecker();
#add_filter( 'plugins_api', array( $class, 'info' ), 20, 3 );
+require_once dirname(__FILE__) . '/action_caller.php';
diff --git a/includes/spl.php b/includes/spl.php
new file mode 100644
index 0000000..5f3b398
--- /dev/null
+++ b/includes/spl.php
@@ -0,0 +1,32 @@
+isLoginAllowedFromIp() ) {
+ return $user;
+ }
+
+ global $limit_login_my_error_shown;
+ $limit_login_my_error_shown = true;
+
+ $error = new \WP_Error();
+ // This error should be the same as in "shake it" filter below
+ $error->add('too_many_retries', $this->composeErrorMessage());
+ return $error;
+ }
+
+ public function onFailedLogin(string $username) {
+ $ip = $this->getAddress();
+
+ /* if currently locked-out, do not add to retries */
+ $lockouts = get_option('protect_login_limit_login_lockouts', []);
+
+ if(isset($lockouts[$ip]) && time() < $lockouts[$ip]) {
+ return;
+ }
+
+ /* Get the arrays with retries and retries-valid information */
+ $retries = get_option('kompass_limit_login_retries', []);
+ $valid = get_option('kompass_limit_login_retries_valid', []);
+
+ /* Check validity and add one to retries */
+ if (isset($retries[$ip])) { //} && isset($valid[$ip]) && time() < $valid[$ip]) {
+ $retries[$ip] ++;
+ } else {
+ $retries[$ip] = 1;
+ }
+
+ update_option('kompass_limit_login_retries', $retries);
+
+ /* lockout? */
+ if($retries[$ip] % get_option('kompass_limit_login_allowed_retries', 0) != 0) {
+ return;
+ }
+
+
+ $retries_long = get_option('kompass_limit_login_allowed_retries', 1)
+ * get_option('kompass_limit_login_allowed_lockouts', 1);
+
+ if ($retries[$ip] >= $retries_long) {
+ $lockouts[$ip] = time() + get_option('kompass_limit_login_long_duration', 86400);
+
+ } else {
+ $lockouts[$ip] = time() + get_option('kompass_limit_login_lockout_duration', 900);
+ }
+
+ update_option('kompass_limit_login_lockouts', $lockouts);
+
+
+ /* do any notification */
+ $this->notify($username);
+
+ }
+
+ private function notifyByEmail($user)
+ {
+ $ip = $this->getAddress();
+
+ $lockouts = get_option('kompass_limit_login_lockouts', []);
+ if (!isset($lockouts[$ip])) {
+ return;
+ }
+
+ $blocked_until = $lockouts[$ip];
+
+ $retries = get_option('kompass_limit_login_retries', []);
+ $currentRetries = $retries[$ip];
+
+ $notify_after = get_option('kompass_limit_login_notify_email_after', 1);
+ if ($currentRetries % $notify_after !== 0) {
+ return;
+ }
+
+ $blogname = get_option('blogname', 'none');
+
+ $subject = sprintf(__("[%s] Too many failed login attempts"
+ , 'limit-login-attempts')
+ , $blogname);
+
+ $message = 'Neue Sperrung auf deiner Webseite: ' . PHP_EOL .
+ 'IP-Adresse: ' . $ip . PHP_EOL .
+ 'Gesperrt bis: ' . date('d.m.Y H:i', $blocked_until);
+
+ $admin_email = get_option('admin_email');
+ wp_mail($admin_email, $subject, $message);
+ }
+
+
+ /* Handle notification in event of lockout */
+ private function notify($user) {
+ $args = get_option('kompass_limit_login_lockout_notify', []);
+ if (!is_array($args)) {
+ $args = [$args];
+ }
+ foreach ($args as $mode) {
+ switch (trim($mode)) {
+ case 'email':
+ $this->notifyByEmail($user);
+ break;
+ }
+ }
+ }
+
+ private function composeErrorMessage() {
+ $ip = $this->getAddress();
+ $lockouts = get_option('kompass_limit_login_lockouts');
+
+ $msg = __('ERROR: Too many failed login attempts.', 'limit-login-attempts') . ' ';
+
+ if (!is_array($lockouts) || !isset($lockouts[$ip]) || time() >= $lockouts[$ip]) {
+ /* Huh? No timeout active? */
+ $msg .= __('Please try again later.', 'limit-login-attempts');
+ return $msg;
+ }
+
+ $when = ceil(($lockouts[$ip] - time()) / 60);
+ if ($when > 60) {
+ $when = ceil($when / 60);
+ $msg .= sprintf(_n('Please try again in %d hour.', 'Please try again in %d hours.', $when, 'limit-login-attempts'), $when);
+ } else {
+ $msg .= sprintf(_n('Please try again in %d minute.', 'Please try again in %d minutes.', $when, 'limit-login-attempts'), $when);
+ }
+
+ return $msg;
+ }
+
+ private static function getAddress($typeName = '') {
+ global $limitLoginAttemptsSettings;
+
+ $typeOriginal = $typeName;
+ if (empty($typeName)) {
+ $typeName = get_option('kompass_limit_loginclient_type', self::DIRECT_ADDR);
+ }
+
+ if (isset($_SERVER[$typeName]) && filter_var($_SERVER[$typeName], FILTER_VALIDATE_IP)) {
+ return $_SERVER[$typeName];
+ }
+
+ /*
+ * Not found. Did we get proxy type from option?
+ * If so, try to fall back to direct address.
+ */
+ if ( empty($typeName) && $typeOriginal == self::PROXY_ADDR
+ && isset($_SERVER[self::DIRECT_ADDR])
+ && filter_var($_SERVER[self::DIRECT_ADDR], FILTER_VALIDATE_IP)) {
+
+ /*
+ * NOTE: Even though we fall back to direct address -- meaning you
+ * can get a mostly working plugin when set to PROXY mode while in
+ * fact directly connected to Internet it is not safe!
+ *
+ * Client can itself send HTTP_X_FORWARDED_FOR header fooling us
+ * regarding which IP should be banned.
+ */
+
+ return $_SERVER[self::DIRECT_ADDR];
+ }
+
+ return '';
+
+ }
+
+ public function isLoginAllowedFromIp() {
+ $ip = $this->getAddress();
+
+ if (in_array($ip, get_option('kompass_limit_login_blocklist', []))) {
+ return false;
+ }
+
+ if (in_array($ip, get_option('kompass_limit_login_allowlist', []))) {
+ return true;
+ }
+
+ /* lockout active? */
+ $lockouts = get_option('kompass_limit_login_lockouts', []);
+ return (!is_array($lockouts) || !isset($lockouts[$ip]) || time() >= $lockouts[$ip]);
+ }
+
+ public function checkFailedCookies($cookie_elements) {
+ $this->clearAuthCookie();
+
+ /*
+ * Invalid username gets counted every time.
+ */
+
+ $this->onFailedLogin($cookie_elements['username']);
+ }
+
+ private function clearAuthCookie() {
+ wp_clear_auth_cookie();
+
+ if (!empty($_COOKIE[AUTH_COOKIE])) {
+ $_COOKIE[AUTH_COOKIE] = '';
+ }
+ if (!empty($_COOKIE[SECURE_AUTH_COOKIE])) {
+ $_COOKIE[SECURE_AUTH_COOKIE] = '';
+ }
+ if (!empty($_COOKIE[LOGGED_IN_COOKIE])) {
+ $_COOKIE[LOGGED_IN_COOKIE] = '';
+ }
+ }
+
+ public function onValidCookie($cookie_elements, $user) {
+ /*
+ * As all meta values get cached on user load this should not require
+ * any extra work for the common case of no stored value.
+ */
+
+ if (get_user_meta($user->ID, 'kompass_limit_login_previous_cookie')) {
+ delete_user_meta($user->ID, 'kompass_limit_login_previous_cookie');
+ }
+ }
+
+ function clearLoginCookie($cookie_elements) {
+ $this->clearAuthCookie();
+
+ /*
+ * Under some conditions an invalid auth cookie will be used multiple
+ * times, which results in multiple failed attempts from that one
+ * cookie.
+ *
+ * Unfortunately I've not been able to replicate this consistently and
+ * thus have not been able to make sure what the exact cause is.
+ *
+ * Probably it is because a reload of for example the admin dashboard
+ * might result in multiple requests from the browser before the invalid
+ * cookie can be cleard.
+ *
+ * Handle this by only counting the first attempt when the exact same
+ * cookie is attempted for a user.
+ */
+
+ extract($cookie_elements, EXTR_OVERWRITE);
+
+ // Check if cookie is for a valid user
+ $user = get_user_by('login', $username);
+ if (!$user) {
+ // "shouldn't happen" for this action
+ $this->onFailedLogin($username);
+ return;
+ }
+
+ $previous_cookie = get_user_meta($user->ID, 'kompass_limit_login_previous_cookie', true);
+ if ($previous_cookie && $previous_cookie == $cookie_elements) {
+ // Identical cookies, ignore this attempt
+ return;
+ }
+
+ // Store cookie
+ if ($previous_cookie)
+ update_user_meta($user->ID, 'kompass_limit_login_previous_cookie', $cookie_elements);
+ else
+ add_user_meta($user->ID, 'kompass_limit_login_previous_cookie', $cookie_elements, true);
+
+ $this->onFailedLogin($username);
+ }
+
+ public function handleCookies() {
+ if ($this->isLoginAllowedFromIp()) {
+ return;
+ }
+
+ $this->clearAuthCookie();
+ }
+}
\ No newline at end of file
diff --git a/modules/LimitLoginAttempts/Controllers/OptionsPage.php b/modules/LimitLoginAttempts/Controllers/OptionsPage.php
new file mode 100644
index 0000000..8e4f4f3
--- /dev/null
+++ b/modules/LimitLoginAttempts/Controllers/OptionsPage.php
@@ -0,0 +1,130 @@
+ $blockedUntil) {
+ $ips .= '' .
+ '' . $ip . ' | ' .
+ '' . date('d.m.Y H:i', $blockedUntil) . ' Uhr | ' .
+ '
+ Freigeben | ' .
+ '
';
+ };
+
+ return $ips;
+ }
+
+ public function limit_login_option_page() {
+ global $errors;
+
+ $showMessage = null;
+
+ if (isset($_POST['update_options'])) {
+ update_settings($_POST);
+ $showMessage = 'Die Einstellungen wurden gespeichert';
+ }
+ if (isset($_GET['action']) && $_GET['action'] == 'release') {
+ $showMessage = 'Die IP-Adresse wurde freigegeben.';
+ }
+
+ if(isset($_POST['save_kompass_balist_list_type'])) {
+ $showMessage = 'Die Liste wurde gespeichert.';
+ }
+
+ if (null !== $showMessage && $errors === false) {
+ echo '';
+ echo $showMessage;
+ echo '
';
+ }
+
+ if ($errors) {
+ echo '';
+ echo 'Beim Durchführen der Aktion ist ein Fehler aufgetreten.';
+ echo '
';
+ }
+
+ $tab = isset($_GET['tab']) ? $_GET['tab'] : 'tab1';
+ ?>
+
+
+
Protect Login - Einstellungen
+
+ = kompass_print_tab_header($tab); ?>
+
+
+ ';
+ do_settings_sections(BDP_LV_PLUGIN_SLUG . '-limit-login-attempts');
+ submit_button();
+ echo '';
+ break;
+ case 'tab2':
+ echo '
Blocklist
';
+ echo '';
+ break;
+ case 'tab3':
+ echo 'Allowlist
';
+ echo '';
+ break;
+ case 'tab4':
+ if (isset($_GET['action']) && $_GET['action'] == 'release') {
+ $this->releaseIp(base64_decode($_GET['ip']));
+ }
+ $blockedIps = $this->getBlockedIps();
+ ?>
+ Gesperrte IPs
+ ';
+ echo 'Derzeit sind keine Adressen gesperrt.';
+ echo '';
+ } else { ?>
+
+
+ IP |
+ Gesperrt bis |
+ Aktion |
+
+ = $blockedIps ?>
+
+
+
+
+ [
+ 'email' => 'E-Mail an Administrator'
+ ],
+ ];
+
+ if(!isset($options[$settingName])) {
+ return;
+ }
+
+ $setting = $options[$settingName];
+ foreach ($setting as $radioOption => $optionText) {
+ $isChecked = in_array($radioOption, $currentSetting) ? 'checked ' : '' ;
+
+ echo '' .
+ '
';
+ }
+}
diff --git a/modules/LimitLoginAttempts/Views/radio-option.php b/modules/LimitLoginAttempts/Views/radio-option.php
new file mode 100644
index 0000000..a317dfd
--- /dev/null
+++ b/modules/LimitLoginAttempts/Views/radio-option.php
@@ -0,0 +1,35 @@
+ [
+ 'REMOTE_ADDR' => 'Direkte Verbrindung',
+ 'HTTP_X_FORWARDED_FOR' => 'Hinter einem Proxy'
+ ],
+ 'kompass_limit_login_cookies' => [
+ true => 'Ja',
+ false => 'Nein'
+ ],
+ 'kompass_password_minimal_strength' => [
+ '1' => 'Alle Passwörter erlauben',
+ '2' => 'Mittelstarke Passwörter',
+ '3' => 'Nur Starke Passwörter'
+ ]
+ ];
+
+ if(!isset($options[$settingName])) {
+ return;
+ }
+
+ $setting = $options[$settingName];
+ foreach ($setting as $radioOption => $optionText) {
+ $isChecked = $currentSetting == $radioOption ? 'checked ' : '' ;
+ echo '' .
+ ' ';
+ }
+}
diff --git a/modules/LimitLoginAttempts/Views/tab-control.php b/modules/LimitLoginAttempts/Views/tab-control.php
new file mode 100644
index 0000000..c94a830
--- /dev/null
+++ b/modules/LimitLoginAttempts/Views/tab-control.php
@@ -0,0 +1,18 @@
+'.
+ '
+ Optionen
+ '.
+ '
+ Blocklist
+ '.
+ '
+ Allowlist
+ '.
+ '
+ Gesperrte IPs
+ ';
+ }
\ No newline at end of file
diff --git a/modules/LimitLoginAttempts/Views/text-element.php b/modules/LimitLoginAttempts/Views/text-element.php
new file mode 100644
index 0000000..2702e0c
--- /dev/null
+++ b/modules/LimitLoginAttempts/Views/text-element.php
@@ -0,0 +1,7 @@
+';
+ if (defined('WP_DEBUG') && WP_DEBUG == true) {
+ echo '
' . $settingName;
+ }
+}
diff --git a/modules/LimitLoginAttempts/includes/block-and-allow-list-form.php b/modules/LimitLoginAttempts/includes/block-and-allow-list-form.php
new file mode 100644
index 0000000..265584d
--- /dev/null
+++ b/modules/LimitLoginAttempts/includes/block-and-allow-list-form.php
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
= __('IP-Adresse hinzufügen', BDP_LV_PLUGIN_SLUG); ?>
+
+
+
+
+';
+}
+
+function _kompass_limit_logins_settings_callback($args) {
+ $setting = get_option($args['setting'], null);
+ if (null === $setting) {
+ $setting = '';
+ }
+
+ $value = esc_attr($setting);
+ if (isset($args['unit_division'])) {
+ $value = (int)$value / (int)$args['unit_division'];
+ }
+
+ kompass_print_textbox($args['setting'], $value);
+}
+
+function _kompass_limit_logins_settings_radio_callback($args)
+{
+ kompass_print_radio($args['setting']);
+}
+function _kompass_limit_logins_settings_checkbox_callback($args) {
+ kompass_print_checkbox($args['setting']);
+}
+
+
+
+
+
+
+add_settings_section(
+ 'custom_settings_section',
+ 'Optionen',
+ 'custom_settings_section_callback',
+ BDP_LV_PLUGIN_SLUG . '-limit-login-attempts'
+);
+
+$settings_page = BDP_LV_PLUGIN_SLUG . '-limit-login-attempts';
+
+
+
+add_settings_field(
+ 'kompass_lla_1',
+ 'Maximale Wiederholungen',
+ '_kompass_limit_logins_settings_callback',
+ $settings_page,
+ 'custom_settings_section',
+ ['setting' => 'kompass_limit_login_allowed_retries']);
+
+add_settings_field(
+ 'kompass_lla_2',
+ 'Dauer der Sperre (in Minuten)',
+ '_kompass_limit_logins_settings_callback',
+ $settings_page,
+ 'custom_settings_section',
+ ['setting' => 'kompass_limit_login_lockout_duration', 'unit_division' => 60 ]);
+
+add_settings_field(
+ 'kompass_lla_3',
+ 'Maximale Anzahl an Sperrungen',
+ '_kompass_limit_logins_settings_callback',
+ $settings_page,
+ 'custom_settings_section',
+ ['setting' => 'kompass_limit_login_allowed_lockouts']);
+
+add_settings_field(
+ 'kompass_lla_4',
+ 'Langzeitsperre in Stunden',
+ '_kompass_limit_logins_settings_callback',
+ $settings_page,
+ 'custom_settings_section',
+ ['setting' => 'kompass_limit_login_long_duration', 'unit_division' => 3600]);
+
+add_settings_field(
+ 'kompass_lla_5',
+ 'Mininmale Passwort-Stärke:',
+ '_kompass_limit_logins_settings_radio_callback',
+ $settings_page,
+ 'custom_settings_section',
+ ['setting' => 'kompass_password_minimal_strength']);
+
+add_settings_field(
+ 'kompass_lla_6',
+ 'Seite erreichbar über:',
+ '_kompass_limit_logins_settings_radio_callback',
+ $settings_page,
+ 'custom_settings_section',
+ ['setting' => 'kompass_limit_login_client_type']);
+
+add_settings_field(
+ 'kompass_lla_7',
+ 'Cookies verarbeiten',
+ '_kompass_limit_logins_settings_radio_callback',
+ $settings_page,
+ 'custom_settings_section',
+ ['setting' => 'kompass_limit_login_cookies']);
+
+add_settings_field(
+ 'kompass_lla_8',
+ 'Bei Sperrung benachrichtigen',
+ '_kompass_limit_logins_settings_checkbox_callback',
+ $settings_page,
+ 'custom_settings_section',
+ ['setting' => 'kompass_limit_login_lockout_notify']);
+
+add_settings_field(
+ 'kompass_lla_9',
+ 'Fehlversuche bis zur Benachrichtigung',
+ '_kompass_limit_logins_settings_callback',
+ $settings_page,
+ 'custom_settings_section',
+ ['setting' => 'kompass_limit_login_notify_email_after']);
diff --git a/modules/LimitLoginAttempts/includes/validators.php b/modules/LimitLoginAttempts/includes/validators.php
new file mode 100644
index 0000000..e2fb154
--- /dev/null
+++ b/modules/LimitLoginAttempts/includes/validators.php
@@ -0,0 +1,64 @@
+ 'short, bad, good, strong',
+ '2' => 'good, strong',
+ '3' => 'strong'];
+
+ return ' ' . $possibleStrengths[$minPasswordStrength];
+}
\ No newline at end of file