Version Description
- Further multisite & WPMU support (again thanks to erik@erikshosting.com)
- Better error handling if option variables are damaged
- Added Traditional Chinese translation, thanks to Denny Huang bigexplorations@bigexplorations.com.tw
Download this release
Release Info
Developer | johanee |
Plugin | Limit Login Attempts |
Version | 1.5.1 |
Comparing to | |
See all releases |
Code changes from version 1.5 to 1.5.1
- limit-login-attempts-zh_TW.mo +0 -0
- limit-login-attempts-zh_TW.po +277 -0
- limit-login-attempts.php +78 -63
- readme.txt +54 -41
limit-login-attempts-zh_TW.mo
ADDED
Binary file
|
limit-login-attempts-zh_TW.po
ADDED
@@ -0,0 +1,277 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# SOME DESCRIPTIVE TITLE.
|
2 |
+
# Copyright (C) YEAR Johan Eenfeldt
|
3 |
+
# This file is distributed under the same license as the PACKAGE package.
|
4 |
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
5 |
+
#
|
6 |
+
msgid ""
|
7 |
+
msgstr ""
|
8 |
+
"Project-Id-Version: Limit Login Attempts v1.5\n"
|
9 |
+
"Report-Msgid-Bugs-To: http://wordpress.org/tag/limit-login-attempts\n"
|
10 |
+
"POT-Creation-Date: 2009-01-28 17:17+0000\n"
|
11 |
+
"PO-Revision-Date: 2010-07-23 03:16+0800\n"
|
12 |
+
"Last-Translator: Denny Huang <bigexplorations@bigexplorations.com.tw>\n"
|
13 |
+
"Language-Team: 小弟的大發現 <bigexplorations@bigexplorations.com.tw>\n"
|
14 |
+
"MIME-Version: 1.0\n"
|
15 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
16 |
+
"Content-Transfer-Encoding: 8bit\n"
|
17 |
+
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
18 |
+
"X-Poedit-Language: Chinese\n"
|
19 |
+
"X-Poedit-Country: TAIWAN\n"
|
20 |
+
|
21 |
+
#: limit-login-attempts.php:372
|
22 |
+
#, php-format
|
23 |
+
msgid "%d hour"
|
24 |
+
msgid_plural "%d hours"
|
25 |
+
msgstr[0] "%d 小時"
|
26 |
+
msgstr[1] "%d 小時"
|
27 |
+
|
28 |
+
#: limit-login-attempts.php:378
|
29 |
+
#, php-format
|
30 |
+
msgid "%d minute"
|
31 |
+
msgid_plural "%d minutes"
|
32 |
+
msgstr[0] "%d 分鐘"
|
33 |
+
msgstr[1] "%d 分鐘"
|
34 |
+
|
35 |
+
#: limit-login-attempts.php:381
|
36 |
+
#, php-format
|
37 |
+
msgid "[%s] Too many failed login attempts"
|
38 |
+
msgstr "[%s] 嘗試過多次的失敗登入"
|
39 |
+
|
40 |
+
#: limit-login-attempts.php:383
|
41 |
+
#, php-format
|
42 |
+
msgid "%d failed login attempts (%d lockout(s)) from IP: %s"
|
43 |
+
msgstr "登入失敗嘗試次數: %d (%d 鎖定) 來自 IP: %s"
|
44 |
+
|
45 |
+
#: limit-login-attempts.php:387
|
46 |
+
#, php-format
|
47 |
+
msgid "Last user attempted: %s"
|
48 |
+
msgstr "最後一位使用者嘗試: %s"
|
49 |
+
|
50 |
+
#: limit-login-attempts.php:390
|
51 |
+
#, php-format
|
52 |
+
msgid "IP was blocked for %s"
|
53 |
+
msgstr "IP已被封鎖。 原因: %s"
|
54 |
+
|
55 |
+
#: limit-login-attempts.php:445
|
56 |
+
msgid "<strong>ERROR</strong>: Too many failed login attempts."
|
57 |
+
msgstr "<strong>錯誤</strong>: 嘗試過多次失敗登入"
|
58 |
+
|
59 |
+
#: limit-login-attempts.php:449
|
60 |
+
msgid "Please try again later."
|
61 |
+
msgstr "請稍候再試."
|
62 |
+
|
63 |
+
#: limit-login-attempts.php:456
|
64 |
+
#, php-format
|
65 |
+
msgid "Please try again in %d hour."
|
66 |
+
msgid_plural "Please try again in %d hours."
|
67 |
+
msgstr[0] "請在%d小時後再重試。"
|
68 |
+
msgstr[1] "請在%d小時後再重試。"
|
69 |
+
|
70 |
+
#: limit-login-attempts.php:458
|
71 |
+
#, php-format
|
72 |
+
msgid "Please try again in %d minute."
|
73 |
+
msgid_plural "Please try again in %d minutes."
|
74 |
+
msgstr[0] "請在%d分鐘後再重試。"
|
75 |
+
msgstr[1] "請在%d分鐘後再重試。"
|
76 |
+
|
77 |
+
#: limit-login-attempts.php:487
|
78 |
+
#, php-format
|
79 |
+
msgid "<strong>%d</strong> attempt remaining."
|
80 |
+
msgid_plural "<strong>%d</strong> attempts remaining."
|
81 |
+
msgstr[0] "嘗試次數剩<strong>%d</strong>次."
|
82 |
+
msgstr[1] "嘗試次數剩<strong>%d</strong>次."
|
83 |
+
|
84 |
+
#: limit-login-attempts.php:551
|
85 |
+
msgid "<strong>ERROR</strong>: Incorrect username or password."
|
86 |
+
msgstr "<strong>錯誤</strong>: 帳號或密碼錯誤."
|
87 |
+
|
88 |
+
#: limit-login-attempts.php:714
|
89 |
+
msgid "IP|Internet address"
|
90 |
+
msgstr "IP|網路位址"
|
91 |
+
|
92 |
+
#: limit-login-attempts.php:714
|
93 |
+
msgid "Tried to log in as"
|
94 |
+
msgstr "嘗試登入為"
|
95 |
+
|
96 |
+
#: limit-login-attempts.php:719
|
97 |
+
#, php-format
|
98 |
+
msgid "%d lockout"
|
99 |
+
msgid_plural "%d lockouts"
|
100 |
+
msgstr[0] "%d 次鎖定"
|
101 |
+
msgstr[1] "%d 次鎖定"
|
102 |
+
|
103 |
+
#: limit-login-attempts.php:743
|
104 |
+
msgid "Cleared IP log"
|
105 |
+
msgstr "清除IP紀錄"
|
106 |
+
|
107 |
+
#: limit-login-attempts.php:751
|
108 |
+
msgid "Reset lockout count"
|
109 |
+
msgstr "重設鎖定計數器"
|
110 |
+
|
111 |
+
#: limit-login-attempts.php:759
|
112 |
+
msgid "Cleared current lockouts"
|
113 |
+
msgstr "目前鎖定次數已重設"
|
114 |
+
|
115 |
+
#: limit-login-attempts.php:788
|
116 |
+
msgid "Options changed"
|
117 |
+
msgstr "設定已儲存"
|
118 |
+
|
119 |
+
#: limit-login-attempts.php:799
|
120 |
+
msgid "<strong>NOTE:</strong> Only works in Wordpress 2.7 or later"
|
121 |
+
msgstr "<strong>注意:</strong> 只在 Wordpress 2.7 或以後版本有效"
|
122 |
+
|
123 |
+
#: limit-login-attempts.php:815
|
124 |
+
#, php-format
|
125 |
+
msgid "It appears the site is reached directly (from your IP: %s)"
|
126 |
+
msgstr "網站與您的電腦(IP: %s)似乎是直接連線"
|
127 |
+
|
128 |
+
#: limit-login-attempts.php:817
|
129 |
+
#, php-format
|
130 |
+
msgid "It appears the site is reached through a proxy server (proxy IP: %s, your IP: %s)"
|
131 |
+
msgstr "網站似乎是透過代理伺服器(IP:%s)再與您的電腦(IP: %s)連線"
|
132 |
+
|
133 |
+
#: limit-login-attempts.php:825
|
134 |
+
#, php-format
|
135 |
+
msgid "<strong>Current setting appears to be invalid</strong>. Please make sure it is correct. Further information can be found <a href=\"%s\" title=\"FAQ\">here</a>"
|
136 |
+
msgstr "<strong>目前設定有些問題</strong>. 請再次檢查. 更多資訊可以在 <a href=\"%s\" title=\"FAQ\">這邊</a>找到"
|
137 |
+
|
138 |
+
#: limit-login-attempts.php:833
|
139 |
+
msgid "Limit Login Attempts Settings"
|
140 |
+
msgstr "Limit Login Attempts 設定"
|
141 |
+
|
142 |
+
#: limit-login-attempts.php:834
|
143 |
+
msgid "Statistics"
|
144 |
+
msgstr "數據"
|
145 |
+
|
146 |
+
#: limit-login-attempts.php:838
|
147 |
+
msgid "Total lockouts"
|
148 |
+
msgstr "總共鎖定次數"
|
149 |
+
|
150 |
+
#: limit-login-attempts.php:841
|
151 |
+
msgid "Reset Counter"
|
152 |
+
msgstr "重設計數器"
|
153 |
+
|
154 |
+
#: limit-login-attempts.php:842
|
155 |
+
#, php-format
|
156 |
+
msgid "%d lockout since last reset"
|
157 |
+
msgid_plural "%d lockouts since last reset"
|
158 |
+
msgstr[0] "自從上次重設,已有%d次鎖定。"
|
159 |
+
msgstr[1] "自從上次重設,已有%d次鎖定。"
|
160 |
+
|
161 |
+
#: limit-login-attempts.php:843
|
162 |
+
msgid "No lockouts yet"
|
163 |
+
msgstr "未有任何鎖定紀錄"
|
164 |
+
|
165 |
+
#: limit-login-attempts.php:848
|
166 |
+
msgid "Active lockouts"
|
167 |
+
msgstr "解除鎖定"
|
168 |
+
|
169 |
+
#: limit-login-attempts.php:850
|
170 |
+
msgid "Restore Lockouts"
|
171 |
+
msgstr "還原鎖定"
|
172 |
+
|
173 |
+
#: limit-login-attempts.php:851
|
174 |
+
#, php-format
|
175 |
+
msgid "%d IP is currently blocked from trying to log in"
|
176 |
+
msgstr "IP: %d嘗試登入,但目前已被阻擋"
|
177 |
+
|
178 |
+
#: limit-login-attempts.php:857
|
179 |
+
msgid "Options"
|
180 |
+
msgstr "選項"
|
181 |
+
|
182 |
+
#: limit-login-attempts.php:861
|
183 |
+
msgid "Lockout"
|
184 |
+
msgstr "鎖定"
|
185 |
+
|
186 |
+
#: limit-login-attempts.php:863
|
187 |
+
msgid "allowed retries"
|
188 |
+
msgstr "允許嘗試次數"
|
189 |
+
|
190 |
+
#: limit-login-attempts.php:864
|
191 |
+
msgid "minutes lockout"
|
192 |
+
msgstr "分鐘鎖定"
|
193 |
+
|
194 |
+
#: limit-login-attempts.php:865
|
195 |
+
msgid "lockouts increase lockout time to"
|
196 |
+
msgstr "次鎖定後,將鎖定時間增加為"
|
197 |
+
|
198 |
+
#: limit-login-attempts.php:865
|
199 |
+
msgid "hours"
|
200 |
+
msgstr "小時"
|
201 |
+
|
202 |
+
#: limit-login-attempts.php:866
|
203 |
+
msgid "hours until retries are reset"
|
204 |
+
msgstr "小時直到重設登入嘗試"
|
205 |
+
|
206 |
+
#: limit-login-attempts.php:870
|
207 |
+
msgid "Site connection"
|
208 |
+
msgstr "網站連結"
|
209 |
+
|
210 |
+
#: limit-login-attempts.php:876
|
211 |
+
msgid "Direct connection"
|
212 |
+
msgstr "直接連線"
|
213 |
+
|
214 |
+
#: limit-login-attempts.php:881
|
215 |
+
msgid "From behind a reversy proxy"
|
216 |
+
msgstr "透過代理伺服器"
|
217 |
+
|
218 |
+
#: limit-login-attempts.php:887
|
219 |
+
msgid "Handle cookie login"
|
220 |
+
msgstr "控管Cookie登入"
|
221 |
+
|
222 |
+
#: limit-login-attempts.php:889
|
223 |
+
msgid "Yes"
|
224 |
+
msgstr "是"
|
225 |
+
|
226 |
+
#: limit-login-attempts.php:889
|
227 |
+
msgid "No"
|
228 |
+
msgstr "否"
|
229 |
+
|
230 |
+
#: limit-login-attempts.php:894
|
231 |
+
msgid "Notify on lockout"
|
232 |
+
msgstr "鎖定的提醒"
|
233 |
+
|
234 |
+
#: limit-login-attempts.php:896
|
235 |
+
msgid "Log IP"
|
236 |
+
msgstr "紀錄 IP"
|
237 |
+
|
238 |
+
#: limit-login-attempts.php:897
|
239 |
+
msgid "Email to admin after"
|
240 |
+
msgstr "Email 給管理員當超過"
|
241 |
+
|
242 |
+
#: limit-login-attempts.php:897
|
243 |
+
msgid "lockouts"
|
244 |
+
msgstr "鎖定次數"
|
245 |
+
|
246 |
+
#: limit-login-attempts.php:902
|
247 |
+
msgid "Change Options"
|
248 |
+
msgstr "儲存設定"
|
249 |
+
|
250 |
+
#: limit-login-attempts.php:910
|
251 |
+
msgid "Lockout log"
|
252 |
+
msgstr "鎖定紀錄"
|
253 |
+
|
254 |
+
#: limit-login-attempts.php:914
|
255 |
+
msgid "Clear Log"
|
256 |
+
msgstr "清除記錄"
|
257 |
+
|
258 |
+
#. Plugin Name of an extension
|
259 |
+
msgid "Limit Login Attempts"
|
260 |
+
msgstr "Limit Login Attempts"
|
261 |
+
|
262 |
+
#. Plugin URI of an extension
|
263 |
+
msgid "http://devel.kostdoktorn.se/limit-login-attempts"
|
264 |
+
msgstr "http://devel.kostdoktorn.se/limit-login-attempts"
|
265 |
+
|
266 |
+
#. Description of an extension
|
267 |
+
msgid "Limit rate of login attempts, including by way of cookies, for each IP."
|
268 |
+
msgstr "限制登入嘗試比率(包含Cookies 和 IP) [外掛中文化: <a href=\"http://blog.bigexplorations.com.tw/\" target=\"_blank\" title=\"小弟的大發現\">Denny Huang</a>]"
|
269 |
+
|
270 |
+
#. Author of an extension
|
271 |
+
msgid "Johan Eenfeldt"
|
272 |
+
msgstr "Johan Eenfeldt"
|
273 |
+
|
274 |
+
#. Author URI of an extension
|
275 |
+
msgid "http://devel.kostdoktorn.se"
|
276 |
+
msgstr "http://devel.kostdoktorn.se"
|
277 |
+
|
limit-login-attempts.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
Description: Limit rate of login attempts, including by way of cookies, for each IP.
|
6 |
Author: Johan Eenfeldt
|
7 |
Author URI: http://devel.kostdoktorn.se
|
8 |
-
Version: 1.5
|
9 |
|
10 |
Copyright 2008, 2009, 2010 Johan Eenfeldt
|
11 |
|
@@ -211,11 +211,6 @@ function limit_login_handle_cookies() {
|
|
211 |
return;
|
212 |
}
|
213 |
|
214 |
-
if (empty($_COOKIE[AUTH_COOKIE]) && empty($_COOKIE[SECURE_AUTH_COOKIE])
|
215 |
-
&& empty($_COOKIE[LOGGED_IN_COOKIE])) {
|
216 |
-
return;
|
217 |
-
}
|
218 |
-
|
219 |
wp_clear_auth_cookie();
|
220 |
|
221 |
if (!empty($_COOKIE[AUTH_COOKIE])) {
|
@@ -247,20 +242,21 @@ function limit_login_failed($arg) {
|
|
247 |
|
248 |
/* if currently locked-out, do not add to retries */
|
249 |
$lockouts = get_option('limit_login_lockouts');
|
250 |
-
if(is_array($lockouts)
|
251 |
-
return;
|
252 |
-
} elseif (!is_array($lockouts)) {
|
253 |
$lockouts = array();
|
254 |
}
|
|
|
|
|
|
|
255 |
|
256 |
/* Get the arrays with retries and retries-valid information */
|
257 |
$retries = get_option('limit_login_retries');
|
258 |
$valid = get_option('limit_login_retries_valid');
|
259 |
-
if ($retries
|
260 |
$retries = array();
|
261 |
add_option('limit_login_retries', $retries, '', 'no');
|
262 |
}
|
263 |
-
if ($valid
|
264 |
$valid = array();
|
265 |
add_option('limit_login_retries_valid', $valid, '', 'no');
|
266 |
}
|
@@ -274,55 +270,60 @@ function limit_login_failed($arg) {
|
|
274 |
$valid[$ip] = time() + limit_login_option('valid_duration');
|
275 |
|
276 |
/* lockout? */
|
277 |
-
if($retries[$ip] % limit_login_option('allowed_retries')
|
278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
|
280 |
-
|
281 |
|
282 |
-
|
283 |
-
|
284 |
-
* limit_login_option('allowed_lockouts');
|
285 |
-
if ($retries[$ip] >= $retries_long) {
|
286 |
-
/* long lockout */
|
287 |
-
$lockouts[$ip] = time() + limit_login_option('long_duration');
|
288 |
-
unset($retries[$ip]);
|
289 |
-
unset($valid[$ip]);
|
290 |
-
} else {
|
291 |
-
/* normal lockout */
|
292 |
-
$lockouts[$ip] = time() + limit_login_option('lockout_duration');
|
293 |
-
}
|
294 |
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
304 |
|
305 |
-
|
306 |
-
|
307 |
|
308 |
-
|
309 |
-
|
310 |
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
} else {
|
316 |
-
update_option('limit_login_lockouts_total', $total + 1);
|
317 |
-
}
|
318 |
} else {
|
319 |
-
|
320 |
-
limit_login_cleanup($retries, null, $valid);
|
321 |
}
|
322 |
}
|
323 |
|
324 |
|
325 |
-
/* Clean up
|
326 |
function limit_login_cleanup($retries = null, $lockouts = null, $valid = null) {
|
327 |
$now = time();
|
328 |
$lockouts = !is_null($lockouts) ? $lockouts : get_option('limit_login_lockouts');
|
@@ -363,11 +364,17 @@ function limit_login_cleanup($retries = null, $lockouts = null, $valid = null) {
|
|
363 |
}
|
364 |
|
365 |
|
|
|
|
|
|
|
|
|
|
|
|
|
366 |
/* Email notification of lockout to admin (if configured) */
|
367 |
function limit_login_notify_email($user) {
|
368 |
$ip = limit_login_get_address();
|
369 |
-
$retries = get_option('limit_login_retries');
|
370 |
|
|
|
371 |
if (!is_array($retries)) {
|
372 |
$retries = array();
|
373 |
}
|
@@ -395,11 +402,8 @@ function limit_login_notify_email($user) {
|
|
395 |
$when = sprintf(__ngettext('%d minute', '%d minutes', $time, 'limit-login-attempts'), $time);
|
396 |
}
|
397 |
|
398 |
-
|
399 |
-
|
400 |
-
} else {
|
401 |
-
$blogname = get_option('blogname');
|
402 |
-
}
|
403 |
$subject = sprintf(__("[%s] Too many failed login attempts", 'limit-login-attempts')
|
404 |
, $blogname);
|
405 |
$message = sprintf(__("%d failed login attempts (%d lockout(s)) from IP: %s"
|
@@ -411,11 +415,7 @@ function limit_login_notify_email($user) {
|
|
411 |
}
|
412 |
$message .= sprintf(__("IP was blocked for %s", 'limit-login-attempts'), $when);
|
413 |
|
414 |
-
|
415 |
-
$admin_email = get_site_option('admin_email');
|
416 |
-
} else {
|
417 |
-
$admin_email = get_option('admin_email');
|
418 |
-
}
|
419 |
|
420 |
@wp_mail($admin_email, $subject, $message);
|
421 |
}
|
@@ -425,7 +425,7 @@ function limit_login_notify_email($user) {
|
|
425 |
function limit_login_notify_log($user) {
|
426 |
$log = get_option('limit_login_logged');
|
427 |
$ip = limit_login_get_address();
|
428 |
-
if ($log
|
429 |
$log = array($ip => array($user => 1));
|
430 |
add_option('limit_login_logged', $log, '', 'no'); /* no autoload */
|
431 |
} else {
|
@@ -730,7 +730,22 @@ function limit_login_sanitize_variables() {
|
|
730 |
|
731 |
/* Add admin options page */
|
732 |
function limit_login_admin_menu() {
|
733 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
734 |
}
|
735 |
|
736 |
|
@@ -978,4 +993,4 @@ function limit_login_option_page() {
|
|
978 |
</div>
|
979 |
<?php
|
980 |
}
|
981 |
-
?>
|
5 |
Description: Limit rate of login attempts, including by way of cookies, for each IP.
|
6 |
Author: Johan Eenfeldt
|
7 |
Author URI: http://devel.kostdoktorn.se
|
8 |
+
Version: 1.5.1
|
9 |
|
10 |
Copyright 2008, 2009, 2010 Johan Eenfeldt
|
11 |
|
211 |
return;
|
212 |
}
|
213 |
|
|
|
|
|
|
|
|
|
|
|
214 |
wp_clear_auth_cookie();
|
215 |
|
216 |
if (!empty($_COOKIE[AUTH_COOKIE])) {
|
242 |
|
243 |
/* if currently locked-out, do not add to retries */
|
244 |
$lockouts = get_option('limit_login_lockouts');
|
245 |
+
if (!is_array($lockouts)) {
|
|
|
|
|
246 |
$lockouts = array();
|
247 |
}
|
248 |
+
if(isset($lockouts[$ip]) && time() < $lockouts[$ip]) {
|
249 |
+
return;
|
250 |
+
}
|
251 |
|
252 |
/* Get the arrays with retries and retries-valid information */
|
253 |
$retries = get_option('limit_login_retries');
|
254 |
$valid = get_option('limit_login_retries_valid');
|
255 |
+
if (!is_array($retries)) {
|
256 |
$retries = array();
|
257 |
add_option('limit_login_retries', $retries, '', 'no');
|
258 |
}
|
259 |
+
if (!is_array($valid)) {
|
260 |
$valid = array();
|
261 |
add_option('limit_login_retries_valid', $valid, '', 'no');
|
262 |
}
|
270 |
$valid[$ip] = time() + limit_login_option('valid_duration');
|
271 |
|
272 |
/* lockout? */
|
273 |
+
if($retries[$ip] % limit_login_option('allowed_retries') != 0) {
|
274 |
+
/*
|
275 |
+
* Not lockout (yet!)
|
276 |
+
* Do housecleaning (which also saves retry/valid values).
|
277 |
+
*/
|
278 |
+
limit_login_cleanup($retries, null, $valid);
|
279 |
+
return;
|
280 |
+
}
|
281 |
|
282 |
+
/* lockout! */
|
283 |
|
284 |
+
global $limit_login_just_lockedout;
|
285 |
+
$limit_login_just_lockedout = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
|
287 |
+
/* setup lockout, reset retries as needed */
|
288 |
+
$retries_long = limit_login_option('allowed_retries')
|
289 |
+
* limit_login_option('allowed_lockouts');
|
290 |
+
if ($retries[$ip] >= $retries_long) {
|
291 |
+
/* long lockout */
|
292 |
+
$lockouts[$ip] = time() + limit_login_option('long_duration');
|
293 |
+
unset($retries[$ip]);
|
294 |
+
unset($valid[$ip]);
|
295 |
+
} else {
|
296 |
+
/* normal lockout */
|
297 |
+
$lockouts[$ip] = time() + limit_login_option('lockout_duration');
|
298 |
+
}
|
299 |
+
|
300 |
+
/* try to find username which failed */
|
301 |
+
$user = '';
|
302 |
+
if (is_string($arg)) {
|
303 |
+
/* action: wp_login_failed */
|
304 |
+
$user = $arg;
|
305 |
+
} elseif (is_array($arg) && array_key_exists('username', $arg)) {
|
306 |
+
/* action: auth_cookie_bad_* */
|
307 |
+
$user = $arg['username'];
|
308 |
+
}
|
309 |
|
310 |
+
/* do housecleaning and save values */
|
311 |
+
limit_login_cleanup($retries, $lockouts, $valid);
|
312 |
|
313 |
+
/* do any notification */
|
314 |
+
limit_login_notify($user);
|
315 |
|
316 |
+
/* increase statistics */
|
317 |
+
$total = get_option('limit_login_lockouts_total');
|
318 |
+
if ($total === false || !is_numeric($total)) {
|
319 |
+
add_option('limit_login_lockouts_total', 1, '', 'no');
|
|
|
|
|
|
|
320 |
} else {
|
321 |
+
update_option('limit_login_lockouts_total', $total + 1);
|
|
|
322 |
}
|
323 |
}
|
324 |
|
325 |
|
326 |
+
/* Clean up old lockouts and retries, and save supplied arrays */
|
327 |
function limit_login_cleanup($retries = null, $lockouts = null, $valid = null) {
|
328 |
$now = time();
|
329 |
$lockouts = !is_null($lockouts) ? $lockouts : get_option('limit_login_lockouts');
|
364 |
}
|
365 |
|
366 |
|
367 |
+
/* Is this WP Multisite? */
|
368 |
+
function is_limit_login_multisite() {
|
369 |
+
return function_exists('get_site_option') && function_exists('is_multisite') && is_multisite();
|
370 |
+
}
|
371 |
+
|
372 |
+
|
373 |
/* Email notification of lockout to admin (if configured) */
|
374 |
function limit_login_notify_email($user) {
|
375 |
$ip = limit_login_get_address();
|
|
|
376 |
|
377 |
+
$retries = get_option('limit_login_retries');
|
378 |
if (!is_array($retries)) {
|
379 |
$retries = array();
|
380 |
}
|
402 |
$when = sprintf(__ngettext('%d minute', '%d minutes', $time, 'limit-login-attempts'), $time);
|
403 |
}
|
404 |
|
405 |
+
$blogname = is_limit_login_multisite() ? get_site_option('site_name') : get_option('blogname');
|
406 |
+
|
|
|
|
|
|
|
407 |
$subject = sprintf(__("[%s] Too many failed login attempts", 'limit-login-attempts')
|
408 |
, $blogname);
|
409 |
$message = sprintf(__("%d failed login attempts (%d lockout(s)) from IP: %s"
|
415 |
}
|
416 |
$message .= sprintf(__("IP was blocked for %s", 'limit-login-attempts'), $when);
|
417 |
|
418 |
+
$admin_email = is_limit_login_multisite() ? get_site_option('admin_email') : get_option('admin_email');
|
|
|
|
|
|
|
|
|
419 |
|
420 |
@wp_mail($admin_email, $subject, $message);
|
421 |
}
|
425 |
function limit_login_notify_log($user) {
|
426 |
$log = get_option('limit_login_logged');
|
427 |
$ip = limit_login_get_address();
|
428 |
+
if (!is_array($log)) {
|
429 |
$log = array($ip => array($user => 1));
|
430 |
add_option('limit_login_logged', $log, '', 'no'); /* no autoload */
|
431 |
} else {
|
730 |
|
731 |
/* Add admin options page */
|
732 |
function limit_login_admin_menu() {
|
733 |
+
global $wp_version;
|
734 |
+
|
735 |
+
// Modern WP?
|
736 |
+
if (version_compare($wp_version, '3.0', '>=')) {
|
737 |
+
add_options_page('Limit Login Attempts', 'Limit Login Attempts', 'manage_options', 'limit-login-attempts', 'limit_login_option_page');
|
738 |
+
return;
|
739 |
+
}
|
740 |
+
|
741 |
+
// Older WPMU?
|
742 |
+
if (function_exists("get_current_site")) {
|
743 |
+
add_submenu_page('wpmu-admin.php', 'Limit Login Attempts', 'Limit Login Attempts', 9, 'limit-login-attempts', 'limit_login_option_page');
|
744 |
+
return;
|
745 |
+
}
|
746 |
+
|
747 |
+
// Older WP
|
748 |
+
add_options_page('Limit Login Attempts', 'Limit Login Attempts', 9, 'limit-login-attempts', 'limit_login_option_page');
|
749 |
}
|
750 |
|
751 |
|
993 |
</div>
|
994 |
<?php
|
995 |
}
|
996 |
+
?>
|
readme.txt
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
Contributors: johanee
|
3 |
Tags: login, security, authentication
|
4 |
Requires at least: 2.5
|
5 |
-
Tested up to: 3.0
|
6 |
-
Stable tag: 1.5
|
7 |
|
8 |
Limit rate of login attempts, including by way of cookies, for each IP.
|
9 |
|
@@ -23,7 +23,7 @@ Features
|
|
23 |
* Optional logging, optional email notification
|
24 |
* Handles server behind reverse proxy
|
25 |
|
26 |
-
Translations: Bulgarian, Catalan, Czech, Dutch, French, German, Hungarian, Norwegian, Persian, Romanian, Russian, Spanish, Swedish, Turkish
|
27 |
|
28 |
Plugin uses standard actions and filters only.
|
29 |
|
@@ -62,41 +62,54 @@ If you have access to the database (for example through phpMyAdmin) you can clea
|
|
62 |
3. Administration interface in WordPress 2.7
|
63 |
4. Administration interface in WordPress 2.5
|
64 |
|
65 |
-
==
|
66 |
-
|
67 |
-
|
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 |
-
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
Contributors: johanee
|
3 |
Tags: login, security, authentication
|
4 |
Requires at least: 2.5
|
5 |
+
Tested up to: 3.0.1
|
6 |
+
Stable tag: 1.5.1
|
7 |
|
8 |
Limit rate of login attempts, including by way of cookies, for each IP.
|
9 |
|
23 |
* Optional logging, optional email notification
|
24 |
* Handles server behind reverse proxy
|
25 |
|
26 |
+
Translations: Bulgarian, Catalan, Chinese (Traditional), Czech, Dutch, French, German, Hungarian, Norwegian, Persian, Romanian, Russian, Spanish, Swedish, Turkish
|
27 |
|
28 |
Plugin uses standard actions and filters only.
|
29 |
|
62 |
3. Administration interface in WordPress 2.7
|
63 |
4. Administration interface in WordPress 2.5
|
64 |
|
65 |
+
== Changelog ==
|
66 |
+
|
67 |
+
= 1.5.1 =
|
68 |
+
* Further multisite & WPMU support (again thanks to <erik@erikshosting.com>)
|
69 |
+
* Better error handling if option variables are damaged
|
70 |
+
* Added Traditional Chinese translation, thanks to Denny Huang <bigexplorations@bigexplorations.com.tw>
|
71 |
+
|
72 |
+
= 1.5 =
|
73 |
+
* Tested against WordPress 3.0
|
74 |
+
* Handle 3.0 login page failure "shake"
|
75 |
+
* Basic multisite support (parts thanks to <erik@erikshosting.com>)
|
76 |
+
* Added Dutch translation, thanks to Bjorn Wijers <burobjorn@burobjorn.nl>
|
77 |
+
* Added Hungarian translation, thanks to B�lint Vereskuti <balint@vereskuti.info>
|
78 |
+
* Added French translation, thanks to oVa <ova13lastar@gmail.com>
|
79 |
+
|
80 |
+
= 1.4.1 =
|
81 |
+
* Added Turkish translation, thanks to Yazan Canarkadas
|
82 |
+
|
83 |
+
= 1.4 =
|
84 |
+
* Protect admin page update using wp_nonce
|
85 |
+
* Added Czech translation, thanks to Jakub Jedelsky
|
86 |
+
|
87 |
+
= 1.3.2 =
|
88 |
+
* Added Bulgarian translation, thanks to Hristo Chakarov
|
89 |
+
* Added Norwegian translation, thanks to Rune Gulbrands�y
|
90 |
+
* Added Spanish translation, thanks to Marcelo Pedra
|
91 |
+
* Added Persian translation, thanks to Mostafa Soufi
|
92 |
+
* Added Russian translation, thanks to Jack Leonid (http://studio-xl.com)
|
93 |
+
|
94 |
+
= 1.3.1 =
|
95 |
+
* Added Catalan translation, thanks to Robert Buj
|
96 |
+
* Added Romanian translation, thanks to Robert Tudor
|
97 |
+
|
98 |
+
= 1.3 =
|
99 |
+
* Support for getting the correct IP for clients while server is behind reverse proxy, thanks to Michael Skerwiderski
|
100 |
+
* Added German translation, thanks to Michael Skerwiderski
|
101 |
+
|
102 |
+
= 1.2 =
|
103 |
+
* No longer replaces pluggable function when cookie handling active. Re-implemented using available actions and filters
|
104 |
+
* Filter error messages during login to avoid information leak regarding available usernames
|
105 |
+
* Do not show retries or lockout messages except for login (registration, lost password pages). No change in actual enforcement
|
106 |
+
* Slightly more aggressive in trimming old retries data
|
107 |
+
|
108 |
+
= 1.1 =
|
109 |
+
* Added translation support
|
110 |
+
* Added Swedish translation
|
111 |
+
* During lockout, filter out all other login errors
|
112 |
+
* Minor cleanups
|
113 |
+
|
114 |
+
= 1.0 =
|
115 |
+
* Initial version
|