Version Description
Download this release
Release Info
Developer | WebFactory |
Plugin | Login LockDown |
Version | 1.82 |
Comparing to | |
See all releases |
Code changes from version 1.8.1 to 1.82
- index.php +2 -0
- loginlockdown.php +485 -522
- readme.txt +28 -18
- version.txt +0 -1
index.php
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
loginlockdown.php
CHANGED
@@ -1,113 +1,45 @@
|
|
1 |
<?php
|
2 |
-
/*
|
3 |
-
Plugin Name: Login LockDown
|
4 |
-
Plugin URI: http://www.bad-neighborhood.com/
|
5 |
-
Version: v1.8.1
|
6 |
-
Author: Michael VanDeMar
|
7 |
-
Description: Adds some extra security to WordPress by restricting the rate at which failed logins can be re-attempted from a given IP range. Distributed through <a href="http://www.bad-neighborhood.com/" target="_blank">Bad Neighborhood</a>.
|
8 |
-
*/
|
9 |
-
|
10 |
-
/*
|
11 |
-
== Change Log ==
|
12 |
-
*
|
13 |
-
* ver. 1.8.1 30-Sep-2019
|
14 |
-
* - adding missing ./languages folder
|
15 |
-
*
|
16 |
-
* ver. 1.8 30-Sep-2019
|
17 |
-
* - fixed issues with internationalization, added .pot file
|
18 |
-
* - changed the credit link to default to not showing
|
19 |
-
*
|
20 |
-
* ver. 1.7.1 13-Sep-2016
|
21 |
-
* - fixed bug causing all ipv6 addresses to get locked out if 1 was
|
22 |
-
* - added in WordPress MultiSite functionality
|
23 |
-
* - fixed bug where subnets could be overly matched, causing more IPs to be blocked than intended
|
24 |
-
* - moved the report for locked out IP addresses to its own tab
|
25 |
-
*
|
26 |
-
* ver. 1.6.1 8-Mar-2014
|
27 |
-
* - fixed html glitch preventing options from being saved
|
28 |
-
*
|
29 |
-
* ver. 1.6 7-Mar-2014
|
30 |
-
* - cleaned up deprecated functions
|
31 |
-
* - fixed bug with invalid property on a non-object when locking out invalid usernames
|
32 |
-
* - fixed utilization of $wpdb->prepare
|
33 |
-
* - added more descriptive help text to each of the options
|
34 |
-
* - added the ability to remove the "Login form protected by Login LockDown." message from within the dashboard
|
35 |
-
*
|
36 |
-
* ver. 1.5 17-Sep-2009
|
37 |
-
* - implemented wp_nonce security in the options and lockdown release forms in the admin screen
|
38 |
-
* - fixed a security hole with an improperly escaped SQL query
|
39 |
-
* - encoded certain outputs in the admin panel using esc_attr() to prevent XSS attacks
|
40 |
-
* - fixed an issue with the 'Lockout Invalid Usernames' option not functioning as intended
|
41 |
-
*
|
42 |
-
* ver. 1.4 29-Aug-2009
|
43 |
-
* - removed erroneous error affecting WP 2.8+
|
44 |
-
* - fixed activation error caused by customizing the location of the wp-content folder
|
45 |
-
* - added in the option to mask which specific login error (invalid username or invalid password) was generated
|
46 |
-
* - added in the option to lock out failed login attempts even if the username doesn't exist
|
47 |
-
*
|
48 |
-
* ver. 1.3 23-Feb-2009
|
49 |
-
* - adjusted positioning of plugin byline
|
50 |
-
* - allowed for dynamic location of plugin files
|
51 |
-
*
|
52 |
-
* ver. 1.2 15-Jun-2008
|
53 |
-
* - now compatible with WordPress 2.5 and up only
|
54 |
-
*
|
55 |
-
* ver. 1.1 01-Sep-2007
|
56 |
-
* - revised time query to MySQL 4.0 compatability
|
57 |
-
*
|
58 |
-
* ver. 1.0 29-Aug-2007
|
59 |
-
* - released
|
60 |
-
*/
|
61 |
-
|
62 |
-
/*
|
63 |
-
== Installation ==
|
64 |
-
|
65 |
-
1. Extract the zip file into your plugins directory into its own folder.
|
66 |
-
2. Activate the plugin in the Plugin options.
|
67 |
-
3. Customize the settings from the Options panel, if desired.
|
68 |
-
|
69 |
-
*/
|
70 |
-
|
71 |
/*
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
*/
|
100 |
|
101 |
$loginlockdown_db_version = "1.0";
|
102 |
-
$loginlockdownOptions =
|
103 |
|
104 |
-
function loginLockdown_install()
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
108 |
|
109 |
-
|
110 |
-
|
111 |
`login_attempt_ID` bigint(20) NOT NULL AUTO_INCREMENT,
|
112 |
`user_id` bigint(20) NOT NULL,
|
113 |
`login_attempt_date` datetime NOT NULL default '0000-00-00 00:00:00',
|
@@ -115,14 +47,14 @@ function loginLockdown_install() {
|
|
115 |
PRIMARY KEY (`login_attempt_ID`)
|
116 |
);";
|
117 |
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
|
122 |
-
|
123 |
|
124 |
-
|
125 |
-
|
126 |
`lockdown_ID` bigint(20) NOT NULL AUTO_INCREMENT,
|
127 |
`user_id` bigint(20) NOT NULL,
|
128 |
`lockdown_date` datetime NOT NULL default '0000-00-00 00:00:00',
|
@@ -131,450 +63,481 @@ function loginLockdown_install() {
|
|
131 |
PRIMARY KEY (`lockdown_ID`)
|
132 |
);";
|
133 |
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
}
|
142 |
|
143 |
-
function
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
|
|
157 |
}
|
158 |
|
159 |
-
function
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
}
|
179 |
|
180 |
-
function
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
}
|
201 |
|
202 |
-
function
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
$stillLockedquery = "SELECT user_id FROM $table_name " .
|
208 |
-
"WHERE release_date > now() AND " .
|
209 |
-
"lockdown_IP LIKE %s";
|
210 |
-
$stillLockedquery = $wpdb->prepare($stillLockedquery,$subnet[1] . "%");
|
211 |
|
212 |
-
|
213 |
|
214 |
-
|
215 |
}
|
216 |
|
217 |
-
function
|
218 |
-
|
219 |
-
|
|
|
220 |
|
221 |
-
|
222 |
-
|
|
|
|
|
|
|
|
|
223 |
|
224 |
-
|
225 |
}
|
226 |
|
227 |
-
function
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
|
|
244 |
}
|
245 |
|
246 |
-
function
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
|
|
257 |
}
|
258 |
|
259 |
-
function
|
260 |
-
|
261 |
-
|
|
|
262 |
|
263 |
-
|
264 |
}
|
265 |
|
266 |
|
267 |
-
function
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
<?php
|
323 |
-
|
324 |
-
$
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
<
|
335 |
-
<?php
|
336 |
-
|
337 |
-
|
338 |
-
?>
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
<
|
346 |
-
<
|
347 |
-
<p
|
348 |
-
<
|
349 |
-
<
|
350 |
-
<p
|
351 |
-
<
|
352 |
-
<
|
353 |
-
<p
|
354 |
-
<
|
355 |
-
<
|
356 |
-
<p
|
357 |
-
<
|
358 |
-
|
359 |
-
<input type="radio" name="
|
360 |
-
<
|
361 |
-
<
|
362 |
-
<
|
363 |
-
|
364 |
-
|
365 |
-
<?php
|
366 |
-
<
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
?>
|
391 |
-
<
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
396 |
<?php
|
397 |
-
}//End function
|
398 |
|
399 |
-
function
|
400 |
-
|
401 |
-
|
402 |
-
|
|
|
403 |
}
|
404 |
|
405 |
-
function
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
|
|
419 |
}
|
420 |
|
421 |
-
//Actions and Filters
|
422 |
-
if (
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
|
|
|
|
|
|
|
|
|
|
574 |
}
|
575 |
|
576 |
-
add_action('plugins_loaded', '
|
577 |
|
578 |
-
function
|
579 |
-
|
|
|
580 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
/*
|
3 |
+
Plugin Name: Login LockDown
|
4 |
+
Plugin URI: https://wploginlockdown.com/
|
5 |
+
Description: Protect login form by banning IP after multiple failed login attempts.
|
6 |
+
Version: 1.82
|
7 |
+
Author: WebFactory Ltd
|
8 |
+
Author URI: https://www.webfactoryltd.com/
|
9 |
+
License: GNU General Public License v3.0
|
10 |
+
Text Domain: login-lockdown
|
11 |
+
Requires at least: 4.0
|
12 |
+
Tested up to: 6.0
|
13 |
+
Requires PHP: 5.2
|
14 |
+
|
15 |
+
Copyright 2022 - 2023 WebFactory Ltd (email: support@webfactoryltd.com)
|
16 |
+
Copyright 2007 - 2022 Michael VanDeMar
|
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
|
20 |
+
published by the Free Software Foundation.
|
21 |
+
|
22 |
+
This program is distributed in the hope that it will be useful,
|
23 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
24 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
25 |
+
GNU General Public License for more details.
|
26 |
+
|
27 |
+
You should have received a copy of the GNU General Public License
|
28 |
+
along with this program; if not, write to the Free Software
|
29 |
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
30 |
*/
|
31 |
|
32 |
$loginlockdown_db_version = "1.0";
|
33 |
+
$loginlockdownOptions = loginLockdown_get_options();
|
34 |
|
35 |
+
function loginLockdown_install()
|
36 |
+
{
|
37 |
+
global $wpdb;
|
38 |
+
global $loginlockdown_db_version;
|
39 |
+
$table_name = $wpdb->prefix . "login_fails";
|
40 |
|
41 |
+
if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
|
42 |
+
$sql = "CREATE TABLE " . $table_name . " (
|
43 |
`login_attempt_ID` bigint(20) NOT NULL AUTO_INCREMENT,
|
44 |
`user_id` bigint(20) NOT NULL,
|
45 |
`login_attempt_date` datetime NOT NULL default '0000-00-00 00:00:00',
|
47 |
PRIMARY KEY (`login_attempt_ID`)
|
48 |
);";
|
49 |
|
50 |
+
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
51 |
+
dbDelta($sql);
|
52 |
+
}
|
53 |
|
54 |
+
$table_name = $wpdb->prefix . "lockdowns";
|
55 |
|
56 |
+
if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
|
57 |
+
$sql = "CREATE TABLE " . $table_name . " (
|
58 |
`lockdown_ID` bigint(20) NOT NULL AUTO_INCREMENT,
|
59 |
`user_id` bigint(20) NOT NULL,
|
60 |
`lockdown_date` datetime NOT NULL default '0000-00-00 00:00:00',
|
63 |
PRIMARY KEY (`lockdown_ID`)
|
64 |
);";
|
65 |
|
66 |
+
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
67 |
+
dbDelta($sql);
|
68 |
+
}
|
69 |
+
add_option("loginlockdown_db_version", "1.0", "", "no");
|
70 |
+
// added in 1.6, cleanup from previously improperly set db versions
|
71 |
+
delete_option("loginlockdown_db1_version");
|
72 |
+
delete_option("loginlockdown_db2_version");
|
73 |
}
|
74 |
|
75 |
+
function loginLockdown_countFails($username = "")
|
76 |
+
{
|
77 |
+
global $wpdb;
|
78 |
+
global $loginlockdownOptions;
|
79 |
+
$table_name = $wpdb->prefix . "login_fails";
|
80 |
+
$subnet = loginLockdown_calc_subnet($_SERVER['REMOTE_ADDR']);
|
81 |
+
|
82 |
+
$numFails = $wpdb->get_var(
|
83 |
+
$wpdb->prepare(
|
84 |
+
"SELECT COUNT(login_attempt_ID) FROM " . $table_name . " WHERE login_attempt_date + INTERVAL %d MINUTE > %s AND login_attempt_IP LIKE %s",
|
85 |
+
array($loginlockdownOptions['retries_within'], current_time('mysql', true), $subnet[1] . "%")
|
86 |
+
)
|
87 |
+
);
|
88 |
+
|
89 |
+
return $numFails;
|
90 |
}
|
91 |
|
92 |
+
function loginLockdown_incrementFails($username = "")
|
93 |
+
{
|
94 |
+
global $wpdb;
|
95 |
+
global $loginlockdownOptions;
|
96 |
+
$table_name = $wpdb->prefix . "login_fails";
|
97 |
+
$subnet = loginLockdown_calc_subnet($_SERVER['REMOTE_ADDR']);
|
98 |
+
|
99 |
+
$username = sanitize_user($username);
|
100 |
+
$user = get_user_by('login', $username);
|
101 |
+
if ($user || "yes" == $loginlockdownOptions['lockout_invalid_usernames']) {
|
102 |
+
if ($user === false) {
|
103 |
+
$user_id = -1;
|
104 |
+
} else {
|
105 |
+
$user_id = $user->ID;
|
106 |
+
}
|
107 |
+
|
108 |
+
$wpdb->insert(
|
109 |
+
$table_name,
|
110 |
+
array(
|
111 |
+
'user_id' => $user_id,
|
112 |
+
'login_attempt_date' => current_time('mysql', false),
|
113 |
+
'login_attempt_IP' => $subnet[0]
|
114 |
+
)
|
115 |
+
);
|
116 |
+
}
|
117 |
}
|
118 |
|
119 |
+
function loginLockdown_lockDown($username = "")
|
120 |
+
{
|
121 |
+
global $wpdb;
|
122 |
+
global $loginlockdownOptions;
|
123 |
+
$table_name = $wpdb->prefix . "lockdowns";
|
124 |
+
$subnet = loginLockdown_calc_subnet($_SERVER['REMOTE_ADDR']);
|
125 |
+
|
126 |
+
$username = sanitize_user($username);
|
127 |
+
$user = get_user_by('login', $username);
|
128 |
+
if ($user || "yes" == $loginlockdownOptions['lockout_invalid_usernames']) {
|
129 |
+
if ($user === false) {
|
130 |
+
$user_id = -1;
|
131 |
+
} else {
|
132 |
+
$user_id = $user->ID;
|
133 |
+
}
|
134 |
+
|
135 |
+
$wpdb->insert(
|
136 |
+
$table_name,
|
137 |
+
array(
|
138 |
+
'user_id' => $user_id,
|
139 |
+
'lockdown_date' => current_time('mysql', false),
|
140 |
+
'release_date' => date('Y-m-d H:i:s', strtotime(current_time('mysql', false)) + $loginlockdownOptions['lockout_length'] * 60),
|
141 |
+
'lockdown_IP' => $subnet[0]
|
142 |
+
)
|
143 |
+
);
|
144 |
+
}
|
145 |
}
|
146 |
|
147 |
+
function loginLockdown_isLockedDown()
|
148 |
+
{
|
149 |
+
global $wpdb;
|
150 |
+
$table_name = $wpdb->prefix . "lockdowns";
|
151 |
+
$subnet = loginLockdown_calc_subnet($_SERVER['REMOTE_ADDR']);
|
|
|
|
|
|
|
|
|
152 |
|
153 |
+
$stillLocked = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM " . $table_name . " WHERE release_date > %s AND lockdown_IP LIKE %s", array(current_time('mysql', true), $subnet[1] . "%")));
|
154 |
|
155 |
+
return $stillLocked;
|
156 |
}
|
157 |
|
158 |
+
function loginLockdown_listLockedDown()
|
159 |
+
{
|
160 |
+
global $wpdb;
|
161 |
+
$table_name = $wpdb->prefix . "lockdowns";
|
162 |
|
163 |
+
$listLocked = $wpdb->get_results(
|
164 |
+
$wpdb->prepare(
|
165 |
+
"SELECT lockdown_ID, floor((UNIX_TIMESTAMP(release_date)-UNIX_TIMESTAMP(%s))/60) AS minutes_left, lockdown_IP FROM $table_name WHERE release_date > %s",
|
166 |
+
array(current_time('mysql', true), current_time('mysql', true))
|
167 |
+
),
|
168 |
+
ARRAY_A);
|
169 |
|
170 |
+
return $listLocked;
|
171 |
}
|
172 |
|
173 |
+
function loginLockdown_get_options()
|
174 |
+
{
|
175 |
+
$loginlockdownAdminOptions = array(
|
176 |
+
'max_login_retries' => 3,
|
177 |
+
'retries_within' => 5,
|
178 |
+
'lockout_length' => 60,
|
179 |
+
'lockout_invalid_usernames' => 'no',
|
180 |
+
'mask_login_errors' => 'no',
|
181 |
+
'show_credit_link' => 'no'
|
182 |
+
);
|
183 |
+
$loginlockdownOptions = get_option("loginlockdownAdminOptions");
|
184 |
+
if (!empty($loginlockdownOptions)) {
|
185 |
+
foreach ($loginlockdownOptions as $key => $option) {
|
186 |
+
$loginlockdownAdminOptions[$key] = $option;
|
187 |
+
}
|
188 |
+
}
|
189 |
+
update_option("loginlockdownAdminOptions", $loginlockdownAdminOptions);
|
190 |
+
return $loginlockdownAdminOptions;
|
191 |
}
|
192 |
|
193 |
+
function loginLockdown_calc_subnet($ip)
|
194 |
+
{
|
195 |
+
$subnet[0] = $ip;
|
196 |
+
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
|
197 |
+
$ip = loginLockdown_expandipv6($ip);
|
198 |
+
preg_match("/^([0-9abcdef]{1,4}:){4}/", $ip, $matches);
|
199 |
+
$subnet[0] = $ip;
|
200 |
+
$subnet[1] = $matches[0];
|
201 |
+
} else {
|
202 |
+
$subnet[1] = substr($ip, 0, strrpos($ip, ".") + 1);
|
203 |
+
}
|
204 |
+
return $subnet;
|
205 |
}
|
206 |
|
207 |
+
function loginLockdown_expandipv6($ip)
|
208 |
+
{
|
209 |
+
$hex = unpack("H*hex", inet_pton($ip));
|
210 |
+
$ip = substr(preg_replace("/([A-f0-9]{4})/", "$1:", $hex['hex']), 0, -1);
|
211 |
|
212 |
+
return $ip;
|
213 |
}
|
214 |
|
215 |
|
216 |
+
function loginLockdown_print_admin_page()
|
217 |
+
{
|
218 |
+
global $wpdb;
|
219 |
+
$table_name = $wpdb->prefix . "lockdowns";
|
220 |
+
$loginlockdownAdminOptions = loginLockdown_get_options();
|
221 |
+
|
222 |
+
if (isset($_POST['update_loginlockdownSettings'])) {
|
223 |
+
|
224 |
+
//wp_nonce check
|
225 |
+
check_admin_referer('login-lockdown_update-options');
|
226 |
+
|
227 |
+
if (isset($_POST['ll_max_login_retries'])) {
|
228 |
+
$loginlockdownAdminOptions['max_login_retries'] = sanitize_text_field($_POST['ll_max_login_retries']);
|
229 |
+
}
|
230 |
+
if (isset($_POST['ll_retries_within'])) {
|
231 |
+
$loginlockdownAdminOptions['retries_within'] = sanitize_text_field($_POST['ll_retries_within']);
|
232 |
+
}
|
233 |
+
if (isset($_POST['ll_lockout_length'])) {
|
234 |
+
$loginlockdownAdminOptions['lockout_length'] = sanitize_text_field($_POST['ll_lockout_length']);
|
235 |
+
}
|
236 |
+
if (isset($_POST['ll_lockout_invalid_usernames'])) {
|
237 |
+
$loginlockdownAdminOptions['lockout_invalid_usernames'] = sanitize_text_field($_POST['ll_lockout_invalid_usernames']);
|
238 |
+
}
|
239 |
+
if (isset($_POST['ll_mask_login_errors'])) {
|
240 |
+
$loginlockdownAdminOptions['mask_login_errors'] = sanitize_text_field($_POST['ll_mask_login_errors']);
|
241 |
+
}
|
242 |
+
if (isset($_POST['ll_show_credit_link'])) {
|
243 |
+
$loginlockdownAdminOptions['show_credit_link'] = sanitize_text_field($_POST['ll_show_credit_link']);
|
244 |
+
}
|
245 |
+
update_option("loginlockdownAdminOptions", $loginlockdownAdminOptions);
|
246 |
+
?>
|
247 |
+
<div class="updated">
|
248 |
+
<p><strong><?php esc_html_e("Settings Updated.", "loginlockdown"); ?></strong></p>
|
249 |
+
</div>
|
250 |
+
<?php
|
251 |
+
}
|
252 |
+
if (isset($_POST['release_lockdowns'])) {
|
253 |
+
|
254 |
+
//wp_nonce check
|
255 |
+
check_admin_referer('login-lockdown_release-lockdowns');
|
256 |
+
|
257 |
+
if (isset($_POST['releaseme'])) {
|
258 |
+
$released = array_map( 'intval', $_POST['releaseme'] );
|
259 |
+
|
260 |
+
foreach ($released as $release_id) {
|
261 |
+
$wpdb->query(
|
262 |
+
$wpdb->prepare("UPDATE $table_name SET release_date = %s WHERE lockdown_ID = %d", array(current_time('mysql', true), $release_id))
|
263 |
+
);
|
264 |
+
}
|
265 |
+
}
|
266 |
+
update_option("loginlockdownAdminOptions", $loginlockdownAdminOptions);
|
267 |
+
?>
|
268 |
+
<div class="updated">
|
269 |
+
<p><strong><?php esc_html_e("Lockdowns Released.", "loginlockdown"); ?></strong></p>
|
270 |
+
</div>
|
271 |
+
<?php
|
272 |
+
}
|
273 |
+
$dalist = loginLockdown_listLockedDown();
|
274 |
+
?>
|
275 |
+
<div class="wrap">
|
276 |
+
<?php
|
277 |
+
|
278 |
+
$active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'settings';
|
279 |
+
|
280 |
+
?>
|
281 |
+
<h2><?php esc_html_e('Login LockDown Options', 'loginlockdown') ?></h2>
|
282 |
+
|
283 |
+
<h2 class="nav-tab-wrapper">
|
284 |
+
<a href="?page=loginlockdown.php&tab=settings" class="nav-tab <?php echo $active_tab == 'settings' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e('Settings', 'loginlockdown') ?></a>
|
285 |
+
<a href="?page=loginlockdown.php&tab=activity" class="nav-tab <?php echo $active_tab == 'activity' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e('Activity', 'loginlockdown') ?> (<?php echo count($dalist); ?>)</a>
|
286 |
+
</h2>
|
287 |
+
<?php if ($active_tab == 'settings') { ?>
|
288 |
+
<form method="post" action="<?php echo esc_attr($_SERVER["REQUEST_URI"]); ?>">
|
289 |
+
<?php
|
290 |
+
if (function_exists('wp_nonce_field'))
|
291 |
+
wp_nonce_field('login-lockdown_update-options');
|
292 |
+
?>
|
293 |
+
|
294 |
+
<h3><?php esc_html_e('Max Login Retries', 'loginlockdown') ?></h3>
|
295 |
+
<p><?php esc_html_e('Number of failed login attempts within the "Retry Time Period Restriction" (defined below) needed to trigger a LockDown.', 'loginlockdown') ?></p>
|
296 |
+
<p><input type="text" name="ll_max_login_retries" size="8" value="<?php echo esc_attr($loginlockdownAdminOptions['max_login_retries']); ?>"></p>
|
297 |
+
<h3><?php esc_html_e('Retry Time Period Restriction (minutes)', 'loginlockdown') ?></h3>
|
298 |
+
<p><?php esc_html_e('Amount of time that determines the rate at which failed login attempts are allowed before a LockDown occurs.', 'loginlockdown') ?></p>
|
299 |
+
<p><input type="text" name="ll_retries_within" size="8" value="<?php echo esc_attr($loginlockdownAdminOptions['retries_within']); ?>"></p>
|
300 |
+
<h3><?php esc_html_e('Lockout Length (minutes)', 'loginlockdown') ?></h3>
|
301 |
+
<p><?php esc_html_e('How long a particular IP block will be locked out for once a LockDown has been triggered.', 'loginlockdown') ?></p>
|
302 |
+
<p><input type="text" name="ll_lockout_length" size="8" value="<?php echo esc_attr($loginlockdownAdminOptions['lockout_length']); ?>"></p>
|
303 |
+
<h3><?php esc_html_e('Lockout Invalid Usernames?', 'loginlockdown') ?></h3>
|
304 |
+
<p><?php esc_html_e('By default Login LockDown will not trigger if an attempt is made to log in using a username that does not exist. You can override this behavior here.', 'loginlockdown') ?></p>
|
305 |
+
<p><input type="radio" name="ll_lockout_invalid_usernames" value="yes" <?php if ($loginlockdownAdminOptions['lockout_invalid_usernames'] == "yes") echo "checked"; ?>> <?php esc_html_e('Yes', 'loginlockdown') ?> <input type="radio" name="ll_lockout_invalid_usernames" value="no" <?php if ($loginlockdownAdminOptions['lockout_invalid_usernames'] == "no") echo "checked"; ?>> <?php esc_html_e('No', 'loginlockdown') ?></p>
|
306 |
+
<h3><?php esc_html_e('Mask Login Errors?', 'loginlockdown') ?></h3>
|
307 |
+
<p><?php esc_html_e('WordPress will normally display distinct messages to the user depending on whether they try and log in with an invalid username, or with a valid username but the incorrect password. Toggling this option will hide why the login failed.', 'loginlockdown') ?></p>
|
308 |
+
<p><input type="radio" name="ll_mask_login_errors" value="yes" <?php if ($loginlockdownAdminOptions['mask_login_errors'] == "yes") echo "checked"; ?>> <?php esc_html_e('Yes', 'loginlockdown') ?> <input type="radio" name="ll_mask_login_errors" value="no" <?php if ($loginlockdownAdminOptions['mask_login_errors'] == "no") echo "checked"; ?>> <?php esc_html_e('No', 'loginlockdown') ?></p>
|
309 |
+
<h3><?php esc_html_e('Show Credit Link?', 'loginlockdown') ?></h3>
|
310 |
+
<p><?php esc_html_e('If enabled, Login LockDown will display the following message on the login form', 'loginlockdown') ?>:<br />
|
311 |
+
<blockquote><?php esc_html_e('Login form protected by', 'loginlockdown') ?> <a href='https://wploginlockdown.com/'>Login LockDown</a>.</blockquote>
|
312 |
+
<?php esc_html_e('This helps others know about the plugin so they can protect their blogs as well if they like. You can enable or disable this message below', 'loginlockdown') ?>:</p>
|
313 |
+
<input type="radio" name="ll_show_credit_link" value="yes" <?php if ($loginlockdownAdminOptions['show_credit_link'] == "yes" || $loginlockdownAdminOptions['show_credit_link'] == "") echo "checked"; ?>> <?php esc_html_e('Yes, display the credit link.', 'loginlockdown') ?><br />
|
314 |
+
<input type="radio" name="ll_show_credit_link" value="shownofollow" <?php if ($loginlockdownAdminOptions['show_credit_link'] == "shownofollow") echo "checked"; ?>> <?php esc_html_e('Display the credit link, but add "rel=\'nofollow\'" (ie. do not pass any link juice).', 'loginlockdown') ?><br />
|
315 |
+
<input type="radio" name="ll_show_credit_link" value="no" <?php if ($loginlockdownAdminOptions['show_credit_link'] == "no") echo "checked"; ?>> <?php esc_html_e('No, do not display the credit link.', 'loginlockdown') ?><br />
|
316 |
+
<div class="submit">
|
317 |
+
<input type="submit" class="button button-primary" name="update_loginlockdownSettings" value="<?php esc_html_e('Update Settings', 'loginlockdown') ?>" />
|
318 |
+
</div>
|
319 |
+
</form>
|
320 |
+
<?php } else { ?>
|
321 |
+
<form method="post" action="<?php echo esc_attr($_SERVER["REQUEST_URI"]); ?>">
|
322 |
+
<?php
|
323 |
+
if (function_exists('wp_nonce_field'))
|
324 |
+
wp_nonce_field('login-lockdown_release-lockdowns');
|
325 |
+
?>
|
326 |
+
<h3><?php
|
327 |
+
if (count($dalist) == 1) {
|
328 |
+
printf(esc_html__('There is currently %d locked out IP address.', 'loginlockdown'), count($dalist));
|
329 |
+
} else {
|
330 |
+
printf(esc_html__('There are currently %d locked out IP addresses.', 'loginlockdown'), count($dalist));
|
331 |
+
} ?></h3>
|
332 |
+
|
333 |
+
<?php
|
334 |
+
$num_lockedout = count($dalist);
|
335 |
+
if (0 == $num_lockedout) {
|
336 |
+
echo "<p>No IP blocks currently locked out.</p>";
|
337 |
+
} else {
|
338 |
+
foreach ($dalist as $key => $option) {
|
339 |
+
?>
|
340 |
+
<li><input type="checkbox" name="releaseme[]" value="<?php echo esc_attr($option['lockdown_ID']); ?>"> <?php echo esc_attr($option['lockdown_IP']); ?> (<?php echo esc_attr($option['minutes_left']); ?> <?php esc_html_e('minutes left', 'loginlockdown') ?>)</li>
|
341 |
+
<?php
|
342 |
+
}
|
343 |
+
}
|
344 |
+
?>
|
345 |
+
<div class="submit">
|
346 |
+
<input type="submit" class="button button-primary" name="release_lockdowns" value="<?php esc_html_e('Release Selected', 'loginlockdown') ?>" />
|
347 |
+
</div>
|
348 |
+
</form>
|
349 |
+
<?php } ?>
|
350 |
+
</div>
|
351 |
<?php
|
352 |
+
} //End function loginLockdown_print_admin_page()
|
353 |
|
354 |
+
function loginLockdown_ap()
|
355 |
+
{
|
356 |
+
if (function_exists('add_options_page')) {
|
357 |
+
add_options_page('Login LockDown', 'Login LockDown', 'manage_options', basename(__FILE__), 'loginLockdown_print_admin_page');
|
358 |
+
}
|
359 |
}
|
360 |
|
361 |
+
function loginLockdown_credit_link()
|
362 |
+
{
|
363 |
+
global $loginlockdownOptions;
|
364 |
+
$thispage = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
|
365 |
+
$homepage = get_option("home");
|
366 |
+
$showcreditlink = $loginlockdownOptions['show_credit_link'];
|
367 |
+
$relnofollow = true;
|
368 |
+
if ($showcreditlink != "shownofollow" && ($thispage == $homepage || $thispage == $homepage . "/" || substr($_SERVER["REQUEST_URI"], strlen($_SERVER["REQUEST_URI"]) - 12) == "wp-login.php")) {
|
369 |
+
$relnofollow = false;
|
370 |
+
}
|
371 |
+
if ($showcreditlink != "no") {
|
372 |
+
echo "<p>";
|
373 |
+
esc_html_e('Login form protected by', 'loginlockdown');
|
374 |
+
echo " <a href='" . esc_url('https://wploginlockdown.com/') . "' " . ($relnofollow ? "rel='nofollow'" : "") . ">Login LockDown</a>.<br /><br /><br /></p>";
|
375 |
+
}
|
376 |
}
|
377 |
|
378 |
+
//Actions and Filters
|
379 |
+
if (isset($loginlockdown_db_version)) {
|
380 |
+
//Actions
|
381 |
+
add_action('admin_menu', 'loginLockdown_ap');
|
382 |
+
register_activation_hook(__FILE__, 'loginLockdown_install');
|
383 |
+
add_action('login_form', 'loginLockdown_credit_link');
|
384 |
+
|
385 |
+
remove_filter('authenticate', 'wp_authenticate_username_password', 20, 3);
|
386 |
+
add_filter('authenticate', 'loginLockdown_wp_authenticate_username_password', 20, 3);
|
387 |
+
//Filters
|
388 |
+
|
389 |
+
//Functions
|
390 |
+
function loginLockdown_wp_authenticate_username_password($user, $username, $password)
|
391 |
+
{
|
392 |
+
if (is_a($user, 'WP_User')) {
|
393 |
+
return $user;
|
394 |
+
}
|
395 |
+
|
396 |
+
if (empty($username) || empty($password)) {
|
397 |
+
$error = new WP_Error();
|
398 |
+
|
399 |
+
if (empty($username))
|
400 |
+
$error->add('empty_username', __('<strong>ERROR</strong>: The username field is empty.', 'loginlockdown'));
|
401 |
+
|
402 |
+
if (empty($password))
|
403 |
+
$error->add('empty_password', __('<strong>ERROR</strong>: The password field is empty.', 'loginlockdown'));
|
404 |
+
|
405 |
+
return $error;
|
406 |
+
}
|
407 |
+
|
408 |
+
$userdata = get_user_by('login', $username);
|
409 |
+
|
410 |
+
if (!$userdata) {
|
411 |
+
return new WP_Error('invalid_username', sprintf(__('<strong>ERROR</strong>: Invalid username. <a href="%s" title="Password Lost and Found">Lost your password</a>?', 'loginlockdown'), site_url('wp-login.php?action=lostpassword', 'login')));
|
412 |
+
}
|
413 |
+
|
414 |
+
$userdata = apply_filters('wp_authenticate_user', $userdata, $password);
|
415 |
+
if (is_wp_error($userdata)) {
|
416 |
+
return $userdata;
|
417 |
+
}
|
418 |
+
|
419 |
+
if (!wp_check_password($password, $userdata->user_pass, $userdata->ID)) {
|
420 |
+
return new WP_Error('incorrect_password', sprintf(__('<strong>ERROR</strong>: Incorrect password. <a href="%s" title="Password Lost and Found">Lost your password</a>?', 'loginlockdown'), site_url('wp-login.php?action=lostpassword', 'login')));
|
421 |
+
}
|
422 |
+
|
423 |
+
$user = new WP_User($userdata->ID);
|
424 |
+
return $user;
|
425 |
+
}
|
426 |
+
|
427 |
+
|
428 |
+
if (!function_exists('wp_authenticate')) {
|
429 |
+
function wp_authenticate($username, $password)
|
430 |
+
{
|
431 |
+
global $wpdb, $error;
|
432 |
+
global $loginlockdownOptions;
|
433 |
+
|
434 |
+
$username = sanitize_user($username);
|
435 |
+
$password = trim($password);
|
436 |
+
|
437 |
+
if ("" != loginLockdown_isLockedDown()) {
|
438 |
+
return new WP_Error('incorrect_password', __("<strong>ERROR</strong>: We're sorry, but this IP range has been blocked due to too many recent failed login attempts.<br /><br />Please try again later.", 'loginlockdown'));
|
439 |
+
}
|
440 |
+
|
441 |
+
$user = apply_filters('authenticate', null, $username, $password);
|
442 |
+
|
443 |
+
if ($user == null) {
|
444 |
+
// TODO what should the error message be? (Or would these even happen?)
|
445 |
+
// Only needed if all authentication handlers fail to return anything.
|
446 |
+
$user = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.', 'loginlockdown'));
|
447 |
+
}
|
448 |
+
|
449 |
+
$ignore_codes = array('empty_username', 'empty_password');
|
450 |
+
|
451 |
+
if (is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes)) {
|
452 |
+
loginLockdown_incrementFails($username);
|
453 |
+
|
454 |
+
if ($loginlockdownOptions['max_login_retries'] <= loginLockdown_countFails($username)) {
|
455 |
+
loginLockdown_lockDown($username);
|
456 |
+
return new WP_Error('incorrect_password', __("<strong>ERROR</strong>: We're sorry, but this IP range has been blocked due to too many recent failed login attempts.<br /><br />Please try again later.", 'loginlockdown'));
|
457 |
+
}
|
458 |
+
if ('yes' == $loginlockdownOptions['mask_login_errors']) {
|
459 |
+
return new WP_Error('authentication_failed', sprintf(__('<strong>ERROR</strong>: Invalid username or incorrect password. <a href="%s" title="Password Lost and Found">Lost your password</a>?', 'loginlockdown'), site_url('wp-login.php?action=lostpassword', 'login')));
|
460 |
+
} else {
|
461 |
+
do_action('wp_login_failed', $username);
|
462 |
+
}
|
463 |
+
}
|
464 |
+
|
465 |
+
return $user;
|
466 |
+
}
|
467 |
+
}
|
468 |
+
|
469 |
+
// multisite network-wide activation
|
470 |
+
register_activation_hook(__FILE__, 'loginLockdown_multisite_activate');
|
471 |
+
function loginLockdown_multisite_activate($networkwide)
|
472 |
+
{
|
473 |
+
global $wpdb;
|
474 |
+
|
475 |
+
if (function_exists('is_multisite') && is_multisite()) {
|
476 |
+
// check if it is a network activation - if so, run the activation function for each blog id
|
477 |
+
if ($networkwide) {
|
478 |
+
$old_blog = $wpdb->blogid;
|
479 |
+
// Get all blog ids
|
480 |
+
$blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
|
481 |
+
foreach ($blogids as $blog_id) {
|
482 |
+
switch_to_blog($blog_id);
|
483 |
+
loginLockdown_install();
|
484 |
+
}
|
485 |
+
switch_to_blog($old_blog);
|
486 |
+
return;
|
487 |
+
}
|
488 |
+
}
|
489 |
+
}
|
490 |
+
|
491 |
+
// multisite new site activation
|
492 |
+
add_action('wpmu_new_blog', 'loginLockdown_multisite_newsite', 10, 6);
|
493 |
+
function loginLockdown_multisite_newsite($blog_id, $user_id, $domain, $path, $site_id, $meta)
|
494 |
+
{
|
495 |
+
global $wpdb;
|
496 |
+
|
497 |
+
if (is_plugin_active_for_network('loginlockdown/loginlockdown.php')) {
|
498 |
+
$old_blog = $wpdb->blogid;
|
499 |
+
switch_to_blog($blog_id);
|
500 |
+
loginLockdown_install();
|
501 |
+
switch_to_blog($old_blog);
|
502 |
+
}
|
503 |
+
}
|
504 |
+
|
505 |
+
// multisite old sites check
|
506 |
+
|
507 |
+
add_action('admin_init', 'loginLockdown_multisite_legacy');
|
508 |
+
function loginLockdown_multisite_legacy()
|
509 |
+
{
|
510 |
+
$loginlockdownMSRunOnce = get_option("loginlockdownmsrunonce");
|
511 |
+
if (empty($loginlockdownMSRunOnce)) {
|
512 |
+
global $wpdb;
|
513 |
+
|
514 |
+
if (function_exists('is_multisite') && is_multisite()) {
|
515 |
+
|
516 |
+
$old_blog = $wpdb->blogid;
|
517 |
+
|
518 |
+
// Get all blog ids
|
519 |
+
$blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
|
520 |
+
foreach ($blogids as $blog_id) {
|
521 |
+
|
522 |
+
// check if already exists
|
523 |
+
$bed_check = $wpdb->query($wpdb->prepare("SHOW TABLES LIKE %s", array($wpdb->base_prefix . $blog_id . '_login_fails')));
|
524 |
+
if (!$bed_check) {
|
525 |
+
|
526 |
+
switch_to_blog($blog_id);
|
527 |
+
loginLockdown_install();
|
528 |
+
}
|
529 |
+
}
|
530 |
+
switch_to_blog($old_blog);
|
531 |
+
}
|
532 |
+
add_option("loginlockdownmsrunonce", "done", "", "no");
|
533 |
+
return;
|
534 |
+
}
|
535 |
+
}
|
536 |
}
|
537 |
|
538 |
+
add_action('plugins_loaded', 'loginLockdown_init', 10);
|
539 |
|
540 |
+
function loginLockdown_init()
|
541 |
+
{
|
542 |
+
load_plugin_textdomain('loginlockdown', false, dirname(plugin_basename(__FILE__)) . '/languages/');
|
543 |
}
|
readme.txt
CHANGED
@@ -1,31 +1,42 @@
|
|
1 |
-
=== Login LockDown ===
|
2 |
-
|
3 |
-
Tags: security, login, login form
|
4 |
-
Requires at least:
|
5 |
-
Tested up to:
|
6 |
-
Stable Tag: 1.
|
7 |
-
|
8 |
-
|
|
|
|
|
|
|
9 |
|
10 |
== Description ==
|
11 |
|
12 |
-
Login LockDown records the IP address and timestamp of every failed login attempt. If more than a
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
to a 1 hour lock out of an IP block after 3 failed login attempts within 5 minutes. This can be modified
|
17 |
-
via the Options panel. Administrators can release locked out IP ranges manually from the panel.
|
18 |
|
19 |
== Installation ==
|
20 |
|
21 |
1. Extract the zip file into your plugins directory into its own folder.
|
22 |
2. Activate the plugin in the Plugin options.
|
23 |
-
3. Customize the settings from
|
|
|
|
|
24 |
|
25 |
-
|
26 |
|
27 |
== Change Log ==
|
28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
ver. 1.8.1 30-Sep-2019
|
30 |
|
31 |
- adding missing ./languages folder
|
@@ -78,9 +89,8 @@ Enjoy.
|
|
78 |
|
79 |
ver. 1.1 01-Sep-2007
|
80 |
|
81 |
-
- revised time query to MySQL 4.0
|
82 |
|
83 |
ver. 1.0 29-Aug-2007
|
84 |
|
85 |
- released
|
86 |
-
|
1 |
+
=== Login LockDown - Protect Login Form ===
|
2 |
+
Contributors: WebFactory
|
3 |
+
Tags: security, login, login form, protect login, login control, login blocking, lockdown, ban ip
|
4 |
+
Requires at least: 4.0
|
5 |
+
Tested up to: 6.0
|
6 |
+
Stable Tag: 1.82
|
7 |
+
Requires PHP: 5.2
|
8 |
+
License: GPLv2 or later
|
9 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
+
|
11 |
+
Protect login form by limiting the number of login attempts from the same IP and banning IPs.
|
12 |
|
13 |
== Description ==
|
14 |
|
15 |
+
<a href="https://wploginlockdown.com/">Login LockDown</a> records the IP address and timestamp of every failed login attempt. If more than a certain number of attempts are detected within a short period of time from the same IP range, then the login function is disabled for all requests from that IP address. This helps to prevent brute force password discovery and attacks.
|
16 |
+
The plugin defaults to a 1 hour lock out of an IP block after 3 failed login attempts within 5 minutes. This can be modified in options. Administrators can release locked out IP ranges manually from the panel.
|
17 |
+
|
18 |
+
Configure the plugin from Settings - Login LockDown
|
|
|
|
|
19 |
|
20 |
== Installation ==
|
21 |
|
22 |
1. Extract the zip file into your plugins directory into its own folder.
|
23 |
2. Activate the plugin in the Plugin options.
|
24 |
+
3. Customize the settings from Settings - Login LockDown panel.
|
25 |
+
|
26 |
+
== Screenshots ==
|
27 |
|
28 |
+
1. Protect your login form by banning IPs with multiple failed login attempts
|
29 |
|
30 |
== Change Log ==
|
31 |
|
32 |
+
= v1.82 =
|
33 |
+
* 2022/09/23
|
34 |
+
* WebFactory took over development
|
35 |
+
* a full rewrite will follow soon, for now we patched some urgent things
|
36 |
+
* prefixed function names that are in global namespace
|
37 |
+
* properly escaped all inputs
|
38 |
+
|
39 |
+
= Old changelog =
|
40 |
ver. 1.8.1 30-Sep-2019
|
41 |
|
42 |
- adding missing ./languages folder
|
89 |
|
90 |
ver. 1.1 01-Sep-2007
|
91 |
|
92 |
+
- revised time query to MySQL 4.0 compatibility
|
93 |
|
94 |
ver. 1.0 29-Aug-2007
|
95 |
|
96 |
- released
|
|
version.txt
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
1.7.1
|
|