Version Description
- Ability to whitelist trusted IPs
- Ability to create custom message to show to blocked users
- Delay execution after a failed login attempt (to slow down brute force attack)
- Performance improvements
Download this release
Release Info
Developer | Jan-Paul Kleemans |
Plugin | Brute Force Login Protection |
Version | 1.4 |
Comparing to | |
See all releases |
Code changes from version 1.3 to 1.4
- brute-force-login-protection.php +198 -155
- includes/htaccess.php +233 -0
- settings-page.php → includes/settings-page.php +72 -23
- languages/brute-force-login-protection-nl_NL.mo +0 -0
- languages/brute-force-login-protection-nl_NL.po +123 -55
- readme.txt +12 -4
brute-force-login-protection.php
CHANGED
@@ -1,19 +1,19 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
require_once ABSPATH . '/wp-admin/includes/misc.php';
|
4 |
require_once ABSPATH . '/wp-admin/includes/file.php';
|
|
|
5 |
|
6 |
/**
|
7 |
* Plugin Name: Brute Force Login Protection
|
8 |
* Plugin URI: http://wordpress.org/plugins/brute-force-login-protection/
|
9 |
* Description: Protects your website against brute force login attacks using .htaccess
|
10 |
* Text Domain: brute-force-login-protection
|
11 |
-
* Author:
|
12 |
-
* Author URI: http://
|
13 |
-
* Version: 1.
|
14 |
* License: GPL2
|
15 |
*
|
16 |
-
* Copyright 2014
|
17 |
*
|
18 |
* This program is free software; you can redistribute it and/or modify
|
19 |
* it under the terms of the GNU General Public License, version 2, as
|
@@ -30,12 +30,21 @@ require_once ABSPATH . '/wp-admin/includes/file.php';
|
|
30 |
*/
|
31 |
class BruteForceLoginProtection {
|
32 |
|
33 |
-
private $__options;
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
public function __construct() {
|
36 |
//Default options
|
37 |
$this->__setDefaultOptions();
|
38 |
|
|
|
|
|
|
|
39 |
//Activation and deactivation hooks
|
40 |
register_activation_hook(__FILE__, array($this, 'activate'));
|
41 |
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
|
@@ -62,12 +71,6 @@ class BruteForceLoginProtection {
|
|
62 |
public function init() {
|
63 |
//Load textdomain for i18n
|
64 |
load_plugin_textdomain('brute-force-login-protection', false, dirname(plugin_basename(__FILE__)) . '/languages/');
|
65 |
-
|
66 |
-
//Overrule default $__options with database options
|
67 |
-
$this->__fillOptions();
|
68 |
-
|
69 |
-
//Call checkRequirements to check for .htaccess errors
|
70 |
-
add_action('admin_notices', array($this, 'showRequirementsErrors'));
|
71 |
}
|
72 |
|
73 |
/**
|
@@ -78,6 +81,12 @@ class BruteForceLoginProtection {
|
|
78 |
public function adminInit() {
|
79 |
//Register plugin settings
|
80 |
$this->__registerOptions();
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
}
|
82 |
|
83 |
/**
|
@@ -92,40 +101,21 @@ class BruteForceLoginProtection {
|
|
92 |
|
93 |
/**
|
94 |
* Called When the plugin is activated
|
95 |
-
* Adds base lines to .htaccess and resets commented denies.
|
96 |
*
|
97 |
* @return boolean
|
98 |
*/
|
99 |
public function activate() {
|
100 |
-
$
|
101 |
-
|
102 |
-
$insertion[] = '<Files "*">';
|
103 |
-
$insertion[] = 'order allow,deny';
|
104 |
-
foreach ($lines as $line) {
|
105 |
-
if (substr($line, 0, 10) === "#deny from") {
|
106 |
-
$insertion[] = 'deny from ' . substr($line, 11);
|
107 |
-
}
|
108 |
-
}
|
109 |
-
$insertion[] = 'allow from all';
|
110 |
-
$insertion[] = '</Files>';
|
111 |
-
|
112 |
-
return insert_with_markers($this->__options['htaccess_dir'] . '/.htaccess', 'Brute Force Login Protection', $insertion);
|
113 |
}
|
114 |
|
115 |
/**
|
116 |
* Called When the plugin is deactivated
|
117 |
-
* Comments out all denies in .htaccess.
|
118 |
*
|
119 |
* @return boolean
|
120 |
*/
|
121 |
public function deactivate() {
|
122 |
-
$
|
123 |
-
|
124 |
-
foreach ($deniedIPs as $deniedIP) {
|
125 |
-
$insertion[] = '#deny from ' . $deniedIP;
|
126 |
-
}
|
127 |
-
|
128 |
-
return insert_with_markers($this->__options['htaccess_dir'] . '/.htaccess', 'Brute Force Login Protection', $insertion);
|
129 |
}
|
130 |
|
131 |
/**
|
@@ -134,7 +124,7 @@ class BruteForceLoginProtection {
|
|
134 |
* @return void
|
135 |
*/
|
136 |
public function showRequirementsErrors() {
|
137 |
-
$status = $this->
|
138 |
|
139 |
if (!$status['found']) {
|
140 |
$this->__showError(__('Brute Force Login Protection error: .htaccess file not found', 'brute-force-login-protection'));
|
@@ -152,28 +142,46 @@ class BruteForceLoginProtection {
|
|
152 |
*/
|
153 |
public function showSettingsPage() {
|
154 |
if (isset($_POST['IP'])) {
|
155 |
-
$IP =
|
156 |
|
157 |
if (isset($_POST['block'])) { //Manually block IP
|
158 |
-
|
|
|
|
|
|
|
159 |
$this->__showMessage(sprintf(__('IP %s blocked', 'brute-force-login-protection'), $IP));
|
160 |
} else {
|
161 |
$this->__showError(sprintf(__('An error occurred while blocking IP %s', 'brute-force-login-protection'), $IP));
|
162 |
}
|
163 |
} elseif (isset($_POST['unblock'])) { //Unblock IP
|
164 |
-
if ($
|
165 |
$this->__showMessage(sprintf(__('IP %s unblocked', 'brute-force-login-protection'), $IP));
|
166 |
} else {
|
167 |
$this->__showError(sprintf(__('An error occurred while unblocking IP %s', 'brute-force-login-protection'), $IP));
|
168 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
}
|
170 |
-
} elseif (isset($_POST['reset'])) {
|
|
|
171 |
$this->__deleteOptions();
|
172 |
$this->__setDefaultOptions();
|
|
|
173 |
$this->__showMessage(sprintf(__('The Options have been successfully reset', 'brute-force-login-protection'), $IP));
|
174 |
}
|
175 |
|
176 |
-
|
|
|
177 |
}
|
178 |
|
179 |
/**
|
@@ -183,39 +191,49 @@ class BruteForceLoginProtection {
|
|
183 |
* @return void
|
184 |
*/
|
185 |
public function loginFailed() {
|
186 |
-
$attempts = get_option('bflp_login_attempts');
|
187 |
-
if (!is_array($attempts)) {
|
188 |
-
$attempts = array();
|
189 |
-
add_option('bflp_login_attempts', $attempts, '', 'no');
|
190 |
-
}
|
191 |
-
|
192 |
$IP = $this->__getClientIP();
|
193 |
-
$
|
194 |
|
195 |
-
if (
|
196 |
-
$
|
197 |
-
|
198 |
-
|
199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
} else {
|
|
|
201 |
$attempts[$IP]['time'] = time();
|
202 |
}
|
203 |
-
} else {
|
204 |
-
$attempts[$IP]['attempts'] = 1;
|
205 |
-
$attempts[$IP]['time'] = time();
|
206 |
-
}
|
207 |
|
208 |
-
|
209 |
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
|
217 |
-
|
218 |
-
|
|
|
|
|
|
|
|
|
219 |
}
|
220 |
}
|
221 |
|
@@ -251,6 +269,7 @@ class BruteForceLoginProtection {
|
|
251 |
return $input;
|
252 |
} else {
|
253 |
add_settings_error('bflp_allowed_attempts', 'bflp_allowed_attempts', __('Allowed login attempts must be a number (between 1 and 100)', 'brute-force-login-protection'));
|
|
|
254 |
return $this->__options['allowed_attempts'];
|
255 |
}
|
256 |
}
|
@@ -266,67 +285,61 @@ class BruteForceLoginProtection {
|
|
266 |
return $input;
|
267 |
} else {
|
268 |
add_settings_error('bflp_reset_time', 'bflp_reset_time', __('Minutes before resetting must be a number (higher than 1)', 'brute-force-login-protection'));
|
|
|
269 |
return $this->__options['reset_time'];
|
270 |
}
|
271 |
}
|
272 |
|
273 |
/**
|
274 |
-
*
|
|
|
|
|
|
|
275 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
276 |
|
277 |
/**
|
278 |
-
*
|
279 |
*
|
280 |
-
* @
|
|
|
281 |
*/
|
282 |
-
public function
|
283 |
-
$
|
284 |
-
'found' => false,
|
285 |
-
'readable' => false,
|
286 |
-
'writeable' => false
|
287 |
-
);
|
288 |
-
|
289 |
-
$htaccessPath = $this->__options['htaccess_dir'] . '/.htaccess';
|
290 |
|
291 |
-
if (
|
292 |
-
$
|
293 |
-
}
|
294 |
-
|
295 |
-
$
|
296 |
-
|
297 |
-
if (is_writeable($htaccessPath)) { //File writeable
|
298 |
-
$status['writeable'] = true;
|
299 |
}
|
300 |
-
|
301 |
-
return $status;
|
302 |
}
|
303 |
|
304 |
/**
|
305 |
-
*
|
306 |
-
*
|
307 |
-
* @return void
|
308 |
*/
|
309 |
-
private function __registerOptions() {
|
310 |
-
register_setting('brute-force-login-protection', 'bflp_allowed_attempts', array($this, 'validateAllowedAttempts'));
|
311 |
-
register_setting('brute-force-login-protection', 'bflp_reset_time', array($this, 'validateResetTime'));
|
312 |
-
register_setting('brute-force-login-protection', 'bflp_inform_user');
|
313 |
-
register_setting('brute-force-login-protection', 'bflp_htaccess_dir');
|
314 |
-
}
|
315 |
|
316 |
/**
|
317 |
-
*
|
318 |
*
|
319 |
* @return void
|
320 |
*/
|
321 |
-
private function
|
322 |
-
$this->
|
323 |
-
$this->
|
324 |
-
$this->__options['inform_user'] = get_option('bflp_inform_user', $this->__options['inform_user']);
|
325 |
-
$this->__options['htaccess_dir'] = get_option('bflp_htaccess_dir', $this->__options['htaccess_dir']);
|
326 |
}
|
327 |
|
328 |
/**
|
329 |
-
*
|
330 |
*
|
331 |
* @return void
|
332 |
*/
|
@@ -334,82 +347,128 @@ class BruteForceLoginProtection {
|
|
334 |
$this->__options = array(
|
335 |
'allowed_attempts' => 20, //Allowed login attempts before deny,
|
336 |
'reset_time' => 60, //Minutes before resetting login attempts count
|
|
|
337 |
'inform_user' => true, //Inform user about remaining login attempts on login page
|
|
|
338 |
'htaccess_dir' => get_home_path() //.htaccess file location
|
339 |
);
|
340 |
}
|
341 |
|
342 |
/**
|
343 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
344 |
*
|
345 |
* @return void
|
346 |
*/
|
347 |
private function __deleteOptions() {
|
348 |
delete_option('bflp_allowed_attempts');
|
349 |
delete_option('bflp_reset_time');
|
|
|
350 |
delete_option('bflp_inform_user');
|
|
|
351 |
delete_option('bflp_htaccess_dir');
|
352 |
}
|
353 |
|
354 |
/**
|
355 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
356 |
*
|
357 |
* @return array
|
358 |
*/
|
359 |
-
private function
|
360 |
-
$
|
361 |
|
362 |
-
|
363 |
-
|
364 |
-
if (substr($line, 0, 9) === "deny from") {
|
365 |
-
$deniedIPs[] = substr($line, 10);
|
366 |
-
}
|
367 |
}
|
368 |
|
369 |
-
return $
|
370 |
}
|
371 |
|
372 |
/**
|
373 |
-
* Adds
|
374 |
*
|
375 |
* @param string $IP
|
376 |
* @return boolean
|
377 |
*/
|
378 |
-
private function
|
379 |
-
$
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
$
|
384 |
-
|
385 |
-
|
|
|
|
|
|
|
386 |
}
|
387 |
-
$insertion[] = 'allow from all';
|
388 |
-
$insertion[] = '</Files>';
|
389 |
|
390 |
-
|
|
|
|
|
391 |
}
|
392 |
|
393 |
/**
|
394 |
-
* Removes
|
395 |
*
|
396 |
* @param string $IP
|
397 |
* @return boolean
|
398 |
*/
|
399 |
-
private function
|
400 |
-
$
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
|
|
|
|
|
|
|
|
|
|
408 |
}
|
409 |
-
$insertion[] = 'allow from all';
|
410 |
-
$insertion[] = '</Files>';
|
411 |
|
412 |
-
|
|
|
|
|
413 |
}
|
414 |
|
415 |
/**
|
@@ -418,23 +477,7 @@ class BruteForceLoginProtection {
|
|
418 |
* @return mixed
|
419 |
*/
|
420 |
private function __getClientIP() {
|
421 |
-
$
|
422 |
-
|
423 |
-
if ($_SERVER['HTTP_CLIENT_IP']) {
|
424 |
-
$IP = $_SERVER['HTTP_CLIENT_IP'];
|
425 |
-
} elseif ($_SERVER['HTTP_X_FORWARDED_FOR']) {
|
426 |
-
$IP = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
427 |
-
} elseif ($_SERVER['HTTP_X_FORWARDED']) {
|
428 |
-
$IP = $_SERVER['HTTP_X_FORWARDED'];
|
429 |
-
} elseif ($_SERVER['HTTP_FORWARDED_FOR']) {
|
430 |
-
$IP = $_SERVER['HTTP_FORWARDED_FOR'];
|
431 |
-
} elseif ($_SERVER['HTTP_FORWARDED']) {
|
432 |
-
$IP = $_SERVER['HTTP_FORWARDED'];
|
433 |
-
} elseif ($_SERVER['REMOTE_ADDR']) {
|
434 |
-
$IP = $_SERVER['REMOTE_ADDR'];
|
435 |
-
}
|
436 |
-
|
437 |
-
return $IP;
|
438 |
}
|
439 |
|
440 |
/**
|
@@ -459,5 +502,5 @@ class BruteForceLoginProtection {
|
|
459 |
|
460 |
}
|
461 |
|
462 |
-
//Instantiate
|
463 |
new BruteForceLoginProtection();
|
1 |
<?php
|
2 |
|
|
|
3 |
require_once ABSPATH . '/wp-admin/includes/file.php';
|
4 |
+
require_once 'includes/htaccess.php';
|
5 |
|
6 |
/**
|
7 |
* Plugin Name: Brute Force Login Protection
|
8 |
* Plugin URI: http://wordpress.org/plugins/brute-force-login-protection/
|
9 |
* Description: Protects your website against brute force login attacks using .htaccess
|
10 |
* Text Domain: brute-force-login-protection
|
11 |
+
* Author: Fresh-Media
|
12 |
+
* Author URI: http://fresh-media.nl/
|
13 |
+
* Version: 1.4
|
14 |
* License: GPL2
|
15 |
*
|
16 |
+
* Copyright 2014 Fresh-Media
|
17 |
*
|
18 |
* This program is free software; you can redistribute it and/or modify
|
19 |
* it under the terms of the GNU General Public License, version 2, as
|
30 |
*/
|
31 |
class BruteForceLoginProtection {
|
32 |
|
33 |
+
private $__options, $__htaccess;
|
34 |
|
35 |
+
/**
|
36 |
+
* Initializes $__options and $__htaccess.
|
37 |
+
* Interacts with WordPress hooks.
|
38 |
+
*
|
39 |
+
* @return void
|
40 |
+
*/
|
41 |
public function __construct() {
|
42 |
//Default options
|
43 |
$this->__setDefaultOptions();
|
44 |
|
45 |
+
//Instantiate Htaccess class
|
46 |
+
$this->__htaccess = new Htaccess();
|
47 |
+
|
48 |
//Activation and deactivation hooks
|
49 |
register_activation_hook(__FILE__, array($this, 'activate'));
|
50 |
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
|
71 |
public function init() {
|
72 |
//Load textdomain for i18n
|
73 |
load_plugin_textdomain('brute-force-login-protection', false, dirname(plugin_basename(__FILE__)) . '/languages/');
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
|
76 |
/**
|
81 |
public function adminInit() {
|
82 |
//Register plugin settings
|
83 |
$this->__registerOptions();
|
84 |
+
|
85 |
+
//Set htaccess path
|
86 |
+
$this->__setHtaccessPath();
|
87 |
+
|
88 |
+
//Call checkRequirements to check for .htaccess errors
|
89 |
+
add_action('admin_notices', array($this, 'showRequirementsErrors'));
|
90 |
}
|
91 |
|
92 |
/**
|
101 |
|
102 |
/**
|
103 |
* Called When the plugin is activated
|
|
|
104 |
*
|
105 |
* @return boolean
|
106 |
*/
|
107 |
public function activate() {
|
108 |
+
$this->__setHtaccessPath();
|
109 |
+
$this->__htaccess->uncommentLines();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
}
|
111 |
|
112 |
/**
|
113 |
* Called When the plugin is deactivated
|
|
|
114 |
*
|
115 |
* @return boolean
|
116 |
*/
|
117 |
public function deactivate() {
|
118 |
+
$this->__htaccess->commentLines();
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
}
|
120 |
|
121 |
/**
|
124 |
* @return void
|
125 |
*/
|
126 |
public function showRequirementsErrors() {
|
127 |
+
$status = $this->__htaccess->checkRequirements();
|
128 |
|
129 |
if (!$status['found']) {
|
130 |
$this->__showError(__('Brute Force Login Protection error: .htaccess file not found', 'brute-force-login-protection'));
|
142 |
*/
|
143 |
public function showSettingsPage() {
|
144 |
if (isset($_POST['IP'])) {
|
145 |
+
$IP = $_POST['IP'];
|
146 |
|
147 |
if (isset($_POST['block'])) { //Manually block IP
|
148 |
+
$whitelist = $this->__getWhitelist();
|
149 |
+
if (in_array($IP, $whitelist)) {
|
150 |
+
$this->__showError(sprintf(__('You can\'t block a whitelisted IP', 'brute-force-login-protection'), $IP));
|
151 |
+
} elseif ($this->__htaccess->denyIP($IP)) {
|
152 |
$this->__showMessage(sprintf(__('IP %s blocked', 'brute-force-login-protection'), $IP));
|
153 |
} else {
|
154 |
$this->__showError(sprintf(__('An error occurred while blocking IP %s', 'brute-force-login-protection'), $IP));
|
155 |
}
|
156 |
} elseif (isset($_POST['unblock'])) { //Unblock IP
|
157 |
+
if ($this->__htaccess->undenyIP($IP)) {
|
158 |
$this->__showMessage(sprintf(__('IP %s unblocked', 'brute-force-login-protection'), $IP));
|
159 |
} else {
|
160 |
$this->__showError(sprintf(__('An error occurred while unblocking IP %s', 'brute-force-login-protection'), $IP));
|
161 |
}
|
162 |
+
} elseif (isset($_POST['whitelist'])) { //Add IP to whitelist
|
163 |
+
if ($this->__whitelistIP($IP)) {
|
164 |
+
$this->__showMessage(sprintf(__('IP %s added to whitelist', 'brute-force-login-protection'), $IP));
|
165 |
+
} else {
|
166 |
+
$this->__showError(sprintf(__('An error occurred while adding IP %s to whitelist', 'brute-force-login-protection'), $IP));
|
167 |
+
}
|
168 |
+
} elseif (isset($_POST['unwhitelist'])) { //Remove IP from whitelist
|
169 |
+
if ($this->__unwhitelistIP($IP)) {
|
170 |
+
$this->__showMessage(sprintf(__('IP %s removed from whitelist', 'brute-force-login-protection'), $IP));
|
171 |
+
} else {
|
172 |
+
$this->__showError(sprintf(__('An error occurred while removing IP %s from whitelist', 'brute-force-login-protection'), $IP));
|
173 |
+
}
|
174 |
}
|
175 |
+
} elseif (isset($_POST['reset'])) { //Reset settings
|
176 |
+
$this->__htaccess->remove403Message();
|
177 |
$this->__deleteOptions();
|
178 |
$this->__setDefaultOptions();
|
179 |
+
$this->__setHtaccessPath();
|
180 |
$this->__showMessage(sprintf(__('The Options have been successfully reset', 'brute-force-login-protection'), $IP));
|
181 |
}
|
182 |
|
183 |
+
$this->__fillOptions();
|
184 |
+
include 'includes/settings-page.php';
|
185 |
}
|
186 |
|
187 |
/**
|
191 |
* @return void
|
192 |
*/
|
193 |
public function loginFailed() {
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
$IP = $this->__getClientIP();
|
195 |
+
$whitelist = $this->__getWhitelist();
|
196 |
|
197 |
+
if (!in_array($IP, $whitelist)) {
|
198 |
+
$this->__fillOptions();
|
199 |
+
|
200 |
+
sleep($this->__options['login_failed_delay']);
|
201 |
+
|
202 |
+
$attempts = get_option('bflp_login_attempts');
|
203 |
+
if (!is_array($attempts)) {
|
204 |
+
$attempts = array();
|
205 |
+
add_option('bflp_login_attempts', $attempts, '', 'no');
|
206 |
+
}
|
207 |
+
|
208 |
+
$denyIP = false;
|
209 |
+
if ($IP && isset($attempts[$IP]) && $attempts[$IP]['time'] > (time() - ($this->__options['reset_time'] * 60))) {
|
210 |
+
$attempts[$IP]['attempts'] ++;
|
211 |
+
if ($attempts[$IP]['attempts'] >= $this->__options['allowed_attempts']) {
|
212 |
+
$denyIP = true;
|
213 |
+
unset($attempts[$IP]);
|
214 |
+
} else {
|
215 |
+
$attempts[$IP]['time'] = time();
|
216 |
+
}
|
217 |
} else {
|
218 |
+
$attempts[$IP]['attempts'] = 1;
|
219 |
$attempts[$IP]['time'] = time();
|
220 |
}
|
|
|
|
|
|
|
|
|
221 |
|
222 |
+
update_option('bflp_login_attempts', $attempts);
|
223 |
|
224 |
+
if ($denyIP) {
|
225 |
+
$this->__setHtaccessPath();
|
226 |
+
$this->__htaccess->denyIP($IP);
|
227 |
+
header('HTTP/1.0 403 Forbidden');
|
228 |
+
die($this->__options['403_message']);
|
229 |
+
}
|
230 |
|
231 |
+
if ($this->__options['inform_user']) {
|
232 |
+
global $error;
|
233 |
+
$remainingAttempts = $this->__options['allowed_attempts'] - $attempts[$IP]['attempts'];
|
234 |
+
$error .= '<br />';
|
235 |
+
$error .= sprintf(_n("%d attempt remaining.", "%d attempts remaining.", $remainingAttempts, 'brute-force-login-protection'), $remainingAttempts);
|
236 |
+
}
|
237 |
}
|
238 |
}
|
239 |
|
269 |
return $input;
|
270 |
} else {
|
271 |
add_settings_error('bflp_allowed_attempts', 'bflp_allowed_attempts', __('Allowed login attempts must be a number (between 1 and 100)', 'brute-force-login-protection'));
|
272 |
+
$this->__fillOption('allowed_attempts');
|
273 |
return $this->__options['allowed_attempts'];
|
274 |
}
|
275 |
}
|
285 |
return $input;
|
286 |
} else {
|
287 |
add_settings_error('bflp_reset_time', 'bflp_reset_time', __('Minutes before resetting must be a number (higher than 1)', 'brute-force-login-protection'));
|
288 |
+
$this->__fillOption('reset_time');
|
289 |
return $this->__options['reset_time'];
|
290 |
}
|
291 |
}
|
292 |
|
293 |
/**
|
294 |
+
* Validates bflp_login_failed_delay field.
|
295 |
+
*
|
296 |
+
* @param mixed $input
|
297 |
+
* @return int
|
298 |
*/
|
299 |
+
public function validateLoginFailedDelay($input) {
|
300 |
+
if (is_numeric($input) && ($input >= 1 && $input <= 10)) {
|
301 |
+
return $input;
|
302 |
+
} else {
|
303 |
+
add_settings_error('bflp_login_failed_delay', 'bflp_login_failed_delay', __('Failed login delay must be a number (between 1 and 10)', 'brute-force-login-protection'));
|
304 |
+
$this->__fillOption('login_failed_delay');
|
305 |
+
return $this->__options['login_failed_delay'];
|
306 |
+
}
|
307 |
+
}
|
308 |
|
309 |
/**
|
310 |
+
* Saves bflp_403_message field to .htaccess.
|
311 |
*
|
312 |
+
* @param mixed $input
|
313 |
+
* @return string
|
314 |
*/
|
315 |
+
public function validate403Message($input) {
|
316 |
+
$message = htmlentities($input);
|
|
|
|
|
|
|
|
|
|
|
|
|
317 |
|
318 |
+
if ($this->__htaccess->edit403Message($message)) {
|
319 |
+
return $message;
|
320 |
+
} else {
|
321 |
+
add_settings_error('bflp_403_message', 'bflp_403_message', __('An error occurred while saving the blocked users message', 'brute-force-login-protection'));
|
322 |
+
$this->__fillOption('403_message');
|
323 |
+
return $this->__options['403_message'];
|
|
|
|
|
324 |
}
|
|
|
|
|
325 |
}
|
326 |
|
327 |
/**
|
328 |
+
* Private functions
|
|
|
|
|
329 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
|
331 |
/**
|
332 |
+
* Sets htaccess path to $__options['htaccess_dir'].
|
333 |
*
|
334 |
* @return void
|
335 |
*/
|
336 |
+
private function __setHtaccessPath() {
|
337 |
+
$this->__fillOption('htaccess_dir');
|
338 |
+
$this->__htaccess->setPath($this->__options['htaccess_dir']);
|
|
|
|
|
339 |
}
|
340 |
|
341 |
/**
|
342 |
+
* Sets default options into $__options
|
343 |
*
|
344 |
* @return void
|
345 |
*/
|
347 |
$this->__options = array(
|
348 |
'allowed_attempts' => 20, //Allowed login attempts before deny,
|
349 |
'reset_time' => 60, //Minutes before resetting login attempts count
|
350 |
+
'login_failed_delay' => 1, //Delay in seconds when a user login has failed
|
351 |
'inform_user' => true, //Inform user about remaining login attempts on login page
|
352 |
+
'403_message' => '', //Message to show to a blocked user
|
353 |
'htaccess_dir' => get_home_path() //.htaccess file location
|
354 |
);
|
355 |
}
|
356 |
|
357 |
/**
|
358 |
+
* Registers options (settings).
|
359 |
+
*
|
360 |
+
* @return void
|
361 |
+
*/
|
362 |
+
private function __registerOptions() {
|
363 |
+
register_setting('brute-force-login-protection', 'bflp_allowed_attempts', array($this, 'validateAllowedAttempts'));
|
364 |
+
register_setting('brute-force-login-protection', 'bflp_reset_time', array($this, 'validateResetTime'));
|
365 |
+
register_setting('brute-force-login-protection', 'bflp_login_failed_delay', array($this, 'validateLoginFailedDelay'));
|
366 |
+
register_setting('brute-force-login-protection', 'bflp_inform_user');
|
367 |
+
register_setting('brute-force-login-protection', 'bflp_403_message', array($this, 'validate403Message'));
|
368 |
+
register_setting('brute-force-login-protection', 'bflp_htaccess_dir');
|
369 |
+
}
|
370 |
+
|
371 |
+
/**
|
372 |
+
* Deletes options from database.
|
373 |
*
|
374 |
* @return void
|
375 |
*/
|
376 |
private function __deleteOptions() {
|
377 |
delete_option('bflp_allowed_attempts');
|
378 |
delete_option('bflp_reset_time');
|
379 |
+
delete_option('bflp_login_failed_delay');
|
380 |
delete_option('bflp_inform_user');
|
381 |
+
delete_option('bflp_403_message');
|
382 |
delete_option('bflp_htaccess_dir');
|
383 |
}
|
384 |
|
385 |
/**
|
386 |
+
* Fills options with value (from database).
|
387 |
+
*
|
388 |
+
* @return void
|
389 |
+
*/
|
390 |
+
private function __fillOptions() {
|
391 |
+
$this->__options['allowed_attempts'] = get_option('bflp_allowed_attempts', $this->__options['allowed_attempts']);
|
392 |
+
$this->__options['reset_time'] = get_option('bflp_reset_time', $this->__options['reset_time']);
|
393 |
+
$this->__options['login_failed_delay'] = get_option('bflp_login_failed_delay', $this->__options['login_failed_delay']);
|
394 |
+
$this->__options['inform_user'] = get_option('bflp_inform_user', $this->__options['inform_user']);
|
395 |
+
$this->__options['403_message'] = get_option('bflp_403_message', $this->__options['403_message']);
|
396 |
+
}
|
397 |
+
|
398 |
+
/**
|
399 |
+
* Fills single option with value (from database).
|
400 |
+
*
|
401 |
+
* @param string $name
|
402 |
+
* @return void
|
403 |
+
*/
|
404 |
+
private function __fillOption($name) {
|
405 |
+
$this->__options[$name] = get_option('bflp_' . $name, $this->__options[$name]);
|
406 |
+
}
|
407 |
+
|
408 |
+
/**
|
409 |
+
* Returs array of whitelisted IP addresses.
|
410 |
*
|
411 |
* @return array
|
412 |
*/
|
413 |
+
private function __getWhitelist() {
|
414 |
+
$whitelist = get_option('bflp_whitelist');
|
415 |
|
416 |
+
if (!is_array($whitelist)) {
|
417 |
+
return array();
|
|
|
|
|
|
|
418 |
}
|
419 |
|
420 |
+
return $whitelist;
|
421 |
}
|
422 |
|
423 |
/**
|
424 |
+
* Adds IP to whitelist.
|
425 |
*
|
426 |
* @param string $IP
|
427 |
* @return boolean
|
428 |
*/
|
429 |
+
private function __whitelistIP($IP) {
|
430 |
+
if (!filter_var($IP, FILTER_VALIDATE_IP)) {
|
431 |
+
return false;
|
432 |
+
}
|
433 |
+
|
434 |
+
$this->__htaccess->undenyIP($IP);
|
435 |
+
|
436 |
+
$whitelist = get_option('bflp_whitelist');
|
437 |
+
if (!is_array($whitelist)) {
|
438 |
+
$whitelist = array($IP);
|
439 |
+
return add_option('bflp_whitelist', $whitelist, '', 'no');
|
440 |
}
|
|
|
|
|
441 |
|
442 |
+
$whitelist[] = $IP;
|
443 |
+
|
444 |
+
return update_option('bflp_whitelist', array_unique($whitelist));
|
445 |
}
|
446 |
|
447 |
/**
|
448 |
+
* Removes IP from whitelist.
|
449 |
*
|
450 |
* @param string $IP
|
451 |
* @return boolean
|
452 |
*/
|
453 |
+
private function __unwhitelistIP($IP) {
|
454 |
+
if (!filter_var($IP, FILTER_VALIDATE_IP)) {
|
455 |
+
return false;
|
456 |
+
}
|
457 |
+
|
458 |
+
$whitelist = get_option('bflp_whitelist');
|
459 |
+
if (!is_array($whitelist)) {
|
460 |
+
return false;
|
461 |
+
}
|
462 |
+
|
463 |
+
$IPKey = array_search($IP, $whitelist);
|
464 |
+
|
465 |
+
if ($IPKey === false) {
|
466 |
+
return false;
|
467 |
}
|
|
|
|
|
468 |
|
469 |
+
unset($whitelist[$IPKey]);
|
470 |
+
|
471 |
+
return update_option('bflp_whitelist', $whitelist);
|
472 |
}
|
473 |
|
474 |
/**
|
477 |
* @return mixed
|
478 |
*/
|
479 |
private function __getClientIP() {
|
480 |
+
return $_SERVER['REMOTE_ADDR'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
481 |
}
|
482 |
|
483 |
/**
|
502 |
|
503 |
}
|
504 |
|
505 |
+
//Instantiate BruteForceLoginProtection class
|
506 |
new BruteForceLoginProtection();
|
includes/htaccess.php
ADDED
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once ABSPATH . '/wp-admin/includes/misc.php';
|
4 |
+
|
5 |
+
class Htaccess {
|
6 |
+
|
7 |
+
private $__path;
|
8 |
+
private $__header = array(
|
9 |
+
'<Files "*">',
|
10 |
+
'Order deny,allow'
|
11 |
+
);
|
12 |
+
private $__footer = array(
|
13 |
+
'</Files>'
|
14 |
+
);
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Initializes $__path.
|
18 |
+
*
|
19 |
+
* @param string $dir
|
20 |
+
*/
|
21 |
+
public function setPath($dir) {
|
22 |
+
$this->__path = $dir . '/.htaccess';
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Checks if .htaccess file is found, readable and writeable.
|
27 |
+
*
|
28 |
+
* @return array
|
29 |
+
*/
|
30 |
+
public function checkRequirements() {
|
31 |
+
$status = array(
|
32 |
+
'found' => false,
|
33 |
+
'readable' => false,
|
34 |
+
'writeable' => false
|
35 |
+
);
|
36 |
+
|
37 |
+
if (file_exists($this->__path)) { //File found
|
38 |
+
$status['found'] = true;
|
39 |
+
}
|
40 |
+
if (is_readable($this->__path)) { //File readable
|
41 |
+
$status['readable'] = true;
|
42 |
+
}
|
43 |
+
if (is_writeable($this->__path)) { //File writeable
|
44 |
+
$status['writeable'] = true;
|
45 |
+
}
|
46 |
+
|
47 |
+
return $status;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Returs array of denied IP addresses from .htaccess.
|
52 |
+
*
|
53 |
+
* @return array
|
54 |
+
*/
|
55 |
+
public function getDeniedIPs() {
|
56 |
+
return $this->__getLines('deny from ');
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Adds 'deny from $IP' to .htaccess.
|
61 |
+
*
|
62 |
+
* @param string $IP
|
63 |
+
* @return boolean
|
64 |
+
*/
|
65 |
+
public function denyIP($IP) {
|
66 |
+
if (!filter_var($IP, FILTER_VALIDATE_IP)) {
|
67 |
+
return false;
|
68 |
+
}
|
69 |
+
|
70 |
+
return $this->__addLine('deny from ' . $IP);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Removes 'deny from $IP' from .htaccess.
|
75 |
+
*
|
76 |
+
* @param string $IP
|
77 |
+
* @return boolean
|
78 |
+
*/
|
79 |
+
public function undenyIP($IP) {
|
80 |
+
if (!filter_var($IP, FILTER_VALIDATE_IP)) {
|
81 |
+
return false;
|
82 |
+
}
|
83 |
+
|
84 |
+
return $this->__removeLine('deny from ' . $IP);
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Edits ErrorDocument 403 line in .htaccess.
|
89 |
+
*
|
90 |
+
* @param string $message
|
91 |
+
* @return boolean
|
92 |
+
*/
|
93 |
+
public function edit403Message($message) {
|
94 |
+
if (empty($message)) {
|
95 |
+
return $this->remove403Message();
|
96 |
+
}
|
97 |
+
|
98 |
+
$line = 'ErrorDocument 403 "' . $message . '"';
|
99 |
+
|
100 |
+
$otherLines = $this->__getLines('ErrorDocument 403 ', true, true);
|
101 |
+
|
102 |
+
$insertion = array_merge($this->__header, array($line), $otherLines, $this->__footer);
|
103 |
+
|
104 |
+
return insert_with_markers($this->__path, 'Brute Force Login Protection', $insertion);
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Removes ErrorDocument 403 line from .htaccess.
|
109 |
+
*
|
110 |
+
* @return boolean
|
111 |
+
*/
|
112 |
+
public function remove403Message() {
|
113 |
+
return $this->__removeLine('', 'ErrorDocument 403 ');
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Comments out all BFLP lines in .htaccess.
|
118 |
+
*
|
119 |
+
* @return boolean
|
120 |
+
*/
|
121 |
+
public function commentLines() {
|
122 |
+
$currentLines = $this->__getLines();
|
123 |
+
|
124 |
+
$insertion = array();
|
125 |
+
foreach ($currentLines as $line) {
|
126 |
+
$insertion[] = '#' . $line;
|
127 |
+
}
|
128 |
+
|
129 |
+
return insert_with_markers($this->__path, 'Brute Force Login Protection', $insertion);
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Uncomments all commented BFLP lines in .htaccess.
|
134 |
+
*
|
135 |
+
* @return boolean
|
136 |
+
*/
|
137 |
+
public function uncommentLines() {
|
138 |
+
$currentLines = $this->__getLines(false, false);
|
139 |
+
|
140 |
+
$lines = array();
|
141 |
+
foreach ($currentLines as $line) {
|
142 |
+
if (substr($line, 0, 1) === '#') {
|
143 |
+
$lines[] = substr($line, 1);
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
$insertion = array_merge($this->__header, $lines, $this->__footer);
|
148 |
+
|
149 |
+
return insert_with_markers($this->__path, 'Brute Force Login Protection', $insertion);
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Private functions
|
154 |
+
*/
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Returs array of (prefixed) lines from .htaccess.
|
158 |
+
*
|
159 |
+
* @param string $prefix
|
160 |
+
* @return array
|
161 |
+
*/
|
162 |
+
private function __getLines($prefix = false, $onlyBody = true, $exceptPrefix = false) {
|
163 |
+
$allLines = extract_from_markers($this->__path, 'Brute Force Login Protection');
|
164 |
+
|
165 |
+
if ($onlyBody) {
|
166 |
+
$allLines = array_diff($allLines, $this->__header, $this->__footer);
|
167 |
+
}
|
168 |
+
|
169 |
+
if (!$prefix) {
|
170 |
+
return $allLines;
|
171 |
+
}
|
172 |
+
|
173 |
+
$prefixLength = strlen($prefix);
|
174 |
+
|
175 |
+
$prefixedLines = array();
|
176 |
+
foreach ($allLines as $line) {
|
177 |
+
if ($exceptPrefix) {
|
178 |
+
if (substr($line, 0, $prefixLength) !== $prefix) {
|
179 |
+
$prefixedLines[] = $line;
|
180 |
+
}
|
181 |
+
} elseif (substr($line, 0, $prefixLength) === $prefix) {
|
182 |
+
$prefixedLines[] = substr($line, $prefixLength);
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
return $prefixedLines;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Adds single line to .htaccess.
|
191 |
+
*
|
192 |
+
* @param string $line
|
193 |
+
* @return boolean
|
194 |
+
*/
|
195 |
+
private function __addLine($line) {
|
196 |
+
$insertion = array_merge($this->__header, $this->__getLines(), array($line), $this->__footer);
|
197 |
+
|
198 |
+
return insert_with_markers($this->__path, 'Brute Force Login Protection', array_unique($insertion));
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Removes single line from .htaccess.
|
203 |
+
*
|
204 |
+
* @param string $line
|
205 |
+
* @param string $prefix
|
206 |
+
* @return boolean
|
207 |
+
*/
|
208 |
+
private function __removeLine($line, $prefix = false) {
|
209 |
+
$insertion = $this->__getLines(false, false);
|
210 |
+
|
211 |
+
if ($prefix !== false) {
|
212 |
+
$lineKey = false;
|
213 |
+
$prefixLength = strlen($prefix);
|
214 |
+
foreach ($insertion as $key => $line) {
|
215 |
+
if (substr($line, 0, $prefixLength) === $prefix) {
|
216 |
+
$lineKey = $key;
|
217 |
+
break;
|
218 |
+
}
|
219 |
+
}
|
220 |
+
} else {
|
221 |
+
$lineKey = array_search($line, $insertion);
|
222 |
+
}
|
223 |
+
|
224 |
+
if ($lineKey === false) {
|
225 |
+
return true;
|
226 |
+
}
|
227 |
+
|
228 |
+
unset($insertion[$lineKey]);
|
229 |
+
|
230 |
+
return insert_with_markers($this->__path, 'Brute Force Login Protection', $insertion);
|
231 |
+
}
|
232 |
+
|
233 |
+
}
|
settings-page.php → includes/settings-page.php
RENAMED
@@ -1,11 +1,11 @@
|
|
1 |
<style type="text/css">
|
2 |
-
.brute-force-login-protection .status-yes{
|
3 |
color:#27ae60;
|
4 |
}
|
5 |
-
.brute-force-login-protection .status-no{
|
6 |
color:#cd3d2e;
|
7 |
}
|
8 |
-
.brute-force-login-protection .postbox-footer{
|
9 |
padding:10px;
|
10 |
clear:both;
|
11 |
border-top:1px solid #ddd;
|
@@ -14,6 +14,9 @@
|
|
14 |
.brute-force-login-protection input[type="number"] {
|
15 |
width:60px;
|
16 |
}
|
|
|
|
|
|
|
17 |
</style>
|
18 |
|
19 |
<script type="text/javascript">
|
@@ -29,7 +32,7 @@
|
|
29 |
|
30 |
<div class="metabox-holder">
|
31 |
<div class="postbox">
|
32 |
-
<?php $status = $this->
|
33 |
<h3>
|
34 |
<?php _e('Status', 'brute-force-login-protection'); ?>
|
35 |
<?php if (in_array(false, $status)): ?>
|
@@ -65,16 +68,22 @@
|
|
65 |
<?php settings_fields('brute-force-login-protection'); ?>
|
66 |
<div class="inside">
|
67 |
<p><strong><?php _e('Allowed login attempts before blocking IP', 'brute-force-login-protection'); ?></strong></p>
|
68 |
-
<p><input type="number" min="1" name="bflp_allowed_attempts" value="<?php echo $this->__options['allowed_attempts']; ?>" /></p>
|
69 |
|
70 |
<p><strong><?php _e('Minutes before resetting login attempts count', 'brute-force-login-protection'); ?></strong></p>
|
71 |
<p><input type="number" min="1" name="bflp_reset_time" value="<?php echo $this->__options['reset_time']; ?>" /></p>
|
72 |
|
|
|
|
|
|
|
73 |
<p><strong><?php _e('Inform user about remaining login attempts on login page', 'brute-force-login-protection'); ?></strong></p>
|
74 |
<p><input type="checkbox" name="bflp_inform_user" value="true" <?php echo ($this->__options['inform_user']) ? 'checked' : ''; ?> /></p>
|
75 |
|
|
|
|
|
|
|
76 |
<p><strong><?php _e('.htaccess file location', 'brute-force-login-protection'); ?></strong></p>
|
77 |
-
<p><input type="text" size="
|
78 |
</div>
|
79 |
<div class="postbox-footer">
|
80 |
<?php submit_button(__('Save', 'brute-force-login-protection'), 'primary', 'submit', false); ?>
|
@@ -82,19 +91,6 @@
|
|
82 |
</div>
|
83 |
</form>
|
84 |
</div>
|
85 |
-
|
86 |
-
<div class="postbox">
|
87 |
-
<h3><?php _e('Manually block IP', 'brute-force-login-protection'); ?></h3>
|
88 |
-
<form method="post" action="">
|
89 |
-
<div class="inside">
|
90 |
-
<p><strong><?php _e('IP address', 'brute-force-login-protection'); ?></strong></p>
|
91 |
-
<p><input type="text" name="IP" /></p>
|
92 |
-
</div>
|
93 |
-
<div class="postbox-footer">
|
94 |
-
<input type="submit" name="block" value="<?php echo __('Block', 'brute-force-login-protection'); ?>" class="button button-primary" />
|
95 |
-
</div>
|
96 |
-
</form>
|
97 |
-
</div>
|
98 |
</div>
|
99 |
|
100 |
<h3><?php _e('Blocked IPs', 'brute-force-login-protection'); ?></h3>
|
@@ -102,16 +98,16 @@
|
|
102 |
<thead>
|
103 |
<tr>
|
104 |
<th width="5%">#</th>
|
105 |
-
<th width="
|
106 |
-
<th width="
|
107 |
</tr>
|
108 |
</thead>
|
109 |
<tbody>
|
110 |
<?php
|
111 |
$i = 1;
|
112 |
-
foreach ($this->
|
113 |
?>
|
114 |
-
<tr
|
115 |
<td><?php echo $i; ?></td>
|
116 |
<td><strong><?php echo $deniedIP ?></strong></td>
|
117 |
<td>
|
@@ -125,6 +121,59 @@
|
|
125 |
$i++;
|
126 |
endforeach;
|
127 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
</tbody>
|
129 |
</table>
|
130 |
|
1 |
<style type="text/css">
|
2 |
+
.brute-force-login-protection .status-yes {
|
3 |
color:#27ae60;
|
4 |
}
|
5 |
+
.brute-force-login-protection .status-no {
|
6 |
color:#cd3d2e;
|
7 |
}
|
8 |
+
.brute-force-login-protection .postbox-footer {
|
9 |
padding:10px;
|
10 |
clear:both;
|
11 |
border-top:1px solid #ddd;
|
14 |
.brute-force-login-protection input[type="number"] {
|
15 |
width:60px;
|
16 |
}
|
17 |
+
.brute-force-login-protection tr.even {
|
18 |
+
background-color:#f5f5f5;
|
19 |
+
}
|
20 |
</style>
|
21 |
|
22 |
<script type="text/javascript">
|
32 |
|
33 |
<div class="metabox-holder">
|
34 |
<div class="postbox">
|
35 |
+
<?php $status = $this->__htaccess->checkRequirements(); ?>
|
36 |
<h3>
|
37 |
<?php _e('Status', 'brute-force-login-protection'); ?>
|
38 |
<?php if (in_array(false, $status)): ?>
|
68 |
<?php settings_fields('brute-force-login-protection'); ?>
|
69 |
<div class="inside">
|
70 |
<p><strong><?php _e('Allowed login attempts before blocking IP', 'brute-force-login-protection'); ?></strong></p>
|
71 |
+
<p><input type="number" min="1" max="100" name="bflp_allowed_attempts" value="<?php echo $this->__options['allowed_attempts']; ?>" /></p>
|
72 |
|
73 |
<p><strong><?php _e('Minutes before resetting login attempts count', 'brute-force-login-protection'); ?></strong></p>
|
74 |
<p><input type="number" min="1" name="bflp_reset_time" value="<?php echo $this->__options['reset_time']; ?>" /></p>
|
75 |
|
76 |
+
<p><strong><?php _e('Delay in seconds when a login attempt has failed (to slow down brute force attack)', 'brute-force-login-protection'); ?></strong></p>
|
77 |
+
<p><input type="number" min="1" max="10" name="bflp_login_failed_delay" value="<?php echo $this->__options['login_failed_delay']; ?>" /></p>
|
78 |
+
|
79 |
<p><strong><?php _e('Inform user about remaining login attempts on login page', 'brute-force-login-protection'); ?></strong></p>
|
80 |
<p><input type="checkbox" name="bflp_inform_user" value="true" <?php echo ($this->__options['inform_user']) ? 'checked' : ''; ?> /></p>
|
81 |
|
82 |
+
<p><strong><?php _e('Message to show to blocked users (leave empty for default message)', 'brute-force-login-protection'); ?></strong></p>
|
83 |
+
<p><input type="text" size="70" name="bflp_403_message" value="<?php echo $this->__options['403_message']; ?>" /></p>
|
84 |
+
|
85 |
<p><strong><?php _e('.htaccess file location', 'brute-force-login-protection'); ?></strong></p>
|
86 |
+
<p><input type="text" size="70" name="bflp_htaccess_dir" value="<?php echo $this->__options['htaccess_dir']; ?>" /></p>
|
87 |
</div>
|
88 |
<div class="postbox-footer">
|
89 |
<?php submit_button(__('Save', 'brute-force-login-protection'), 'primary', 'submit', false); ?>
|
91 |
</div>
|
92 |
</form>
|
93 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
</div>
|
95 |
|
96 |
<h3><?php _e('Blocked IPs', 'brute-force-login-protection'); ?></h3>
|
98 |
<thead>
|
99 |
<tr>
|
100 |
<th width="5%">#</th>
|
101 |
+
<th width="30%"><?php _e('Address', 'brute-force-login-protection'); ?></th>
|
102 |
+
<th width="65%"><?php _e('Actions', 'brute-force-login-protection'); ?></th>
|
103 |
</tr>
|
104 |
</thead>
|
105 |
<tbody>
|
106 |
<?php
|
107 |
$i = 1;
|
108 |
+
foreach ($this->__htaccess->getDeniedIPs() as $deniedIP):
|
109 |
?>
|
110 |
+
<tr <?php echo ($i % 2 == 0) ? 'class="even"' : ''; ?>>
|
111 |
<td><?php echo $i; ?></td>
|
112 |
<td><strong><?php echo $deniedIP ?></strong></td>
|
113 |
<td>
|
121 |
$i++;
|
122 |
endforeach;
|
123 |
?>
|
124 |
+
<tr <?php echo ($i % 2 == 0) ? 'class="even"' : ''; ?>>
|
125 |
+
<td><?php echo $i; ?></td>
|
126 |
+
<form method="post" action="">
|
127 |
+
<td>
|
128 |
+
<input type="text" name="IP" placeholder="<?php _e('IP to block', 'brute-force-login-protection'); ?>" required />
|
129 |
+
</td>
|
130 |
+
<td>
|
131 |
+
<input type="submit" name="block" value="<?php _e('Manually block IP', 'brute-force-login-protection'); ?>" class="button button-primary" />
|
132 |
+
</td>
|
133 |
+
</form>
|
134 |
+
</tr>
|
135 |
+
</tbody>
|
136 |
+
</table>
|
137 |
+
|
138 |
+
<h3><?php _e('Whitelisted IPs', 'brute-force-login-protection'); ?></h3>
|
139 |
+
<table class="wp-list-table widefat fixed">
|
140 |
+
<thead>
|
141 |
+
<tr>
|
142 |
+
<th width="5%">#</th>
|
143 |
+
<th width="30%"><?php _e('Address', 'brute-force-login-protection'); ?></th>
|
144 |
+
<th width="65%"><?php _e('Actions', 'brute-force-login-protection'); ?></th>
|
145 |
+
</tr>
|
146 |
+
</thead>
|
147 |
+
<tbody>
|
148 |
+
<?php
|
149 |
+
$i = 1;
|
150 |
+
foreach ($this->__getWhitelist() as $whitelistedIP):
|
151 |
+
?>
|
152 |
+
<tr <?php echo ($i % 2 == 0) ? 'class="even"' : ''; ?>>
|
153 |
+
<td><?php echo $i; ?></td>
|
154 |
+
<td><strong><?php echo $whitelistedIP ?></strong></td>
|
155 |
+
<td>
|
156 |
+
<form method="post" action="">
|
157 |
+
<input type="hidden" name="IP" value="<?php echo $whitelistedIP ?>" />
|
158 |
+
<input type="submit" name="unwhitelist" value="<?php echo __('Remove from whitelist', 'brute-force-login-protection'); ?>" class="button" />
|
159 |
+
</form>
|
160 |
+
</td>
|
161 |
+
</tr>
|
162 |
+
<?php
|
163 |
+
$i++;
|
164 |
+
endforeach;
|
165 |
+
?>
|
166 |
+
<tr <?php echo ($i % 2 == 0) ? 'class="even"' : ''; ?>>
|
167 |
+
<td><?php echo $i; ?></td>
|
168 |
+
<form method="post" action="">
|
169 |
+
<td>
|
170 |
+
<input type="text" name="IP" placeholder="<?php _e('IP to whitelist', 'brute-force-login-protection'); ?>" required />
|
171 |
+
</td>
|
172 |
+
<td>
|
173 |
+
<input type="submit" name="whitelist" value="<?php _e('Add to whitelist', 'brute-force-login-protection'); ?>" class="button button-primary" />
|
174 |
+
</td>
|
175 |
+
</form>
|
176 |
+
</tr>
|
177 |
</tbody>
|
178 |
</table>
|
179 |
|
languages/brute-force-login-protection-nl_NL.mo
CHANGED
Binary file
|
languages/brute-force-login-protection-nl_NL.po
CHANGED
@@ -2,167 +2,223 @@
|
|
2 |
# This file is distributed under the same license as the Brute Force Login Protection package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: Brute Force Login Protection 1.
|
6 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/brute-force-login-protection\n"
|
7 |
-
"POT-Creation-Date: 2014-
|
8 |
-
"PO-Revision-Date: 2014-
|
9 |
-
"Last-Translator:
|
10 |
-
"Language-Team:
|
11 |
"Language: nl\n"
|
12 |
"MIME-Version: 1.0\n"
|
13 |
"Content-Type: text/plain; charset=UTF-8\n"
|
14 |
"Content-Transfer-Encoding: 8bit\n"
|
15 |
-
"X-Generator: Poedit 1.6.
|
16 |
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
17 |
|
18 |
-
#: brute-force-login-protection.php:
|
19 |
msgid "Brute Force Login Protection Settings"
|
20 |
msgstr "Brute Force Login Protection Instellingen"
|
21 |
|
22 |
-
#: brute-force-login-protection.php:
|
23 |
msgid "Brute Force Login Protection error: .htaccess file not found"
|
24 |
msgstr "Brute Force Login Protection fout: .htaccess bestand niet gevonden"
|
25 |
|
26 |
-
#: brute-force-login-protection.php:
|
27 |
msgid "Brute Force Login Protection error: .htaccess file not readable"
|
28 |
msgstr "Brute Force Login Protection fout: .htaccess bestand niet leesbaar"
|
29 |
|
30 |
-
#: brute-force-login-protection.php:
|
31 |
msgid "Brute Force Login Protection error: .htaccess file not writeable"
|
32 |
msgstr "Brute Force Login Protection fout: .htaccess bestand niet schrijfbaar"
|
33 |
|
34 |
-
#: brute-force-login-protection.php:
|
|
|
|
|
|
|
|
|
35 |
msgid "IP %s blocked"
|
36 |
msgstr "IP %s geblokkeerd"
|
37 |
|
38 |
-
#: brute-force-login-protection.php:
|
39 |
msgid "An error occurred while blocking IP %s"
|
40 |
msgstr "Er is een fout opgetreden bij het blokkeren van IP %s"
|
41 |
|
42 |
-
#: brute-force-login-protection.php:
|
43 |
msgid "IP %s unblocked"
|
44 |
msgstr "IP %s gedeblokkeerd"
|
45 |
|
46 |
-
#: brute-force-login-protection.php:
|
47 |
msgid "An error occurred while unblocking IP %s"
|
48 |
msgstr "Er is een fout opgetreden bij het deblokkeren van IP %s"
|
49 |
|
50 |
-
#: brute-force-login-protection.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
msgid "The Options have been successfully reset"
|
52 |
msgstr "De opties zijn succesvol gereset"
|
53 |
|
54 |
-
#: brute-force-login-protection.php:
|
55 |
msgid "%d attempt remaining."
|
56 |
msgid_plural "%d attempts remaining."
|
57 |
msgstr[0] "%d resterende loginpoging."
|
58 |
msgstr[1] "%d resterende loginpogingen."
|
59 |
|
60 |
-
#: brute-force-login-protection.php:
|
61 |
msgid "Allowed login attempts must be a number (between 1 and 100)"
|
62 |
msgstr "Toegestane inlogpogingen moet een getal zijn (tussen 1 en 100)"
|
63 |
|
64 |
-
#: brute-force-login-protection.php:
|
65 |
msgid "Minutes before resetting must be a number (higher than 1)"
|
66 |
msgstr ""
|
67 |
"Minuten voordat loginpogingen teller wordt gereset moet een getal zijn "
|
68 |
"(groter dan 1)"
|
69 |
|
70 |
-
#:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
msgid "Are you sure you want to reset all options?"
|
72 |
msgstr "Weet u zeker dat u alle opties wilt resetten?"
|
73 |
|
74 |
-
#: settings-page.php:
|
75 |
msgid "Status"
|
76 |
msgstr "Status"
|
77 |
|
78 |
-
#: settings-page.php:
|
79 |
msgid "You are not protected!"
|
80 |
msgstr "U bent niet beschermd"
|
81 |
|
82 |
-
#: settings-page.php:
|
83 |
msgid "You are protected!"
|
84 |
msgstr "U bent beschermd"
|
85 |
|
86 |
-
#: settings-page.php:
|
87 |
msgid ".htaccess file found"
|
88 |
msgstr ".htaccess bestand gevonden"
|
89 |
|
90 |
-
#: settings-page.php:
|
91 |
msgid ".htaccess file not found"
|
92 |
msgstr ".htaccess bestand niet gevonden"
|
93 |
|
94 |
-
#: settings-page.php:
|
95 |
msgid ".htaccess file readable"
|
96 |
msgstr ".htaccess bestand leesbaar"
|
97 |
|
98 |
-
#: settings-page.php:
|
99 |
msgid ".htaccess file not readable"
|
100 |
msgstr ".htaccess niet leesbaar"
|
101 |
|
102 |
-
#: settings-page.php:
|
103 |
msgid ".htaccess file writeable"
|
104 |
msgstr ".htaccess bestand beschrijfbaar"
|
105 |
|
106 |
-
#: settings-page.php:
|
107 |
msgid ".htaccess file not writeable"
|
108 |
msgstr ".htaccess bestand niet beschrijfbaar"
|
109 |
|
110 |
-
#: settings-page.php:
|
111 |
msgid "Options"
|
112 |
msgstr "Opties"
|
113 |
|
114 |
-
#: settings-page.php:
|
115 |
msgid "Allowed login attempts before blocking IP"
|
116 |
msgstr "Toegestane inlogpogingen voordat IP wordt geblokkeerd"
|
117 |
|
118 |
-
#: settings-page.php:
|
119 |
msgid "Minutes before resetting login attempts count"
|
120 |
msgstr "Minuten voordat loginpogingen teller wordt gereset"
|
121 |
|
122 |
-
#: settings-page.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
msgid "Inform user about remaining login attempts on login page"
|
124 |
msgstr "Informeer de gebruiker over resterende loginpogingen op de loginpagina"
|
125 |
|
126 |
-
#: settings-page.php:
|
|
|
|
|
|
|
|
|
|
|
127 |
msgid ".htaccess file location"
|
128 |
msgstr ".htaccess bestandslocatie"
|
129 |
|
130 |
-
#: settings-page.php:
|
131 |
msgid "Save"
|
132 |
msgstr "Opslaan"
|
133 |
|
134 |
-
#: settings-page.php:
|
135 |
msgid "Reset"
|
136 |
msgstr "Reset"
|
137 |
|
138 |
-
#: settings-page.php:
|
139 |
-
msgid "Manually block IP"
|
140 |
-
msgstr "Handmatig IP blokkeren"
|
141 |
-
|
142 |
-
#: settings-page.php:90
|
143 |
-
msgid "IP address"
|
144 |
-
msgstr "IP adres"
|
145 |
-
|
146 |
-
#: settings-page.php:94
|
147 |
-
msgid "Block"
|
148 |
-
msgstr "Blokkeren"
|
149 |
-
|
150 |
-
#: settings-page.php:100
|
151 |
msgid "Blocked IPs"
|
152 |
msgstr "Geblokkeerde IPs"
|
153 |
|
154 |
-
#: settings-page.php:
|
155 |
msgid "Address"
|
156 |
msgstr "Adres"
|
157 |
|
158 |
-
#: settings-page.php:
|
159 |
msgid "Actions"
|
160 |
msgstr "Acties"
|
161 |
|
162 |
-
#: settings-page.php:
|
163 |
msgid "Unblock"
|
164 |
msgstr "Deblokkeren"
|
165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
#. Plugin Name of the plugin/theme
|
167 |
msgid "Brute Force Login Protection"
|
168 |
msgstr "Brute Force Login Protection"
|
@@ -178,9 +234,21 @@ msgstr ""
|
|
178 |
"htaccess"
|
179 |
|
180 |
#. Author of the plugin/theme
|
181 |
-
msgid "
|
182 |
-
msgstr "
|
183 |
|
184 |
#. Author URI of the plugin/theme
|
185 |
-
msgid "http://
|
186 |
-
msgstr "http://
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
# This file is distributed under the same license as the Brute Force Login Protection package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: Brute Force Login Protection 1.4\n"
|
6 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/brute-force-login-protection\n"
|
7 |
+
"POT-Creation-Date: 2014-08-31 15:37:15+00:00\n"
|
8 |
+
"PO-Revision-Date: 2014-08-31 17:40+0100\n"
|
9 |
+
"Last-Translator: Jan-Paul Kleemans <jpkleemans@gmail.com>\n"
|
10 |
+
"Language-Team: Jan-Paul Kleemans <jpkleemans@gmail.com>\n"
|
11 |
"Language: nl\n"
|
12 |
"MIME-Version: 1.0\n"
|
13 |
"Content-Type: text/plain; charset=UTF-8\n"
|
14 |
"Content-Transfer-Encoding: 8bit\n"
|
15 |
+
"X-Generator: Poedit 1.6.9\n"
|
16 |
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
17 |
|
18 |
+
#: brute-force-login-protection.php:99 includes/settings-page.php:31
|
19 |
msgid "Brute Force Login Protection Settings"
|
20 |
msgstr "Brute Force Login Protection Instellingen"
|
21 |
|
22 |
+
#: brute-force-login-protection.php:130
|
23 |
msgid "Brute Force Login Protection error: .htaccess file not found"
|
24 |
msgstr "Brute Force Login Protection fout: .htaccess bestand niet gevonden"
|
25 |
|
26 |
+
#: brute-force-login-protection.php:132
|
27 |
msgid "Brute Force Login Protection error: .htaccess file not readable"
|
28 |
msgstr "Brute Force Login Protection fout: .htaccess bestand niet leesbaar"
|
29 |
|
30 |
+
#: brute-force-login-protection.php:134
|
31 |
msgid "Brute Force Login Protection error: .htaccess file not writeable"
|
32 |
msgstr "Brute Force Login Protection fout: .htaccess bestand niet schrijfbaar"
|
33 |
|
34 |
+
#: brute-force-login-protection.php:150
|
35 |
+
msgid "You can't block a whitelisted IP"
|
36 |
+
msgstr "U kunt een IP van de whitelist niet blokkeren"
|
37 |
+
|
38 |
+
#: brute-force-login-protection.php:152
|
39 |
msgid "IP %s blocked"
|
40 |
msgstr "IP %s geblokkeerd"
|
41 |
|
42 |
+
#: brute-force-login-protection.php:154
|
43 |
msgid "An error occurred while blocking IP %s"
|
44 |
msgstr "Er is een fout opgetreden bij het blokkeren van IP %s"
|
45 |
|
46 |
+
#: brute-force-login-protection.php:158
|
47 |
msgid "IP %s unblocked"
|
48 |
msgstr "IP %s gedeblokkeerd"
|
49 |
|
50 |
+
#: brute-force-login-protection.php:160
|
51 |
msgid "An error occurred while unblocking IP %s"
|
52 |
msgstr "Er is een fout opgetreden bij het deblokkeren van IP %s"
|
53 |
|
54 |
+
#: brute-force-login-protection.php:164
|
55 |
+
msgid "IP %s added to whitelist"
|
56 |
+
msgstr "IP %s toegevoegd aan whitelist"
|
57 |
+
|
58 |
+
#: brute-force-login-protection.php:166
|
59 |
+
msgid "An error occurred while adding IP %s to whitelist"
|
60 |
+
msgstr "Er is een fout opgetreden bij het toevoegen van IP %s aan de whitelist"
|
61 |
+
|
62 |
+
#: brute-force-login-protection.php:170
|
63 |
+
msgid "IP %s removed from whitelist"
|
64 |
+
msgstr "IP %s verwijderd van whitelist"
|
65 |
+
|
66 |
+
#: brute-force-login-protection.php:172
|
67 |
+
msgid "An error occurred while removing IP %s from whitelist"
|
68 |
+
msgstr ""
|
69 |
+
"Er is een fout opgetreden bij het verwijderen van IP %s van de whitelist"
|
70 |
+
|
71 |
+
#: brute-force-login-protection.php:180
|
72 |
msgid "The Options have been successfully reset"
|
73 |
msgstr "De opties zijn succesvol gereset"
|
74 |
|
75 |
+
#: brute-force-login-protection.php:235
|
76 |
msgid "%d attempt remaining."
|
77 |
msgid_plural "%d attempts remaining."
|
78 |
msgstr[0] "%d resterende loginpoging."
|
79 |
msgstr[1] "%d resterende loginpogingen."
|
80 |
|
81 |
+
#: brute-force-login-protection.php:271
|
82 |
msgid "Allowed login attempts must be a number (between 1 and 100)"
|
83 |
msgstr "Toegestane inlogpogingen moet een getal zijn (tussen 1 en 100)"
|
84 |
|
85 |
+
#: brute-force-login-protection.php:287
|
86 |
msgid "Minutes before resetting must be a number (higher than 1)"
|
87 |
msgstr ""
|
88 |
"Minuten voordat loginpogingen teller wordt gereset moet een getal zijn "
|
89 |
"(groter dan 1)"
|
90 |
|
91 |
+
#: brute-force-login-protection.php:303
|
92 |
+
msgid "Failed login delay must be a number (between 1 and 10)"
|
93 |
+
msgstr "Mislukte login vertraging moet een getal zijn (tussen 1 en 10)"
|
94 |
+
|
95 |
+
#: brute-force-login-protection.php:321
|
96 |
+
msgid "An error occurred while saving the blocked users message"
|
97 |
+
msgstr ""
|
98 |
+
"Er is een fout opgetreden bij het opslaan van het geblokkeerde gebruikers "
|
99 |
+
"bericht"
|
100 |
+
|
101 |
+
#: includes/settings-page.php:24
|
102 |
msgid "Are you sure you want to reset all options?"
|
103 |
msgstr "Weet u zeker dat u alle opties wilt resetten?"
|
104 |
|
105 |
+
#: includes/settings-page.php:37
|
106 |
msgid "Status"
|
107 |
msgstr "Status"
|
108 |
|
109 |
+
#: includes/settings-page.php:39
|
110 |
msgid "You are not protected!"
|
111 |
msgstr "U bent niet beschermd"
|
112 |
|
113 |
+
#: includes/settings-page.php:41
|
114 |
msgid "You are protected!"
|
115 |
msgstr "U bent beschermd"
|
116 |
|
117 |
+
#: includes/settings-page.php:46
|
118 |
msgid ".htaccess file found"
|
119 |
msgstr ".htaccess bestand gevonden"
|
120 |
|
121 |
+
#: includes/settings-page.php:48
|
122 |
msgid ".htaccess file not found"
|
123 |
msgstr ".htaccess bestand niet gevonden"
|
124 |
|
125 |
+
#: includes/settings-page.php:52
|
126 |
msgid ".htaccess file readable"
|
127 |
msgstr ".htaccess bestand leesbaar"
|
128 |
|
129 |
+
#: includes/settings-page.php:54
|
130 |
msgid ".htaccess file not readable"
|
131 |
msgstr ".htaccess niet leesbaar"
|
132 |
|
133 |
+
#: includes/settings-page.php:58
|
134 |
msgid ".htaccess file writeable"
|
135 |
msgstr ".htaccess bestand beschrijfbaar"
|
136 |
|
137 |
+
#: includes/settings-page.php:60
|
138 |
msgid ".htaccess file not writeable"
|
139 |
msgstr ".htaccess bestand niet beschrijfbaar"
|
140 |
|
141 |
+
#: includes/settings-page.php:66
|
142 |
msgid "Options"
|
143 |
msgstr "Opties"
|
144 |
|
145 |
+
#: includes/settings-page.php:70
|
146 |
msgid "Allowed login attempts before blocking IP"
|
147 |
msgstr "Toegestane inlogpogingen voordat IP wordt geblokkeerd"
|
148 |
|
149 |
+
#: includes/settings-page.php:73
|
150 |
msgid "Minutes before resetting login attempts count"
|
151 |
msgstr "Minuten voordat loginpogingen teller wordt gereset"
|
152 |
|
153 |
+
#: includes/settings-page.php:76
|
154 |
+
msgid ""
|
155 |
+
"Delay in seconds when a login attempt has failed (to slow down brute force "
|
156 |
+
"attack)"
|
157 |
+
msgstr ""
|
158 |
+
"Vertraging in seconden wanneer een loginpoging is mislukt (om brute force "
|
159 |
+
"aanvallen te vertragen)"
|
160 |
+
|
161 |
+
#: includes/settings-page.php:79
|
162 |
msgid "Inform user about remaining login attempts on login page"
|
163 |
msgstr "Informeer de gebruiker over resterende loginpogingen op de loginpagina"
|
164 |
|
165 |
+
#: includes/settings-page.php:82
|
166 |
+
msgid "Message to show to blocked users (leave empty for default message)"
|
167 |
+
msgstr ""
|
168 |
+
"Bericht voor geblokkeerde gebruikers (laat leeg voor standaard bericht)"
|
169 |
+
|
170 |
+
#: includes/settings-page.php:85
|
171 |
msgid ".htaccess file location"
|
172 |
msgstr ".htaccess bestandslocatie"
|
173 |
|
174 |
+
#: includes/settings-page.php:89
|
175 |
msgid "Save"
|
176 |
msgstr "Opslaan"
|
177 |
|
178 |
+
#: includes/settings-page.php:90
|
179 |
msgid "Reset"
|
180 |
msgstr "Reset"
|
181 |
|
182 |
+
#: includes/settings-page.php:96
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
msgid "Blocked IPs"
|
184 |
msgstr "Geblokkeerde IPs"
|
185 |
|
186 |
+
#: includes/settings-page.php:101 includes/settings-page.php:143
|
187 |
msgid "Address"
|
188 |
msgstr "Adres"
|
189 |
|
190 |
+
#: includes/settings-page.php:102 includes/settings-page.php:144
|
191 |
msgid "Actions"
|
192 |
msgstr "Acties"
|
193 |
|
194 |
+
#: includes/settings-page.php:116
|
195 |
msgid "Unblock"
|
196 |
msgstr "Deblokkeren"
|
197 |
|
198 |
+
#: includes/settings-page.php:128
|
199 |
+
msgid "IP to block"
|
200 |
+
msgstr "Te blokkeren IP"
|
201 |
+
|
202 |
+
#: includes/settings-page.php:131
|
203 |
+
msgid "Manually block IP"
|
204 |
+
msgstr "Handmatig IP blokkeren"
|
205 |
+
|
206 |
+
#: includes/settings-page.php:138
|
207 |
+
msgid "Whitelisted IPs"
|
208 |
+
msgstr "Whitelist (Toegestane IPs)"
|
209 |
+
|
210 |
+
#: includes/settings-page.php:158
|
211 |
+
msgid "Remove from whitelist"
|
212 |
+
msgstr "Verwijder van whitelist"
|
213 |
+
|
214 |
+
#: includes/settings-page.php:170
|
215 |
+
msgid "IP to whitelist"
|
216 |
+
msgstr "Toe te voegen IP"
|
217 |
+
|
218 |
+
#: includes/settings-page.php:173
|
219 |
+
msgid "Add to whitelist"
|
220 |
+
msgstr "Voeg toe aan whitelist"
|
221 |
+
|
222 |
#. Plugin Name of the plugin/theme
|
223 |
msgid "Brute Force Login Protection"
|
224 |
msgstr "Brute Force Login Protection"
|
234 |
"htaccess"
|
235 |
|
236 |
#. Author of the plugin/theme
|
237 |
+
msgid "Fresh-Media"
|
238 |
+
msgstr "Fresh-Media"
|
239 |
|
240 |
#. Author URI of the plugin/theme
|
241 |
+
msgid "http://fresh-media.nl/"
|
242 |
+
msgstr "http://fresh-media.nl/"
|
243 |
+
|
244 |
+
#~ msgid "IP address"
|
245 |
+
#~ msgstr "IP adres"
|
246 |
+
|
247 |
+
#~ msgid "Block"
|
248 |
+
#~ msgstr "Blokkeren"
|
249 |
+
|
250 |
+
#~ msgid "Jan-Paul Kleemans"
|
251 |
+
#~ msgstr "Jan-Paul Kleemans"
|
252 |
+
|
253 |
+
#~ msgid "http://profiles.wordpress.org/jan-paul-kleemans/"
|
254 |
+
#~ msgstr "http://profiles.wordpress.org/jan-paul-kleemans/"
|
readme.txt
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
Contributors: Jan-Paul Kleemans
|
3 |
Tags: brute force, bruteforce, login, wp-login, protection, shield, security, htaccess, block, ip
|
4 |
Requires at least: 2.7.0
|
5 |
-
Tested up to:
|
6 |
-
Stable tag: 1.
|
7 |
License: GPL2
|
8 |
|
9 |
Protects your website against brute force login attacks using .htaccess
|
@@ -17,9 +17,11 @@ Features
|
|
17 |
|
18 |
* Limit the number of allowed login attempts using normal login form
|
19 |
* Limit the number of allowed login attempts using Auth Cookies
|
20 |
-
* Manually block IP addresses
|
21 |
-
* Manually
|
|
|
22 |
* Option to inform user about remaining attempts on login page
|
|
|
23 |
|
24 |
Your feedback is highly appreciated!
|
25 |
|
@@ -41,6 +43,12 @@ Brute Force Login Protection will only work if your .htaccess file is writeable
|
|
41 |
1. Plugin settings page
|
42 |
|
43 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
= 1.3 =
|
45 |
* Protection against brute force attacks using Auth Cookies
|
46 |
|
2 |
Contributors: Jan-Paul Kleemans
|
3 |
Tags: brute force, bruteforce, login, wp-login, protection, shield, security, htaccess, block, ip
|
4 |
Requires at least: 2.7.0
|
5 |
+
Tested up to: 4.0
|
6 |
+
Stable tag: 1.4
|
7 |
License: GPL2
|
8 |
|
9 |
Protects your website against brute force login attacks using .htaccess
|
17 |
|
18 |
* Limit the number of allowed login attempts using normal login form
|
19 |
* Limit the number of allowed login attempts using Auth Cookies
|
20 |
+
* Manually block/unblock IP addresses
|
21 |
+
* Manually whitelist trusted IP addresses
|
22 |
+
* Delay execution after a failed login attempt (to slow down brute force attack)
|
23 |
* Option to inform user about remaining attempts on login page
|
24 |
+
* Custom message to show to blocked users
|
25 |
|
26 |
Your feedback is highly appreciated!
|
27 |
|
43 |
1. Plugin settings page
|
44 |
|
45 |
== Changelog ==
|
46 |
+
= 1.4 =
|
47 |
+
* Ability to whitelist trusted IPs
|
48 |
+
* Ability to create custom message to show to blocked users
|
49 |
+
* Delay execution after a failed login attempt (to slow down brute force attack)
|
50 |
+
* Performance improvements
|
51 |
+
|
52 |
= 1.3 =
|
53 |
* Protection against brute force attacks using Auth Cookies
|
54 |
|