IP Geo Block - Version 3.0.2.2

Version Description

  • Improvement: Change the behavior of "Referrer Suppressor" not to open a new window on public facing pages.
  • Improvement: Improve some of the descriptions of help text.
  • Bug fix: Fix the bug of undefined symbol in admin class related to the Google Map API.
  • Bug fix: Fix the bug of incompatible function arguments when the number of login fails reaches the limit.
  • Bug fix: Fix the issue of not working blocking by country on specific pages correctly as the validation target.
Download this release

Release Info

Developer tokkonopapa
Plugin Icon 128x128 IP Geo Block
Version 3.0.2.2
Comparing to
See all releases

Code changes from version 2.2.9.1 to 3.0.2.2

Files changed (61) hide show
  1. README.md +58 -0
  2. README.txt +282 -583
  3. admin/class-ip-geo-block-admin.php +129 -83
  4. admin/css/admin.css +33 -2
  5. admin/css/admin.min.css +1 -1
  6. admin/css/fonts/LICENSE +4 -0
  7. admin/css/footable.core.min.css +9 -0
  8. admin/includes/class-admin-ajax.php +114 -10
  9. admin/includes/tab-accesslog.php +24 -6
  10. admin/includes/tab-settings.php +387 -33
  11. admin/includes/tab-statistics.php +15 -17
  12. admin/js/admin.js +207 -77
  13. admin/js/admin.min.js +6 -6
  14. admin/js/authenticate.js +59 -29
  15. admin/js/authenticate.min.js +6 -6
  16. admin/js/footable.min.js +4 -2
  17. admin/js/gmap.js +2 -2
  18. admin/js/gmap.min.js +7 -7
  19. admin/js/whois.min.js +7 -7
  20. classes/class-ip-geo-block-actv.php +13 -9
  21. classes/class-ip-geo-block-apis.php +32 -55
  22. classes/class-ip-geo-block-cron.php +225 -4
  23. classes/class-ip-geo-block-lkup.php +42 -33
  24. classes/class-ip-geo-block-load.php +17 -17
  25. classes/class-ip-geo-block-logs.php +184 -56
  26. classes/class-ip-geo-block-opts.php +60 -9
  27. classes/class-ip-geo-block-util.php +145 -230
  28. classes/class-ip-geo-block.php +352 -162
  29. includes/Net/DNS2.php +76 -76
  30. includes/Net/DNS2/Cache.php +6 -0
  31. includes/Net/DNS2/Cache/File.php +7 -2
  32. includes/Net/DNS2/Cache/Shm.php +13 -0
  33. includes/Net/DNS2/Header.php +4 -9
  34. includes/Net/DNS2/Lookups.php +30 -4
  35. includes/Net/DNS2/Packet.php +0 -15
  36. includes/Net/DNS2/Question.php +2 -2
  37. includes/Net/DNS2/RR.php +6 -3
  38. includes/Net/DNS2/RR/AVC.php +75 -0
  39. includes/Net/DNS2/RR/NSAP.php +3 -3
  40. includes/Net/DNS2/RR/OPENPGPKEY.php +1 -1
  41. includes/Net/DNS2/RR/SMIMEA.php +75 -0
  42. includes/Net/DNS2/RR/SSHFP.php +13 -7
  43. includes/Net/DNS2/Resolver.php +3 -3
  44. includes/Net/IPv4.php +9 -462
  45. includes/Net/IPv6.php +22 -7
  46. includes/Net/LICENSE +33 -0
  47. ip-geo-block.php +14 -8
  48. languages/ip-geo-block-ja.mo +0 -0
  49. languages/ip-geo-block-ja.po +545 -222
  50. languages/ip-geo-block.mo +0 -0
  51. languages/ip-geo-block.po +464 -195
  52. languages/ip-geo-block.pot +464 -195
  53. rewrite.php +22 -16
  54. samples.php +8 -13
  55. uninstall.php +6 -6
  56. wp-content/ip-geo-api/drop-in-sample.php +34 -3
  57. wp-content/ip-geo-api/ip2location/IP2Location.php +17 -0
  58. wp-content/ip-geo-api/ip2location/class-ip2location.php +17 -5
  59. wp-content/ip-geo-api/maxmind/class-maxmind.php +26 -4
  60. wp-content/ip-geo-api/maxmind/geoip.inc +52 -2
  61. wp-content/mu-plugins/ip-geo-block-mu.php +32 -12
README.md ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ IP Geo Block
2
+ ==============
3
+
4
+ ### Description:
5
+
6
+ It blocks any spams, login attempts and malicious access to the admin area
7
+ posted from the specific countries, and also prevents zero-day exploit.
8
+
9
+ See more detail at [WordPress.org][IPGB].
10
+
11
+ ### Dependency:
12
+
13
+ [IP Geo API 1.1.6][IPGeoAPI]
14
+
15
+ ### Requirement:
16
+
17
+ - WordPress 3.7+
18
+
19
+ ### Attribution:
20
+
21
+ This package includes GeoLite data created by MaxMind, available from
22
+ [MaxMind][MaxMind],
23
+ and also includes IP2Location open source libraries available from
24
+ [IP2Location][IP2Loc].
25
+
26
+ Also thanks for providing the following great services and REST APIs for free.
27
+
28
+ Provider | Supported type | Licence
29
+ ---------------------------------------|----------------|--------
30
+ [http://freegeoip.net/] [freegeoip] | IPv4, IPv6 | free
31
+ [http://ipinfo.io/] [ipinfo] | IPv4, IPv6 | free
32
+ [http://geoip.nekudo.com/] [Nekudo] | IPv4, IPv6 | free
33
+ [http://xhanch.com/] [Xhanch] | IPv4 | free
34
+ [http://www.geoplugin.com/][geoplugin] | IPv4, IPv6 | free, need an attribution link
35
+ [http://geoiplookup.net/] [geoiplkup] | IPv4, IPv6 | free
36
+ [http://ip-api.com/] [ipapi] | IPv4, IPv6 | free for non-commercial use
37
+ [http://ipinfodb.com/] [IPInfoDB] | IPv4, IPv6 | free for registered user
38
+
39
+ ### License:
40
+
41
+ This plugin is licensed under the GPL v2 or later.
42
+
43
+ [IPGB]: https://wordpress.org/plugins/ip-geo-block/ "IP Geo Block — WordPress Plugins"
44
+ [freegeoip]: http://freegeoip.net/ "freegeoip.net: FREE IP Geolocation Web Service"
45
+ [ipinfo]: http://ipinfo.io/ "ipinfo.io - ip address information including geolocation, hostname and network details"
46
+ [Telize]: http://www.telize.com/ "Telize - JSON IP and GeoIP REST API"
47
+ [IPJson]: http://ip-json.rhcloud.com/ "Free IP Geolocation Web Service"
48
+ [Pycox]: http://ip.pycox.com/ "Free IP Geolocation Web Service"
49
+ [Nekudo]: http://geoip.nekudo.com/ "eoip.nekudo.com | Free IP geolocation API"
50
+ [Xhanch]: http://xhanch.com/xhanch-api-ip-get-detail/ "Xhanch API - IP Get Detail | Xhanch Studio"
51
+ [geoplugin]: http://www.geoplugin.com/ "geoPlugin to geolocate your visitors"
52
+ [ipapi]: http://ip-api.com/ "IP-API.com - Free Geolocation API"
53
+ [IPInfoDB]: http://ipinfodb.com/ "IPInfoDB | Free IP Address Geolocation Tools"
54
+ [MaxMind]: http://www.maxmind.com "MaxMind - IP Geolocation and Online Fraud Prevention"
55
+ [IP2Loc]: http://www.ip2location.com "IP Address Geolocation to Identify Website Visitor's Geographical Location"
56
+ [Cache]: http://www.designbombs.com/top-wordpress-caching-plugins-compared/ "Top 6 Fastest WordPress Caching Plugins Compared (2016 Edition)"
57
+ [IPGeoAPI]: https://github.com/tokkonopapa/WordPress-IP-Geo-API "GitHub - tokkonopapa/WordPress-IP-Geo-API: A class library combined with WordPress plugin IP Geo Block to handle geo-location database of Maxmind and IP2Location."
58
+ [geoiplkup]: http://geoiplookup.net/ "What Is My IP Address | GeoIP Lookup"
README.txt CHANGED
@@ -1,158 +1,74 @@
1
  === IP Geo Block ===
2
  Contributors: tokkonopapa
3
  Donate link:
4
- Tags: buddypress, bbPress, comment, pingback, trackback, spam, IP address, geo, geolocation, xmlrpc, login, wp-admin, admin, ajax, security, brute force, firewall, vulnerability
5
  Requires at least: 3.7
6
- Tested up to: 4.6.1
7
- Stable tag: 2.2.9.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
- It blocks any spams, login attempts and malicious access to the admin area
12
- posted from the specific countries, and also prevents zero-day exploit.
13
 
14
  == Description ==
15
 
16
- There're some cases of a site being infected. The first one is the case that
17
- contaminated files are uploaded via FTP or something. In this case, scaning
18
- and verifing integrity of files in the site is needed to detect the infection.
19
 
20
- The second one is cracking of the login username and password. In this case,
21
- the rule of right is to strengthen the password.
22
 
23
- The third one may be caused by malicious accesses to the core files. The major
24
- issue in this case is that a plugin or theme in your site can potentially has
25
- some vulnerability such as XSS, CSRF, SQLi, LFI and so on. For example, if a
26
- plugin has Local File Inclusion (LFI) vulnerability, the attackers can easily
27
- download the `wp-config.php` by simply hitting
28
- [wp-admin/admin-ajax.php?action=show&file=../wp-config.php](http://blog.sucuri.net/2014/09/slider-revolution-plugin-critical-vulnerability-being-exploited.html "Slider Revolution Plugin Critical Vulnerability Being Exploited | Sucuri Blog")
29
- on their browser instead of cracking username and password.
30
 
31
- For these cases, the protection based on the IP address is not a perfect
32
- solution for everyone. But for some site owners or some certain cases such
33
- as 'zero-day attack', combination with the original feature 'Zero-day Exploit
34
- Prevention' can reduce the risk of infection against the specific attacks.
35
-
36
- That's why this plugin is here.
37
 
38
  = Features =
39
 
40
- This plugin will examine a country code based on the IP address. If a
41
- comment, pingback or trackback comes from the specific country, it can be
42
- blocked before Akismet validate it.
43
-
44
- With the same mechanism, it fights against burst accesses by brute-force
45
- and reverse-brute-force attacks to the login form and XML-RPC.
46
-
47
  * **Immigration control:**
48
- Access to the basic and important entrances into the back-end such as
49
- `wp-comments-post.php`, `xmlrpc.php`, `wp-login.php`, `wp-signup.php`,
50
- `wp-admin/admin.php`, `wp-admin/admin-ajax.php`, `wp-admin/admin-post.php`
51
- will be validated by means of a country code based on IP address. It allows
52
- you to configure either whitelist or blacklist to specify the countires.
53
 
54
  * **Zero-day Exploit Prevention:**
55
- The original feature "**Z**ero-day **E**xploit **P**revention for WP"
56
- (WP-ZEP) is simple but still smart and strong enough to block any malicious
57
- accesses to `wp-admin/*.php`, `plugins/*.php` and `themes/*.php` even from
58
- the permitted countries. It will protect your site against certain types of
59
- attack such as CSRF, LFI, SQLi, XSS and so on, **even if you have some
60
- [vulnerable plugins or themes](https://wpvulndb.com/ "WPScan Vulnerability Database")
61
- in your site**. Find more details in
62
- [FAQ](https://wordpress.org/plugins/ip-geo-block/faq/ "IP Geo Block - WordPress Plugins")
63
- and
64
- [this plugin's blog](http://www.ipgeoblock.com/article/how-wpzep-works.html "How does WP-ZEP prevent zero-day attack? | IP Geo Block").
65
 
66
  * **Guard against login attempts:**
67
- In order to prevent the invasion through the login form and XML-RPC by
68
- the brute-force and the reverse-brute-force attacks, the number of login
69
- attempts will be limited per IP address even from the permitted countries.
70
 
71
  * **Protection of wp-config.php:**
72
- A malicious request to try to expose `wp-config.php` via vulnerable plugins
73
- or themes can be blocked. A numerous such attacks can be found in
74
- [this article](http://www.ipgeoblock.com/article/exposure-of-wp-config-php.html "Prevent exposure of wp-config.php").
75
-
76
- * ** Minimize server load against brute-force attacks:**
77
- You can configure this plugin as a
78
- [Must Use Plugins](https://codex.wordpress.org/Must_Use_Plugins "Must Use Plugins « WordPress Codex")
79
- which would be loaded prior to regular plugins and can massively
80
- [reduce the load on server](http://www.ipgeoblock.com/codex/validation-timing.html "Validation timing | IP Geo Block")
81
- especially against brute-force attacks.
82
- And furthermore, a cache mechanism for the fetched IP addresses and country
83
- code can help to reduce load on the server against the burst accesses with
84
- a short period of time.
85
 
86
  * **Support of BuddyPress and bbPress:**
87
- You can configure this plugin such that a registered user can login as the
88
- membership from anywhere, but a request such as a new user registration,
89
- lost password, creating a new topic, and subscribing comment is blocked by
90
- the country code. It is suitable for
91
- [BuddyPress](https://wordpress.org/plugins/buddypress/ "WordPress › BuddyPress « WordPress Plugins")
92
- and [bbPress](https://wordpress.org/plugins/bbpress/ "WordPress › bbPress « WordPress Plugins")
93
- to help reducing spams.
94
 
95
  * **Referrer suppressor for external links:**
96
- When you click an external hyperlink on admin screen, http referrer will be
97
- eliminated to hide a footprint of your site.
98
 
99
  * **Multiple source of IP Geolocation databases:**
100
- Free IP Geolocation database and REST APIs are installed into this plugin to
101
- get a country code from an IP address. There are two types of API which
102
- support only IPv4 or both IPv4 and IPv6. This plugin will automatically
103
- choose an appropriate API.
104
-
105
- * **Database auto updater:**
106
- [MaxMind](http://www.maxmind.com "MaxMind - IP Geolocation and Online Fraud Prevention")
107
- GeoLite free databases and
108
- [IP2Location](http://www.ip2location.com/ "IP Address Geolocation to Identify Website Visitor's Geographical Location")
109
- LITE databases can be incorporated with this plugin. Those will be downloaded
110
- and updated (once a month) automatically.
111
 
112
  * **Customizing response:**
113
- HTTP response code can be selectable as `403 Forbidden` to deny access pages,
114
- `404 Not Found` to hide pages or even `200 OK` to redirect to the top page.
115
- You can also have the custom error page (for example `403.php`) in your theme
116
- template directory or child theme directory to fit your theme.
117
 
118
  * **Validation logs:**
119
- Logs will be recorded into MySQL data table to audit posting pattern under
120
- the specified condition.
121
 
122
  * **Cooperation with full spec security plugin:**
123
- This plugin is simple and lite enough to be able to cooperate with other
124
- full spec security plugin such as
125
- [Wordfence Security](https://wordpress.org/plugins/wordfence/ "WordPress › Wordfence Security « WordPress Plugins")
126
- (because the function of country bloking is available only for premium users).
127
 
128
  * **Extendability:**
129
- "Settings minimum, Customizability maximum" is the basic concept of this
130
- plugin. You can customize the behavior of this plugin via `add_filter()`
131
- with pre-defined filter hook. See various use cases in
132
- [the documents](http://www.ipgeoblock.com/codex/ "Codex | IP Geo Block")
133
- and
134
- [samples.php](https://github.com/tokkonopapa/WordPress-IP-Geo-Block/blob/master/ip-geo-block/samples.php "WordPress-IP-Geo-Block/samples.php at master - tokkonopapa/WordPress-IP-Geo-Block - GitHub")
135
- bundled within this package.
136
 
137
  * **Self blocking prevention and easy rescue:**
138
- Most of users do not prefer themselves to be blocked. This plugin prevents
139
- such a sad thing unless you force it.
140
- ([release 2.1.4](http://www.ipgeoblock.com/changelog/release-2.1.4.html "2.1.4 Release Note"))
141
- And futhermore, if such a situation occurs, you can rescue yourself easily.
142
- ([release 2.1.3](http://www.ipgeoblock.com/changelog/release-2.1.3.html "2.1.3 Release Note"))
143
 
144
  * **Clean uninstallation:**
145
- Nothing is left in your precious mySQL database after uninstallation. So you
146
- can feel free to install and activate to make a trial of this plugin's
147
- functionality. Several days later, you'll find many undesirable accesses in
148
- your validation logs if all validation targets are enabled.
149
 
150
  = Attribution =
151
 
152
- This package includes GeoLite library distributed by MaxMind, available from
153
- [MaxMind](http://www.maxmind.com "MaxMind - IP Geolocation and Online Fraud Prevention"),
154
- and also includes IP2Location open source libraries available from
155
- [IP2Location](http://www.ip2location.com "IP Address Geolocation to Identify Website Visitor's Geographical Location").
156
 
157
  Also thanks for providing the following great services and REST APIs for free.
158
 
@@ -166,13 +82,9 @@ Also thanks for providing the following great services and REST APIs for free.
166
 
167
  = Development =
168
 
169
- Development of this plugin is promoted at
170
- [WordPress-IP-Geo-Block](https://github.com/tokkonopapa/WordPress-IP-Geo-Block "tokkonopapa/WordPress-IP-Geo-Block - GitHub")
171
- and class libraries to handle geo-location database for Maxmind and IP2Location
172
- are developed separately as "add-in"s at
173
- [WordPress-IP-Geo-API](https://github.com/tokkonopapa/WordPress-IP-Geo-API "tokkonopapa/WordPress-IP-Geo-API - GitHub").
174
- All contributions will always be welcome. Or visit my
175
- [development blog](http://www.ipgeoblock.com/ "IP Geo Block").
176
 
177
  == Installation ==
178
 
@@ -182,55 +94,42 @@ All contributions will always be welcome. Or visit my
182
  2. Search for 'IP Geo Block'
183
  3. Click 'Install Now'
184
  4. Activate the plugin on the Plugin dashboard
 
 
 
 
185
 
186
  = Validation rule settings =
187
 
188
  * **Matching rule**
189
- Choose either `White list` (recommended) or `Black list` to specify the
190
- countries from which you want to pass or block.
191
 
192
  * **Country code for matching rule**
193
- Specify the country code with two letters (see
194
- [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements "ISO 3166-1 alpha-2 - Wikipedia, the free encyclopedia")
195
- ). Each of them should be separated by comma.
196
 
197
  * **White/Black list of extra IPs for prior validation**
198
- The list of extra IP addresses prior to the validation of country code.
199
- [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing "Classless Inter-Domain Routing - Wikipedia, the free encyclopedia")
200
- is acceptable to specify the range.
201
 
202
  * **$_SERVER keys for extra IPs**
203
- Additional IP addresses will be validated if some of keys in `$_SERVER`
204
- variable are specified in this textfield. Typically `HTTP_X_FORWARDED_FOR`.
205
 
206
  * **Bad signatures in query**
207
- It validates malicious signatures independently of **Block by country** and
208
- **Prevent Zero-day Exploit** for the target **Admin area**,
209
- **Admin ajax/post**, **Plugins area** and **Themes area**.
210
- Typically, `/wp-config.php` and `/passwd`.
211
 
212
  * **Response code**
213
- Choose one of the
214
- [response code](http://tools.ietf.org/html/rfc2616#section-10 "RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1")
215
- to be sent when it blocks a comment.
216
- The 2xx code will lead to your top page, the 3xx code will redirect to
217
- [Black Hole Server](http://blackhole.webpagetest.org/),
218
- the 4xx code will lead to WordPress error page, and the 5xx will pretend
219
- an server error.
220
 
221
  * **Validation timing**
222
- Choose **"init" action hook** or **"mu-plugins" (ip-geo-block-mu.php)** to
223
- specify the timing of validation.
224
 
225
- = Validation target settings =
226
 
227
  * **Comment post**
228
- Validate post to `wp-comment-post.php`. Comment post and trackback will be
229
- validated.
230
 
231
  * **XML-RPC**
232
- Validate access to `xmlrpc.php`. Pingback and other remote command with
233
- username and password will be validated.
234
 
235
  * **Login form**
236
  Validate access to `wp-login.php` and `wp-signup.php`.
@@ -247,19 +146,32 @@ All contributions will always be welcome. Or visit my
247
  * **Themes area**
248
  Validate direct access to themes. Typically `wp-content/themes/…/*.php`.
249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  = Geolocation API settings =
251
 
252
  * **API selection and key settings**
253
- If you wish to use `IPInfoDB`, you should register at
254
- [their site](http://ipinfodb.com/ "IPInfoDB | Free IP Address Geolocation Tools")
255
- to get a free API key and set it into the textfield. And `ip-api.com` and
256
- `Smart-IP.net` require non-commercial use.
257
 
258
  = Local database settings settings =
259
 
260
  * **Auto updating (once a month)**
261
- If `Enable`, Maxmind GeoLite database will be downloaded automatically by
262
- WordPress cron job.
263
 
264
  = Record settings =
265
 
@@ -267,50 +179,48 @@ All contributions will always be welcome. Or visit my
267
  If `Enable`, you can see `Statistics of validation` on Statistics tab.
268
 
269
  * **Record validation logs**
270
- If you choose anything but `Disable`, you can see `Validation logs` on
271
- Logs tab.
272
 
273
  * **$_POST keys in logs**
274
- Normally, you can see just keys at `$_POST data:` on Logs tab. If you put
275
- some of interested keys into this textfield, you can see the value of key
276
- like `key=value`.
277
 
278
  * **Anonymize IP address**
279
- It will mask the last three digits of IP address when it is recorded into
280
- the log.
281
 
282
  = Cache settings =
283
 
284
- * **Number of entries**
285
- Maximum number of IPs to be cached.
286
-
287
  * **Expiration time [sec]**
288
  Maximum time in sec to keep cache.
289
 
 
 
 
290
  = Submission settings =
291
 
292
  * **Text position on comment form**
293
- If you want to put some text message on your comment form, please choose
294
- `Top` or `Bottom` and put text with some tags into the **Text message on
295
- comment form** textfield.
296
 
297
  = Plugin settings =
298
 
299
  * **Remove settings at uninstallation**
300
- If you checked this option, all settings will be removed when this plugin
301
- is uninstalled for clean uninstalling.
302
 
303
  == Frequently Asked Questions ==
304
 
 
 
 
 
305
  = I was locked down. What shall I do? =
306
 
307
- Activate the following codes at the bottom of `ip-geo-block.php` and upload
308
- it via FTP.
309
 
310
  `/**
311
  * Invalidate blocking behavior in case yourself is locked out.
312
- * @note: activate the following code and upload this file via FTP.
313
- */ /* -- EDIT THIS LINE AND ACTIVATE THE FOLLOWING FUNCTION -- */
 
 
314
  function ip_geo_block_emergency( $validate ) {
315
  $validate['result'] = 'passed';
316
  return $validate;
@@ -319,31 +229,66 @@ add_filter( 'ip-geo-block-login', 'ip_geo_block_emergency' );
319
  add_filter( 'ip-geo-block-admin', 'ip_geo_block_emergency' );
320
  // */`
321
 
322
- Then "**Clear cache**" at "**Statistics**" tab on your dashborad. Remember
323
- that you should upload the original one to deactivate above feature.
 
324
 
325
- [This release note](http://www.ipgeoblock.com/changelog/release-2.1.3.html "2.1.3 Release Note")
326
- can also help you.
 
 
 
 
 
 
 
327
 
328
  = How can I fix "Unable to write" error? =
329
 
330
- When you enable "**Force to load WP core**" options, this plugin will try to
331
- configure `.htaccess` in your `/wp-content/plugins/` and `/wp-content/themes/`
332
- directory in order to protect your site against the malicous attacks to the
333
- [OMG plugins and shemes](http://www.ipgeoblock.com/article/exposure-of-wp-config-php.html "Prevent exposure of wp-config.php | IP Geo Block").
334
 
335
- But some servers doesn't give reading / writing permission against `.htaccess`
336
- to WordPress. In this case, you can configure these `.htaccess` files by your
337
- own hand instead of enabling "**Force to load WP core**" options.
338
 
339
- Please refer to
340
- "[How can I fix permission troubles?](http://www.ipgeoblock.com/codex/how-can-i-fix-permission-troubles.html 'How can I fix permission troubles? | IP Geo Block')"
341
- in order to fix this error.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
 
343
  = Do I have to turn on all the selection to enhance security? =
344
 
345
- Yes. Roughly speaking, the strategy of this plugin has been constructed as
346
- follows:
347
 
348
  - **Block by country**
349
  It blocks malicious requests from outside your country.
@@ -357,242 +302,163 @@ follows:
357
  - **Bad signatures in query**
358
  It blocks the request which has not been covered in the above three.
359
 
360
- See more details in
361
- "[The best practice of target settings](http://www.ipgeoblock.com/codex/the-best-practice-of-target-settings.html 'The best practice of target settings | IP Geo Block')".
362
 
363
- = Does this plugin validate all the requests to the server? =
364
 
365
- Unfortunately, no. This plugin can't handle the requests that are not
366
- parsed by WordPress. In other words, a standalone file (PHP, CGI or
367
- something excutable) that is unrelated to WordPress can't be validated
368
- by this plugin even if it is is in the WordPress install directory.
369
 
370
- But there're exceptions: When you enable "**Force to load WP core**" for
371
- **Plugins area** or **Themes area**, a standalone PHP file becomes to be
372
- able to be blocked. Sometimes this kind of file in a plugin or theme has
373
- vulnerability. This function is provided against such a case.
374
-
375
- = How can I test this plugin works? =
376
-
377
- The easiest way is to use
378
- [free proxy browser addon](https://www.google.com/search?q=free+proxy+browser+addon "free proxy browser addon - Google Search").
379
- Another one is to use
380
- [http header browser addon](https://www.google.com/search?q=browser+add+on+modify+http+header "browser add on modify http header - Google Search").
381
- You can add an IP address to the `X-Forwarded-For` header to emulate the
382
- access behind the proxy. In this case, you should add `HTTP_X_FORWARDED_FOR`
383
- into the "**$_SERVER keys for extra IPs**" on "**Settings**" tab.
384
-
385
- See more details in
386
- "[Using VPN browser addon](http://www.ipgeoblock.com/codex/using-vpn-browser-addon.html 'Using VPN browser addon | IP Geo Block')"
387
- and
388
- "[Using WordPress post simulator](http://www.ipgeoblock.com/codex/using-post-simulator.html 'Using WordPress post simulator | IP Geo Block')".
389
-
390
- = Some admin function doesn't work when WP-ZEP is enabled. =
391
-
392
- There are a few cases that WP-ZEP would not work. One is redirection at server
393
- side (caused by PHP or `.htaccess`) and client side (caused by JavaScript
394
- location object or meta tag for refresh).
395
-
396
- Another is the case related to the content type. This plugin will only support
397
- `application/x-www-form-urlencoded` and `multipart/form-data`.
398
-
399
- The other case is that a ajax/post request comes from not jQuery but flash or
400
- something.
401
-
402
- In those cases, this plugin should bypass WP-ZEP. So please find the unique
403
- strings in the requested queries and add it into the safe query list via the
404
- filter hook `ip-geo-block-bypass-admins`.
405
-
406
- If you can not figure out your troubles, please let me know about the plugin
407
- you are using at the support forum.
408
-
409
- = Are there any other useful filter hooks? =
410
-
411
- Yes, here is the list of all hooks to extend the feature of this plugin.
412
-
413
- * `ip-geo-block-ip-addr` : IP address of accessor.
414
- * `ip-geo-block-headers` : compose http request headers.
415
- * `ip-geo-block-comment` : validate IP address at `wp-comments-post.php`.
416
- * `ip-geo-block-xmlrpc` : validate IP address at `xmlrpc.php`.
417
- * `ip-geo-block-login` : validate IP address at `wp-login.php`.
418
- * `ip-geo-block-admin` : validate IP address at `wp-admin/*.php`.
419
- * `ip-geo-block-extra-ips` : white/black list of extra IPs for prior validation.
420
- * `ip-geo-block-xxxxxx-status` : http response status code for comment|xmlrpc|login|admin.
421
- * `ip-geo-block-xxxxxx-reason` : http response reason for comment|xmlrpc|login|admin.
422
- * `ip-geo-block-bypass-admins` : array of admin queries which should bypass WP-ZEP.
423
- * `ip-geo-block-bypass-plugins` : array of plugin name which should bypass WP-ZEP.
424
- * `ip-geo-block-bypass-themes` : array of theme name which should bypass WP-ZEP.
425
- * `ip-geo-block-backup-dir` : full path where log files should be saved.
426
- * `ip-geo-block-api-dir` : full path to the API class libraries and local DB files.
427
- * `ip-geo-block-maxmind-dir` : full path where Maxmind GeoLite DB files should be saved.
428
- * `ip-geo-block-maxmind-zip-ipv4` : url to Maxmind GeoLite DB zip file for IPv4.
429
- * `ip-geo-block-maxmind-zip-ipv6` : url to Maxmind GeoLite DB zip file for IPv6.
430
- * `ip-geo-block-ip2location-dir` : full path where IP2Location LITE DB files should be saved.
431
- * `ip-geo-block-ip2location-path` : full path to IP2Location LITE DB file (IPv4).
432
- * `ip-geo-block-record-logs` : change the condition of recording logs
433
-
434
- For more details, see
435
- [the documents](http://www.ipgeoblock.com/codex/ "Codex | IP Geo Block").
436
 
437
  == Other Notes ==
438
 
439
  = Known issues =
440
 
441
- * No image is shown after drag & drop a image in grid view at "Media Library".
442
- For more details, please refer to
443
- [this ticket at Github](https://github.com/tokkonopapa/WordPress-IP-Geo-Block/issues/2 "No image is shown after drag & drop a image in grid view at "Media Library". - Issue #2 - tokkonopapa/WordPress-IP-Geo-Block - GitHub").
444
-
445
- * From [WordPress 4.5](https://make.wordpress.org/core/2016/03/09/comment-changes-in-wordpress-4-5/ "Comment Changes in WordPress 4.5 – Make WordPress Core"),
446
- `rel=nofollow` attribute and value pair had no longer be added to relative
447
- or same domain links within `comment_content`. This change prevents to block
448
- "Self Site Request Forgeries" (not Cross Site but a malicious link in the
449
- comment field of own site).
450
-
451
- * Wordfence makes an ajax request whose action is `wordfence_testAjax` using
452
- `wp_remote_post()` and would receive 403 forbidden (it depends on your
453
- configuration) when you enable "**Prevent Zero-day Exploit**" at "**Admin
454
- ajax/post**". It does't affect its functionality because the response code
455
- never be verified.
456
 
457
  == Screenshots ==
458
 
459
- 1. **IP Geo Plugin** - Settings.
460
- 2. **IP Geo Plugin** - Statistics.
461
- 3. **IP Geo Plugin** - Logs.
462
- 4. **IP Geo Plugin** - Search.
463
- 5. **IP Geo Plugin** - Attribution.
 
 
 
 
 
464
 
465
  == Changelog ==
466
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  = 2.2.9.1 =
468
- * **Bug fix:** Blocking Wordfence scanning.
469
- ([@](https://wordpress.org/support/topic/wordfence-conflict-2/ "WordFence Conflict"))
470
- * **Bug fix:** Illegal elimination of colon in text field for IP address.
471
- ([@](https://wordpress.org/support/topic/adding-ipv6-to-white-list/ "Adding IPv6 to white list"))
472
- * **Improved:** Compatibility with PHP 7 that cause to feel relaxed.
473
- ([@](https://wordpress.org/support/topic/plans-for-php-7-compatiblity/ "Plans for PHP 7 compatiblity?"))
474
- * **Improved:** Avoid resetting whitelist on update by InfiniteWP.
475
- ([@](https://wordpress.org/support/topic/whitelist-resets-on-update/ "[Resolved] Whitelist resets on update"))
476
- * **Trial feature:** `X-Robots-Tag` HTTP header with `noindex, nofollow`
477
- for login page.
478
- ([@](https://wordpress.org/support/topic/ip-geo-block-and-searchmachines/ "IP GEo-block and searchmachines"))
479
 
480
  = 2.2.9 =
481
- * **New feature:** A new option that makes this plugin configured as a
482
- "Must-use plugin". It can massively reduce the server load especially
483
- against brute-force attacks because it initiates this plugin prior to
484
- other typical plugins.
485
- * **Improvement:** Validation of a certain signature against XSS is internally
486
- added to "Bad signature in query" by default.
487
- * **Improvement:** Improved compatibility with PHP 7
488
- (Thanks to [FireMyst](https://wordpress.org/support/topic/plans-for-php-7-compatiblity/ "Topic: Plans for PHP 7 compatiblity? « WordPress.org Forums").
489
  * Find details in [2.2.9 Release Note](http://www.ipgeoblock.com/changelog/release-2.2.9.html "2.2.9 Release Note").
490
 
491
  = 2.2.8.2 =
492
  * **Bug fix:** Fixed the mismatched internal version number.
493
 
494
  = 2.2.8.1 =
495
- * **Bug fix:** Fixed the issue of undefined function `wp_get_raw_referer()`
496
- error that happened under certain condition. See
497
- [the issue](https://wordpress.org/support/topic/since-php-update-fatal-error-everytime-i-want-to-edit-a-post/ "Since PHP update Fatal error everytime I want to edit a post")
498
- at forum.
499
- * **Improved:** Avoid resetting country code on update. See
500
- [the issue](https://wordpress.org/support/topic/whitelist-resets-on-update/ "Whitelist resets on update")
501
- at forum.
502
 
503
  = 2.2.8 =
504
- * **Bug fix:** Fixed the issue of stripping some required characters for Google
505
- maps API key.
506
  * **New feature:** Whois database Lookup for IP address on search tab.
507
  * **Update:** Updated geolocation API libraries and services.
508
  * Find more details in [2.2.8 Release Note](http://www.ipgeoblock.com/changelog/release-2.2.8.html "2.2.8 Release Note").
509
 
510
  = 2.2.7 =
511
  * **Bug fix:** Fix inadequate validation of "**Bad signatures in query**".
512
- * **Improvement:** Add fallback for Google Maps API key
513
- ([@](https://wordpress.org/support/topic/226-problem-with-search-resp-google-maps "WordPress › Support » [2.2.6] Problem with SEARCH resp. Google Maps"))
514
- and corruption of "Bad signatures"
515
- ([@](https://wordpress.org/support/topic/226-problem-with-bad-signatures-in-query "WordPress › Support » [2.2.6] Problem with "Bad signatures in query"")).
516
  * **Update:** Update geolocation service api.
517
  * Find details about Google Maps API in [2.2.7 Release Note](http://www.ipgeoblock.com/changelog/release-2.2.7.html "2.2.7 Release Note").
518
 
519
  = 2.2.6 =
520
  * **New feature:** Add saving csv file of logs in "Logs" tab.
521
- * **New feature:** Add filter hook `ip-geo-block-record-log` to control over
522
- the conditions of recording in more detail.
523
- * **Bug fix:** Fixed the issue that "Exceptions" for Plugins/Themes area does
524
- not work properly. Please confirm your settings again.
525
  * See details at [release 2.2.6](http://www.ipgeoblock.com/changelog/release-2.2.6.html "2.2.6 Release Note").
526
 
527
  = 2.2.5 =
528
- * **New feature:** On the settings page, you can specify the pliugin or theme
529
- which would cause undesired blocking in order to exclude it from the
530
- validation target without embedding any codes into `functions.php`.
531
  * **Improvement:** Optimize resource loading on admin dashboard.
532
  * **Improvement:** Support clean uninstall for network / multisite.
533
- * **Improvement:** Improve the compatibility of downloading IP address
534
- databases for Microsoft IIS.
535
  * **Bug fix:** Support `FORCE_SSL_ADMIN`.
536
- * **Bug fix:** Fix the issue of
537
- [@](https://wordpress.org/support/topic/compatibility-with-ag-custom-admin "WordPress › Support » Compatibility with AG Custom Admin")
538
- and change the option name
539
- "**Important files**" to "**Bad signatures in query**" to avoid misuse.
540
- * **Bug fix:** Fix the issue of
541
- [@](https://wordpress.org/support/topic/gb-added-to-whitelist "WordPress › Support » GB added to whitelist")
542
- which might be caused by some race condition.
543
  * **Bug fix:** Fix the issue of restoring post revisions which was blocked.
544
 
545
  = 2.2.4.1 =
546
  Sorry for frequent updating.
547
 
548
- * **Bug fix:** Fixed the issue of `Warning: strpos(): Empty needle in...` that
549
- was reported in
550
- [@](https://wordpress.org/support/topic/version-224-produces-warning-message "WordPress › Support » Version 2.2.4 Produces Warning Message")
551
- and
552
- [@](https://wordpress.org/support/topic/error-after-update-to-newest-version "WordPress › Support » Error after Update to newest version").
553
 
554
  = 2.2.4 =
555
- * **Bug fix:** Fixed the issue that some links on network admin of multisite
556
- were blocked when WP-ZEP for `admin area` or `admin ajax/post` was enabled.
557
  * **New feature:** Added configure of `.htaccess` for the plugins/themes area.
558
  * **Enhancement:** Added `wp-signup.php` to the list of validation target.
559
  * **Enhancement:** Added exporting and importing the setting parameters.
560
- * **Improvement:** Made the logout url compatible with
561
- [Rename wp-login.php](https://wordpress.org/plugins/rename-wp-login/).
562
- * **Improvement:** Made condition of validation more strictly at admin
563
- diagnosis to prevent unnecessary notice of self blocking.
564
- ([@](https://wordpress.org/support/topic/youll-be-blocked-after-you-log-out-notice-doesnt-disappear "[resolved] "You'll be blocked after you log out" notice doesn't disappear"))
565
- * **Improvement:** Improved some of UI.
566
- ([@](https://wordpress.org/support/topic/possible-to-select-which-countries-are-blocked "[resolved] Possible to select which countries are blocked?"),
567
- [@](https://wordpress.org/support/topic/ip-geo-block-black-list "IP Geo Block Black List"))
568
  * See some details at [release 2.2.4](http://www.ipgeoblock.com/changelog/release-2.2.4.html "2.2.4 Release Note").
569
 
570
  = 2.2.3.1 =
571
- * **Bug fix:** Fixed the issue that disabled validation target was still
572
- blocked by country.
573
- ([@](https://wordpress.org/support/topic/logs-whitelist-comments-still-blocked "[resolved] logs whitelist comments still blocked?"))
574
- * **Improvement:** Better handling of charset and errors for MySQL.
575
- ([@](https://wordpress.org/support/topic/whitelist-log "[resolved] Whitelist + Log"))
576
 
577
  = 2.2.3 =
578
- * **Improvement:** Since WordPress 4.4, XML-RPC system.multicall is disabled
579
- when the authentication fails, but still processed all the methods to the
580
- end. Now this plugin immediately blocks the request when the authentication
581
- fails without processing the rest of the methods.
582
  * **Improvement:** Add UI to change the maximum number of login attempts.
583
- * **Improvement:** Add a fallback process of setting up the directory where
584
- the geo location database APIs should be installed. It will be set as
585
- `wp-content/uploads/` instead of `wp-content/plugins/ip-geo-block/` or
586
- `wp-content/` in case of being unable to obtain proper permission.
587
- ([@](https://wordpress.org/support/topic/deactivated-after-updte-why "[resolved] Deactivated after update - why?"),
588
- [@](https://wordpress.org/support/topic/the-plugin-caused-an-error-message "[resolved] The plugin caused an error message"))
589
- * **Improvement:** Moderate the conditions of redirection after logout.
590
- ([@](https://wordpress.org/support/topic/logout-redirect-doesnt-work-when-plugin-is-active "[resolved] Logout redirect doesn't work when plugin is active"))
591
- * **Improvement:** Prevent self blocking caused by irrelevant signature.
592
- ([@](https://wordpress.org/support/topic/works-too-well-blocked-my-wp-admin-myself "[resolved] Works too well - Blocked my wp-admin myself"))
593
- * **Bug fix:** Fixed the issue of conflicting with certain plugins due to the
594
- irrelevant handling of js event.
595
- ([@](https://wordpress.org/support/topic/cannot-edit-pages-when-ip-geo-block-is-enabled "[resolved] Cannot edit pages when ip-geo-block is enabled."))
596
  * **New feature:** Add "Blocked per day" graph for the daily statistics.
597
  * See some details at [2.2.3 release note](http://www.ipgeoblock.com/changelog/release-2.2.3.html "2.2.3 Release Note").
598
 
@@ -600,32 +466,21 @@ Sorry for frequent updating.
600
  Sorry for frequent update again but the following obvious bugs should be fixed.
601
 
602
  * **Bug fix:** Fixed the issue of not initializing country code at activation.
603
- * **Bug fix:** Fixed the issue that scheme less notation like '//example.com'
604
- could not be handled correctly.
605
 
606
  = 2.2.2.2 =
607
  Sorry for frequent update.
608
 
609
- * **Bug fix:** Fixed the issue of race condition at activation. This fix is
610
- related to the urgent security update at **2.2.2.1 which was not actually
611
- the security issue but a bug**.
612
- See [this thread](https://wordpress.org/support/topic/white-list-hack "white list hack")
613
- about little more details.
614
  * **Improvement:** Improved the compatibility with Jetpack.
615
 
616
  = 2.2.2.1 =
617
- * **Urgent security update:** Killed the possibility of the options being
618
- altered.
619
 
620
  = 2.2.2 =
621
- * **Enhancement:** Refactored some codes and components. The number of attacks
622
- that can be proccessed per second has been improved by 25% at the maximum.
623
- * **Improvement:** In the previous version, the statistical data was recorded
624
- into `wp_options`. It caused the uncertainty of recording especially in case
625
- of burst attacks. Now the data will be recorded in an independent table to
626
- improve this issue.
627
- * **Bug fix:** Fixed conflict with NextGEN Gallary Pro.
628
- Thanks to [bodowewer](https://wordpress.org/support/profile/bodowewer).
629
  * **Bug fix:** Fixed some filter hooks that did not work as intended.
630
  * See more details at [2.2.2 release note](http://www.ipgeoblock.com/changelog/release-2.2.2.html "2.2.2 Release Note").
631
 
@@ -633,30 +488,14 @@ Sorry for frequent update.
633
  * **Bug fix:** Fixed "open_basedir restriction" issue caused by `file_exists()`.
634
 
635
  = 2.2.1 =
636
- * **Enhancement:** In previous version, local geolocation databases will always
637
- be removed and downloaded again at every upgrading. Now, the class library
638
- for Maxmind and IP2Location have become independent of this plugin and you
639
- can put them outside this plugin in order to cut the above useless process.
640
- The library can be available from
641
- [WordPress-IP-Geo-API](https://github.com/tokkonopapa/WordPress-IP-Geo-API).
642
- * **Deprecated:** Cooperation with IP2Location plugins such as
643
- [IP2Location Tags](http://wordpress.org/plugins/ip2location-tags/ "WordPress - IP2Location Tags - WordPress Plugins"),
644
- [IP2Location Variables](http://wordpress.org/plugins/ip2location-variables/ "WordPress - IP2Location Variables - WordPress Plugins"),
645
- [IP2Location Country Blocker](http://wordpress.org/plugins/ip2location-country-blocker/ "WordPress - IP2Location Country Blocker - WordPress Plugins")
646
- is out of use. Instead of it, free [IP2Location LITE databases for IPv4 and
647
- IPv6](http://lite.ip2location.com/ "Free IP Geolocation Database") will be
648
- downloaded.
649
  * **Improvement:** Improved connectivity with Jetpack.
650
  * **Improvement:** Improved immediacy of downloading databases at upgrading.
651
  * **Improvement:** Replaced a terminated RESTful API service with a new stuff.
652
- * **Bug fix:** Fixed issue that clicking a link tag without href always
653
- refreshed the page. Thanks to
654
- [wyclef](https://wordpress.org/support/topic/conflict-with-menu-editor-plugin "WordPress Support » Conflict with Menu Editor plugin?").
655
- * **Bug fix:** Fixed issue that deactivating and activating repeatedly caused
656
- to show the welcome message.
657
- * **Bug fix:** Fixed issue that a misaligned argument in the function caused
658
- 500 internal server error when a request to the php files in plugins/themes
659
- area was rewrited to `rewrite.php`.
660
 
661
  = 2.2.0.1 =
662
  Sorry for frequent update.
@@ -664,58 +503,34 @@ Sorry for frequent update.
664
  * **Fix:** Fixed the issue that some actions of other plugins were blocked.
665
 
666
  = 2.2.0 =
667
- * **Important:** Now **Block by country** and **Prevent Zero-day Exploit**
668
- become to work independently on **Admin area**, **Admin ajax/post** at
669
- **Validation target settings**. Please reconfirm them.
670
- * **Important:** Previously, a request whose country code can't be available
671
- was always blocked. But from this release, such a request is considered as
672
- comming from the country whose code is `ZZ`. It means that you can put `ZZ`
673
- into the white list and black list.
674
- * **New feature:** White list and Black list of extra IP addresses prior to
675
- the validation of country code. Thanks to Fabiano for good suggestions at
676
- [support forum](https://wordpress.org/support/topic/white-list-of-ip-addresses-or-ranges "WordPress › Support » White list of IP addresses or ranges?")
677
- * **New feature:** Malicious signatures to prevent disclosing the important
678
- files via vulnerable plugins or themes. A malicious request to try to expose
679
- `wp-config.php` or `passwd` can be blocked.
680
- * **New feature:** Add privacy considerations related to IP address. Add
681
- **Anonymize IP address** at **Record settings**.
682
- * **Bug fix:** Fix the issue that spaces in **Text message on comment form**
683
- are deleted.
684
  * See details at [2.2.0 release note](http://www.ipgeoblock.com/changelog/release-2.2.0.html "2.2.0 Release Note").
685
 
686
  = 2.1.5.1 =
687
- * **Bug fix:** Fixed the issue that the Blacklist did not work properly. Thanks
688
- to TJayYay for reporting this issue at
689
- [support forum](https://wordpress.org/support/topic/hackers-from-country-in-blocked-list-of-countries-trying-to-login "WordPress › Support » Hackers from country in Blocked List of Countries trying to login").
690
 
691
  = 2.1.5 =
692
- * **Enhancement:** Enforce preventing self blocking at the first installation.
693
- And add the scan button to get all the country code using selected API.
694
- Thanks to **Nils** for a nice idea at
695
- [support forum](https://wordpress.org/support/topic/locked-out-due-to-eu-vs-country "WordPress › Support » Locked out due to EU vs. Country").
696
  * **New feature:** Add pie chart to display statistics of "Blocked by country".
697
  * **Enhancement:** WP-ZEP is reinforced against CSRF.
698
  * **Bug fix:** Fix illegal handling of the fragment in a link.
699
  * See details at [2.1.5 release note](http://www.ipgeoblock.com/changelog/release-2.1.5.html "2.1.5 Release Note").
700
 
701
  = 2.1.4 =
702
- * **Bug fix:** Fix the issue that this plugin broke functionality of a certain
703
- plugin. Thanks to **opsec** for reporting this issue at
704
- [support forum](https://wordpress.org/support/topic/blocks-saves-in-types-or-any-plugins-from-wp-typescom "WordPress Support » Blocks saves in Types or any plugins from wp-types.com").
705
- * **Improvement:** Add checking process for validation rule to prevent being
706
- blocked itself. Thanks to **internationals** for proposing at
707
- [support forum](https://wordpress.org/support/topic/locked-out-due-to-eu-vs-country "WordPress › Support » Locked out due to EU vs. Country")
708
- * **Improvement:** Arrage the order of setting sections to focus the goal of
709
- this plugin.
710
  * See details at [2.1.4 release note](http://www.ipgeoblock.com/changelog/release-2.1.4.html "2.1.4 Release Note").
711
 
712
  = 2.1.3 =
713
  * **New feature:** Add "show" / "hide" at each section on the "Settings" tab.
714
- * **New feature:** Add an emergency function that invalidate blocking behavior
715
- in case yourself is locked out. This feature is commented out by default at
716
- the bottom of `ip-geo-block.php`.
717
- * **Improvement:** Prevent adding query strings to the static resources when
718
- users logged in.
719
  * **Improvement:** Improved the compatibility with Autoptimize.
720
  * **Bug fix:** Fix the issue related to showing featured themes on dashboard.
721
  * **Bug fix:** Fix minor bug in `rewrite.php` for the advanced use case.
@@ -724,62 +539,30 @@ Sorry for frequent update.
724
  = 2.1.2 =
725
  This is a maintenance release.
726
 
727
- * **Bug fix:** Fix the issue that the login-fail-counter didn't work when the
728
- validation at `Login form` was `block by country (register, lost password)`.
729
- In this release, the login-fail-counter works correctly.
730
- * **Bug fix:** Fix the issue that the validation settings of `Admin area` and
731
- `Admin ajax/post` were influential with each other. Now each of those works
732
- individually.
733
- * **Bug fix:** "Site Stats" of Jetpack is now shown on the admin bar which
734
- issue was reported on [support forum](https://wordpress.org/support/topic/admin-area-prevent-zero-day-exploit-incompatible-with-jetpack-site-stats-in-a "WordPress › Support » Admin area - Prevent zero-day exploit: Incompatible with Jetpack Site Stats in A").
735
- * **Improvement:** Hide checking the existence of log db behind the symbol
736
- `IP_GEO_BLOCK_DEBUG` to reduce 1 query on admin screen.
737
- * **Improvement:** Add alternative functions of BCMath extension to avoid
738
- `PHP Fatal error: Call to undefined function` in `IP2Location.php` when
739
- IPv6 is specified.
740
- * **Improvement:** Use MaxMind database at the activating process not to be
741
- locked out by means of inconsistency of database at the activation and after.
742
  * See more details at [2.1.2 release note](http://www.ipgeoblock.com/changelog/release-2.1.2.html "2.1.2 Release Note").
743
 
744
  = 2.1.1 =
745
- * **New feature:** Added `Block by country (register, lost password)` at
746
- `Login form` on `Settings` tab in order to accept the registered users as
747
- membership from anywhere but block the request of new user ragistration and
748
- lost password by the country code. Is't suitable for BuddyPress and bbPress.
749
- * **Improvement:** Added showing the custom error page for http response code
750
- 4xx and 5xx. For example the `403.php` in the theme template directory or in
751
- the child theme directory is used if it exists. And new filter hooks
752
- `ip-geo-block-(comment|xmlrpc|login|admin)-(status|reason)` are available
753
- to customize the response code and reason for human.
754
- * **Obsoleted:** Obsoleted the filter hooks
755
- `ip-geo-block-(admin-actions|admin-pages|wp-content)`. Alternatively new
756
- filter hooks `ip-geo-block-bypass-(admins|plugins|themes)` are added to
757
- bypass WP-ZEP.
758
  * Find out more details in the [2.1.1 release note](http://www.ipgeoblock.com/changelog/release-2.1.1.html "2.1.1 Release Note").
759
 
760
  = 2.1.0 =
761
- * **New feature:** Expanded the operating range of ZP-ZEP, that includes admin
762
- area, plugins area, themes area. Now it can prevent a direct malicios attack
763
- to the file in plugins and themes area. Please go to the "Validation Settings"
764
- on "Settings" tab and check it. Also check my article in
765
- "[Analysis of Attack Vector against WP Plugins](http://www.ipgeoblock.com/article/analysis-attack-vector.html)".
766
- * **Bug fix:** Fixed the issue that action hook `ip-geo-block-backup-dir` did
767
- not work correctly because the order of argument was mismatched.
768
- * **Bug fix:** Fixed the issue that a record including utf8 4 bytes character
769
- in its columns was not logged into DB in WordPress 4.2.
770
- * **Improvement:** Fixed the issue that Referrer Suppressor do nothing with a
771
- new element which is added into DOM after DOM ready. The event handler is
772
- now delegated at the `body`.
773
 
774
  = 2.0.8 =
775
- * Fixed an issue that a certain type of attack vector to the admin area (
776
- [example](https://blog.sucuri.net/2014/08/database-takeover-in-custom-contact-forms.html "Critical Vulnerability Disclosed on WordPress Custom Contact Forms Plugin")
777
- ) could not be blocked by the reason that some plugins accept it on earlier
778
- hook (ie `init`) than this plugin (previously `admin_init`).
779
- * Added re-creating DB table for validation logs in case of accidentally
780
- failed at activation process.
781
- * The time of day is shown with local time by adding GMT offset based on
782
- the time zone setting.
783
  * Optimized resource loading and settings to avoid redundancy.
784
  * See details at [this plugin's blog](http://www.ipgeoblock.com/changelog/release-2.0.8.html "2.0.8 Release Note").
785
 
@@ -792,110 +575,26 @@ This is a maintenance release.
792
  * Sorry for urgent update but avoid an javascript error.
793
 
794
  = 2.0.4 =
795
- * Sorry for frequent update but added a function of showing admin notice
796
- when none of the IP geolocation providers is selected. Because the user
797
- will be locked out from admin screen when the cache expires.
798
- * **Bug fix:** Fixed an issue of `get_geolocation()` method at a time of
799
- when the cache of IP address is cleared.
800
  * Referrer suppressor now supports [meta referrer](https://wiki.whatwg.org/wiki/Meta_referrer "Meta referrer - WHATWG Wiki")
801
 
802
  = 2.0.3 =
803
- * **Bug fix:** Fixed an issue that empty black list doesn't work correctly
804
- when matching rule is black list.
805
- * **New feature:** Added 'Zero-day Exploit Prevention for wp-admin'.
806
- Because it is an experimental feature, please open a new issue at
807
- [support forum](https://wordpress.org/support/plugin/ip-geo-block "WordPress › Support » IP Geo Block")
808
- if you have any troubles with it.
809
- * **New feature:** Referrer suppressor for external link. When you click an
810
- external hyperlink on admin screen, http referrer will be suppressed to
811
- hide a footprint of your site.
812
- * Also added the filter hook `ip-geo-block-admin-actions` for safe actions
813
- on back-end.
814
 
815
  = 2.0.2 =
816
- * **New feature:** Include `wp-admin/admin-post.php` as a validation target
817
- in the `Admin area`. This feature is to protect against a vulnerability
818
- such as
819
- [Analysis of the Fancybox-For-WordPress Vulnerability](http://blog.sucuri.net/2015/02/analysis-of-the-fancybox-for-wordpress-vulnerability.html)
820
- on Sucuri Blog.
821
- * Added a sample code snippet as a use case for 'Give ajax permission in
822
- case of safe actions on front facing page'. See Example 10 in `sample.php`.
823
 
824
  = 2.0.1 =
825
- * Fixed the issue of improper scheme from the HTTPS site when loading js
826
- for google map.
827
- * In order to prevent accidental disclosure of the length of password,
828
- changed the length of `*` (masked password) which is logged into the
829
- database.
830
 
831
  = 2.0.0 =
832
- * **New feature:** Protection against brute-force and reverse-brute-force
833
- attacks to `wp-login.php`, `xmlrpc.php` and admin area.
834
- This is an experimental function and can be enabled on `Settings` tab.
835
- Malicious access can try to login only 5 times per IP address. This retry
836
- counter can be reset to zero by `Clear statistics` on `Statistics` tab.
837
-
838
- = 1.4.0 =
839
- * **New feature:** Added a new class for recording the validation logs to
840
- analyze posting pattern.
841
- * Fixed an issue of not being set the own country code at first installation.
842
- * Fixed an error which occurs when ip address is unknown.
843
-
844
- = 1.3.1 =
845
- * **New feature:** Added validation of trackback spam.
846
- * Added `$_SERVER keys for extra IPs` into options to validate additional
847
- IP addresses.
848
- * Removed some redundant codes and corrected all PHP notices and warnings
849
- which had been suppressed by WordPress.
850
-
851
- = 1.3.0 =
852
- * **New feature:** Added validation of pingback.ping through `xmlrpc.php` and
853
- new option to validate all the IP addresses in HTTP_X_FORWARDED_FOR.
854
- * **Fixed an issue:** Maxmind database file may be downloaded automatically
855
- without deactivate/re-activate when upgrade is finished.
856
- * This is the final version on 1.x. On next release, accesses to `login.php`
857
- and admin area will be also validated for security purpose.
858
-
859
- = 1.2.1 =
860
- * **Fixed an issue:** Option table will be updated automatically without
861
- deactivate/re-activate when this plugin is upgraded.
862
- * **A little bit performance improvement:**
863
- Less memory footprint at the time of downloading Maxmind database file.
864
- Less sql queries when `Save statistics` is enabled.
865
-
866
- = 1.2.0 =
867
- * **New feature:** Added Maxmind GeoLite database auto downloader and updater.
868
- * The filter hook `ip-geo-block-validate` was discontinued.
869
- Instead of it, the new filter hook `ip-geo-block-comment` is introduced.
870
- * **Performance improvement:** IP address is verified at an earlier stage
871
- than before.
872
- * **Others:** Fix a bug of handling cache, update status of some REST APIs.
873
-
874
- = 1.1.1 =
875
- * Fixed issue of default country code.
876
- When activating this plugin for the first time, get the country code
877
- from admin's IP address and set it into white list.
878
- * Add number of calls in cache of IP address.
879
-
880
- = 1.1.0 =
881
- * Implement the cache mechanism to reduce load on the server.
882
- * Better handling of errors on the search tab so as to facilitate the
883
- analysis of the service problems.
884
- * Fixed a bug of setting user agent strings in 1.0.2.
885
- Now the user agent strings (`WordPress/3.9.2; http://example.com/`)
886
- becomes to its own (`WordPress/3.9.2; ip-geo-block 1.1.0`).
887
-
888
- = 1.0.3 =
889
- * Temporarily stop setting user agent strings to supress a bug in 1.0.2.
890
-
891
- = 1.0.2 =
892
- * Update provider settings. Smart-IP.net was terminated, ipinfo.io is now
893
- available for IPv6.
894
- * Set the own user agent strings for `WP_Http`.
895
-
896
- = 1.0.1 =
897
- * Modify Plugin URL.
898
- * Add `apply_filters()` to be able to change headers.
899
 
900
  = 1.0.0 =
901
  * Ready to release.
1
  === IP Geo Block ===
2
  Contributors: tokkonopapa
3
  Donate link:
4
+ Tags: security, firewall, brute force, vulnerability, login, wp-admin, admin, ajax, xmlrpc, comment, pingback, trackback, spam, IP address, geo, geolocation, buddypress, bbPress
5
  Requires at least: 3.7
6
+ Tested up to: 4.7.3
7
+ Stable tag: 3.0.2.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
+ It blocks spam posts, login attempts and malicious access to the back-end requested from the specific countries, and also prevents zero-day exploit.
 
12
 
13
  == Description ==
14
 
15
+ A considerable number of WordPress vulnerabilities in plugins and themes have been disclosed every month. You can easily find them at [WPScan Vulnerability Database](https://wpvulndb.com/ "WPScan Vulnerability Database") and [Exploits Database](https://www.exploit-db.com/ "Exploits Database by Offensive Security") for example. It means that many WordPress sites can be always exposed to the threats of being exploited caused by those vulnerabilities.
 
 
16
 
17
+ This plugin protects your site against such threats of attack to the back-end of your site not only by blocking requests from undesired countries but also with the original feature 'Zero-day Exploit Prevention' (WP-ZEP).
 
18
 
19
+ And it also blocks undesired requests to the login form (login attempt), comment form (spam and trackback) and XML-RPC (login attempt and pingback).
 
 
 
 
 
 
20
 
21
+ Up to version 2.x, this plugin had been dedicated to protect the back-end of your site. From version 3.x, it becomes to be able to block access to your public facing pages, aka front-end. See [this analysis](http://www.ipgeoblock.com/codex/analysis-of-attack-vectors.html "Analysis of Attack Vectors | IP Geo Block") about protection performance against 50 samples of vulnerable plugins.
 
 
 
 
 
22
 
23
  = Features =
24
 
 
 
 
 
 
 
 
25
  * **Immigration control:**
26
+ Access to the basic and important entrances into the back-end such as `wp-comments-post.php`, `xmlrpc.php`, `wp-login.php`, `wp-signup.php`, `wp-admin/admin.php`, `wp-admin/admin-ajax.php`, `wp-admin/admin-post.php` will be validated by means of a country code based on IP address. It allows you to configure either whitelist or blacklist to specify the countires.
 
 
 
 
27
 
28
  * **Zero-day Exploit Prevention:**
29
+ The original feature "**Z**ero-day **E**xploit **P**revention for WP" (WP-ZEP) is simple but still smart and strong enough to block any malicious accesses to `wp-admin/*.php`, `plugins/*.php` and `themes/*.php` even from the permitted countries. It will protect your site against certain types of attack such as CSRF, LFI, SQLi, XSS and so on, **even if you have some in your site**. Find more details in [FAQ](https://wordpress.org/plugins/ip-geo-block/faq/ "IP Geo Block - WordPress Plugins") and [this plugin's blog](http://www.ipgeoblock.com/article/how-wpzep-works.html "How does WP-ZEP prevent zero-day attack? | IP Geo Block").
 
 
 
 
 
 
 
 
 
30
 
31
  * **Guard against login attempts:**
32
+ In order to prevent hacking through the login form and XML-RPC by brute-force and the reverse-brute-force attacks, the number of login attempts will be limited per IP address even from the permitted countries.
 
 
33
 
34
  * **Protection of wp-config.php:**
35
+ A malicious request to try to expose `wp-config.php` via vulnerable plugins or themes can be blocked. A numerous such attacks can be found in [this article](http://www.ipgeoblock.com/article/exposure-of-wp-config-php.html "Prevent exposure of wp-config.php").
36
+
37
+ * **Minimize server load against brute-force attacks:**
38
+ You can configure this plugin as a [Must Use Plugins](https://codex.wordpress.org/Must_Use_Plugins "Must Use Plugins « WordPress Codex") which would be loaded prior to regular plugins and can massively [reduce the load on server](http://www.ipgeoblock.com/codex/validation-timing.html "Validation timing | IP Geo Block").
39
+ And furthermore, a cache mechanism for the fetched IP addresses and country code can help to reduce load on the server against the burst accesses with a short period of time.
 
 
 
 
 
 
 
 
40
 
41
  * **Support of BuddyPress and bbPress:**
42
+ You can configure this plugin such that a registered user can login as the membership from anywhere, but a request such as a new user registration, lost password, creating a new topic, and subscribing comment is blocked by the country code. It is suitable for [BuddyPress](https://wordpress.org/plugins/buddypress/ "WordPress › BuddyPress « WordPress Plugins") and [bbPress](https://wordpress.org/plugins/bbpress/ "WordPress › bbPress « WordPress Plugins") to help reducing spams.
 
 
 
 
 
 
43
 
44
  * **Referrer suppressor for external links:**
45
+ When you click an external hyperlink on admin screen, http referrer will be liminated to hide a footprint of your site.
 
46
 
47
  * **Multiple source of IP Geolocation databases:**
48
+ Free IP Geolocation database and REST APIs are installed into this plugin to get a country code from an IP address. [MaxMind](http://www.maxmind.com "MaxMind - IP Geolocation and Online Fraud Prevention") GeoLite free databases and [IP2Location](http://www.ip2location.com/ "IP Address Geolocation to Identify Website Visitor's Geographical Location") LITE databases can be available in this plugin. Those will be downloaded and updated (once a month) automatically.
 
 
 
 
 
 
 
 
 
 
49
 
50
  * **Customizing response:**
51
+ HTTP response code can be selectable as `403 Forbidden` to deny access pages, `404 Not Found` to hide pages or even `200 OK` to redirect to the top page.
52
+ You can also have the custom error page (for example `403.php`) in your theme template directory or child theme directory to fit your theme.
 
 
53
 
54
  * **Validation logs:**
55
+ Logs will be recorded into MySQL data table to audit posting pattern under the specified condition.
 
56
 
57
  * **Cooperation with full spec security plugin:**
58
+ This plugin is simple and lite enough to be able to cooperate with other full spec security plugin such as [Wordfence Security](https://wordpress.org/plugins/wordfence/ "WordPress › Wordfence Security « WordPress Plugins") (because country bloking is available only for premium users). See [this report](http://www.ipgeoblock.com/codex/page-speed-performance.html "Page speed performance | IP Geo Block") about page speed performance.
 
 
 
59
 
60
  * **Extendability:**
61
+ "Settings minimum, Customizability maximum" is the basic concept of this plugin. You can customize the behavior of this plugin via `add_filter()` with pre-defined filter hook. See various use cases in [the documents](http://www.ipgeoblock.com/codex/ "Codex | IP Geo Block") and [samples.php](https://github.com/tokkonopapa/WordPress-IP-Geo-Block/blob/master/ip-geo-block/samples.php "WordPress-IP-Geo-Block/samples.php at master - tokkonopapa/WordPress-IP-Geo-Block - GitHub") bundled within this package.
 
 
 
 
 
 
62
 
63
  * **Self blocking prevention and easy rescue:**
64
+ Most of users do not prefer themselves to be blocked. This plugin prevents such a sad thing unless you force it. And futhermore, if such a situation occurs, you can [rescue yourself](http://www.ipgeoblock.com/codex/what-should-i-do-when-i-m-locked-out.html "What should I do when I'm locked out? | IP Geo Block") easily.
 
 
 
 
65
 
66
  * **Clean uninstallation:**
67
+ Nothing is left in your precious mySQL database after uninstallation. So you can feel free to install and activate to make a trial of this plugin's functionality. Several days later, you'll find many undesirable accesses in your validation logs if all validation targets are enabled.
 
 
 
68
 
69
  = Attribution =
70
 
71
+ This package includes GeoLite library distributed by MaxMind, available from [MaxMind](http://www.maxmind.com "MaxMind - IP Geolocation and Online Fraud Prevention"), and also includes IP2Location open source libraries available from [IP2Location](http://www.ip2location.com "IP Address Geolocation to Identify Website Visitor's Geographical Location").
 
 
 
72
 
73
  Also thanks for providing the following great services and REST APIs for free.
74
 
82
 
83
  = Development =
84
 
85
+ Development of this plugin is promoted at [WordPress-IP-Geo-Block](https://github.com/tokkonopapa/WordPress-IP-Geo-Block "tokkonopapa/WordPress-IP-Geo-Block - GitHub") and class libraries to handle geo-location database are developed separately as "add-in"s at [WordPress-IP-Geo-API](https://github.com/tokkonopapa/WordPress-IP-Geo-API "tokkonopapa/WordPress-IP-Geo-API - GitHub").
86
+
87
+ All contributions will always be welcome. Or visit my [development blog](http://www.ipgeoblock.com/ "IP Geo Block").
 
 
 
 
88
 
89
  == Installation ==
90
 
94
  2. Search for 'IP Geo Block'
95
  3. Click 'Install Now'
96
  4. Activate the plugin on the Plugin dashboard
97
+ 5. Try 'Best settings' button for easy setup at the bottom of this plugin's setting page.
98
+
99
+ Please refer to [the document](http://www.ipgeoblock.com/codex/ "Codex | IP Geo Block")
100
+ or following descriptions for your best setup.
101
 
102
  = Validation rule settings =
103
 
104
  * **Matching rule**
105
+ Choose either `White list` (recommended) or `Black list` to specify the countries from which you want to pass or block.
 
106
 
107
  * **Country code for matching rule**
108
+ Specify the country code with two letters (see [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements "ISO 3166-1 alpha-2 - Wikipedia, the free encyclopedia")). Each of them should be separated by comma.
 
 
109
 
110
  * **White/Black list of extra IPs for prior validation**
111
+ The list of extra IP addresses prior to the validation of country code. [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing "Classless Inter-Domain Routing - Wikipedia, the free encyclopedia") is acceptable to specify the range.
 
 
112
 
113
  * **$_SERVER keys for extra IPs**
114
+ Additional IP addresses will be validated if some of keys in `$_SERVER` variable are specified in this textfield. Typically `HTTP_X_FORWARDED_FOR`.
 
115
 
116
  * **Bad signatures in query**
117
+ It validates malicious signatures independently of **Block by country** and **Prevent Zero-day Exploit** for the target **Admin area**, **Admin ajax/post**, **Plugins area** and **Themes area**. Typically, `/wp-config.php` and `/passwd`.
 
 
 
118
 
119
  * **Response code**
120
+ Choose one of the [response code](http://tools.ietf.org/html/rfc2616#section-10 "RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1") to be sent when it blocks a comment.
121
+ The 2xx code will lead to your top page, the 3xx code will redirect to [Black Hole Server](http://blackhole.webpagetest.org/), the 4xx code will lead to WordPress error page, and the 5xx will pretend an server error.
 
 
 
 
 
122
 
123
  * **Validation timing**
124
+ Choose **"init" action hook** or **"mu-plugins" (ip-geo-block-mu.php)** to specify the timing of validation.
 
125
 
126
+ = Back-end target settings =
127
 
128
  * **Comment post**
129
+ Validate post to `wp-comment-post.php`. Comment post and trackback will be validated.
 
130
 
131
  * **XML-RPC**
132
+ Validate access to `xmlrpc.php`. Pingback and other remote command with username and password will be validated.
 
133
 
134
  * **Login form**
135
  Validate access to `wp-login.php` and `wp-signup.php`.
146
  * **Themes area**
147
  Validate direct access to themes. Typically `wp-content/themes/…/*.php`.
148
 
149
+ = Front-end target settings =
150
+
151
+ * **Block by country**
152
+ Enables validation of country code on public facing pages.
153
+
154
+ * **Matching rule**
155
+ Same as **Validation target settings** but can be set independently.
156
+
157
+ * **Validation target**
158
+ Specify the single and archive page by post type, category and tag as blocking target.
159
+
160
+ * **UA string and qualification**
161
+ Additional rules targeted at SEO which can specify acceptable requests based on user agent.
162
+
163
+ * **Simulation mode**
164
+ You can simulate the 'blocking on front-end' functionality before deploying.
165
+
166
  = Geolocation API settings =
167
 
168
  * **API selection and key settings**
169
+ If you wish to use `IPInfoDB`, you should register at [their site](http://ipinfodb.com/ "IPInfoDB | Free IP Address Geolocation Tools") to get a free API key and set it into the textfield. And `ip-api.com` and `Smart-IP.net` require non-commercial use.
 
 
 
170
 
171
  = Local database settings settings =
172
 
173
  * **Auto updating (once a month)**
174
+ If `Enable`, Maxmind GeoLite database will be downloaded automatically by WordPress cron job.
 
175
 
176
  = Record settings =
177
 
179
  If `Enable`, you can see `Statistics of validation` on Statistics tab.
180
 
181
  * **Record validation logs**
182
+ If you choose anything but `Disable`, you can see `Validation logs` on Logs tab.
 
183
 
184
  * **$_POST keys in logs**
185
+ Normally, you can see just keys at `$_POST data:` on Logs tab. If you put some of interested keys into this textfield, you can see the value of key like `key=value`.
 
 
186
 
187
  * **Anonymize IP address**
188
+ It will mask the last three digits of IP address when it is recorded into the log.
 
189
 
190
  = Cache settings =
191
 
 
 
 
192
  * **Expiration time [sec]**
193
  Maximum time in sec to keep cache.
194
 
195
+ * **Garbage collection period [sec]**
196
+ Period of garbage collection to clean cache.
197
+
198
  = Submission settings =
199
 
200
  * **Text position on comment form**
201
+ If you want to put some text message on your comment form, please choose `Top` or `Bottom` and put text with some tags into the **Text message on comment form** textfield.
 
 
202
 
203
  = Plugin settings =
204
 
205
  * **Remove settings at uninstallation**
206
+ If you checked this option, all settings will be removed when this plugin is uninstalled for clean uninstalling.
 
207
 
208
  == Frequently Asked Questions ==
209
 
210
+ = Does it support multisite? =
211
+
212
+ It works on multisite, but there's no network setting at this moment.
213
+
214
  = I was locked down. What shall I do? =
215
 
216
+ You can find the "**Emergent Functionality**" code section near the bottom of `ip-geo-block.php`. This code block can be activated by replacing `/*` (opening multi-line comment) at the top of the line to `//` (single line comment), or `*` at the end of the line to `*/` (closing multi-line comment).
 
217
 
218
  `/**
219
  * Invalidate blocking behavior in case yourself is locked out.
220
+ *
221
+ * How to use: Activate the following code and upload this file via FTP.
222
+ */
223
+ /* -- ADD `/` TO THE TOP OR END OF THIS LINE TO ACTIVATE THE FOLLOWINGS -- */
224
  function ip_geo_block_emergency( $validate ) {
225
  $validate['result'] = 'passed';
226
  return $validate;
229
  add_filter( 'ip-geo-block-admin', 'ip_geo_block_emergency' );
230
  // */`
231
 
232
+ Please not that you have to use an [appropriate editor](https://codex.wordpress.org/Editing_Files#Using_Text_Editors "Editing Files « WordPress Codex").
233
+
234
+ After saving and uploading it to `/wp-content/plugins/ip-geo-block/` on your server via FTP, you become to be able to login again as an admin.
235
 
236
+ Remember that you should upload the original one after re-configuration to deactivate this feature.
237
+
238
+ [This document](http://www.ipgeoblock.com/codex/what-should-i-do-when-i-m-locked-out.html "What should I do when I'm locked out? | IP Geo Block") can also help you.
239
+
240
+ = How to resolve "Sorry, your request cannot be accepted."? =
241
+
242
+ If you encounter this message, please refer to [this document](http://www.ipgeoblock.com/codex/you-are-not-allowed-to-access.html "Why “Sorry, your request cannot be accepted” ? | IP Geo Block") to resolve your blocking issue.
243
+
244
+ If you can't solve your issue, please let me know about it on the [support forum](https://wordpress.org/support/plugin/ip-geo-block/ "View: Plugin Support « WordPress.org Forums"). Your logs in this plugin and "**Installation information**" at "**Plugin settings**" will be a great help to resolve the issue.
245
 
246
  = How can I fix "Unable to write" error? =
247
 
248
+ When you enable "**Force to load WP core**" options, this plugin will try to configure `.htaccess` in your `/wp-content/plugins/` and `/wp-content/themes/` directory in order to protect your site against the malicous attacks to the [OMG plugins and shemes](http://www.ipgeoblock.com/article/exposure-of-wp-config-php.html "Prevent exposure of wp-config.php | IP Geo Block").
249
+
250
+ But some servers doesn't give reading / writing permission against `.htaccess` to WordPress. In this case, you can configure these `.htaccess` files by your own hand instead of enabling "**Force to load WP core**" options.
 
251
 
252
+ Please refer to "[How can I fix permission troubles?](http://www.ipgeoblock.com/codex/how-can-i-fix-permission-troubles.html 'How can I fix permission troubles? | IP Geo Block')" in order to fix this error.
 
 
253
 
254
+ = I still have access from blacklisted country. Does it work correctly? =
255
+
256
+ Absolutely, YES. But unfortunately, accuracy of country code depends on the geolocation databases. Actually, there is a case that a same IP address has different country code.
257
+
258
+ For more detail, please refer to "[I still have access from blacklisted country.](http://www.ipgeoblock.com/codex/access-from-blacklisted-country.html 'I still have access from blacklisted country. | IP Geo Block')".
259
+
260
+ = How can I test this plugin works? =
261
+
262
+ The easiest way is to use [free proxy browser addon](https://www.google.com/search?q=free+proxy+browser+addon "free proxy browser addon - Google Search").
263
+
264
+ Another one is to use [http header browser addon](https://www.google.com/search?q=browser+add+on+modify+http+header "browser add on modify http header - Google Search").
265
+
266
+ You can add an IP address to the `X-Forwarded-For` header to emulate the access behind the proxy. In this case, you should add `HTTP_X_FORWARDED_FOR` into the "**$_SERVER keys for extra IPs**" on "**Settings**" tab.
267
+
268
+ See more details at "[How to test prevention of attacks](http://www.ipgeoblock.com/codex/#how-to-test-prevention-of-attacks 'Codex | IP Geo Block')".
269
+
270
+ = Does this plugin works well with caching? =
271
+
272
+ For the back-end protection, the answer is YES if you disable caching on back-end. But for the front-end, the answer depends on the caching method you are employing.
273
+
274
+ Currently, the following cache plugins and configurations can be supported:
275
+
276
+ - [WP Super Cache](https://wordpress.org/plugins/wp-super-cache/ "WP Super Cache — WordPress Plugins")
277
+ Select "**Use PHP to serve cache files**" and enable "**Late init**".
278
+
279
+ - [W3 Total Cache](https://wordpress.org/plugins/w3-total-cache/ "W3 Total Cache — WordPress Plugins")
280
+ Select "**Disk: Basic**" and enable "**Late initialization**" for page cache. "**Disk: Enhanced**" (where "**Late initialization**" is not available) in W3TC 0.9.5.1 seems to work good without any imcompatibility with this plugin.
281
+
282
+ - [Vendi Cache](https://wordpress.org/plugins/vendi-cache/ "Vendi Cache — WordPress Plugins")
283
+ This was formerly built in Wordfence. Select "**basic caching**" for Vendi Cache and **"mu-plugin" (ip-geo-block-mu.php)** for IP Geo Block.
284
+
285
+ If your plugin serves page caching by `mod_rewrite` via `.htaccess` (e.g. WP Fastest Cache) or caching by `advanced-cache.php` drop-in (e.g. Comet Cache) or your hosting provider serves page caching at server side, "**Blocking on front-end**" might lead to generate inconsistent pages.
286
+
287
+ For more details, please refer to some documents at "[Blocking on front-end](http://www.ipgeoblock.com/codex/#blocking-on-front-end 'Codex | IP Geo Block')".
288
 
289
  = Do I have to turn on all the selection to enhance security? =
290
 
291
+ Yes. Roughly speaking, the strategy of this plugin has been constructed as follows:
 
292
 
293
  - **Block by country**
294
  It blocks malicious requests from outside your country.
302
  - **Bad signatures in query**
303
  It blocks the request which has not been covered in the above three.
304
 
305
+ Please try "**Best settings**" button at the bottom of this plugin's setting page for easy setup. And also see more details in "[The best practice of target settings](http://www.ipgeoblock.com/codex/the-best-practice-for-target-settings.html 'The best practice of target settings | IP Geo Block')".
 
306
 
307
+ = Does this plugin validate all the requests? =
308
 
309
+ Unfortunately, no. This plugin can't handle the requests that are not parsed by WordPress. In other words, a standalone file (PHP, CGI or something excutable) that is unrelated to WordPress can't be validated by this plugin even if it is in the WordPress install directory.
 
 
 
310
 
311
+ But there're exceptions: When you enable "**Force to load WP core**" for **Plugins area** or **Themes area**, a standalone PHP file becomes to be able to be blocked. Sometimes this kind of file has some vulnerabilities. This function protects your site against such a case.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
 
313
  == Other Notes ==
314
 
315
  = Known issues =
316
 
317
+ * No image is shown after drag & drop a image in grid view at "Media Library". For more details, please refer to [this ticket at Github](https://github.com/tokkonopapa/WordPress-IP-Geo-Block/issues/2 "No image is shown after drag & drop a image in grid view at "Media Library". - Issue #2 - tokkonopapa/WordPress-IP-Geo-Block - GitHub").
318
+ * From [WordPress 4.5](https://make.wordpress.org/core/2016/03/09/comment-changes-in-wordpress-4-5/ "Comment Changes in WordPress 4.5 – Make WordPress Core"), `rel=nofollow` attribute and value pair had no longer be added to relative or same domain links within `comment_content`. This change prevents to block "Server Side Request Forgeries" (not Cross Site but a malicious link in the comment field of own site).
 
 
 
 
 
 
 
 
 
 
 
 
 
319
 
320
  == Screenshots ==
321
 
322
+ 1. **IP Geo Plugin** - Settings tab
323
+ 2. **IP Geo Plugin** - Validation rule settings
324
+ 3. **IP Geo Plugin** - Back-end target settings
325
+ 4. **IP Geo Plugin** - Front-end target settings
326
+ 5. **IP Geo Plugin** - Geolocation API settings
327
+ 6. **IP Geo Plugin** - IP address cache settings
328
+ 7. **IP Geo Plugin** - Statistics tab
329
+ 8. **IP Geo Plugin** - Logs tab
330
+ 9. **IP Geo Plugin** - Search tab
331
+ 10. **IP Geo Plugin** - Attribution tab
332
 
333
  == Changelog ==
334
 
335
+ = 3.0.2.2 =
336
+ * **Improvement:** Change the behavior of "Referrer Suppressor" not to open a new window on public facing pages.
337
+ * **Improvement:** Improve some of the descriptions of help text.
338
+ * **Bug fix:** Fix the bug of undefined symbol in admin class related to the Google Map API.
339
+ * **Bug fix:** Fix the bug of incompatible function arguments when the number of login fails reaches the limit.
340
+ * **Bug fix:** Fix the issue of not working blocking by country on specific pages correctly as the validation target.
341
+
342
+ = 3.0.2.1 =
343
+ This is a maintenance release addressing some issues.
344
+
345
+ * **Update:** Net_DNS2, Net_IPv6, Net_IPv4 to the newest.
346
+ * **Update:** Geolocation database API for Maxmind and IP2Location to 1.1.8.
347
+ * **Update:** Bring back the priority of validation for wp-zep and badsig as same as 3.0.2 and before.
348
+ * **Improvement:** Handle some of loop back and private IP addresses for localhost and host inside load balancer.
349
+ * **Improvement:** Update instructions when the geolocation API libraries fails to install.
350
+ * **Bug fix:** Fix the blocking issue of admin ajax/post on front-end.
351
+ * **Bug fix:** Fix the issue of improper IPv6 handling on setting page.
352
+
353
+ = 3.0.2 =
354
+ * **New feature:** Add "Exceptions" for "Admin ajax/post" to specify the name of action which causes undesired blocking (typically on the public facing pages).
355
+ * **Improvement:** Add "Disable" to "Max number of failed login attempts per IP address" to avoid conflict with other similar plugin.
356
+ * **Improvement:** Update geolocation database libraries to 1.1.7 for better compatibility on some platform.
357
+ * **Trial feature:** Add custom action hook `ip-geo-block-send-response`. This is useful to control firewall via [fail2ban](http://www.fail2ban.org/ "Fail2ban") like [WP fail2ban](https://wordpress.org/plugins/wp-fail2ban/ "WP fail2ban - WordPress Plugins").
358
+ * See some details at [release 3.0.2](http://www.ipgeoblock.com/changelog/release-3.0.2.html "3.0.2 Release Note | IP Geo Block").
359
+
360
+ = 3.0.1.2 =
361
+ * **Bug fix:** Fix the blocking issue in some environments when upgrading from 2.2.9.1 to 3.0.0.
362
+ * **Bug fix:** Fix the blocking issue at opening a new window via context menu on dashboard.
363
+ * **Bug fix:** Fix the potential issue of 500 Internal error in cron job.
364
+ * **Improvement:** Revive 410 Gone for response code.
365
+ * **Improvement:** Prevent the issue of resetting matching rule and country code at upgrading.
366
+
367
+ = 3.0.1.1 =
368
+ * **Bug fix:** Fix the issue where **Login form** could not be disabled on **Back-end target settings**.
369
+ * **Bug fix:** Fix the issue where trackback and pingback could not be blocked since 2.2.4.
370
+ * **Improved:** Apply the action hook 'pre_trackback_post' that was introduced in WP 4.7.0.
371
+ * **Improved:** Use 'safe_redirect()' instead of 'redirect()' for secured internal redirection. If you set an external url for **Redirect URL**, please use the filter hook 'allowed_redirect_hosts'.
372
+ * **Improved:** Better compatibility with the plugin "Anti-Malware Security and Brute-Force Firewall".
373
+
374
+ = 3.0.1 =
375
+ * **Bug fix:** Add lock mechanism for local geolocation DBs to avoid potential fatal error.
376
+ * **Improvement:** Add self blocking prevention potentially caused by login attempts with the same IP address of logged in user.
377
+ * **New feature:** Add "**Installation information**" button to make it easy to submit an issue at support forum.
378
+
379
+ = 3.0.0 =
380
+ * **New feature:** Add the function of blocking on front-end.
381
+ * **New filter hook:** Add `ip-geo-block-public` to extend validation on front-end.
382
+ * **Improvement:** Avoid conflict with "Open external links in a new window" plugin and some other reason to prevent duplicated window open. For more detail, see [this discussion at support forum](https://wordpress.org/support/topic/ip-geoblock-opens-2-windows-on-link-clicks-when-user-is-logged-in/ "Topic: IP Geoblock opens 2 windows on link clicks when user is logged in « WordPress.org Forums").
383
+ * **Improvement:** Better compatibility with some plugins, themes and widgets.
384
+ * **Improvement:** Deferred execution of SQL command to improve the response.
385
+ * **Improvement:** Make the response compatible with WP original when it is requested by GET method.
386
+ * See some details at [release 3.0.0](http://www.ipgeoblock.com/changelog/release-3.0.0.html "3.0.0 Release Note | IP Geo Block").
387
+
388
  = 2.2.9.1 =
389
+ * **Bug fix:** Blocking Wordfence scanning. ([@](https://wordpress.org/support/topic/wordfence-conflict-2/ "WordFence Conflict"))
390
+ * **Bug fix:** Illegal elimination of colon in text field for IP address. ([@](https://wordpress.org/support/topic/adding-ipv6-to-white-list/ "Adding IPv6 to white list"))
391
+ * **Improved:** Compatibility with PHP 7 that cause to feel relaxed. ([@](https://wordpress.org/support/topic/plans-for-php-7-compatiblity/ "Plans for PHP 7 compatiblity?"))
392
+ * **Improved:** Avoid resetting whitelist on update by InfiniteWP. ([@](https://wordpress.org/support/topic/whitelist-resets-on-update/ "[Resolved] Whitelist resets on update"))
393
+ * **Trial feature:** `X-Robots-Tag` HTTP header with `noindex, nofollow` for login page. ([@](https://wordpress.org/support/topic/ip-geo-block-and-searchmachines/ "IP GEo-block and searchmachines"))
 
 
 
 
 
 
394
 
395
  = 2.2.9 =
396
+ * **New feature:** A new option that makes this plugin configured as a "Must-use plugin". It can massively reduce the server load especially against brute-force attacks because it initiates this plugin prior to other typical plugins.
397
+ * **Improvement:** Validation of a certain signature against XSS is internally added to "Bad signature in query" by default.
398
+ * **Improvement:** Improved compatibility with PHP 7 (Thanks to [FireMyst](https://wordpress.org/support/topic/plans-for-php-7-compatiblity/ "Topic: Plans for PHP 7 compatiblity? « WordPress.org Forums")).
 
 
 
 
 
399
  * Find details in [2.2.9 Release Note](http://www.ipgeoblock.com/changelog/release-2.2.9.html "2.2.9 Release Note").
400
 
401
  = 2.2.8.2 =
402
  * **Bug fix:** Fixed the mismatched internal version number.
403
 
404
  = 2.2.8.1 =
405
+ * **Bug fix:** Fixed the issue of undefined function `wp_get_raw_referer()` error that happened under certain condition. See [the issue](https://wordpress.org/support/topic/since-php-update-fatal-error-everytime-i-want-to-edit-a-post/ "Since PHP update Fatal error everytime I want to edit a post") at forum.
406
+ * **Improved:** Avoid resetting country code on update. See [the issue](https://wordpress.org/support/topic/whitelist-resets-on-update/ "Whitelist resets on update") at forum.
 
 
 
 
 
407
 
408
  = 2.2.8 =
409
+ * **Bug fix:** Fixed the issue of stripping some required characters for Google maps API key.
 
410
  * **New feature:** Whois database Lookup for IP address on search tab.
411
  * **Update:** Updated geolocation API libraries and services.
412
  * Find more details in [2.2.8 Release Note](http://www.ipgeoblock.com/changelog/release-2.2.8.html "2.2.8 Release Note").
413
 
414
  = 2.2.7 =
415
  * **Bug fix:** Fix inadequate validation of "**Bad signatures in query**".
416
+ * **Improvement:** Add fallback for Google Maps API key ([@](https://wordpress.org/support/topic/226-problem-with-search-resp-google-maps "WordPress › Support » [2.2.6] Problem with SEARCH resp. Google Maps")) and corruption of "Bad signatures" ([@](https://wordpress.org/support/topic/226-problem-with-bad-signatures-in-query "WordPress › Support » [2.2.6] Problem with "Bad signatures in query"")).
 
 
 
417
  * **Update:** Update geolocation service api.
418
  * Find details about Google Maps API in [2.2.7 Release Note](http://www.ipgeoblock.com/changelog/release-2.2.7.html "2.2.7 Release Note").
419
 
420
  = 2.2.6 =
421
  * **New feature:** Add saving csv file of logs in "Logs" tab.
422
+ * **New feature:** Add filter hook `ip-geo-block-record-log` to control over the conditions of recording in more detail.
423
+ * **Bug fix:** Fixed the issue that "Exceptions" for Plugins/Themes area does not work properly. Please confirm your settings again.
 
 
424
  * See details at [release 2.2.6](http://www.ipgeoblock.com/changelog/release-2.2.6.html "2.2.6 Release Note").
425
 
426
  = 2.2.5 =
427
+ * **New feature:** On the settings page, you can specify the pliugin or theme which would cause undesired blocking in order to exclude it from the validation target without embedding any codes into `functions.php`.
 
 
428
  * **Improvement:** Optimize resource loading on admin dashboard.
429
  * **Improvement:** Support clean uninstall for network / multisite.
430
+ * **Improvement:** Improve the compatibility of downloading IP address databases for Microsoft IIS.
 
431
  * **Bug fix:** Support `FORCE_SSL_ADMIN`.
432
+ * **Bug fix:** Fix the issue of [@](https://wordpress.org/support/topic/compatibility-with-ag-custom-admin "WordPress › Support » Compatibility with AG Custom Admin") and change the option name "**Important files**" to "**Bad signatures in query**" to avoid misuse.
433
+ * **Bug fix:** Fix the issue of [@](https://wordpress.org/support/topic/gb-added-to-whitelist "WordPress › Support » GB added to whitelist") which might be caused by some race condition.
 
 
 
 
 
434
  * **Bug fix:** Fix the issue of restoring post revisions which was blocked.
435
 
436
  = 2.2.4.1 =
437
  Sorry for frequent updating.
438
 
439
+ * **Bug fix:** Fixed the issue of `Warning: strpos(): Empty needle in...` that was reported in [@](https://wordpress.org/support/topic/version-224-produces-warning-message "WordPress › Support » Version 2.2.4 Produces Warning Message") and [@](https://wordpress.org/support/topic/error-after-update-to-newest-version "WordPress › Support » Error after Update to newest version").
 
 
 
 
440
 
441
  = 2.2.4 =
442
+ * **Bug fix:** Fixed the issue that some links on network admin of multisite were blocked when WP-ZEP for `admin area` or `admin ajax/post` was enabled.
 
443
  * **New feature:** Added configure of `.htaccess` for the plugins/themes area.
444
  * **Enhancement:** Added `wp-signup.php` to the list of validation target.
445
  * **Enhancement:** Added exporting and importing the setting parameters.
446
+ * **Improvement:** Made the logout url compatible with [Rename wp-login.php](https://wordpress.org/plugins/rename-wp-login/).
447
+ * **Improvement:** Made condition of validation more strictly at admin diagnosis to prevent unnecessary notice of self blocking. ([@](https://wordpress.org/support/topic/youll-be-blocked-after-you-log-out-notice-doesnt-disappear "[resolved] "You'll be blocked after you log out" notice doesn't disappear"))
448
+ * **Improvement:** Improved some of UI. ([@](https://wordpress.org/support/topic/possible-to-select-which-countries-are-blocked "[resolved] Possible to select which countries are blocked?"), [@](https://wordpress.org/support/topic/ip-geo-block-black-list "IP Geo Block Black List"))
 
 
 
 
 
449
  * See some details at [release 2.2.4](http://www.ipgeoblock.com/changelog/release-2.2.4.html "2.2.4 Release Note").
450
 
451
  = 2.2.3.1 =
452
+ * **Bug fix:** Fixed the issue that disabled validation target was still blocked by country. ([@](https://wordpress.org/support/topic/logs-whitelist-comments-still-blocked "[resolved] logs whitelist comments still blocked?"))
453
+ * **Improvement:** Better handling of charset and errors for MySQL. ([@](https://wordpress.org/support/topic/whitelist-log "[resolved] Whitelist + Log"))
 
 
 
454
 
455
  = 2.2.3 =
456
+ * **Improvement:** Since WordPress 4.4, XML-RPC system.multicall is disabled when the authentication fails, but still processed all the methods to the end. Now this plugin immediately blocks the request when the authentication fails without processing the rest of the methods.
 
 
 
457
  * **Improvement:** Add UI to change the maximum number of login attempts.
458
+ * **Improvement:** Add a fallback process of setting up the directory where the geo location database APIs should be installed. It will be set as `wp-content/uploads/` instead of `wp-content/plugins/ip-geo-block/` or `wp-content/` in case of being unable to obtain proper permission. ([@](https://wordpress.org/support/topic/deactivated-after-updte-why "[resolved] Deactivated after update - why?"), [@](https://wordpress.org/support/topic/the-plugin-caused-an-error-message "[resolved] The plugin caused an error message"))
459
+ * **Improvement:** Moderate the conditions of redirection after logout. ([@](https://wordpress.org/support/topic/logout-redirect-doesnt-work-when-plugin-is-active "[resolved] Logout redirect doesn't work when plugin is active"))
460
+ * **Improvement:** Prevent self blocking caused by irrelevant signature. ([@](https://wordpress.org/support/topic/works-too-well-blocked-my-wp-admin-myself "[resolved] Works too well - Blocked my wp-admin myself"))
461
+ * **Bug fix:** Fixed the issue of conflicting with certain plugins due to the irrelevant handling of js event. ([@](https://wordpress.org/support/topic/cannot-edit-pages-when-ip-geo-block-is-enabled "[resolved] Cannot edit pages when ip-geo-block is enabled."))
 
 
 
 
 
 
 
 
 
462
  * **New feature:** Add "Blocked per day" graph for the daily statistics.
463
  * See some details at [2.2.3 release note](http://www.ipgeoblock.com/changelog/release-2.2.3.html "2.2.3 Release Note").
464
 
466
  Sorry for frequent update again but the following obvious bugs should be fixed.
467
 
468
  * **Bug fix:** Fixed the issue of not initializing country code at activation.
469
+ * **Bug fix:** Fixed the issue that scheme less notation like '//example.com' could not be handled correctly.
 
470
 
471
  = 2.2.2.2 =
472
  Sorry for frequent update.
473
 
474
+ * **Bug fix:** Fixed the issue of race condition at activation. This fix is related to the urgent security update at **2.2.2.1 which was not actually the security issue but a bug**. See [this thread](https://wordpress.org/support/topic/white-list-hack "white list hack") about little more details.
 
 
 
 
475
  * **Improvement:** Improved the compatibility with Jetpack.
476
 
477
  = 2.2.2.1 =
478
+ * **Urgent security update:** Killed the possibility of the options being altered.
 
479
 
480
  = 2.2.2 =
481
+ * **Enhancement:** Refactored some codes and components. The number of attacks that can be proccessed per second has been improved by 25% at the maximum.
482
+ * **Improvement:** In the previous version, the statistical data was recorded into `wp_options`. It caused the uncertainty of recording especially in case of burst attacks. Now the data will be recorded in an independent table to improve this issue.
483
+ * **Bug fix:** Fixed conflict with NextGEN Gallary Pro. Thanks to [bodowewer](https://wordpress.org/support/profile/bodowewer).
 
 
 
 
 
484
  * **Bug fix:** Fixed some filter hooks that did not work as intended.
485
  * See more details at [2.2.2 release note](http://www.ipgeoblock.com/changelog/release-2.2.2.html "2.2.2 Release Note").
486
 
488
  * **Bug fix:** Fixed "open_basedir restriction" issue caused by `file_exists()`.
489
 
490
  = 2.2.1 =
491
+ * **Enhancement:** In previous version, local geolocation databases will always be removed and downloaded again at every upgrading. Now, the class library for Maxmind and IP2Location have become independent of this plugin and you can put them outside this plugin in order to cut the above useless process. The library can be available from [WordPress-IP-Geo-API](https://github.com/tokkonopapa/WordPress-IP-Geo-API).
492
+ * **Deprecated:** Cooperation with IP2Location plugins such as [IP2Location Tags](http://wordpress.org/plugins/ip2location-tags/ "WordPress - IP2Location Tags - WordPress Plugins"), [IP2Location Variables](http://wordpress.org/plugins/ip2location-variables/ "WordPress - IP2Location Variables - WordPress Plugins"), [IP2Location Country Blocker](http://wordpress.org/plugins/ip2location-country-blocker/ "WordPress - IP2Location Country Blocker - WordPress Plugins") is out of use. Instead of it, free [IP2Location LITE databases for IPv4 and IPv6](http://lite.ip2location.com/ "Free IP Geolocation Database") will be downloaded.
 
 
 
 
 
 
 
 
 
 
 
493
  * **Improvement:** Improved connectivity with Jetpack.
494
  * **Improvement:** Improved immediacy of downloading databases at upgrading.
495
  * **Improvement:** Replaced a terminated RESTful API service with a new stuff.
496
+ * **Bug fix:** Fixed issue that clicking a link tag without href always refreshed the page. Thanks to [wyclef](https://wordpress.org/support/topic/conflict-with-menu-editor-plugin "WordPress › Support » Conflict with Menu Editor plugin?").
497
+ * **Bug fix:** Fixed issue that deactivating and activating repeatedly caused to show the welcome message.
498
+ * **Bug fix:** Fixed issue that a misaligned argument in the function caused 500 internal server error when a request to the php files in plugins/themes area was rewrited to `rewrite.php`.
 
 
 
 
 
499
 
500
  = 2.2.0.1 =
501
  Sorry for frequent update.
503
  * **Fix:** Fixed the issue that some actions of other plugins were blocked.
504
 
505
  = 2.2.0 =
506
+ * **Important:** Now **Block by country** and **Prevent Zero-day Exploit** become to work independently on **Admin area**, **Admin ajax/post** at **Validation target settings**. Please reconfirm them.
507
+ * **Important:** Previously, a request whose country code can't be available was always blocked. But from this release, such a request is considered as comming from the country whose code is `ZZ`. It means that you can put `ZZ` into the white list and black list.
508
+ * **New feature:** White list and Black list of extra IP addresses prior to the validation of country code. Thanks to Fabiano for good suggestions at [support forum](https://wordpress.org/support/topic/white-list-of-ip-addresses-or-ranges "WordPress › Support » White list of IP addresses or ranges?")
509
+ * **New feature:** Malicious signatures to prevent disclosing the important files via vulnerable plugins or themes. A malicious request to try to expose `wp-config.php` or `passwd` can be blocked.
510
+ * **New feature:** Add privacy considerations related to IP address. Add **Anonymize IP address** at **Record settings**.
511
+ * **Bug fix:** Fix the issue that spaces in **Text message on comment form** are deleted.
 
 
 
 
 
 
 
 
 
 
 
512
  * See details at [2.2.0 release note](http://www.ipgeoblock.com/changelog/release-2.2.0.html "2.2.0 Release Note").
513
 
514
  = 2.1.5.1 =
515
+ * **Bug fix:** Fixed the issue that the Blacklist did not work properly. Thanks to TJayYay for reporting this issue at [support forum](https://wordpress.org/support/topic/hackers-from-country-in-blocked-list-of-countries-trying-to-login "WordPress › Support » Hackers from country in Blocked List of Countries trying to login").
 
 
516
 
517
  = 2.1.5 =
518
+ * **Enhancement:** Enforce preventing self blocking at the first installation. And add the scan button to get all the country code using selected API. Thanks to **Nils** for a nice idea at [support forum](https://wordpress.org/support/topic/locked-out-due-to-eu-vs-country "WordPress › Support » Locked out due to EU vs. Country").
 
 
 
519
  * **New feature:** Add pie chart to display statistics of "Blocked by country".
520
  * **Enhancement:** WP-ZEP is reinforced against CSRF.
521
  * **Bug fix:** Fix illegal handling of the fragment in a link.
522
  * See details at [2.1.5 release note](http://www.ipgeoblock.com/changelog/release-2.1.5.html "2.1.5 Release Note").
523
 
524
  = 2.1.4 =
525
+ * **Bug fix:** Fix the issue that this plugin broke functionality of a certain plugin. Thanks to **opsec** for reporting this issue at [support forum](https://wordpress.org/support/topic/blocks-saves-in-types-or-any-plugins-from-wp-typescom "WordPress › Support » Blocks saves in Types or any plugins from wp-types.com").
526
+ * **Improvement:** Add checking process for validation rule to prevent being blocked itself. Thanks to **internationals** for proposing at [support forum](https://wordpress.org/support/topic/locked-out-due-to-eu-vs-country "WordPress › Support » Locked out due to EU vs. Country")
527
+ * **Improvement:** Arrage the order of setting sections to focus the goal of this plugin.
 
 
 
 
 
528
  * See details at [2.1.4 release note](http://www.ipgeoblock.com/changelog/release-2.1.4.html "2.1.4 Release Note").
529
 
530
  = 2.1.3 =
531
  * **New feature:** Add "show" / "hide" at each section on the "Settings" tab.
532
+ * **New feature:** Add an emergency function that invalidate blocking behavior in case yourself is locked out. This feature is commented out by default at the bottom of `ip-geo-block.php`.
533
+ * **Improvement:** Prevent adding query strings to the static resources when users logged in.
 
 
 
534
  * **Improvement:** Improved the compatibility with Autoptimize.
535
  * **Bug fix:** Fix the issue related to showing featured themes on dashboard.
536
  * **Bug fix:** Fix minor bug in `rewrite.php` for the advanced use case.
539
  = 2.1.2 =
540
  This is a maintenance release.
541
 
542
+ * **Bug fix:** Fix the issue that the login-fail-counter didn't work when the validation at `Login form` was `block by country (register, lost password)`. In this release, the login-fail-counter works correctly.
543
+ * **Bug fix:** Fix the issue that the validation settings of `Admin area` and `Admin ajax/post` were influential with each other. Now each of those works individually.
544
+ * **Bug fix:** "Site Stats" of Jetpack is now shown on the admin bar which issue was reported on [support forum](https://wordpress.org/support/topic/admin-area-prevent-zero-day-exploit-incompatible-with-jetpack-site-stats-in-a "WordPress › Support » Admin area - Prevent zero-day exploit: Incompatible with Jetpack Site Stats in A").
545
+ * **Improvement:** Hide checking the existence of log db behind the symbol `IP_GEO_BLOCK_DEBUG` to reduce 1 query on admin screen.
546
+ * **Improvement:** Add alternative functions of BCMath extension to avoid `PHP Fatal error: Call to undefined function` in `IP2Location.php` when IPv6 is specified.
547
+ * **Improvement:** Use MaxMind database at the activating process not to be locked out by means of inconsistency of database at the activation and after.
 
 
 
 
 
 
 
 
 
548
  * See more details at [2.1.2 release note](http://www.ipgeoblock.com/changelog/release-2.1.2.html "2.1.2 Release Note").
549
 
550
  = 2.1.1 =
551
+ * **New feature:** Added `Block by country (register, lost password)` at `Login form` on `Settings` tab in order to accept the registered users as membership from anywhere but block the request of new user ragistration and lost password by the country code. Is't suitable for BuddyPress and bbPress.
552
+ * **Improvement:** Added showing the custom error page for http response code 4xx and 5xx. For example the `403.php` in the theme template directory or in the child theme directory is used if it exists. And new filter hooks `ip-geo-block-(comment|xmlrpc|login|admin)-(status|reason)` are available to customize the response code and reason for human.
553
+ * **Obsoleted:** Obsoleted the filter hooks `ip-geo-block-(admin-actions|admin-pages|wp-content)`. Alternatively new filter hooks `ip-geo-block-bypass-(admins|plugins|themes)` are added to bypass WP-ZEP.
 
 
 
 
 
 
 
 
 
 
554
  * Find out more details in the [2.1.1 release note](http://www.ipgeoblock.com/changelog/release-2.1.1.html "2.1.1 Release Note").
555
 
556
  = 2.1.0 =
557
+ * **New feature:** Expanded the operating range of ZP-ZEP, that includes admin area, plugins area, themes area. Now it can prevent a direct malicios attack to the file in plugins and themes area. Please go to the "Validation Settings" on "Settings" tab and check it. Also check my article in "[Analysis of Attack Vector against WP Plugins](http://www.ipgeoblock.com/article/analysis-attack-vector.html)".
558
+ * **Bug fix:** Fixed the issue that action hook `ip-geo-block-backup-dir` did not work correctly because the order of argument was mismatched.
559
+ * **Bug fix:** Fixed the issue that a record including utf8 4 bytes character in its columns was not logged into DB in WordPress 4.2.
560
+ * **Improvement:** Fixed the issue that Referrer Suppressor do nothing with a new element which is added into DOM after DOM ready. The event handler is now delegated at the `body`.
 
 
 
 
 
 
 
 
561
 
562
  = 2.0.8 =
563
+ * Fixed an issue that a certain type of attack vector to the admin area ([example](https://blog.sucuri.net/2014/08/database-takeover-in-custom-contact-forms.html "Critical Vulnerability Disclosed on WordPress Custom Contact Forms Plugin")) could not be blocked by the reason that some plugins accept it on earlier hook (ie `init`) than this plugin (previously `admin_init`).
564
+ * Added re-creating DB table for validation logs in case of accidentally failed at activation process.
565
+ * The time of day is shown with local time by adding GMT offset based on the time zone setting.
 
 
 
 
 
566
  * Optimized resource loading and settings to avoid redundancy.
567
  * See details at [this plugin's blog](http://www.ipgeoblock.com/changelog/release-2.0.8.html "2.0.8 Release Note").
568
 
575
  * Sorry for urgent update but avoid an javascript error.
576
 
577
  = 2.0.4 =
578
+ * Sorry for frequent update but added a function of showing admin notice when none of the IP geolocation providers is selected. Because the user will be locked out from admin screen when the cache expires.
579
+ * **Bug fix:** Fixed an issue of `get_geolocation()` method at a time of when the cache of IP address is cleared.
 
 
 
580
  * Referrer suppressor now supports [meta referrer](https://wiki.whatwg.org/wiki/Meta_referrer "Meta referrer - WHATWG Wiki")
581
 
582
  = 2.0.3 =
583
+ * **Bug fix:** Fixed an issue that empty black list doesn't work correctly when matching rule is black list.
584
+ * **New feature:** Added 'Zero-day Exploit Prevention for wp-admin'. Because it is an experimental feature, please open a new issue at [support forum](https://wordpress.org/support/plugin/ip-geo-block "WordPress › Support » IP Geo Block") if you have any troubles with it.
585
+ * **New feature:** Referrer suppressor for external link. When you click an external hyperlink on admin screen, http referrer will be suppressed to hide a footprint of your site.
586
+ * Also added the filter hook `ip-geo-block-admin-actions` for safe actions on back-end.
 
 
 
 
 
 
 
587
 
588
  = 2.0.2 =
589
+ * **New feature:** Include `wp-admin/admin-post.php` as a validation target in the `Admin area`. This feature is to protect against a vulnerability such as [Analysis of the Fancybox-For-WordPress Vulnerability](http://blog.sucuri.net/2015/02/analysis-of-the-fancybox-for-wordpress-vulnerability.html) on Sucuri Blog.
590
+ * Added a sample code snippet as a use case for 'Give ajax permission in case of safe actions on front facing page'. See Example 10 in `sample.php`.
 
 
 
 
 
591
 
592
  = 2.0.1 =
593
+ * Fixed the issue of improper scheme from the HTTPS site when loading js for google map.
594
+ * In order to prevent accidental disclosure of the length of password, changed the length of `*` (masked password) which is logged into the database.
 
 
 
595
 
596
  = 2.0.0 =
597
+ * **New feature:** Protection against brute-force and reverse-brute-force attacks to `wp-login.php`, `xmlrpc.php` and admin area. This is an experimental function and can be enabled on `Settings` tab. Malicious access can try to login only 5 times per IP address. This retry counter can be reset to zero by `Clear statistics` on `Statistics` tab.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
598
 
599
  = 1.0.0 =
600
  * Ready to release.
admin/class-ip-geo-block-admin.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2013-2016 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block_Admin {
@@ -28,9 +28,6 @@ class IP_Geo_Block_Admin {
28
  * and adding a settings page and menu.
29
  */
30
  private function __construct() {
31
- $this->admin_tab = isset( $_GET['tab'] ) ? (int)$_GET['tab'] : 0;
32
- $this->admin_tab = min( 4, max( 0, $this->admin_tab ) );
33
-
34
  // Load plugin text domain.
35
  add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
36
 
@@ -44,8 +41,9 @@ class IP_Geo_Block_Admin {
44
  add_filter( 'wp_prepare_revision_for_js', array( $this, 'add_revision_nonce' ), 10, 3 );
45
 
46
  // If multisite, then enque the authentication script for network admin
47
- if ( is_multisite() )
48
  add_action( 'network_admin_menu', 'IP_Geo_Block::enqueue_nonce' );
 
49
  }
50
 
51
  /**
@@ -85,7 +83,7 @@ class IP_Geo_Block_Admin {
85
  *
86
  */
87
  public function enqueue_admin_assets() {
88
- $footer = TRUE;
89
  $dependency = array( 'jquery' );
90
 
91
  // css for option page
@@ -155,8 +153,18 @@ class IP_Geo_Block_Admin {
155
  'IP_GEO_BLOCK',
156
  array(
157
  'action' => 'ip_geo_block',
 
158
  'url' => admin_url( 'admin-ajax.php' ),
159
  'nonce' => IP_Geo_Block_Util::create_nonce( $this->get_ajax_action() ),
 
 
 
 
 
 
 
 
 
160
  )
161
  );
162
  wp_enqueue_script( $handle );
@@ -206,43 +214,52 @@ class IP_Geo_Block_Admin {
206
  }
207
 
208
  /**
209
- * Display global notice
210
  *
211
- * @notice: Sanitization should be done at the caller
212
  */
213
  public function show_admin_notices() {
214
  $key = IP_Geo_Block::PLUGIN_NAME . '-notice';
 
215
  if ( FALSE !== ( $notices = get_transient( $key ) ) ) {
216
  foreach ( $notices as $msg => $type ) {
217
- echo "\n<div class=\"notice is-dismissible ", esc_attr( $type ), "\"><p><strong>IP Geo Block:</strong> ", IP_Geo_Block_Util::kses( $msg ), "</p></div>\n";
 
 
 
 
 
218
  }
219
  }
 
 
 
220
  }
221
 
 
 
 
 
222
  public static function add_admin_notice( $type, $msg ) {
223
  $key = IP_Geo_Block::PLUGIN_NAME . '-notice';
224
  if ( FALSE === ( $notices = get_transient( $key ) ) )
225
  $notices = array();
226
 
 
227
  if ( ! isset( $notices[ $msg ] ) ) {
228
  $notices[ $msg ] = $type;
229
  set_transient( $key, $notices, MINUTE_IN_SECONDS );
230
  }
231
  }
232
 
233
- /**
234
- * Display local notice
235
- *
236
- */
237
- private function show_setting_notice( $type, $msg ) {
238
- add_settings_error( IP_Geo_Block::PLUGIN_NAME, IP_Geo_Block::OPTION_NAME, $msg, $type );
239
- }
240
-
241
  /**
242
  * Register the administration menu into the WordPress Dashboard menu.
243
  *
244
  */
245
- private function add_plugin_admin_page() {
 
 
 
 
246
  // Add a settings page for this plugin to the Settings menu.
247
  $hook = add_options_page(
248
  __( 'IP Geo Block', 'ip-geo-block' ),
@@ -262,27 +279,25 @@ class IP_Geo_Block_Admin {
262
  *
263
  */
264
  private function diagnose_admin_screen() {
265
- // delete all admin noties
266
- delete_transient( IP_Geo_Block::PLUGIN_NAME . '-notice' );
267
-
268
  // Check version and compatibility
269
  if ( version_compare( get_bloginfo( 'version' ), '3.7.0' ) < 0 )
270
  self::add_admin_notice( 'error', __( 'You need WordPress 3.7+.', 'ip-geo-block' ) );
271
 
272
  $settings = IP_Geo_Block::get_option();
 
273
 
274
  // Check consistency of matching rule
275
  if ( -1 === (int)$settings['matching_rule'] ) {
276
  if ( FALSE !== get_transient( IP_Geo_Block::CRON_NAME ) ) {
277
  self::add_admin_notice( 'notice-warning', sprintf(
278
  __( 'Now downloading geolocation databases in background. After a little while, please check your country code and &#8220;<strong>Matching rule</strong>&#8221; at <a href="%s">Validation rule settings</a>.', 'ip-geo-block' ),
279
- esc_url( admin_url( 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME ) )
280
  ) );
281
  }
282
  else {
283
  self::add_admin_notice( 'error', sprintf(
284
  __( 'The &#8220;<strong>Matching rule</strong>&#8221; is not set properly. Please confirm it at <a href="%s">Validation rule settings</a>.', 'ip-geo-block' ),
285
- esc_url( admin_url( 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME ) )
286
  ) );
287
  }
288
  }
@@ -290,23 +305,35 @@ class IP_Geo_Block_Admin {
290
  // Check to finish updating matching rule
291
  elseif ( 'done' === get_transient( IP_Geo_Block::CRON_NAME ) ) {
292
  delete_transient( IP_Geo_Block::CRON_NAME );
293
- self::add_admin_notice( 'updated', __( 'Local database and matching rule have been updated.', 'ip-geo-block' ) );
294
  }
295
 
296
  // Check self blocking
297
  if ( 1 === (int)$settings['validation']['login'] ) {
298
  $instance = IP_Geo_Block::get_instance();
299
- $validate = $instance->validate_ip( 'login', $settings, TRUE, FALSE, FALSE );
 
 
 
 
 
 
 
 
 
 
 
300
 
301
- if ( 'passed' !== $validate['result'] ) {
 
302
  self::add_admin_notice( 'error',
303
  ( $settings['matching_rule'] ?
304
  __( 'Once you logout, you will be unable to login again because your country code or IP address is in the blacklist.', 'ip-geo-block' ) :
305
  __( 'Once you logout, you will be unable to login again because your country code or IP address is not in the whitelist.', 'ip-geo-block' )
306
- ) .
307
  sprintf(
308
  __( 'Please check your <a href="%s">Validation rule settings</a>.', 'ip-geo-block' ),
309
- esc_url( admin_url( 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME . '#' . IP_Geo_Block::PLUGIN_NAME . '-settings-0' ) )
310
  )
311
  );
312
  }
@@ -328,13 +355,17 @@ class IP_Geo_Block_Admin {
328
  *
329
  */
330
  public function setup_admin_page() {
331
- $this->diagnose_admin_screen();
332
- $this->add_plugin_admin_page();
 
 
 
333
 
334
- // Register settings page only if it is needed
335
  if ( ( isset( $_GET ['page' ] ) && IP_Geo_Block::PLUGIN_NAME === $_GET ['page' ] ) ||
336
- ( isset( $_POST['option_page'] ) && IP_Geo_Block::PLUGIN_NAME === $_POST['option_page'] ) )
337
  $this->register_settings_tab();
 
338
 
339
  // Add an action link pointing to the options page. @since 2.7
340
  else {
@@ -342,8 +373,10 @@ class IP_Geo_Block_Admin {
342
  add_filter( 'plugin_action_links_' . IP_GEO_BLOCK_BASE, array( $this, 'add_action_links' ), 10, 1 );
343
  }
344
 
345
- // Register scripts and admin notice
346
  add_action( 'admin_enqueue_scripts', array( 'IP_Geo_Block', 'enqueue_nonce' ) );
 
 
347
  add_action( 'admin_notices', array( $this, 'show_admin_notices' ) );
348
  }
349
 
@@ -352,6 +385,7 @@ class IP_Geo_Block_Admin {
352
  *
353
  */
354
  public function display_plugin_admin_page() {
 
355
  $tabs = array(
356
  0 => __( 'Settings', 'ip-geo-block' ),
357
  1 => __( 'Statistics', 'ip-geo-block' ),
@@ -359,7 +393,6 @@ class IP_Geo_Block_Admin {
359
  2 => __( 'Search', 'ip-geo-block' ),
360
  3 => __( 'Attribution', 'ip-geo-block' ),
361
  );
362
- $tab = $this->admin_tab;
363
  ?>
364
  <div class="wrap">
365
  <h2><?php echo esc_html( get_admin_page_title() ); ?></h2>
@@ -417,7 +450,7 @@ class IP_Geo_Block_Admin {
417
  3 => 'admin/includes/tab-attribution.php',
418
  );
419
 
420
- require_once( IP_GEO_BLOCK_PATH . $files[ $this->admin_tab ] );
421
  IP_Geo_Block_Admin_Tab::tab_setup( $this );
422
  }
423
 
@@ -540,7 +573,7 @@ class IP_Geo_Block_Admin {
540
  }
541
 
542
  /**
543
- * A callback function that validates the option's value.
544
  *
545
  * @param array $input The values to be validated.
546
  *
@@ -555,13 +588,15 @@ class IP_Geo_Block_Admin {
555
  $output = IP_Geo_Block::get_option();
556
  $default = IP_Geo_Block::get_default();
557
 
558
- // checkboxes not on the form (added after 2.0.0, just in case)
559
- foreach ( array( 'anonymize' ) as $key )
560
  $output[ $key ] = 0;
 
561
 
562
- // checkboxes not on the form
563
- foreach ( array( 'admin', 'ajax', 'plugins', 'themes' ) as $key )
564
  $output['validation'][ $key ] = 0;
 
565
 
566
  // restore the 'signature' that might be transformed to avoid self blocking
567
  if ( isset( $input['signature'] ) && FALSE === strpos( $input['signature'], ',' ) )
@@ -607,18 +642,16 @@ class IP_Geo_Block_Admin {
607
  }
608
 
609
  // Check providers setting
610
- if ( $error = IP_Geo_Block_Provider::diag_providers( $output[ $key ] ) ) {
611
- $this->show_setting_notice( 'error', $error );
612
- }
613
  break;
614
 
615
  case 'comment':
616
- if ( isset( $input[ $key ]['pos'] ) ) {
617
  $output[ $key ]['pos'] = (int)$input[ $key ]['pos'];
618
- }
619
- if ( isset( $input[ $key ]['msg'] ) ) {
620
  $output[ $key ]['msg'] = IP_Geo_Block_Util::kses( $input[ $key ]['msg'] );
621
- }
622
  break;
623
 
624
  case 'white_list':
@@ -675,7 +708,7 @@ class IP_Geo_Block_Admin {
675
  else {
676
  $output[ $key ][ $sub ] = ( is_int( $default[ $key ][ $sub ] ) ?
677
  (int)$input[ $key ][ $sub ] :
678
- IP_Geo_Block_Util::kses( preg_replace( '/[^-,:!*#+=\.\/\w\s]/', '', $input[ $key ][ $sub ] ), FALSE )
679
  );
680
  }
681
  }
@@ -693,7 +726,7 @@ class IP_Geo_Block_Admin {
693
  ) );
694
 
695
  // sanitize and format ip address
696
- $key = array( '/[^\d\n\.\/,:]/', '/([\s,])+/', '/(?:^,|,$)/' );
697
  $val = array( '', '$1', '' );
698
  $output['extra_ips']['white_list'] = preg_replace( $key, $val, trim( $output['extra_ips']['white_list'] ) );
699
  $output['extra_ips']['black_list'] = preg_replace( $key, $val, trim( $output['extra_ips']['black_list'] ) );
@@ -703,19 +736,40 @@ class IP_Geo_Block_Admin {
703
  array_shift( $val );
704
  $output['signature'] = preg_replace( $key, $val, trim( $output['signature'] ) );
705
 
 
 
 
 
 
706
  // reject invalid signature which potentially blocks itself
707
  $output['signature'] = implode( ',', $this->trim( $output['signature'] ) );
708
 
709
  // 2.2.5 exception : convert associative array to simple array
710
- foreach ( array( 'plugins', 'themes' ) as $key )
711
  $output['exception'][ $key ] = array_keys( $output['exception'][ $key ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
712
 
713
  return $output;
714
  }
715
 
716
  // Callback for preg_replace_callback()
717
  public function strtoupper( $matches ) {
718
- return strtoupper( $matches[0] );
719
  }
720
 
721
  // Trim extra space and comma avoiding invalid signature which potentially blocks itself
@@ -734,29 +788,28 @@ class IP_Geo_Block_Admin {
734
  * Check admin post
735
  *
736
  */
737
- private function check_admin_post( $ajax ) {
738
- $nonce = TRUE;
739
-
740
- if ( $ajax ) {
741
- $action = $this->get_ajax_action();
742
- $nonce &= IP_Geo_Block_Util::verify_nonce( IP_Geo_Block_Util::retrieve_nonce( 'nonce' ), $action );
743
- // $nonce &= check_admin_referer( $this->get_ajax_action(), 'nonce' );
744
  }
745
 
746
  $action = IP_Geo_Block::PLUGIN_NAME . '-auth-nonce';
747
  $nonce &= IP_Geo_Block_Util::verify_nonce( IP_Geo_Block_Util::retrieve_nonce( $action ), $action );
748
 
749
- if ( ! current_user_can( 'manage_options' ) || ! $nonce ) {
750
  status_header( 403 );
751
  wp_die(
752
  __( 'You do not have sufficient permissions to access this page.' ), '',
753
- array( 'response' => 403, 'back_link' => true )
754
  );
755
  }
756
  }
757
 
758
  /**
759
- * Sanitize options before saving them into DB.
760
  *
761
  */
762
  public function validate_settings( $input = array() ) {
@@ -766,10 +819,8 @@ class IP_Geo_Block_Admin {
766
  // validate setting options
767
  $options = $this->validate_options( $input );
768
 
769
- //----------------------------------------
770
  // activate rewrite rules
771
- //----------------------------------------
772
- require_once( IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-rewrite.php' );
773
  $stat = IP_Geo_Block_Admin_Rewrite::activate_rewrite_all( $options['rewrite'] );
774
 
775
  // check the status of rewrite rules
@@ -785,20 +836,18 @@ class IP_Geo_Block_Admin {
785
  $file[] = '<code>' . $dirs[ $key ] . '.htaccess</code>';
786
  }
787
 
788
- $this->show_setting_notice( 'error',
789
  sprintf( __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), implode( ', ', $file ) ) . '&nbsp;' .
790
  sprintf( _n( 'Or please refer to %s to set it manually.', 'Or please refer to %s to set them manually.', count( $file ), 'ip-geo-block' ), '<a href="http://ipgeoblock.com/codex/how-to-fix-permission-troubles.html" title="How to fix permission troubles? | IP Geo Block">How to fix permission troubles?</a>' )
791
  );
792
  }
793
 
794
- //----------------------------------------
795
- // additional installation
796
- //----------------------------------------
797
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php' );
798
  $file = IP_Geo_Block_Opts::setup_validation_timing( $options );
799
  if ( TRUE !== $file ) {
800
  $options['validation']['timing'] = 0;
801
- $this->show_setting_notice( 'error', sprintf(
802
  __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), $file
803
  ) );
804
  }
@@ -806,9 +855,6 @@ class IP_Geo_Block_Admin {
806
  // Force to finish update matching rule
807
  delete_transient( IP_Geo_Block::CRON_NAME );
808
 
809
- // register a settings error to be displayed to the user
810
- $this->show_setting_notice( 'updated', __( 'Settings saved.' ) );
811
-
812
  return $options;
813
  }
814
 
@@ -823,6 +869,8 @@ class IP_Geo_Block_Admin {
823
  // Check request origin, nonce, capability.
824
  $this->check_admin_post( TRUE );
825
 
 
 
826
  $which = isset( $_POST['which'] ) ? $_POST['which'] : NULL;
827
  switch ( isset( $_POST['cmd' ] ) ? $_POST['cmd' ] : NULL ) {
828
  case 'download':
@@ -832,14 +880,12 @@ class IP_Geo_Block_Admin {
832
 
833
  case 'search':
834
  // Get geolocation by IP
835
- require_once( IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-ajax.php' );
836
  $res = IP_Geo_Block_Admin_Ajax::search_ip( $which );
837
  break;
838
 
839
  case 'scan-code':
840
  // Fetch providers to get country code
841
- require_once( IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-ajax.php' );
842
- $res = IP_Geo_Block_Admin_Ajax::scan_country();
843
  break;
844
 
845
  case 'clear-statistics':
@@ -862,7 +908,7 @@ class IP_Geo_Block_Admin {
862
 
863
  case 'clear-logs':
864
  // Delete logs in MySQL DB
865
- $hook = array( 'comment', 'login', 'admin', 'xmlrpc' );
866
  $which = in_array( $which, $hook ) ? $which : NULL;
867
  IP_Geo_Block_Logs::clear_logs( $which );
868
  $res = array(
@@ -873,31 +919,26 @@ class IP_Geo_Block_Admin {
873
 
874
  case 'export-logs':
875
  // Export logs from MySQL DB
876
- require_once( IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-ajax.php' );
877
  IP_Geo_Block_Admin_Ajax::export_logs( $which );
878
  break;
879
 
880
  case 'restore':
881
  // Get logs from MySQL DB
882
- require_once( IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-ajax.php' );
883
  $res = IP_Geo_Block_Admin_Ajax::restore_logs( $which );
884
  break;
885
 
886
  case 'validate':
887
  // Validate settings
888
- require_once( IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-ajax.php' );
889
  IP_Geo_Block_Admin_Ajax::validate_settings( $this );
890
  break;
891
 
892
  case 'import-default':
893
  // Import initial settings
894
- require_once( IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-ajax.php' );
895
  $res = IP_Geo_Block_Admin_Ajax::settings_to_json( IP_Geo_Block::get_default() );
896
  break;
897
 
898
  case 'import-preferred':
899
  // Import preference
900
- require_once( IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-ajax.php' );
901
  $res = IP_Geo_Block_Admin_Ajax::preferred_to_json();
902
  break;
903
 
@@ -908,12 +949,16 @@ class IP_Geo_Block_Admin {
908
  $which['api_key']['GoogleMap'] = NULL;
909
  update_option( IP_Geo_Block::OPTION_NAME, $which );
910
  $res = array(
911
- 'page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_SLUG,
912
  'tab' => 'tab=2'
913
  );
914
  }
915
  break;
916
 
 
 
 
 
917
  case 'create-table':
918
  case 'delete-table':
919
  // Need to define `IP_GEO_BLOCK_DEBUG` to true
@@ -925,6 +970,7 @@ class IP_Geo_Block_Admin {
925
  $res = array(
926
  'page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME,
927
  );
 
928
  }
929
 
930
  if ( isset( $res ) ) // wp_send_json_{success,error}() @since 3.5.0
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block_Admin {
28
  * and adding a settings page and menu.
29
  */
30
  private function __construct() {
 
 
 
31
  // Load plugin text domain.
32
  add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
33
 
41
  add_filter( 'wp_prepare_revision_for_js', array( $this, 'add_revision_nonce' ), 10, 3 );
42
 
43
  // If multisite, then enque the authentication script for network admin
44
+ if ( is_multisite() ) {
45
  add_action( 'network_admin_menu', 'IP_Geo_Block::enqueue_nonce' );
46
+ }
47
  }
48
 
49
  /**
83
  *
84
  */
85
  public function enqueue_admin_assets() {
86
+ $footer = FALSE;
87
  $dependency = array( 'jquery' );
88
 
89
  // css for option page
153
  'IP_GEO_BLOCK',
154
  array(
155
  'action' => 'ip_geo_block',
156
+ 'tab' => $this->admin_tab,
157
  'url' => admin_url( 'admin-ajax.php' ),
158
  'nonce' => IP_Geo_Block_Util::create_nonce( $this->get_ajax_action() ),
159
+ 'msg' => array(
160
+ __( 'Import settings ?', 'ip-geo-block' ),
161
+ __( 'Create table ?', 'ip-geo-block' ),
162
+ __( 'Delete table ?', 'ip-geo-block' ),
163
+ __( 'Clear statistics ?', 'ip-geo-block' ),
164
+ __( 'Clear cache ?', 'ip-geo-block' ),
165
+ __( 'Clear logs ?', 'ip-geo-block' ),
166
+ __( 'This feature is available with HTML5 compliant browsers.', 'ip-geo-block' ),
167
+ ),
168
  )
169
  );
170
  wp_enqueue_script( $handle );
214
  }
215
 
216
  /**
217
+ * Show global notice.
218
  *
 
219
  */
220
  public function show_admin_notices() {
221
  $key = IP_Geo_Block::PLUGIN_NAME . '-notice';
222
+
223
  if ( FALSE !== ( $notices = get_transient( $key ) ) ) {
224
  foreach ( $notices as $msg => $type ) {
225
+ echo "\n", '<div class="notice is-dismissible ', esc_attr( $type ), '"><p>';
226
+ if ( 'updated' === $type )
227
+ echo '<strong>', IP_Geo_Block_Util::kses( $msg ), '</strong>';
228
+ else
229
+ echo '<strong>IP Geo Block:</strong> ', IP_Geo_Block_Util::kses( $msg );
230
+ echo '</p></div>', "\n";
231
  }
232
  }
233
+
234
+ // delete all admin noties
235
+ delete_transient( $key );
236
  }
237
 
238
+ /**
239
+ * Add global notice.
240
+ *
241
+ */
242
  public static function add_admin_notice( $type, $msg ) {
243
  $key = IP_Geo_Block::PLUGIN_NAME . '-notice';
244
  if ( FALSE === ( $notices = get_transient( $key ) ) )
245
  $notices = array();
246
 
247
+ // can't overwrite the existent notice
248
  if ( ! isset( $notices[ $msg ] ) ) {
249
  $notices[ $msg ] = $type;
250
  set_transient( $key, $notices, MINUTE_IN_SECONDS );
251
  }
252
  }
253
 
 
 
 
 
 
 
 
 
254
  /**
255
  * Register the administration menu into the WordPress Dashboard menu.
256
  *
257
  */
258
+ private function add_plugin_admin_menu() {
259
+ // Setup the tab number
260
+ $this->admin_tab = isset( $_GET['tab'] ) ? (int)$_GET['tab'] : 0;
261
+ $this->admin_tab = min( 4, max( 0, $this->admin_tab ) );
262
+
263
  // Add a settings page for this plugin to the Settings menu.
264
  $hook = add_options_page(
265
  __( 'IP Geo Block', 'ip-geo-block' ),
279
  *
280
  */
281
  private function diagnose_admin_screen() {
 
 
 
282
  // Check version and compatibility
283
  if ( version_compare( get_bloginfo( 'version' ), '3.7.0' ) < 0 )
284
  self::add_admin_notice( 'error', __( 'You need WordPress 3.7+.', 'ip-geo-block' ) );
285
 
286
  $settings = IP_Geo_Block::get_option();
287
+ $adminurl = 'options-general.php';
288
 
289
  // Check consistency of matching rule
290
  if ( -1 === (int)$settings['matching_rule'] ) {
291
  if ( FALSE !== get_transient( IP_Geo_Block::CRON_NAME ) ) {
292
  self::add_admin_notice( 'notice-warning', sprintf(
293
  __( 'Now downloading geolocation databases in background. After a little while, please check your country code and &#8220;<strong>Matching rule</strong>&#8221; at <a href="%s">Validation rule settings</a>.', 'ip-geo-block' ),
294
+ esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME ), $adminurl ) )
295
  ) );
296
  }
297
  else {
298
  self::add_admin_notice( 'error', sprintf(
299
  __( 'The &#8220;<strong>Matching rule</strong>&#8221; is not set properly. Please confirm it at <a href="%s">Validation rule settings</a>.', 'ip-geo-block' ),
300
+ esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME ), $adminurl ) )
301
  ) );
302
  }
303
  }
305
  // Check to finish updating matching rule
306
  elseif ( 'done' === get_transient( IP_Geo_Block::CRON_NAME ) ) {
307
  delete_transient( IP_Geo_Block::CRON_NAME );
308
+ self::add_admin_notice( 'updated ', __( 'Local database and matching rule have been updated.', 'ip-geo-block' ) );
309
  }
310
 
311
  // Check self blocking
312
  if ( 1 === (int)$settings['validation']['login'] ) {
313
  $instance = IP_Geo_Block::get_instance();
314
+ $validate = $instance->validate_ip( 'login', $settings, TRUE, FALSE, FALSE ); // skip authentication check
315
+
316
+ switch( $validate['result'] ) {
317
+ case 'limited':
318
+ self::add_admin_notice( 'error',
319
+ __( 'Once you logout, you will be unable to login again because the number of login attempts reaches the limit.', 'ip-geo-block' ) . ' ' .
320
+ sprintf(
321
+ __( 'Please execute "<strong>Clear cache</strong>" on <a href="%s">Statistics tab</a> to prevent locking yourself out.', 'ip-geo-block' ),
322
+ esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME, 'tab' => 1 ), $adminurl ) )
323
+ )
324
+ );
325
+ break;
326
 
327
+ case 'blocked':
328
+ case 'extra':
329
  self::add_admin_notice( 'error',
330
  ( $settings['matching_rule'] ?
331
  __( 'Once you logout, you will be unable to login again because your country code or IP address is in the blacklist.', 'ip-geo-block' ) :
332
  __( 'Once you logout, you will be unable to login again because your country code or IP address is not in the whitelist.', 'ip-geo-block' )
333
+ ) . ' ' .
334
  sprintf(
335
  __( 'Please check your <a href="%s">Validation rule settings</a>.', 'ip-geo-block' ),
336
+ esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME ), $adminurl ) ) . '#' . IP_Geo_Block::PLUGIN_NAME . '-settings-0'
337
  )
338
  );
339
  }
355
  *
356
  */
357
  public function setup_admin_page() {
358
+ // Avoid multiple validation.
359
+ if ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
360
+ $this->diagnose_admin_screen();
361
+ $this->add_plugin_admin_menu();
362
+ }
363
 
364
+ // Register settings page only if it is needed.
365
  if ( ( isset( $_GET ['page' ] ) && IP_Geo_Block::PLUGIN_NAME === $_GET ['page' ] ) ||
366
+ ( isset( $_POST['option_page'] ) && IP_Geo_Block::PLUGIN_NAME === $_POST['option_page'] ) ) {
367
  $this->register_settings_tab();
368
+ }
369
 
370
  // Add an action link pointing to the options page. @since 2.7
371
  else {
373
  add_filter( 'plugin_action_links_' . IP_GEO_BLOCK_BASE, array( $this, 'add_action_links' ), 10, 1 );
374
  }
375
 
376
+ // Register scripts for admin.
377
  add_action( 'admin_enqueue_scripts', array( 'IP_Geo_Block', 'enqueue_nonce' ) );
378
+
379
+ // Show admin notices at the place where it should be.
380
  add_action( 'admin_notices', array( $this, 'show_admin_notices' ) );
381
  }
382
 
385
  *
386
  */
387
  public function display_plugin_admin_page() {
388
+ $tab = $this->admin_tab;
389
  $tabs = array(
390
  0 => __( 'Settings', 'ip-geo-block' ),
391
  1 => __( 'Statistics', 'ip-geo-block' ),
393
  2 => __( 'Search', 'ip-geo-block' ),
394
  3 => __( 'Attribution', 'ip-geo-block' ),
395
  );
 
396
  ?>
397
  <div class="wrap">
398
  <h2><?php echo esc_html( get_admin_page_title() ); ?></h2>
450
  3 => 'admin/includes/tab-attribution.php',
451
  );
452
 
453
+ require_once IP_GEO_BLOCK_PATH . $files[ $this->admin_tab ];
454
  IP_Geo_Block_Admin_Tab::tab_setup( $this );
455
  }
456
 
573
  }
574
 
575
  /**
576
+ * Sanitize options before saving them into DB.
577
  *
578
  * @param array $input The values to be validated.
579
  *
588
  $output = IP_Geo_Block::get_option();
589
  $default = IP_Geo_Block::get_default();
590
 
591
+ // initialize checkboxes not in the form (added after 2.0.0, just in case)
592
+ foreach ( array( 'anonymize', 'network_wide' ) as $key ) {
593
  $output[ $key ] = 0;
594
+ }
595
 
596
+ // initialize checkboxes not in the form
597
+ foreach ( array( 'login', 'admin', 'ajax', 'plugins', 'themes', 'public' ) as $key ) {
598
  $output['validation'][ $key ] = 0;
599
+ }
600
 
601
  // restore the 'signature' that might be transformed to avoid self blocking
602
  if ( isset( $input['signature'] ) && FALSE === strpos( $input['signature'], ',' ) )
642
  }
643
 
644
  // Check providers setting
645
+ if ( $error = IP_Geo_Block_Provider::diag_providers( $output[ $key ] ) )
646
+ self::add_admin_notice( 'error', $error );
 
647
  break;
648
 
649
  case 'comment':
650
+ if ( isset( $input[ $key ]['pos'] ) )
651
  $output[ $key ]['pos'] = (int)$input[ $key ]['pos'];
652
+
653
+ if ( isset( $input[ $key ]['msg'] ) )
654
  $output[ $key ]['msg'] = IP_Geo_Block_Util::kses( $input[ $key ]['msg'] );
 
655
  break;
656
 
657
  case 'white_list':
708
  else {
709
  $output[ $key ][ $sub ] = ( is_int( $default[ $key ][ $sub ] ) ?
710
  (int)$input[ $key ][ $sub ] :
711
+ IP_Geo_Block_Util::kses( trim( $input[ $key ][ $sub ] ), FALSE )
712
  );
713
  }
714
  }
726
  ) );
727
 
728
  // sanitize and format ip address
729
+ $key = array( '/[^\w\n\.\/,:]/', '/([\s,])+/', '/(?:^,|,$)/' );
730
  $val = array( '', '$1', '' );
731
  $output['extra_ips']['white_list'] = preg_replace( $key, $val, trim( $output['extra_ips']['white_list'] ) );
732
  $output['extra_ips']['black_list'] = preg_replace( $key, $val, trim( $output['extra_ips']['black_list'] ) );
736
  array_shift( $val );
737
  $output['signature'] = preg_replace( $key, $val, trim( $output['signature'] ) );
738
 
739
+ // 3.0.0 convert country code to upper case, remove redundant spaces
740
+ $output['public']['ua_list'] = preg_replace( $key, $val, trim( $output['public']['ua_list'] ) );
741
+ $output['public']['ua_list'] = preg_replace( '/([:#]) *([!]+) *([^ ]+) *([,\n]+)/', '$1$2$3$4', $output['public']['ua_list'] );
742
+ $output['public']['ua_list'] = preg_replace_callback( '/[:#]([\w:]+)/', array( $this, 'strtoupper' ), $output['public']['ua_list'] );
743
+
744
  // reject invalid signature which potentially blocks itself
745
  $output['signature'] = implode( ',', $this->trim( $output['signature'] ) );
746
 
747
  // 2.2.5 exception : convert associative array to simple array
748
+ foreach ( array( 'plugins', 'themes' ) as $key ) {
749
  $output['exception'][ $key ] = array_keys( $output['exception'][ $key ] );
750
+ }
751
+
752
+ // 3.0.0 public : convert country code to upper case
753
+ foreach ( array( 'white_list', 'black_list' ) as $key ) {
754
+ $output['public'][ $key ] = strtoupper( preg_replace( '/\s/', '', $output['public'][ $key ] ) );
755
+ }
756
+
757
+ // 3.0.0 exception : trim extra space and comma
758
+ foreach ( array( 'admin', 'public', 'includes', 'uploads', 'languages' ) as $key ) {
759
+ if ( empty( $output['exception'][ $key ] ) ) {
760
+ $output['exception'][ $key ] = $default['exception'][ $key ];
761
+ } else {
762
+ $output['exception'][ $key ] = ( is_array( $output['exception'][ $key ] ) ?
763
+ $output['exception'][ $key ] : $this->trim( $output['exception'][ $key ] ) );
764
+ }
765
+ }
766
 
767
  return $output;
768
  }
769
 
770
  // Callback for preg_replace_callback()
771
  public function strtoupper( $matches ) {
772
+ return filter_var( $matches[1], FILTER_VALIDATE_IP ) ? $matches[0] : strtoupper( $matches[0] );
773
  }
774
 
775
  // Trim extra space and comma avoiding invalid signature which potentially blocks itself
788
  * Check admin post
789
  *
790
  */
791
+ private function check_admin_post( $ajax = FALSE ) {
792
+ if ( FALSE === $ajax ) {
793
+ // a postfix '-options' is added at settings_fields().
794
+ $nonce = check_admin_referer( IP_Geo_Block::PLUGIN_NAME . '-options' );
795
+ } else {
796
+ $nonce = IP_Geo_Block_Util::verify_nonce( IP_Geo_Block_Util::retrieve_nonce( 'nonce' ), $this->get_ajax_action() );
 
797
  }
798
 
799
  $action = IP_Geo_Block::PLUGIN_NAME . '-auth-nonce';
800
  $nonce &= IP_Geo_Block_Util::verify_nonce( IP_Geo_Block_Util::retrieve_nonce( $action ), $action );
801
 
802
+ if ( ! $nonce || ( ! current_user_can( 'manage_options' ) ) ) {
803
  status_header( 403 );
804
  wp_die(
805
  __( 'You do not have sufficient permissions to access this page.' ), '',
806
+ array( 'response' => 403, 'back_link' => TRUE )
807
  );
808
  }
809
  }
810
 
811
  /**
812
+ * Validate settings and configure some features.
813
  *
814
  */
815
  public function validate_settings( $input = array() ) {
819
  // validate setting options
820
  $options = $this->validate_options( $input );
821
 
 
822
  // activate rewrite rules
823
+ require_once IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-rewrite.php';
 
824
  $stat = IP_Geo_Block_Admin_Rewrite::activate_rewrite_all( $options['rewrite'] );
825
 
826
  // check the status of rewrite rules
836
  $file[] = '<code>' . $dirs[ $key ] . '.htaccess</code>';
837
  }
838
 
839
+ self::add_admin_notice( 'error',
840
  sprintf( __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), implode( ', ', $file ) ) . '&nbsp;' .
841
  sprintf( _n( 'Or please refer to %s to set it manually.', 'Or please refer to %s to set them manually.', count( $file ), 'ip-geo-block' ), '<a href="http://ipgeoblock.com/codex/how-to-fix-permission-troubles.html" title="How to fix permission troubles? | IP Geo Block">How to fix permission troubles?</a>' )
842
  );
843
  }
844
 
845
+ // additional configuration
846
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php';
 
 
847
  $file = IP_Geo_Block_Opts::setup_validation_timing( $options );
848
  if ( TRUE !== $file ) {
849
  $options['validation']['timing'] = 0;
850
+ self::add_admin_notice( 'error', sprintf(
851
  __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), $file
852
  ) );
853
  }
855
  // Force to finish update matching rule
856
  delete_transient( IP_Geo_Block::CRON_NAME );
857
 
 
 
 
858
  return $options;
859
  }
860
 
869
  // Check request origin, nonce, capability.
870
  $this->check_admin_post( TRUE );
871
 
872
+ require_once IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-ajax.php';
873
+
874
  $which = isset( $_POST['which'] ) ? $_POST['which'] : NULL;
875
  switch ( isset( $_POST['cmd' ] ) ? $_POST['cmd' ] : NULL ) {
876
  case 'download':
880
 
881
  case 'search':
882
  // Get geolocation by IP
 
883
  $res = IP_Geo_Block_Admin_Ajax::search_ip( $which );
884
  break;
885
 
886
  case 'scan-code':
887
  // Fetch providers to get country code
888
+ $res = IP_Geo_Block_Admin_Ajax::scan_country( $which );
 
889
  break;
890
 
891
  case 'clear-statistics':
908
 
909
  case 'clear-logs':
910
  // Delete logs in MySQL DB
911
+ $hook = array( 'comment', 'login', 'admin', 'xmlrpc', 'public' );
912
  $which = in_array( $which, $hook ) ? $which : NULL;
913
  IP_Geo_Block_Logs::clear_logs( $which );
914
  $res = array(
919
 
920
  case 'export-logs':
921
  // Export logs from MySQL DB
 
922
  IP_Geo_Block_Admin_Ajax::export_logs( $which );
923
  break;
924
 
925
  case 'restore':
926
  // Get logs from MySQL DB
 
927
  $res = IP_Geo_Block_Admin_Ajax::restore_logs( $which );
928
  break;
929
 
930
  case 'validate':
931
  // Validate settings
 
932
  IP_Geo_Block_Admin_Ajax::validate_settings( $this );
933
  break;
934
 
935
  case 'import-default':
936
  // Import initial settings
 
937
  $res = IP_Geo_Block_Admin_Ajax::settings_to_json( IP_Geo_Block::get_default() );
938
  break;
939
 
940
  case 'import-preferred':
941
  // Import preference
 
942
  $res = IP_Geo_Block_Admin_Ajax::preferred_to_json();
943
  break;
944
 
949
  $which['api_key']['GoogleMap'] = NULL;
950
  update_option( IP_Geo_Block::OPTION_NAME, $which );
951
  $res = array(
952
+ 'page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME,
953
  'tab' => 'tab=2'
954
  );
955
  }
956
  break;
957
 
958
+ case 'show-info':
959
+ $res = IP_Geo_Block_Admin_Ajax::get_wp_info();
960
+ break;
961
+
962
  case 'create-table':
963
  case 'delete-table':
964
  // Need to define `IP_GEO_BLOCK_DEBUG` to true
970
  $res = array(
971
  'page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME,
972
  );
973
+ break;
974
  }
975
 
976
  if ( isset( $res ) ) // wp_send_json_{success,error}() @since 3.5.0
admin/css/admin.css CHANGED
@@ -57,13 +57,13 @@ textarea.regular-text {
57
  }
58
 
59
  ul.ip_geo_block_settings_folding {
60
- margin: 0.3em 0;
61
  }
62
  ul.ip_geo_block_settings_folding ul {
63
  margin-bottom: 0;
64
  }
65
  ul.ip_geo_block_settings_folding li:first-child {
66
- margin-top: 0.6em;
67
  }
68
  .folding-disable {
69
  pointer-events: none;
@@ -74,6 +74,25 @@ ul.ip_geo_block_settings_folding li:first-child {
74
  font-style:oblique !important;
75
  }
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  .ip-geo-block-sup {
78
  margin-left: 0.2em;
79
  display: inline-block;
@@ -297,6 +316,10 @@ table.ip-geo-block-table {
297
  word-wrap: break-word;
298
  word-break: break-all;
299
  }
 
 
 
 
300
 
301
  /* Scan the country code */
302
  #ip-geo-block-scan-code {
@@ -334,6 +357,14 @@ table.ip-geo-block-table {
334
  position: relative;
335
  top: 1px;
336
  }
 
 
 
 
 
 
 
 
337
  #ip-geo-block-cycle {
338
  height: 16px;
339
  width: 16px;
57
  }
58
 
59
  ul.ip_geo_block_settings_folding {
60
+ margin: 0.5em 0;
61
  }
62
  ul.ip_geo_block_settings_folding ul {
63
  margin-bottom: 0;
64
  }
65
  ul.ip_geo_block_settings_folding li:first-child {
66
+ margin-top: 0.5em;
67
  }
68
  .folding-disable {
69
  pointer-events: none;
74
  font-style:oblique !important;
75
  }
76
 
77
+ ul#ip-geo-block-actions dfn {
78
+ border: none;
79
+ }
80
+ ul#ip-geo-block-actions span.dashicons {
81
+ font-size: 90%;
82
+ }
83
+ .ip-geo-block-checked {
84
+ list-style-type: disc;
85
+ }
86
+
87
+ .ip-geo-block-ip-addr {
88
+ display: inline-block;
89
+ padding-top: 5px;
90
+ }
91
+
92
+ .ip-geo-block-hide {
93
+ display: none;
94
+ }
95
+
96
  .ip-geo-block-sup {
97
  margin-left: 0.2em;
98
  display: inline-block;
316
  word-wrap: break-word;
317
  word-break: break-all;
318
  }
319
+ input#ip_geo_block_settings_filter_logs {
320
+ width: 16em;
321
+ padding-top: 3px;
322
+ }
323
 
324
  /* Scan the country code */
325
  #ip-geo-block-scan-code {
357
  position: relative;
358
  top: 1px;
359
  }
360
+ #ip-geo-block-wp-info textarea {
361
+ margin-top: 0.5em;
362
+ overflow: auto;
363
+ width: 100%;
364
+ word-wrap: normal;
365
+ word-break: normal;
366
+ white-space: pre;
367
+ }
368
  #ip-geo-block-cycle {
369
  height: 16px;
370
  width: 16px;
admin/css/admin.min.css CHANGED
@@ -1,2 +1,2 @@
1
  /* This stylesheet is used to style the admin option form of the plugin. */
2
- .ip-geo-block-desc,.ip-geo-block-loading,.ip-geo-block-result,.ip-geo-block-sup,.ip-geo-block-title,ul.ip-geo-block-list label{display:inline-block}.ip-geo-block-log .footable-row-detail-value,table.ip-geo-block-table{white-space:normal;word-wrap:break-word;word-break:break-all}#ip-geo-block-scan-code,.ip-geo-block-loading,.ip-geo-block-log *{vertical-align:middle}#ip-geo-block-cycle,.ip-geo-block-loading{background-size:16px 16px;background-position:center center;background-repeat:no-repeat}dfn{cursor:help;border-bottom:1px dotted #888}.form-table{margin:0 1em}fieldset.ip-geo-block-field{border:1px solid #ccc;padding:.35em .625em .75em 1em;margin:1.35em 0 1.5em}fieldset.ip-geo-block-field h2,fieldset.ip-geo-block-field h3{padding:0;margin:0}fieldset.ip-geo-block-field .ip-geo-block-dropdown,fieldset.ip-geo-block-field .ip-geo-block-dropup{cursor:pointer;position:relative;padding-left:1em}fieldset.ip-geo-block-field .ip-geo-block-dropdown:before,fieldset.ip-geo-block-field .ip-geo-block-dropup:before{content:'';height:0;width:0;border:.4em solid transparent;position:absolute}fieldset.ip-geo-block-field .ip-geo-block-dropup:before{border-left:.4em solid #555;left:3px;top:15%}fieldset.ip-geo-block-field .ip-geo-block-dropdown:before{border-top:.4em solid #555;left:0;top:35%}fieldset.ip-geo-block-field ul.ip-geo-block-dropup:before{top:.25em}fieldset.ip-geo-block-field ul.ip-geo-block-dropdown:before{top:.45em}fieldset.ip-geo-block-field .form-table{margin:.5em 0 0}textarea.regular-text{width:25em}ul.ip_geo_block_settings_folding{margin:.3em 0}ul.ip_geo_block_settings_folding ul{margin-bottom:0}ul.ip_geo_block_settings_folding li:first-child{margin-top:.6em}.ip-geo-block-desc,ul.ip-geo-block-list{margin-top:.25em;margin-bottom:.25em}.folding-disable{pointer-events:none;opacity:.5}.folding-inactive{opacity:.5;font-style:oblique!important}.ip-geo-block-sup{margin-left:.2em}ul.ip-geo-block-note{list-style:disc;margin-left:1em}@media screen and (min-width:782px){ul.ip-geo-block-list .code{width:15em}}.ip-geo-block-loading{background-image:url(data:image/gif;base64,R0lGODlhEAAQAPIGAAAAAMLCwkJCQpKSkmJiYoKCgv///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAGACwAAAAAEAAQAAADM2i63P4wyklrC0IEKgAQnAdOmGYFBLExwboQWcG2rlHEwTDQLUsUOd2mBxkUCgNKa+dIAAAh+QQJCgAGACwAAAIACgAOAAADLWgWIqHQCABEVLPe1R4MBOFFRFNsRUNsYDFewTC8iixvQ1EMyxjEvyBLODQkAAAh+QQJCgAGACwAAAAACgAOAAADLWi6IRJrCQCECoU0ag1xxeBARuEQ0UUU5DUM7fK+qTEUYR0EcM3Ev51uB7wAEwAh+QQJCgAGACwAAAAADgAKAAADLWi6URQrLiJEkSaM0eqrkLFtAVEEAgAIylAUQ5SuSqCFNZjhWG3zmB8wOJQkAAAh+QQJCgAGACwCAAAADgAKAAADK2hqMRMrLuekCnCU8gqBDCZ2glBcYkSUxIJJgQdaUVDOtAAAAr3oPN/llgAAIfkECQoABgAsBgAAAAoADgAAAytoEdauiz0Yx5BQFTvN2EMXWNgUFETZFIJQdERLiGgZtKohAIDQ7T0RrpEAACH5BAkKAAYALAYAAgAKAA4AAAMqaKoR+609Fie1K4zhZiibNRSg1XAQUXQPIQgE835voQgAIARqh+ummSUBACH5BAUKAAYALAIABgAOAAoAAAMsaLpsES2+F9mEddEgBFbBMGACAAiMOCrlGRBFWBQD2L0dYYjfUuQZEKynSAAAOw==);height:16px;width:16px;margin-left:1em;margin-top:.2em}.ip-geo-block-notice{color:#dd3d36}.ip-geo-block-title{width:100px}.ip-geo-block-result{color:#2786C2}#ip-geo-block-map{height:400px;margin:1em auto}.gm-style-iw{width:18em;height:auto!important;height:100%;min-height:100%:}.gm-style-iw ul{margin:.1em}.gm-style-iw li{margin:.2em}ul.ip-geo-block-statistics-countries li{width:12em;float:left;text-align:right;padding:.2em}table.ip-geo-block-statistics-table{float:right}table.ip-geo-block-statistics-table td,table.ip-geo-block-statistics-table th{width:12em;margin:0;padding:.2em;text-align:right;line-height:1.5em;word-wrap:break-word}table.ip-geo-block-statistics-table tr:nth-child(even){background-color:#f7f7f7}.ip-geo-block-log{width:100%!important}.ip-geo-block-log *{font-size:13px!important;line-height:1.5em}.ip-geo-block-log .pagination ul{border-radius:4px;display:inline-block;margin-bottom:0;margin-left:0;padding-left:0}.ip-geo-block-log .pagination ul>li{display:inline}.ip-geo-block-log .pagination ul>li:first-child>a,.ip-geo-block-log .pagination ul>li:first-child>span{border-bottom-left-radius:4px;border-left-width:1px;border-top-left-radius:4px}.ip-geo-block-log .pagination ul>li:last-child>a,.ip-geo-block-log .pagination ul>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.ip-geo-block-log .pagination ul>.disabled>a,.ip-geo-block-log .pagination ul>.disabled>a:focus,.ip-geo-block-log .pagination ul>.disabled>a:hover,.ip-geo-block-log .pagination ul>.disabled>span{background-color:transparent;color:#999;cursor:default}.ip-geo-block-log .pagination ul>li>a,.ip-geo-block-log .pagination ul>li>span{border-color:#ddd;border-image:none;border-style:solid;border-width:1px 1px 1px 0;float:left;line-height:20px;padding:4px;width:20px;text-decoration:none}.ip-geo-block-log .pagination ul>.active>a,.ip-geo-block-log .pagination ul>.active>span{color:#999;cursor:default}.ip-geo-block-log .pagination ul>.active>a,.ip-geo-block-log .pagination ul>.active>span,.ip-geo-block-log .pagination ul>li>a:focus,.ip-geo-block-log .pagination ul>li>a:hover{background-color:#f7f7f7}.ip-geo-block-log .pagination-centered{text-align:center}.ip-geo-block-log.breakpoint>tbody>tr>td>span.footable-toggle{font-size:60%!important;position:relative;top:-1px;left:2px}.ip-geo-block-log>tbody>tr>td,.ip-geo-block-log>thead>tr>th{padding:4px 0;word-wrap:break-word;width:20%}.ip-geo-block-log>tbody>tr>td:first-child,.ip-geo-block-log>thead>tr>th:first-child{width:25%}.ip-geo-block-log>tbody>tr>td:first-child+td,.ip-geo-block-log>thead>tr>th:first-child+th{width:35%}.ip-geo-block-log>tbody>tr>td:nth-child(5),.ip-geo-block-log>tbody>tr>td:nth-child(5)+td,.ip-geo-block-log>thead>tr>th:nth-child(5),.ip-geo-block-log>thead>tr>th:nth-child(5)+th{width:60%;text-align:left}@media screen and (min-width:1024px){.ip-geo-block-log>tbody>tr>td:nth-child(3),.ip-geo-block-log>tbody>tr>td:nth-child(3)+td,.ip-geo-block-log>thead>tr>th:nth-child(3),.ip-geo-block-log>thead>tr>th:nth-child(3)+th{width:10%}}.ip-geo-block-log>thead>tr>th>span.footable-sort-indicator{color:#888}.ip-geo-block-log>tbody>tr>td{text-align:center}.ip-geo-block-log>tbody>tr>td:first-child{text-align:left}.ip-geo-block-log .footable-row-detail-name,.ip-geo-block-log .footable-row-detail-row,.ip-geo-block-log .footable-row-detail-value{display:block}.ip-geo-block-log .footable-row-detail-value{padding:0 1em 4px}#ip-geo-block-code-list{display:none;margin-bottom:0}#ip-geo-block-countries,#ip-geo-block-targets{display:none}#ip-geo-block-chart-countries{height:200px}#ip-geo-block-chart-daily{height:240px}#ip_geo_block_settings_validation_plugins,#ip_geo_block_settings_validation_themes{margin-top:.5em}#ip-geo-block-back-to-top,#ip-geo-block-toggle-sections{box-shadow:none}#ip-geo-block-decode{box-shadow:none;text-decoration:none}#ip-geo-block-decode:active{position:relative;top:1px}#ip-geo-block-cycle{height:16px;width:16px;margin:0;border:none;display:inline-block;vertical-align:text-bottom;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAh1BMVEUAda2otLp+rsSHprWHr8IBd7EpfKRGhaNajqeUqrRymKuKoq5yo7prlKgAcqoVe6w8gqQmgq5Tj6wIdqsVdKIshrEMea1Uhp+Anqw0hawDdq4gfKhljqE7hqoLdKYbgbM4jLQygKUGeK8CdawQd6gVeKcad6NKkrSerrZAj7UAc6sAc6rc3NySrVGQAAAALXRSTlP//////////////////////////////////////////////////////////wCl7wv9AAACOklEQVR4Ae2W15rzKgxF9xTZzhTX9B7S/gN6/9ebYqzzGZsw/S7LV3FZgCSIwD/kQ8FVcBU8xatZUczy8luC/ABNOn0DSHEsvyZ4PgLatNCYR3efFxyhTQ8g+qQgJxgv2JefERzJXATRh4LHOUwAHD4S7OGEztRJaN86hAUxtaNWDUf/bRdDBbQMWVDAO8jn89WUhag1MeyCAh6hHofyrliLgZKggDMYgzF3eVAwFq0uCZq5KY0TezjIHDDzC0qqmkwe2ctGDOQVLMkgu+F3/rGXwb4xIPcJ6P3JgkM8wFjmfcFAWfeKQywaAz33BJVuHsUcAt09gVbuLDThAJkdR687ggLmf4gDJLIGV7BydtB8yn3u+fbtuj/LS7G9wZAd1AKK+yxJ1x+aBmibTtgCcEHGHsh0wdbOgNLek4L7lI5BigY8nWuZUQ3qGEXes9JzOKGJztPaGtLslu3lIXJirdxCWkASHGDTMqg7V1DKPplygDG61YJukLHjEErGSXqCSos6xNSOgzP3BDmsQBcchNwkoV8oiNnPA78zIefUgCdJeGIfE7LmFWXsFTCFdzTJ/RlfEMRiSGnFXXbkC7AIeqcKDu4ynseozeouKJiSEYBDwkJyIC1nRUjgblkNWp/e/1vXc2gjoAoLksYgjrrFMi0oDgjEEIDij1scBXMJSH6DAj6RNl7o8MkuLak8Co15/Pk+MRmT0xilQJV/sdWNKg2kTaeroudvNNsDjmejYjSL+e6v2/2r4Cp4BXNajr0H7hRfAAAAAElFTkSuQmCC)}
1
  /* This stylesheet is used to style the admin option form of the plugin. */
2
+ .ip-geo-block-log .footable-row-detail-value,table.ip-geo-block-table{white-space:normal;word-wrap:break-word;word-break:break-all}#ip-geo-block-scan-code,.ip-geo-block-loading,.ip-geo-block-log *{vertical-align:middle}#ip-geo-block-cycle,.ip-geo-block-loading{background-size:16px 16px;background-position:center center;background-repeat:no-repeat}dfn{cursor:help;border-bottom:1px dotted #888}.form-table{margin:0 1em}fieldset.ip-geo-block-field{border:1px solid #ccc;padding:.35em .625em .75em 1em;margin:1.35em 0 1.5em}fieldset.ip-geo-block-field h2,fieldset.ip-geo-block-field h3{padding:0;margin:0}fieldset.ip-geo-block-field .ip-geo-block-dropdown,fieldset.ip-geo-block-field .ip-geo-block-dropup{cursor:pointer;position:relative;padding-left:1em}fieldset.ip-geo-block-field .ip-geo-block-dropdown:before,fieldset.ip-geo-block-field .ip-geo-block-dropup:before{content:'';height:0;width:0;border:.4em solid transparent;position:absolute}fieldset.ip-geo-block-field .ip-geo-block-dropup:before{border-left:.4em solid #555;left:3px;top:15%}fieldset.ip-geo-block-field .ip-geo-block-dropdown:before{border-top:.4em solid #555;left:0;top:35%}fieldset.ip-geo-block-field ul.ip-geo-block-dropup:before{top:.25em}fieldset.ip-geo-block-field ul.ip-geo-block-dropdown:before{top:.45em}fieldset.ip-geo-block-field .form-table{margin:.5em 0 0}textarea.regular-text{width:25em}ul.ip_geo_block_settings_folding{margin:.5em 0}ul.ip_geo_block_settings_folding ul{margin-bottom:0}ul.ip_geo_block_settings_folding li:first-child{margin-top:.5em}.ip-geo-block-desc,ul.ip-geo-block-list{margin-top:.25em;margin-bottom:.25em}.folding-disable{pointer-events:none;opacity:.5}.folding-inactive{opacity:.5;font-style:oblique!important}ul#ip-geo-block-actions dfn{border:none}ul#ip-geo-block-actions span.dashicons{font-size:90%}.ip-geo-block-checked{list-style-type:disc}.ip-geo-block-ip-addr{display:inline-block;padding-top:5px}.ip-geo-block-hide{display:none}.ip-geo-block-desc,.ip-geo-block-loading,.ip-geo-block-result,.ip-geo-block-sup,.ip-geo-block-title,ul.ip-geo-block-list label{display:inline-block}.ip-geo-block-sup{margin-left:.2em}ul.ip-geo-block-note{list-style:disc;margin-left:1em}@media screen and (min-width:782px){ul.ip-geo-block-list .code{width:15em}}.ip-geo-block-loading{background-image:url(data:image/gif;base64,R0lGODlhEAAQAPIGAAAAAMLCwkJCQpKSkmJiYoKCgv///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAGACwAAAAAEAAQAAADM2i63P4wyklrC0IEKgAQnAdOmGYFBLExwboQWcG2rlHEwTDQLUsUOd2mBxkUCgNKa+dIAAAh+QQJCgAGACwAAAIACgAOAAADLWgWIqHQCABEVLPe1R4MBOFFRFNsRUNsYDFewTC8iixvQ1EMyxjEvyBLODQkAAAh+QQJCgAGACwAAAAACgAOAAADLWi6IRJrCQCECoU0ag1xxeBARuEQ0UUU5DUM7fK+qTEUYR0EcM3Ev51uB7wAEwAh+QQJCgAGACwAAAAADgAKAAADLWi6URQrLiJEkSaM0eqrkLFtAVEEAgAIylAUQ5SuSqCFNZjhWG3zmB8wOJQkAAAh+QQJCgAGACwCAAAADgAKAAADK2hqMRMrLuekCnCU8gqBDCZ2glBcYkSUxIJJgQdaUVDOtAAAAr3oPN/llgAAIfkECQoABgAsBgAAAAoADgAAAytoEdauiz0Yx5BQFTvN2EMXWNgUFETZFIJQdERLiGgZtKohAIDQ7T0RrpEAACH5BAkKAAYALAYAAgAKAA4AAAMqaKoR+609Fie1K4zhZiibNRSg1XAQUXQPIQgE835voQgAIARqh+ummSUBACH5BAUKAAYALAIABgAOAAoAAAMsaLpsES2+F9mEddEgBFbBMGACAAiMOCrlGRBFWBQD2L0dYYjfUuQZEKynSAAAOw==);height:16px;width:16px;margin-left:1em;margin-top:.2em}.ip-geo-block-notice{color:#dd3d36}.ip-geo-block-title{width:100px}.ip-geo-block-result{color:#2786C2}#ip-geo-block-map{height:400px;margin:1em auto}.gm-style-iw{width:18em;height:auto!important;height:100%;min-height:100%:}.gm-style-iw ul{margin:.1em}.gm-style-iw li{margin:.2em}ul.ip-geo-block-statistics-countries li{width:12em;float:left;text-align:right;padding:.2em}table.ip-geo-block-statistics-table{float:right}table.ip-geo-block-statistics-table td,table.ip-geo-block-statistics-table th{width:12em;margin:0;padding:.2em;text-align:right;line-height:1.5em;word-wrap:break-word}table.ip-geo-block-statistics-table tr:nth-child(even){background-color:#f7f7f7}.ip-geo-block-log{width:100%!important}.ip-geo-block-log *{font-size:13px!important;line-height:1.5em}.ip-geo-block-log .pagination ul{border-radius:4px;display:inline-block;margin-bottom:0;margin-left:0;padding-left:0}.ip-geo-block-log .pagination ul>li{display:inline}.ip-geo-block-log .pagination ul>li:first-child>a,.ip-geo-block-log .pagination ul>li:first-child>span{border-bottom-left-radius:4px;border-left-width:1px;border-top-left-radius:4px}.ip-geo-block-log .pagination ul>li:last-child>a,.ip-geo-block-log .pagination ul>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.ip-geo-block-log .pagination ul>.disabled>a,.ip-geo-block-log .pagination ul>.disabled>a:focus,.ip-geo-block-log .pagination ul>.disabled>a:hover,.ip-geo-block-log .pagination ul>.disabled>span{background-color:transparent;color:#999;cursor:default}.ip-geo-block-log .pagination ul>li>a,.ip-geo-block-log .pagination ul>li>span{border-color:#ddd;border-image:none;border-style:solid;border-width:1px 1px 1px 0;float:left;line-height:20px;padding:4px;width:20px;text-decoration:none}.ip-geo-block-log .pagination ul>.active>a,.ip-geo-block-log .pagination ul>.active>span{color:#999;cursor:default}.ip-geo-block-log .pagination ul>.active>a,.ip-geo-block-log .pagination ul>.active>span,.ip-geo-block-log .pagination ul>li>a:focus,.ip-geo-block-log .pagination ul>li>a:hover{background-color:#f7f7f7}.ip-geo-block-log .pagination-centered{text-align:center}.ip-geo-block-log.breakpoint>tbody>tr>td>span.footable-toggle{font-size:60%!important;position:relative;top:-1px;left:2px}.ip-geo-block-log>tbody>tr>td,.ip-geo-block-log>thead>tr>th{padding:4px 0;word-wrap:break-word;width:20%}.ip-geo-block-log>tbody>tr>td:first-child,.ip-geo-block-log>thead>tr>th:first-child{width:25%}.ip-geo-block-log>tbody>tr>td:first-child+td,.ip-geo-block-log>thead>tr>th:first-child+th{width:35%}.ip-geo-block-log>tbody>tr>td:nth-child(5),.ip-geo-block-log>tbody>tr>td:nth-child(5)+td,.ip-geo-block-log>thead>tr>th:nth-child(5),.ip-geo-block-log>thead>tr>th:nth-child(5)+th{width:60%;text-align:left}@media screen and (min-width:1024px){.ip-geo-block-log>tbody>tr>td:nth-child(3),.ip-geo-block-log>tbody>tr>td:nth-child(3)+td,.ip-geo-block-log>thead>tr>th:nth-child(3),.ip-geo-block-log>thead>tr>th:nth-child(3)+th{width:10%}}.ip-geo-block-log>thead>tr>th>span.footable-sort-indicator{color:#888}.ip-geo-block-log>tbody>tr>td{text-align:center}.ip-geo-block-log>tbody>tr>td:first-child{text-align:left}.ip-geo-block-log .footable-row-detail-name,.ip-geo-block-log .footable-row-detail-row,.ip-geo-block-log .footable-row-detail-value{display:block}.ip-geo-block-log .footable-row-detail-value{padding:0 1em 4px}input#ip_geo_block_settings_filter_logs{width:16em;padding-top:3px}#ip-geo-block-code-list{display:none;margin-bottom:0}#ip-geo-block-countries,#ip-geo-block-targets{display:none}#ip-geo-block-chart-countries{height:200px}#ip-geo-block-chart-daily{height:240px}#ip_geo_block_settings_validation_plugins,#ip_geo_block_settings_validation_themes{margin-top:.5em}#ip-geo-block-back-to-top,#ip-geo-block-toggle-sections{box-shadow:none}#ip-geo-block-decode{box-shadow:none;text-decoration:none}#ip-geo-block-decode:active{position:relative;top:1px}#ip-geo-block-wp-info textarea{margin-top:.5em;overflow:auto;width:100%;word-wrap:normal;word-break:normal;white-space:pre}#ip-geo-block-cycle{height:16px;width:16px;margin:0;border:none;display:inline-block;vertical-align:text-bottom;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAh1BMVEUAda2otLp+rsSHprWHr8IBd7EpfKRGhaNajqeUqrRymKuKoq5yo7prlKgAcqoVe6w8gqQmgq5Tj6wIdqsVdKIshrEMea1Uhp+Anqw0hawDdq4gfKhljqE7hqoLdKYbgbM4jLQygKUGeK8CdawQd6gVeKcad6NKkrSerrZAj7UAc6sAc6rc3NySrVGQAAAALXRSTlP//////////////////////////////////////////////////////////wCl7wv9AAACOklEQVR4Ae2W15rzKgxF9xTZzhTX9B7S/gN6/9ebYqzzGZsw/S7LV3FZgCSIwD/kQ8FVcBU8xatZUczy8luC/ABNOn0DSHEsvyZ4PgLatNCYR3efFxyhTQ8g+qQgJxgv2JefERzJXATRh4LHOUwAHD4S7OGEztRJaN86hAUxtaNWDUf/bRdDBbQMWVDAO8jn89WUhag1MeyCAh6hHofyrliLgZKggDMYgzF3eVAwFq0uCZq5KY0TezjIHDDzC0qqmkwe2ctGDOQVLMkgu+F3/rGXwb4xIPcJ6P3JgkM8wFjmfcFAWfeKQywaAz33BJVuHsUcAt09gVbuLDThAJkdR687ggLmf4gDJLIGV7BydtB8yn3u+fbtuj/LS7G9wZAd1AKK+yxJ1x+aBmibTtgCcEHGHsh0wdbOgNLek4L7lI5BigY8nWuZUQ3qGEXes9JzOKGJztPaGtLslu3lIXJirdxCWkASHGDTMqg7V1DKPplygDG61YJukLHjEErGSXqCSos6xNSOgzP3BDmsQBcchNwkoV8oiNnPA78zIefUgCdJeGIfE7LmFWXsFTCFdzTJ/RlfEMRiSGnFXXbkC7AIeqcKDu4ynseozeouKJiSEYBDwkJyIC1nRUjgblkNWp/e/1vXc2gjoAoLksYgjrrFMi0oDgjEEIDij1scBXMJSH6DAj6RNl7o8MkuLak8Co15/Pk+MRmT0xilQJV/sdWNKg2kTaeroudvNNsDjmejYjSL+e6v2/2r4Cp4BXNajr0H7hRfAAAAAElFTkSuQmCC)}
admin/css/fonts/LICENSE ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ Copyright 2012 Steven Usher & Brad Vincent
2
+
3
+ Released under the MIT license
4
+ You are free to use FooTable in commercial projects as long as this copyright header is left intact.
admin/css/footable.core.min.css CHANGED
@@ -1 +1,10 @@
 
 
 
 
 
 
 
 
 
1
  @font-face{font-family:'footable';src:url('fonts/footable.eot');src:url('fonts/footable.eot?#iefix') format('embedded-opentype'),url('fonts/footable.woff') format('woff'),url('fonts/footable.ttf') format('truetype'),url('fonts/footable.svg#footable') format('svg');font-weight:normal;font-style:normal}@media screen and (-webkit-min-device-pixel-ratio:0){@font-face{font-family:'footable';src:url('fonts/footable.svg#footable') format('svg');font-weight:normal;font-style:normal}}.footable{width:100%}.footable.breakpoint>tbody>tr.footable-detail-show>td{border-bottom:0}.footable.breakpoint>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e001"}.footable.breakpoint>tbody>tr:hover:not(.footable-row-detail){cursor:pointer}.footable.breakpoint>tbody>tr>td.footable-cell-detail{background:#eee;border-top:0}.footable.breakpoint>tbody>tr>td>span.footable-toggle{display:inline-block;font-family:'footable';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;padding-right:5px;font-size:14px;color:#888}.footable.breakpoint>tbody>tr>td>span.footable-toggle:before{content:"\e000"}.footable.breakpoint.toggle-circle>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e005"}.footable.breakpoint.toggle-circle>tbody>tr>td>span.footable-toggle:before{content:"\e004"}.footable.breakpoint.toggle-circle-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e003"}.footable.breakpoint.toggle-circle-filled>tbody>tr>td>span.footable-toggle:before{content:"\e002"}.footable.breakpoint.toggle-square>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e007"}.footable.breakpoint.toggle-square>tbody>tr>td>span.footable-toggle:before{content:"\e006"}.footable.breakpoint.toggle-square-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e009"}.footable.breakpoint.toggle-square-filled>tbody>tr>td>span.footable-toggle:before{content:"\e008"}.footable.breakpoint.toggle-arrow>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e00f"}.footable.breakpoint.toggle-arrow>tbody>tr>td>span.footable-toggle:before{content:"\e011"}.footable.breakpoint.toggle-arrow-small>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e013"}.footable.breakpoint.toggle-arrow-small>tbody>tr>td>span.footable-toggle:before{content:"\e015"}.footable.breakpoint.toggle-arrow-circle>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e01b"}.footable.breakpoint.toggle-arrow-circle>tbody>tr>td>span.footable-toggle:before{content:"\e01d"}.footable.breakpoint.toggle-arrow-circle-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e00b"}.footable.breakpoint.toggle-arrow-circle-filled>tbody>tr>td>span.footable-toggle:before{content:"\e00d"}.footable.breakpoint.toggle-arrow-tiny>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e01f"}.footable.breakpoint.toggle-arrow-tiny>tbody>tr>td>span.footable-toggle:before{content:"\e021"}.footable.breakpoint.toggle-arrow-alt>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e017"}.footable.breakpoint.toggle-arrow-alt>tbody>tr>td>span.footable-toggle:before{content:"\e019"}.footable.breakpoint.toggle-medium>tbody>tr>td>span.footable-toggle{font-size:18px}.footable.breakpoint.toggle-large>tbody>tr>td>span.footable-toggle{font-size:24px}.footable>thead>tr>th{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none}.footable>thead>tr>th.footable-sortable:hover{cursor:pointer}.footable>thead>tr>th.footable-sorted>span.footable-sort-indicator:before{content:"\e013"}.footable>thead>tr>th.footable-sorted-desc>span.footable-sort-indicator:before{content:"\e012"}.footable>thead>tr>th>span.footable-sort-indicator{display:inline-block;font-family:'footable';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;padding-left:5px}.footable>thead>tr>th>span.footable-sort-indicator:before{content:"\e022"}.footable>tfoot .pagination{margin:0}.footable.no-paging .hide-if-no-paging{display:none}.footable-row-detail-inner{display:table}.footable-row-detail-row{display:table-row;line-height:1.5em}.footable-row-detail-group{display:block;line-height:2em;font-size:1.2em;font-weight:bold}.footable-row-detail-name{display:table-cell;font-weight:bold;padding-right:.5em}.footable-row-detail-value{display:table-cell}.footable-odd{background-color:#f7f7f7}
1
+ /*!
2
+ * FooTable - Awesome Responsive Tables
3
+ * Version : 2.0.3
4
+ * http://fooplugins.com/plugins/footable-jquery/
5
+ *
6
+ * Copyright 2014 Steven Usher & Brad Vincent
7
+ * Released under the MIT license
8
+ * You are free to use FooTable in commercial projects as long as this copyright header is left intact.
9
+ */
10
  @font-face{font-family:'footable';src:url('fonts/footable.eot');src:url('fonts/footable.eot?#iefix') format('embedded-opentype'),url('fonts/footable.woff') format('woff'),url('fonts/footable.ttf') format('truetype'),url('fonts/footable.svg#footable') format('svg');font-weight:normal;font-style:normal}@media screen and (-webkit-min-device-pixel-ratio:0){@font-face{font-family:'footable';src:url('fonts/footable.svg#footable') format('svg');font-weight:normal;font-style:normal}}.footable{width:100%}.footable.breakpoint>tbody>tr.footable-detail-show>td{border-bottom:0}.footable.breakpoint>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e001"}.footable.breakpoint>tbody>tr:hover:not(.footable-row-detail){cursor:pointer}.footable.breakpoint>tbody>tr>td.footable-cell-detail{background:#eee;border-top:0}.footable.breakpoint>tbody>tr>td>span.footable-toggle{display:inline-block;font-family:'footable';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;padding-right:5px;font-size:14px;color:#888}.footable.breakpoint>tbody>tr>td>span.footable-toggle:before{content:"\e000"}.footable.breakpoint.toggle-circle>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e005"}.footable.breakpoint.toggle-circle>tbody>tr>td>span.footable-toggle:before{content:"\e004"}.footable.breakpoint.toggle-circle-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e003"}.footable.breakpoint.toggle-circle-filled>tbody>tr>td>span.footable-toggle:before{content:"\e002"}.footable.breakpoint.toggle-square>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e007"}.footable.breakpoint.toggle-square>tbody>tr>td>span.footable-toggle:before{content:"\e006"}.footable.breakpoint.toggle-square-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e009"}.footable.breakpoint.toggle-square-filled>tbody>tr>td>span.footable-toggle:before{content:"\e008"}.footable.breakpoint.toggle-arrow>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e00f"}.footable.breakpoint.toggle-arrow>tbody>tr>td>span.footable-toggle:before{content:"\e011"}.footable.breakpoint.toggle-arrow-small>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e013"}.footable.breakpoint.toggle-arrow-small>tbody>tr>td>span.footable-toggle:before{content:"\e015"}.footable.breakpoint.toggle-arrow-circle>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e01b"}.footable.breakpoint.toggle-arrow-circle>tbody>tr>td>span.footable-toggle:before{content:"\e01d"}.footable.breakpoint.toggle-arrow-circle-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e00b"}.footable.breakpoint.toggle-arrow-circle-filled>tbody>tr>td>span.footable-toggle:before{content:"\e00d"}.footable.breakpoint.toggle-arrow-tiny>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e01f"}.footable.breakpoint.toggle-arrow-tiny>tbody>tr>td>span.footable-toggle:before{content:"\e021"}.footable.breakpoint.toggle-arrow-alt>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e017"}.footable.breakpoint.toggle-arrow-alt>tbody>tr>td>span.footable-toggle:before{content:"\e019"}.footable.breakpoint.toggle-medium>tbody>tr>td>span.footable-toggle{font-size:18px}.footable.breakpoint.toggle-large>tbody>tr>td>span.footable-toggle{font-size:24px}.footable>thead>tr>th{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none}.footable>thead>tr>th.footable-sortable:hover{cursor:pointer}.footable>thead>tr>th.footable-sorted>span.footable-sort-indicator:before{content:"\e013"}.footable>thead>tr>th.footable-sorted-desc>span.footable-sort-indicator:before{content:"\e012"}.footable>thead>tr>th>span.footable-sort-indicator{display:inline-block;font-family:'footable';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;padding-left:5px}.footable>thead>tr>th>span.footable-sort-indicator:before{content:"\e022"}.footable>tfoot .pagination{margin:0}.footable.no-paging .hide-if-no-paging{display:none}.footable-row-detail-inner{display:table}.footable-row-detail-row{display:table-row;line-height:1.5em}.footable-row-detail-group{display:block;line-height:2em;font-size:1.2em;font-weight:bold}.footable-row-detail-name{display:table-cell;font-weight:bold;padding-right:.5em}.footable-row-detail-value{display:table-cell}.footable-odd{background-color:#f7f7f7}
admin/includes/class-admin-ajax.php CHANGED
@@ -4,19 +4,20 @@ class IP_Geo_Block_Admin_Ajax {
4
  /**
5
  * Admin ajax sub functions
6
  *
 
7
  */
8
  static public function search_ip( $which ) {
9
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-lkup.php' );
10
 
11
  // check format
12
  if ( filter_var( $ip = $_POST['ip'], FILTER_VALIDATE_IP ) ) {
13
  // get option settings and compose request headers
14
  $options = IP_Geo_Block::get_option();
15
- $args = IP_Geo_Block::get_request_headers( $options );
16
 
17
  // create object for provider and get location
18
  if ( $geo = IP_Geo_Block_API::get_instance( $which, $options ) )
19
- $res = $geo->get_location( $ip, $args );
20
  else
21
  $res = array( 'errorMessage' => 'Unknown service.' );
22
  }
@@ -25,8 +26,12 @@ class IP_Geo_Block_Admin_Ajax {
25
  $res = array( 'errorMessage' => 'Invalid IP address.' );
26
  }
27
 
28
- if ( empty( $res['errorMessage'] ) )
 
29
  $res['host'] = IP_Geo_Block_Lkup::gethostbyaddr( $ip );
 
 
 
30
 
31
  return $res;
32
  }
@@ -34,8 +39,9 @@ class IP_Geo_Block_Admin_Ajax {
34
  /**
35
  * Get country code from providers
36
  *
 
37
  */
38
- static public function scan_country() {
39
  // scan all the country code using selected APIs
40
  $ip = IP_Geo_Block::get_ip_address();
41
  $options = IP_Geo_Block::get_option();
@@ -82,6 +88,7 @@ class IP_Geo_Block_Admin_Ajax {
82
  /**
83
  * Export logs from MySQL DB
84
  *
 
85
  */
86
  static public function export_logs( $which ) {
87
  $csv = '';
@@ -110,6 +117,7 @@ class IP_Geo_Block_Admin_Ajax {
110
  /**
111
  * Restore logs from MySQL DB
112
  *
 
113
  */
114
  static public function restore_logs( $which ) {
115
  // if js is slow then limit the number of rows
@@ -163,7 +171,7 @@ class IP_Geo_Block_Admin_Ajax {
163
  if ( NULL === ( $data = json_decode( $json, TRUE ) ) )
164
  wp_die( 'Illegal JSON format.', '', array( 'response' => 500, 'back_link' => TRUE ) ); // @Since 2.0.4
165
 
166
- // Sanitize to fit the type of each field
167
  $temp = self::json_to_settings( $data );
168
 
169
  // Integrate posted data into current settings because if can be a part of hole data
@@ -238,8 +246,10 @@ class IP_Geo_Block_Admin_Ajax {
238
  '[extra_ips][white_list]',
239
  '[extra_ips][black_list]',
240
  '[signature]',
241
- '[response_code]',
242
  '[login_fails]',
 
 
 
243
  '[validation][timing]', // 2.2.9
244
  '[validation][proxy]',
245
  '[validation][comment]',
@@ -256,10 +266,32 @@ class IP_Geo_Block_Admin_Ajax {
256
  '[validation][ajax][2]',
257
  '[validation][plugins]',
258
  '[validation][themes]',
 
 
 
 
259
  '[rewrite][plugins]',
260
  '[rewrite][themes]',
 
 
 
261
  '[exception][plugins][*]', // 2.2.5
262
  '[exception][themes][*]', // 2.2.5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  '[providers][Maxmind]',
264
  '[providers][IP2Location]',
265
  '[providers][freegeoip.net]',
@@ -277,12 +309,14 @@ class IP_Geo_Block_Admin_Ajax {
277
  '[validation][postkey]',
278
  '[update][auto]',
279
  '[anonymize]',
 
280
  '[cache_hold]',
281
  '[cache_time]',
282
  '[comment][pos]',
283
  '[comment][msg]',
284
  '[clean_uninstall]',
285
  '[api_key][GoogleMap]', // 2.2.7
 
286
  );
287
  $json = array();
288
  $prfx = IP_Geo_Block::OPTION_NAME;
@@ -317,7 +351,7 @@ class IP_Geo_Block_Admin_Ajax {
317
  foreach ( $input[ $m[1] ][ $m[2] ] as $val ) {
318
  $json[ $prfx.'['.$m[1].']['.$m[2].']'.'['.$val.']' ] = 1;
319
  }
320
- } else {
321
  $json[ $prfx.'['.$m[1].']['.$m[2].']' ] = implode( ',', $input[ $m[1] ][ $m[2] ] );
322
  }
323
  }
@@ -394,9 +428,79 @@ class IP_Geo_Block_Admin_Ajax {
394
  // Fallback function for PHP 5.3 and under
395
  static private function convert_encoding( $matches ) {
396
  return mb_convert_encoding(
397
- pack( 'H*', str_replace( '\\u', '', $matches[0] ) ),
398
- 'UTF-8', 'UTF-16'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
  }
401
 
402
  }
4
  /**
5
  * Admin ajax sub functions
6
  *
7
+ * @param string $which name of the geolocation api provider
8
  */
9
  static public function search_ip( $which ) {
10
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-lkup.php';
11
 
12
  // check format
13
  if ( filter_var( $ip = $_POST['ip'], FILTER_VALIDATE_IP ) ) {
14
  // get option settings and compose request headers
15
  $options = IP_Geo_Block::get_option();
16
+ $tmp = IP_Geo_Block::get_request_headers( $options );
17
 
18
  // create object for provider and get location
19
  if ( $geo = IP_Geo_Block_API::get_instance( $which, $options ) )
20
+ $res = $geo->get_location( $ip, $tmp );
21
  else
22
  $res = array( 'errorMessage' => 'Unknown service.' );
23
  }
26
  $res = array( 'errorMessage' => 'Invalid IP address.' );
27
  }
28
 
29
+ if ( empty( $res['errorMessage'] ) ) {
30
+ $tmp = microtime( TRUE );
31
  $res['host'] = IP_Geo_Block_Lkup::gethostbyaddr( $ip );
32
+ $tmp = microtime( TRUE ) - $tmp;
33
+ $res['DNS lookup'] = sprintf( '%.1f [msec]', $tmp * 1000.0 );
34
+ }
35
 
36
  return $res;
37
  }
39
  /**
40
  * Get country code from providers
41
  *
42
+ * @param string $which 'ip_client' or 'ip_server'
43
  */
44
+ static public function scan_country( $which ) {
45
  // scan all the country code using selected APIs
46
  $ip = IP_Geo_Block::get_ip_address();
47
  $options = IP_Geo_Block::get_option();
88
  /**
89
  * Export logs from MySQL DB
90
  *
91
+ * @param string $which 'comment', 'xmlrpc', 'login', 'admin' or 'public'
92
  */
93
  static public function export_logs( $which ) {
94
  $csv = '';
117
  /**
118
  * Restore logs from MySQL DB
119
  *
120
+ * @param string $which 'comment', 'xmlrpc', 'login', 'admin' or 'public'
121
  */
122
  static public function restore_logs( $which ) {
123
  // if js is slow then limit the number of rows
171
  if ( NULL === ( $data = json_decode( $json, TRUE ) ) )
172
  wp_die( 'Illegal JSON format.', '', array( 'response' => 500, 'back_link' => TRUE ) ); // @Since 2.0.4
173
 
174
+ // Convert json to setting data
175
  $temp = self::json_to_settings( $data );
176
 
177
  // Integrate posted data into current settings because if can be a part of hole data
246
  '[extra_ips][white_list]',
247
  '[extra_ips][black_list]',
248
  '[signature]',
 
249
  '[login_fails]',
250
+ '[response_code]',
251
+ '[response_msg]', // 3.0.0
252
+ '[redirect_uri]', // 3.0.0
253
  '[validation][timing]', // 2.2.9
254
  '[validation][proxy]',
255
  '[validation][comment]',
266
  '[validation][ajax][2]',
267
  '[validation][plugins]',
268
  '[validation][themes]',
269
+ '[validation][includes]', // 3.0.0
270
+ '[validation][uploads]', // 3.0.0
271
+ '[validation][languages]', // 3.0.0
272
+ '[validation][public]', // 3.0.0
273
  '[rewrite][plugins]',
274
  '[rewrite][themes]',
275
+ '[rewrite][includes]', // 3.0.0
276
+ '[rewrite][uploads]', // 3.0.0
277
+ '[rewrite][languages]', // 3.0.0
278
  '[exception][plugins][*]', // 2.2.5
279
  '[exception][themes][*]', // 2.2.5
280
+ '[exception][admin][$]', // 3.0.0
281
+ '[exception][public][$]', // 3.0.0
282
+ '[exception][includes][$]', // 3.0.0
283
+ '[exception][uploads][$]', // 3.0.0
284
+ '[exception][languages][$]', // 3.0.0
285
+ '[public][matching_rule]', // 3.0.0
286
+ '[public][white_list]', // 3.0.0
287
+ '[public][black_list]', // 3.0.0
288
+ '[public][target_rule]', // 3.0.0
289
+ '[public][target_pages][$]', // 3.0.0
290
+ '[public][target_posts][$]', // 3.0.0
291
+ '[public][target_cates][$]', // 3.0.0
292
+ '[public][target_tags][$]', // 3.0.0
293
+ '[public][ua_list]', // 3.0.0
294
+ '[public][simulate]', // 3.0.0
295
  '[providers][Maxmind]',
296
  '[providers][IP2Location]',
297
  '[providers][freegeoip.net]',
309
  '[validation][postkey]',
310
  '[update][auto]',
311
  '[anonymize]',
312
+ '[cache_time_gc]', // 3.0.0
313
  '[cache_hold]',
314
  '[cache_time]',
315
  '[comment][pos]',
316
  '[comment][msg]',
317
  '[clean_uninstall]',
318
  '[api_key][GoogleMap]', // 2.2.7
319
+ '[network_wide]', // 3.0.0
320
  );
321
  $json = array();
322
  $prfx = IP_Geo_Block::OPTION_NAME;
351
  foreach ( $input[ $m[1] ][ $m[2] ] as $val ) {
352
  $json[ $prfx.'['.$m[1].']['.$m[2].']'.'['.$val.']' ] = 1;
353
  }
354
+ } elseif ( is_array( $input[ $m[1] ][ $m[2] ] ) ) {
355
  $json[ $prfx.'['.$m[1].']['.$m[2].']' ] = implode( ',', $input[ $m[1] ][ $m[2] ] );
356
  }
357
  }
428
  // Fallback function for PHP 5.3 and under
429
  static private function convert_encoding( $matches ) {
430
  return mb_convert_encoding(
431
+ pack( 'H*', str_replace( '\\u', '', $matches[0] ) ), 'UTF-8', 'UTF-16'
432
+ );
433
+ }
434
+
435
+ static public function get_wp_info() {
436
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-lkup.php';
437
+
438
+ // DNS reverse lookup
439
+ $key = microtime( TRUE );
440
+ $val = IP_Geo_Block_Lkup::gethostbyaddr( '8.8.8.8' );
441
+ $key = microtime( TRUE ) - $key;
442
+
443
+ // Server, PHP, WordPress
444
+ $res = array(
445
+ 'Server:' => $_SERVER['SERVER_SOFTWARE'],
446
+ 'PHP:' => PHP_VERSION,
447
+ 'WordPress:' => $GLOBALS['wp_version'],
448
+ 'Multisite:' => is_multisite() ? 'yes' : 'no',
449
+ 'Zlib:' => function_exists( 'gzopen' ) ? 'yes' : 'no',
450
+ 'ZipArchive:' => class_exists( 'ZipArchive' ) ? 'yes' : 'no',
451
+ 'BC Math:' => (extension_loaded('gmp') ? 'gmp ' : '') . (function_exists('bcadd') ? 'yes' : 'no'),
452
+ 'mb_strcut:' => function_exists( 'mb_strcut' ) ? 'yes' : 'no',
453
+ 'DNS lookup:' => ('8.8.8.8' !== $val ? 'available' : 'n/a') . sprintf( ' [%.1f msec]', $key * 1000.0 ),
454
  );
455
+
456
+ // Child and parent themes
457
+ $activated = wp_get_theme(); // @since 3.4.0
458
+ $res += array( esc_html( $activated->get( 'Name' ) ) => esc_html( $activated->get( 'Version' ) ) );
459
+
460
+ if ( $installed = $activated->get( 'Template' ) ) {
461
+ $activated = wp_get_theme( $installed );
462
+ $res += array( esc_html( $activated->get( 'Name' ) ) => esc_html( $activated->get( 'Version' ) ) );
463
+ }
464
+
465
+ // Plugins
466
+ $installed = get_plugins(); // @since 1.5.0
467
+ $activated = get_site_option( 'active_sitewide_plugins' ); // @since 2.8.0
468
+ ! is_array( $activated ) and $activated = array();
469
+ $activated = array_merge( $activated, array_fill_keys( get_option( 'active_plugins' ), TRUE ) );
470
+
471
+ foreach ( $installed as $key => $val ) {
472
+ if ( isset( $activated[ $key ] ) ) {
473
+ $res += array(
474
+ esc_html( $val['Name'] ) => esc_html( $val['Version'] )
475
+ );
476
+ }
477
+ }
478
+
479
+ // Logs (hook, time, ip, code, result, method, user_agent, headers, data)
480
+ $installed = IP_Geo_Block_Logs::search_logs( IP_Geo_Block::get_ip_address() );
481
+
482
+ foreach ( array_reverse( $installed ) as $val ) {
483
+ // hide port and nonce
484
+ $method = preg_replace( '/\[\d+\]/', '', $val['method'] );
485
+ $method = preg_replace( '/(' . IP_Geo_Block::PLUGIN_NAME . '-auth-nonce)(?:=|%3D)([\w]+)/', '$1=...', $method );
486
+
487
+ // add post data
488
+ $query = array();
489
+ foreach ( explode( ',', $val['data'] ) as $str ) {
490
+ if ( FALSE !== strpos( $str, '=' ) )
491
+ $query[] = $str;
492
+ }
493
+
494
+ if ( ! empty( $query ) )
495
+ $method .= '(' . implode( ',', $query ) . ')';
496
+
497
+ $res += array(
498
+ esc_html( IP_Geo_Block_Util::localdate( $val['time'], 'Y-m-d H:i:s' ) ) =>
499
+ esc_html( str_pad( $val['result'], 8 ) . $method )
500
+ );
501
+ }
502
+
503
+ return $res;
504
  }
505
 
506
  }
admin/includes/tab-accesslog.php CHANGED
@@ -24,6 +24,23 @@ if ( $settings['validation']['reclogs'] ) :
24
  $option_slug
25
  );
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  $field = 'clear_logs';
28
  add_settings_field(
29
  $option_name.'_'.$field,
@@ -89,17 +106,18 @@ endif;
89
  */
90
  public static function list_accesslog() {
91
  // same as in tab-settings.php
92
- $dfn = __( '<dfn title="Validate request to %s.">%s</dfn>', 'ip-geo-block' );
93
  $target = array(
94
- 'comment' => sprintf( $dfn, 'wp-comments-post.php', __( 'Comment post', 'ip-geo-block' ) ),
95
- 'xmlrpc' => sprintf( $dfn, 'xmlrpc.php', __( 'XML-RPC', 'ip-geo-block' ) ),
96
- 'login' => sprintf( $dfn, 'wp-login.php', __( 'Login form', 'ip-geo-block' ) ),
97
- 'admin' => sprintf( $dfn, 'wp-admin/*.php', __( 'Admin area', 'ip-geo-block' ) ),
 
98
  );
99
 
100
  foreach ( $target as $key => $val ) {
101
  echo '<h4>', $val, '</h4>', "\n";
102
- echo '<table class="fixed ', IP_Geo_Block::PLUGIN_NAME, '-log" data-page-size="10" data-limit-navigation="5"><thead><tr>', "\n";
103
  echo '<th data-type="numeric">', __( 'Date', 'ip-geo-block' ), '</th>', "\n";
104
  echo '<th>', __( 'IP address', 'ip-geo-block' ), '</th>', "\n";
105
  echo '<th>', __( 'Code', 'ip-geo-block' ), '</th>', "\n";
24
  $option_slug
25
  );
26
 
27
+ // footable filter
28
+ $field = 'filter_logs';
29
+ add_settings_field(
30
+ $option_name.'_'.$field,
31
+ __( 'Filter logs', 'ip-geo-block' ),
32
+ array( $context, 'callback_field' ),
33
+ $option_slug,
34
+ $section,
35
+ array(
36
+ 'type' => 'text',
37
+ 'option' => $option_name,
38
+ 'field' => $field,
39
+ 'value' => '',
40
+ 'after' => '<a class="button button-secondary" id="ip-geo-block-reset-filter" title="' . __( 'Reset', 'ip-geo-block' ) . '" href="javascript:void(0)">'. __( 'Reset', 'ip-geo-block' ) . '</a>',
41
+ )
42
+ );
43
+
44
  $field = 'clear_logs';
45
  add_settings_field(
46
  $option_name.'_'.$field,
106
  */
107
  public static function list_accesslog() {
108
  // same as in tab-settings.php
109
+ $dfn = __( '<dfn title="Validation log of request to %s.">%s</dfn>', 'ip-geo-block' );
110
  $target = array(
111
+ 'comment' => sprintf( $dfn, 'wp-comments-post.php', __( 'Comment post', 'ip-geo-block' ) ),
112
+ 'xmlrpc' => sprintf( $dfn, 'xmlrpc.php', __( 'XML-RPC', 'ip-geo-block' ) ),
113
+ 'login' => sprintf( $dfn, 'wp-login.php', __( 'Login form', 'ip-geo-block' ) ),
114
+ 'admin' => sprintf( $dfn, 'wp-admin/*.php', __( 'Admin area', 'ip-geo-block' ) ),
115
+ 'public' => sprintf( $dfn, __( 'public facing pages', 'ip-geo-block' ), __( 'Public facing pages', 'ip-geo-block' ) ),
116
  );
117
 
118
  foreach ( $target as $key => $val ) {
119
  echo '<h4>', $val, '</h4>', "\n";
120
+ echo '<table class="fixed ', IP_Geo_Block::PLUGIN_NAME, '-log" data-page-size="10" data-limit-navigation="5" data-filter="#', IP_Geo_Block::OPTION_NAME, '_filter_logs" data-filter-text-only="true"><thead><tr>', "\n";
121
  echo '<th data-type="numeric">', __( 'Date', 'ip-geo-block' ), '</th>', "\n";
122
  echo '<th>', __( 'IP address', 'ip-geo-block' ), '</th>', "\n";
123
  echo '<th>', __( 'Code', 'ip-geo-block' ), '</th>', "\n";
admin/includes/tab-settings.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php' );
3
- require_once( IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-rewrite.php' );
4
 
5
  if ( ! function_exists( 'get_plugins' ) )
6
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
7
 
8
  class IP_Geo_Block_Admin_Tab {
9
 
@@ -13,9 +13,6 @@ class IP_Geo_Block_Admin_Tab {
13
  $option_name = IP_Geo_Block::OPTION_NAME; // 'ip_geo_block_settings'
14
  $options = IP_Geo_Block::get_option();
15
 
16
- // Get the country code
17
- $key = IP_Geo_Block::get_geolocation();
18
-
19
  /**
20
  * Register a setting and its sanitization callback.
21
  * @link http://codex.wordpress.org/Function_Reference/register_setting
@@ -66,10 +63,14 @@ class IP_Geo_Block_Admin_Tab {
66
  * @param string $section The section of the settings page in which to show the box.
67
  * @param array $args Additional arguments that are passed to the $callback function.
68
  */
69
- $field = 'ip_country';
 
 
 
 
70
  add_settings_field(
71
  $option_name.'_'.$field,
72
- __( '<dfn title="You can confirm the appropriate Geolocation APIs and country code by referring &#8220;Scan your country code&#8221;.">Your IP address / Country</dfn>', 'ip-geo-block' ),
73
  array( $context, 'callback_field' ),
74
  $option_slug,
75
  $section,
@@ -77,8 +78,8 @@ class IP_Geo_Block_Admin_Tab {
77
  'type' => 'html',
78
  'option' => $option_name,
79
  'field' => $field,
80
- 'value' => esc_html( $key['ip'] . ' / ' . ( $key['code'] && isset( $key['provider'] ) ? $key['code'] . ' (' . $key['provider'] . ')' : __( 'UNKNOWN', 'ip-geo-block' ) ) ),
81
- 'after' => '&nbsp;<a class="button button-secondary" id="ip-geo-block-scan-code" title="' . __( 'Scan all the APIs you selected at Geolocation API settings', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Scan your country code', 'ip-geo-block' ) . '</a><div id="ip-geo-block-scanning"></div>',
82
  )
83
  );
84
 
@@ -91,8 +92,8 @@ class IP_Geo_Block_Admin_Tab {
91
 
92
  $rule_desc = array(
93
  __( 'Please select either &#8220;Whitelist&#8221; or &#8220;Blacklist&#8221;.', 'ip-geo-block' ),
94
- __( '<dfn title="&#8220;Block by country&#8221; will be bypassed in case of empty. All the countries will be blocked in case you put &#8220;XX&#8221; only.">Whitelist of country code</dfn>', 'ip-geo-block' ) . '<br/>(<a class="ip-geo-block-link" href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements" title="ISO 3166-1 alpha-2 - Wikipedia, the free encyclopedia" target=_blank>ISO 3166-1 alpha-2</a>)',
95
- __( '<dfn title="&#8220;Block by country&#8221; will be bypassed in case of empty. Please consider to include &#8220;ZZ&#8221; which means UNKNOWN country.">Blacklist of country code</dfn>', 'ip-geo-block' ) . '<br/>(<a class="ip-geo-block-link" href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements" title="ISO 3166-1 alpha-2 - Wikipedia, the free encyclopedia" target=_blank>ISO 3166-1 alpha-2</a>)',
96
  );
97
 
98
  $comma = array(
@@ -163,7 +164,7 @@ class IP_Geo_Block_Admin_Tab {
163
  add_settings_field(
164
  $option_name.'_'.$field.'_'.$key,
165
  __( '<dfn title="e.g. &#8220;192.0.64.0/18&#8221; for Jetpack server, &#8220;69.46.36.0/27&#8221; for WordFence server">Whitelist of extra IP addresses prior to country code</dfn>', 'ip-geo-block' ) .
166
- ' (<a class="ip-geo-block-link" href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" title="Classless Inter-Domain Routing - Wikipedia, the free encyclopedia" target=_blank>CIDR</a>)',
167
  array( $context, 'callback_field' ),
168
  $option_slug,
169
  $section,
@@ -182,7 +183,7 @@ class IP_Geo_Block_Admin_Tab {
182
  add_settings_field(
183
  $option_name.'_'.$field.'_'.$key,
184
  __( '<dfn title="Server level access control is recommended (e.g. .htaccess).">Blacklist of extra IP addresses prior to country code</dfn>', 'ip-geo-block' ) .
185
- ' (<a class="ip-geo-block-link" href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" title="Classless Inter-Domain Routing - Wikipedia, the free encyclopedia" target=_blank>CIDR</a>)',
186
  array( $context, 'callback_field' ),
187
  $option_slug,
188
  $section,
@@ -236,7 +237,7 @@ class IP_Geo_Block_Admin_Tab {
236
  $field = 'response_code';
237
  add_settings_field(
238
  $option_name.'_'.$field,
239
- sprintf( __( '<dfn title="You can put your original 403.php and so on into your theme directory.">Response code</dfn> %s', 'ip-geo-block' ), '(<a class="ip-geo-block-link" href="http://tools.ietf.org/html/rfc2616#section-10" title="RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1" target=_blank>RFC 2616</a>)' ),
240
  array( $context, 'callback_field' ),
241
  $option_slug,
242
  $section,
@@ -247,9 +248,9 @@ class IP_Geo_Block_Admin_Tab {
247
  'value' => $options[ $field ],
248
  'list' => array(
249
  200 => '200 OK',
250
- 205 => '205 Reset Content',
251
  301 => '301 Moved Permanently',
252
  302 => '302 Found',
 
253
  307 => '307 Temporary Redirect',
254
  400 => '400 Bad Request',
255
  403 => '403 Forbidden',
@@ -262,6 +263,40 @@ class IP_Geo_Block_Admin_Tab {
262
  )
263
  );
264
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  // Max number of failed login attempts per IP address
266
  $field = 'login_fails';
267
  add_settings_field(
@@ -276,6 +311,7 @@ class IP_Geo_Block_Admin_Tab {
276
  'field' => $field,
277
  'value' => $options[ $field ],
278
  'list' => array(
 
279
  0 => 0,
280
  1 => 1,
281
  3 => 3,
@@ -309,19 +345,19 @@ class IP_Geo_Block_Admin_Tab {
309
  ),
310
  'desc' => array(
311
  0 => __( 'Validate at &#8220;init&#8221; action hook in the same manner as typical plugins.', 'ip-geo-block' ),
312
- 1 => __( 'Validate at an earlier phase than other typical plugins. It can reduce load on server but has <a href=\'http://www.ipgeoblock.com/codex/validation-timing.html\' title=\'Validation timing | IP Geo Block\'>some restrictions</a>.', 'ip-geo-block' ),
313
  ),
314
  'after' => '<div class="ip-geo-block-desc"></div>',
315
  )
316
  );
317
 
318
  /*----------------------------------------*
319
- * Validation target settings
320
  *----------------------------------------*/
321
  $section = $plugin_slug . '-validation-target';
322
  add_settings_section(
323
  $section,
324
- __( 'Validation target settings', 'ip-geo-block' ),
325
  array( __CLASS__, 'note_target' ),
326
  $option_slug
327
  );
@@ -329,10 +365,12 @@ class IP_Geo_Block_Admin_Tab {
329
  // same as in tab-accesslog.php
330
  $dfn = __( '<dfn title="Validate request to %s.">%s</dfn>', 'ip-geo-block' );
331
  $target = array(
332
- 'comment' => sprintf( $dfn, 'wp-comments-post.php', __( 'Comment post', 'ip-geo-block' ) ),
333
- 'xmlrpc' => sprintf( $dfn, 'xmlrpc.php', __( 'XML-RPC', 'ip-geo-block' ) ),
334
- 'login' => sprintf( $dfn, 'wp-login.php', __( 'Login form', 'ip-geo-block' ) ),
335
- 'admin' => sprintf( $dfn, 'wp-admin/*.php', __( 'Admin area', 'ip-geo-block' ) ),
 
 
336
  );
337
 
338
  // Comment post
@@ -412,6 +450,7 @@ class IP_Geo_Block_Admin_Tab {
412
  1 => __( 'Block by country', 'ip-geo-block' ),
413
  2 => __( 'Prevent Zero-day Exploit', 'ip-geo-block' ),
414
  );
 
415
  $desc = array(
416
  1 => __( 'It will block a request related to the services for both public facing pages and the dashboard.', 'ip-geo-block' ),
417
  2 => __( 'Regardless of the country code, it will block a malicious request related to the services only for the dashboard.', 'ip-geo-block' ),
@@ -436,6 +475,50 @@ class IP_Geo_Block_Admin_Tab {
436
  )
437
  );
438
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  // Admin ajax/post
440
  $key = 'ajax';
441
  $val = esc_html( substr( IP_Geo_Block::$wp_path['admin'], 1 ) );
@@ -453,13 +536,22 @@ class IP_Geo_Block_Admin_Tab {
453
  'value' => $options[ $field ][ $key ],
454
  'list' => $list,
455
  'desc' => $desc,
 
 
 
 
 
 
 
 
 
456
  )
457
  );
458
 
459
  array_unshift( $list, __( 'Disable', 'ip-geo-block' ) );
460
  $desc = array(
461
  __( 'Regardless of the country code, it will block a malicious request to <code>%s&hellip;/*.php</code>.', 'ip-geo-block' ),
462
- __( 'It configures &#8220%s&#8221 to validate a request to the PHP file which does not load WordPress core.', 'ip-geo-block' ),
463
  __( '<dfn title="Select the item which causes undesired blocking in order to exclude from the validation target. Grayed item indicates &#8220;INACTIVE&#8221;.">Exceptions</dfn>', 'ip-geo-block' ),
464
  );
465
 
@@ -576,6 +668,220 @@ class IP_Geo_Block_Admin_Tab {
576
  )
577
  );
578
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  /*----------------------------------------*
580
  * Geolocation service settings
581
  *----------------------------------------*/
@@ -613,7 +919,7 @@ class IP_Geo_Block_Admin_Tab {
613
  if ( empty( $providers ) ) {
614
  $context->add_admin_notice( 'error',
615
  sprintf(
616
- __( 'Please download <a href="https://github.com/tokkonopapa/WordPress-IP-Geo-API/archive/master.zip" title="Download the contents of tokkonopapa/WordPress-IP-Geo-API as a zip file">ZIP file</a> from <a href="https://github.com/tokkonopapa/WordPress-IP-Geo-API" title="tokkonopapa/WordPress-IP-Geo-API - GitHub">WordPress-IP-Geo-API</a> and upload <code>ip-geo-api</code> to <code>%s</code> with write permission.', 'ip-geo-block' ),
617
  apply_filters( 'ip-geo-block-api-dir', basename( WP_CONTENT_DIR ) )
618
  )
619
  );
@@ -685,7 +991,7 @@ class IP_Geo_Block_Admin_Tab {
685
  add_settings_section(
686
  $section,
687
  __( 'Record settings', 'ip-geo-block' ),
688
- NULL,
689
  $option_slug
690
  );
691
 
@@ -803,7 +1109,7 @@ endif;
803
  $section = $plugin_slug . '-cache';
804
  add_settings_section(
805
  $section,
806
- __( 'Cache settings', 'ip-geo-block' ),
807
  NULL,
808
  $option_slug
809
  );
@@ -824,6 +1130,23 @@ endif;
824
  )
825
  );
826
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
827
  // Number of entries
828
  $field = 'cache_hold';
829
  add_settings_field(
@@ -839,6 +1162,7 @@ endif;
839
  'value' => $options[ $field ],
840
  )
841
  );
 
842
 
843
  /*----------------------------------------*
844
  * Submission settings
@@ -908,8 +1232,7 @@ endif;
908
  // Google Maps API key
909
  $field = 'api_key';
910
  $key = 'GoogleMap';
911
- if ( 'default' !== $options[ $field ][ $key ] or
912
- defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ) {
913
  add_settings_field(
914
  $option_name.'_'.$field,
915
  __( '<dfn title="Valid key for Google Maps JavaScript API">Google Maps API key</dfn>', 'ip-geo-block' ),
@@ -956,8 +1279,8 @@ endif;
956
  array(
957
  'type' => 'none',
958
  'before' =>
959
- '<a class="button button-secondary" id="ip-geo-block-default" title="' . __( 'Import the default settings to revert to the &#8220;Right after installing&#8221; state', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Default settings', 'ip-geo-block' ) . '</a>&nbsp;' .
960
- '<a class="button button-secondary" id="ip-geo-block-preferred" title="' . __( 'Import the preferred settings mainly for the &#8220;Validation target settings&#8221;', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Best practice', 'ip-geo-block' ) . '</a>',
961
  'after' => '<div id="ip-geo-block-pre-defined"></div>',
962
  )
963
  );
@@ -997,6 +1320,22 @@ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ):
997
  );
998
  endif;
999
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1000
  }
1001
 
1002
  /**
@@ -1006,8 +1345,8 @@ endif;
1006
  public static function note_target() {
1007
  echo
1008
  '<ul class="ip-geo-block-note">', "\n",
1009
- '<li>', __( 'To enhance the protection ability, please refer to &#8220;<a href="http://www.ipgeoblock.com/codex/the-best-practice-of-target-settings.html" title="The best practice of target settings | IP Geo Block">The best practice of target settings</a>&#8221;.', 'ip-geo-block' ), '</li>', "\n",
1010
- '<li>', __( 'If you have any troubles with these, please open an issue at <a class="ip-geo-block-link" href="http://wordpress.org/support/plugin/ip-geo-block" title="WordPress &#8250; Support &raquo; IP Geo Block" target=_blank>support forum</a>.', 'ip-geo-block' ), '</li>', "\n",
1011
  '</ul>', "\n";
1012
  }
1013
 
@@ -1019,4 +1358,19 @@ endif;
1019
  '</ul>', "\n";
1020
  }
1021
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1022
  }
1
  <?php
2
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php';
3
+ require_once IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-rewrite.php';
4
 
5
  if ( ! function_exists( 'get_plugins' ) )
6
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
7
 
8
  class IP_Geo_Block_Admin_Tab {
9
 
13
  $option_name = IP_Geo_Block::OPTION_NAME; // 'ip_geo_block_settings'
14
  $options = IP_Geo_Block::get_option();
15
 
 
 
 
16
  /**
17
  * Register a setting and its sanitization callback.
18
  * @link http://codex.wordpress.org/Function_Reference/register_setting
63
  * @param string $section The section of the settings page in which to show the box.
64
  * @param array $args Additional arguments that are passed to the $callback function.
65
  */
66
+
67
+ // Get the country code
68
+ $key = IP_Geo_Block::get_geolocation( IP_Geo_Block::get_ip_address() );
69
+
70
+ $field = 'ip_client';
71
  add_settings_field(
72
  $option_name.'_'.$field,
73
+ __( '<dfn title="You can confirm the appropriate Geolocation APIs and country code by referring &#8220;Scan country code&#8221;.">Your IP address / Country</dfn>', 'ip-geo-block' ),
74
  array( $context, 'callback_field' ),
75
  $option_slug,
76
  $section,
78
  'type' => 'html',
79
  'option' => $option_name,
80
  'field' => $field,
81
+ 'value' => '<span class="ip-geo-block-ip-addr">' . esc_html( $key['ip'] . ' / ' . ( $key['code'] && isset( $key['provider'] ) ? $key['code'] . ' (' . $key['provider'] . ')' : __( 'UNKNOWN', 'ip-geo-block' ) ) ) . '</span>',
82
+ 'after' => '&nbsp;<a class="button button-secondary" id="ip-geo-block-scan-' . $field . '" title="' . __( 'Scan all the APIs you selected at Geolocation API settings', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Scan country code', 'ip-geo-block' ) . '</a><div id="ip-geo-block-scanning-' . $field . '"></div>',
83
  )
84
  );
85
 
92
 
93
  $rule_desc = array(
94
  __( 'Please select either &#8220;Whitelist&#8221; or &#8220;Blacklist&#8221;.', 'ip-geo-block' ),
95
+ __( '<dfn title="&#8220;Block by country&#8221; will be bypassed in case of empty. All the countries will be blocked in case you put &#8220;XX&#8221; only.">Whitelist of country code</dfn>', 'ip-geo-block' ) . '<br />(<a rel="noreferrer" href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements" title="ISO 3166-1 alpha-2 - Wikipedia, the free encyclopedia">ISO 3166-1 alpha-2</a>)',
96
+ __( '<dfn title="&#8220;Block by country&#8221; will be bypassed in case of empty. Please consider to include &#8220;ZZ&#8221; which means UNKNOWN country.">Blacklist of country code</dfn>', 'ip-geo-block' ) . '<br />(<a rel="noreferrer" href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements" title="ISO 3166-1 alpha-2 - Wikipedia, the free encyclopedia">ISO 3166-1 alpha-2</a>)',
97
  );
98
 
99
  $comma = array(
164
  add_settings_field(
165
  $option_name.'_'.$field.'_'.$key,
166
  __( '<dfn title="e.g. &#8220;192.0.64.0/18&#8221; for Jetpack server, &#8220;69.46.36.0/27&#8221; for WordFence server">Whitelist of extra IP addresses prior to country code</dfn>', 'ip-geo-block' ) .
167
+ ' (<a rel="noreferrer" href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" title="Classless Inter-Domain Routing - Wikipedia, the free encyclopedia">CIDR</a>)',
168
  array( $context, 'callback_field' ),
169
  $option_slug,
170
  $section,
183
  add_settings_field(
184
  $option_name.'_'.$field.'_'.$key,
185
  __( '<dfn title="Server level access control is recommended (e.g. .htaccess).">Blacklist of extra IP addresses prior to country code</dfn>', 'ip-geo-block' ) .
186
+ ' (<a rel="noreferrer" href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" title="Classless Inter-Domain Routing - Wikipedia, the free encyclopedia">CIDR</a>)',
187
  array( $context, 'callback_field' ),
188
  $option_slug,
189
  $section,
237
  $field = 'response_code';
238
  add_settings_field(
239
  $option_name.'_'.$field,
240
+ sprintf( __( '<dfn title="You can put your original 403.php and so on into your theme directory.">Response code</dfn> %s', 'ip-geo-block' ), '(<a rel="noreferrer" href="http://tools.ietf.org/html/rfc2616#section-10" title="RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1">RFC 2616</a>)' ),
241
  array( $context, 'callback_field' ),
242
  $option_slug,
243
  $section,
248
  'value' => $options[ $field ],
249
  'list' => array(
250
  200 => '200 OK',
 
251
  301 => '301 Moved Permanently',
252
  302 => '302 Found',
253
+ 303 => '303 See Other',
254
  307 => '307 Temporary Redirect',
255
  400 => '400 Bad Request',
256
  403 => '403 Forbidden',
263
  )
264
  );
265
 
266
+ // Redirect URI
267
+ $field = 'redirect_uri';
268
+ add_settings_field(
269
+ $option_name.'_'.$field,
270
+ __( '<dfn title="Specify the URL for response code 2xx and 3xx. Front-end URL on your site would not be blocked to prevent loop of redirection even when you enable [Front-end target settings]. Empty URL is altered to your home.">Redirect URL</dfn>', 'ip-geo-block' ),
271
+ array( $context, 'callback_field' ),
272
+ $option_slug,
273
+ $section,
274
+ array(
275
+ 'class' => 'ip-geo-block-hide',
276
+ 'type' => 'text',
277
+ 'option' => $option_name,
278
+ 'field' => $field,
279
+ 'value' => $options[ $field ],
280
+ )
281
+ );
282
+
283
+ // Response message
284
+ $field = 'response_msg';
285
+ add_settings_field(
286
+ $option_name.'_'.$field,
287
+ __( '<dfn title="Specify the message for response code 4xx and 5xx.">Response message</dfn>', 'ip-geo-block' ),
288
+ array( $context, 'callback_field' ),
289
+ $option_slug,
290
+ $section,
291
+ array(
292
+ 'class' => 'ip-geo-block-hide',
293
+ 'type' => 'text',
294
+ 'option' => $option_name,
295
+ 'field' => $field,
296
+ 'value' => $options[ $field ],
297
+ )
298
+ );
299
+
300
  // Max number of failed login attempts per IP address
301
  $field = 'login_fails';
302
  add_settings_field(
311
  'field' => $field,
312
  'value' => $options[ $field ],
313
  'list' => array(
314
+ -1 => 'Disable',
315
  0 => 0,
316
  1 => 1,
317
  3 => 3,
345
  ),
346
  'desc' => array(
347
  0 => __( 'Validate at &#8220;init&#8221; action hook in the same manner as typical plugins.', 'ip-geo-block' ),
348
+ 1 => __( 'Validate at an earlier phase than other typical plugins. It can reduce load on server but has <a rel=\'noreferrer\' href=\'http://www.ipgeoblock.com/codex/validation-timing.html\' title=\'Validation timing | IP Geo Block\'>some restrictions</a>.', 'ip-geo-block' ),
349
  ),
350
  'after' => '<div class="ip-geo-block-desc"></div>',
351
  )
352
  );
353
 
354
  /*----------------------------------------*
355
+ * Back-end target settings
356
  *----------------------------------------*/
357
  $section = $plugin_slug . '-validation-target';
358
  add_settings_section(
359
  $section,
360
+ __( 'Back-end target settings', 'ip-geo-block' ),
361
  array( __CLASS__, 'note_target' ),
362
  $option_slug
363
  );
365
  // same as in tab-accesslog.php
366
  $dfn = __( '<dfn title="Validate request to %s.">%s</dfn>', 'ip-geo-block' );
367
  $target = array(
368
+ 'comment' => sprintf( $dfn, 'wp-comments-post.php', __( 'Comment post', 'ip-geo-block' ) ),
369
+ 'xmlrpc' => sprintf( $dfn, 'xmlrpc.php', __( 'XML-RPC', 'ip-geo-block' ) ),
370
+ 'login' => sprintf( $dfn, 'wp-login.php', __( 'Login form', 'ip-geo-block' ) ),
371
+ 'admin' => sprintf( $dfn, 'wp-admin/*.php', __( 'Admin area', 'ip-geo-block' ) ),
372
+ 'others' => sprintf( $dfn, 'executable files', __( 'Other areas', 'ip-geo-block' ) ),
373
+ 'public' => sprintf( $dfn, __( 'public facing pages', 'ip-geo-block' ), __( 'Public facing pages', 'ip-geo-block' ) ),
374
  );
375
 
376
  // Comment post
450
  1 => __( 'Block by country', 'ip-geo-block' ),
451
  2 => __( 'Prevent Zero-day Exploit', 'ip-geo-block' ),
452
  );
453
+
454
  $desc = array(
455
  1 => __( 'It will block a request related to the services for both public facing pages and the dashboard.', 'ip-geo-block' ),
456
  2 => __( 'Regardless of the country code, it will block a malicious request related to the services only for the dashboard.', 'ip-geo-block' ),
475
  )
476
  );
477
 
478
+ // Get all the ajax/post actions
479
+ $exception = '';
480
+ $installed = array();
481
+
482
+ global $wp_filter;
483
+ foreach ( $wp_filter as $key => $val ) {
484
+ if ( FALSE !== strpos( $key, 'wp_ajax_' ) ) {
485
+ if ( 0 === strpos( $key, 'wp_ajax_nopriv_' ) ) {
486
+ $key = substr( $key, 15 );
487
+ $val = 2;
488
+ } else {
489
+ $key = substr( $key, 8 );
490
+ $val = 1;
491
+ }
492
+ $installed[ $key ] = isset( $installed[ $key ] ) ? $installed[ $key ] | $val : $val;
493
+ } elseif ( FALSE !== strpos( $key, 'admin_post_' ) ) {
494
+ if ( 0 === strpos( $key, 'admin_post_nopriv_' ) ) {
495
+ $key = substr( $key, 18 );
496
+ $val = 2;
497
+ } else {
498
+ $key = substr( $key, 11 );
499
+ $val = 1;
500
+ }
501
+ $installed[ $key ] = isset( $installed[ $key ] ) ? $installed[ $key ] | $val : $val;
502
+ }
503
+ }
504
+ unset( $installed['ip_geo_block'] );
505
+
506
+ $tmp = array(
507
+ __( 'for logged-in users', 'ip-geo-block' ),
508
+ __( 'for non logged-in users', 'ip-geo-block' ),
509
+ );
510
+
511
+ foreach ( $installed as $key => $val ) {
512
+ $val = '';
513
+ $val .= $installed[ $key ] & 1 ? '<dfn title="' . $tmp[0] . '"><span class="dashicons dashicons-lock"></span></dfn>' : '';
514
+ $val .= $installed[ $key ] & 2 ? '<dfn title="' . $tmp[1] . '"><span class="dashicons dashicons-unlock"></span></dfn>' : '';
515
+ $key = esc_attr( $key );
516
+ $exception .= '<li>'
517
+ . '<input id="ip_geo_block_' . $key . '" type="checkbox" value="1"' . checked( in_array( $key, $options['exception']['admin'] ), TRUE, FALSE ) . ' />'
518
+ . '<label for="ip_geo_block_' . $key . '">' . $key . '</label>' . $val
519
+ . '</li>' . "\n";
520
+ }
521
+
522
  // Admin ajax/post
523
  $key = 'ajax';
524
  $val = esc_html( substr( IP_Geo_Block::$wp_path['admin'], 1 ) );
536
  'value' => $options[ $field ][ $key ],
537
  'list' => $list,
538
  'desc' => $desc,
539
+ 'after' => '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">'
540
+ . __( '<dfn title="Select actions that cause undesired blocking to skip &#8220;Prevent Zero-day Exploit&#8221; for logged-in users and &#8220;Block by country&#8221; for non logged-in users. If you can not find the right one in the candidate list, you can put a certain page name (&#8220;&hellip;&#8221; in &#8220;page=&hellip;&#8221;) or action name (&#8220;&hellip;&#8221; in &#8220;action=&hellip;&#8221;), which would be implemented with a non WordPress standard way, into the field to specify the request.">Exceptions</dfn>', 'ip-geo-block' )
541
+ . '<li style="display:none"><ul><li>' . "\n"
542
+ . '<input class="regular-text code" id="ip_geo_block_settings_exception_admin" name="ip_geo_block_settings[exception][admin]" type="text" value="' . esc_attr( implode( ',', $options['exception']['admin'] ) ) . '">' . "\n"
543
+ . $comma[0]
544
+ . '</li><li><ul id="ip-geo-block-actions">'
545
+ . '<h4>' . __( 'Candidate actions', 'ip-geo-block' ) . '</h4>'
546
+ . $exception
547
+ . '</ul></li></ul></li></ul>' . "\n",
548
  )
549
  );
550
 
551
  array_unshift( $list, __( 'Disable', 'ip-geo-block' ) );
552
  $desc = array(
553
  __( 'Regardless of the country code, it will block a malicious request to <code>%s&hellip;/*.php</code>.', 'ip-geo-block' ),
554
+ __( 'It configures &#8220;%s&#8221; to validate a request to the PHP file which does not load WordPress core.', 'ip-geo-block' ),
555
  __( '<dfn title="Select the item which causes undesired blocking in order to exclude from the validation target. Grayed item indicates &#8220;INACTIVE&#8221;.">Exceptions</dfn>', 'ip-geo-block' ),
556
  );
557
 
668
  )
669
  );
670
 
671
+ /*----------------------------------------*
672
+ * Front-end settings
673
+ *----------------------------------------*/
674
+ $section = $plugin_slug . '-public';
675
+ add_settings_section(
676
+ $section,
677
+ __( 'Front-end target settings', 'ip-geo-block' ),
678
+ array( __CLASS__, 'note_public' ),
679
+ $option_slug
680
+ );
681
+
682
+ // Public facing pages
683
+ $key = 'public';
684
+ add_settings_field(
685
+ $option_name.'_'.$field.'_'.$key,
686
+ $target[ $key ],
687
+ array( $context, 'callback_field' ),
688
+ $option_slug,
689
+ $section,
690
+ array(
691
+ 'type' => 'checkbox',
692
+ 'option' => $option_name,
693
+ 'field' => $field,
694
+ 'sub-field' => $key,
695
+ 'value' => $options[ $field ][ $key ],
696
+ 'text' => __( 'Block by country', 'ip-geo-block' ),
697
+ )
698
+ );
699
+
700
+ // Default for matching rule on front-end
701
+ $rule[-1] = __( 'Follow &#8220;Validation rule settings&#8221;', 'ip-geo-block' );
702
+
703
+ // Matching rule
704
+ $field = 'public';
705
+ $key = 'matching_rule';
706
+ add_settings_field(
707
+ $option_name.'_'.$field.'_'.$key,
708
+ '<dfn title="' . $rule_desc[0] . '">' . __( 'Matching rule', 'ip-geo-block' ) . '</dfn>',
709
+ array( $context, 'callback_field' ),
710
+ $option_slug,
711
+ $section,
712
+ array(
713
+ 'type' => 'select',
714
+ 'option' => $option_name,
715
+ 'field' => $field,
716
+ 'sub-field' => $key,
717
+ 'value' => $options[ $field ][ $key ],
718
+ 'list' => $rule,
719
+ )
720
+ );
721
+
722
+ // Country code for matching rule (ISO 3166-1 alpha-2)
723
+ $key = 'white_list';
724
+ add_settings_field(
725
+ $option_name.'_'.$field.'_'.$key,
726
+ $rule_desc[1],
727
+ array( $context, 'callback_field' ),
728
+ $option_slug,
729
+ $section,
730
+ array(
731
+ 'type' => 'text',
732
+ 'option' => $option_name,
733
+ 'field' => $field,
734
+ 'sub-field' => $key,
735
+ 'value' => $options[ $field ][ $key ],
736
+ 'after' => $comma[0],
737
+ )
738
+ );
739
+
740
+ $key = 'black_list';
741
+ add_settings_field(
742
+ $option_name.'_'.$field.'_'.$key,
743
+ $rule_desc[2],
744
+ array( $context, 'callback_field' ),
745
+ $option_slug,
746
+ $section,
747
+ array(
748
+ 'type' => 'text',
749
+ 'option' => $option_name,
750
+ 'field' => $field,
751
+ 'sub-field' => $key,
752
+ 'value' => $options[ $field ][ $key ],
753
+ 'after' => $comma[0],
754
+ )
755
+ );
756
+
757
+ // List of page
758
+ $exception = '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . __( '<dfn title="Specify the individual page as a blocking target.">Page</dfn>', 'ip-geo-block' ) . "<li style='display:none'><ul>\n";
759
+ $tmp = get_pages();
760
+ if ( ! empty( $tmp ) ) {
761
+ foreach ( $tmp as $key ) {
762
+ $val = esc_attr( $key->post_name );
763
+ $exception .= '<li><input type="checkbox" id="ip_geo_block_settings_public_target_pages_' . $val . '" name="ip_geo_block_settings[public][target_pages][' . $val . ']" value="1"' . checked( isset( $options[ $field ]['target_pages'][ $val ] ), TRUE, FALSE ) . ' />';
764
+ $exception .= '<label for="ip_geo_block_settings_public_target_pages_' . $val . '">' . esc_html( $key->post_title ) . '</label></li>' . "\n";
765
+ }
766
+ }
767
+ $exception .= '</ul></li></ul>' . "\n";
768
+
769
+ // List of post type
770
+ $exception .= '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . __( '<dfn title="Specify the individual post type on a single page as a blocking target.">Post type</dfn>', 'ip-geo-block' ) . "<li style='display:none'><ul>\n";
771
+ $tmp = get_post_types( array( 'public' => TRUE ) );
772
+ if ( ! empty( $tmp ) ) {
773
+ foreach ( $tmp as $key ) {
774
+ $val = esc_attr( $key );
775
+ $exception .= '<li><input type="checkbox" id="ip_geo_block_settings_public_target_posts_' . $val . '" name="ip_geo_block_settings[public][target_posts][' . $val . ']" value="1"' . checked( isset( $options[ $field ]['target_posts'][ $val ] ), TRUE, FALSE ) . ' />';
776
+ $exception .= '<label for="ip_geo_block_settings_public_target_posts_' . $val . '">' . esc_html( $key ) . '</label></li>' . "\n";
777
+ }
778
+ }
779
+ $exception .= '</ul></li></ul>' . "\n";
780
+
781
+ // List of category
782
+ $exception .= '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . __( '<dfn title="Specify the individual category on a single page or archive page as a blocking target.">Category</dfn>', 'ip-geo-block' ) . "<li style='display:none'><ul>\n";
783
+ $tmp = get_categories( array( 'hide_empty' => FALSE ) );
784
+ if ( ! empty( $tmp ) ) {
785
+ foreach ( $tmp as $key ) {
786
+ $val = esc_attr( $key->slug );
787
+ $exception .= '<li><input type="checkbox" id="ip_geo_block_settings_public_target_cates_' . $val . '" name="ip_geo_block_settings[public][target_cates][' . $val . ']" value="1"' . checked( isset( $options[ $field ]['target_cates'][ $val ] ), TRUE, FALSE ) . ' />';
788
+ $exception .= '<label for="ip_geo_block_settings_public_target_cates_' . $val . '">' . esc_html( $key->name ) . '</label></li>' . "\n";
789
+ }
790
+ }
791
+ $exception .= '</ul></li></ul>' . "\n";
792
+
793
+ // List of tag
794
+ $exception .= '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . __( '<dfn title="Specify the individual tag on a single page or archive page as a blocking target.">Tag</dfn>', 'ip-geo-block' ) . "<li style='display:none'><ul>\n";
795
+ $tmp = get_tags( array( 'hide_empty' => FALSE ) );
796
+ if ( ! empty( $tmp ) ) {
797
+ foreach ( $tmp as $key ) {
798
+ $val = esc_attr( $key->slug );
799
+ $exception .= '<li><input type="checkbox" id="ip_geo_block_settings_public_target_tags_' . $val . '" name="ip_geo_block_settings[public][target_tags][' . $val . ']" value="1"' . checked( isset( $options[ $field ]['target_tags'][ $val ] ), TRUE, FALSE ) . ' />';
800
+ $exception .= '<label for="ip_geo_block_settings_public_target_tags_' . $val . '">' . esc_html( $key->name ) . '</label></li>' . "\n";
801
+ }
802
+ }
803
+ $exception .= '</ul></li></ul>' . "\n";
804
+
805
+ // Validation target
806
+ $key = 'target_rule';
807
+ add_settings_field(
808
+ $option_name.'_'.$field.'_'.$key,
809
+ '<dfn title="' . __( 'Specify the validation target on front-end.', 'ip-geo-block' ) . '">' . __( 'Validation target', 'ip-geo-block' ) . '</dfn>',
810
+ array( $context, 'callback_field' ),
811
+ $option_slug,
812
+ $section,
813
+ array(
814
+ 'type' => 'select',
815
+ 'option' => $option_name,
816
+ 'field' => $field,
817
+ 'sub-field' => $key,
818
+ 'value' => $options[ $field ][ $key ],
819
+ 'list' => array(
820
+ 0 => __( 'All requests', 'ip-geo-block' ),
821
+ 1 => __( 'Specify the targets', 'ip-geo-block' ),
822
+ ),
823
+ 'desc' => array(
824
+ 1 => __( "Notice that &#8220;Validation timing&#8221; is deferred till &#8220;wp&#8221; action hook. It means that this feature would not be compatible with any page caching.", 'ip-geo-block' ),
825
+ ),
826
+ 'after' => '<div class="ip-geo-block-desc"></div>' . "\n" . $exception,
827
+ )
828
+ );
829
+
830
+ // UA string and qualification
831
+ $key = 'ua_list';
832
+ add_settings_field(
833
+ $option_name.'_'.$field.'_'.$key,
834
+ '<dfn title="' . __( 'A part of user agent string and a qualification connected with a separator that indicates an applicable rule and can be &#8220;:&#8221; (pass) or &#8220;#&#8221; (block). A &#8220;qualification&#8221; can be &#8220;DNS&#8221;, &#8220;FEED&#8221;, country code or IP address with CIDR. A negative operator &#8220;!&#8221; can be placed just before a &#8220;qualification&#8221;.', 'ip-geo-block' ) . '">' . __( 'UA string and qualification', 'ip-geo-block' ) . '</dfn>',
835
+ array( $context, 'callback_field' ),
836
+ $option_slug,
837
+ $section,
838
+ array(
839
+ 'type' => 'textarea',
840
+ 'option' => $option_name,
841
+ 'field' => $field,
842
+ 'sub-field' => $key,
843
+ 'value' => $options[ $field ][ $key ],
844
+ 'after' => $comma[1],
845
+ )
846
+ );
847
+
848
+ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ):
849
+ // Excluded action
850
+ $key = 'exception';
851
+ add_settings_field(
852
+ $option_name.'_'.$key.'_'.$field,
853
+ '<dfn title="' . __( 'Specify the name of action that is invariably blocked.', 'ip-geo-block' ) . '">' . __( 'Excluded actions', 'ip-geo-block' ) . '</dfn>',
854
+ array( $context, 'callback_field' ),
855
+ $option_slug,
856
+ $section,
857
+ array(
858
+ 'type' => 'text',
859
+ 'option' => $option_name,
860
+ 'field' => $key,
861
+ 'sub-field' => $field,
862
+ 'value' => implode( ',', $options[ $key ][ $field ] ),
863
+ 'after' => $comma[0],
864
+ )
865
+ );
866
+ endif;
867
+
868
+ // Simulation mode
869
+ $key = 'simulate';
870
+ add_settings_field(
871
+ $option_name.'_'.$field.'_'.$key,
872
+ '<dfn title="' . __( 'It enables to simulate validation without deployment. The results can be found at &#8220;Public facing pages&#8221; in Logs.', 'ip-geo-block' ) . '">' . __( 'Simulation mode', 'ip-geo-block' ) . '</dfn>',
873
+ array( $context, 'callback_field' ),
874
+ $option_slug,
875
+ $section,
876
+ array(
877
+ 'type' => 'checkbox',
878
+ 'option' => $option_name,
879
+ 'field' => $field,
880
+ 'sub-field' => $key,
881
+ 'value' => $options[ $field ][ $key ],
882
+ )
883
+ );
884
+
885
  /*----------------------------------------*
886
  * Geolocation service settings
887
  *----------------------------------------*/
919
  if ( empty( $providers ) ) {
920
  $context->add_admin_notice( 'error',
921
  sprintf(
922
+ __( 'Can not find geolocation API libraries in <code>%s</code>. It seems to have failed downloading <a rel="noreferrer" href="https://github.com/tokkonopapa/WordPress-IP-Geo-API/archive/master.zip" title="Download the contents of tokkonopapa/WordPress-IP-Geo-API as a zip file">ZIP file</a> from <a rel="noreferrer" href="https://github.com/tokkonopapa/WordPress-IP-Geo-API" title="tokkonopapa/WordPress-IP-Geo-API - GitHub">WordPress-IP-Geo-API</a>. Please refer to the <a rel="noreferrer" href="http://www.ipgeoblock.com/codex/how-to-fix-permission-troubles.html" title="How can I fix permission troubles? | IP Geo Block">FAQ</a> to install <code>ip-geo-api</code> with write permission.', 'ip-geo-block' ),
923
  apply_filters( 'ip-geo-block-api-dir', basename( WP_CONTENT_DIR ) )
924
  )
925
  );
991
  add_settings_section(
992
  $section,
993
  __( 'Record settings', 'ip-geo-block' ),
994
+ array( __CLASS__, 'note_record' ),
995
  $option_slug
996
  );
997
 
1109
  $section = $plugin_slug . '-cache';
1110
  add_settings_section(
1111
  $section,
1112
+ __( 'IP address cache settings', 'ip-geo-block' ),
1113
  NULL,
1114
  $option_slug
1115
  );
1130
  )
1131
  );
1132
 
1133
+ // Garbage collection period [sec]
1134
+ $field = 'cache_time_gc';
1135
+ add_settings_field(
1136
+ $option_name.'_'.$field,
1137
+ __( 'Garbage collection period [sec]', 'ip-geo-block' ),
1138
+ array( $context, 'callback_field' ),
1139
+ $option_slug,
1140
+ $section,
1141
+ array(
1142
+ 'type' => 'text',
1143
+ 'option' => $option_name,
1144
+ 'field' => $field,
1145
+ 'value' => $options[ $field ],
1146
+ )
1147
+ );
1148
+
1149
+ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ):
1150
  // Number of entries
1151
  $field = 'cache_hold';
1152
  add_settings_field(
1162
  'value' => $options[ $field ],
1163
  )
1164
  );
1165
+ endif;
1166
 
1167
  /*----------------------------------------*
1168
  * Submission settings
1232
  // Google Maps API key
1233
  $field = 'api_key';
1234
  $key = 'GoogleMap';
1235
+ if ( 'default' !== $options[ $field ][ $key ] or defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ) {
 
1236
  add_settings_field(
1237
  $option_name.'_'.$field,
1238
  __( '<dfn title="Valid key for Google Maps JavaScript API">Google Maps API key</dfn>', 'ip-geo-block' ),
1279
  array(
1280
  'type' => 'none',
1281
  'before' =>
1282
+ '<a class="button button-secondary" id="ip-geo-block-preferred" title="' . __( 'Import the preferred settings mainly for the &#8220;Back-end target settings&#8221;', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Best settings', 'ip-geo-block' ) . '</a>&nbsp;' .
1283
+ '<a class="button button-secondary" id="ip-geo-block-default" title="' . __( 'Import the default settings to revert to the &#8220;Right after installing&#8221; state', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Default settings', 'ip-geo-block' ) . '</a>',
1284
  'after' => '<div id="ip-geo-block-pre-defined"></div>',
1285
  )
1286
  );
1320
  );
1321
  endif;
1322
 
1323
+ // Show WordPress installation info
1324
+ $field = 'show-info';
1325
+ add_settings_field(
1326
+ $option_name.'_'.$field,
1327
+ __( '<dfn title="Please copy &amp; paste when submitting your issue to support forum.">Installation information</dfn><br />[ <a rel="noreferrer" href="https://wordpress.org/support/plugin/ip-geo-block" title="WordPress &#8250; Support &raquo; IP Geo Block">support forum</a> ]', 'ip-geo-block' ),
1328
+ array( $context, 'callback_field' ),
1329
+ $option_slug,
1330
+ $section,
1331
+ array(
1332
+ 'type' => 'none',
1333
+ 'before' =>
1334
+ '<a class="button button-secondary" id="ip-geo-block-show-info" title="' . __( 'Show PHP, WordPress, theme and plugins information.', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Show information', 'ip-geo-block' ) . '</a>&nbsp;',
1335
+ 'after' => '<div id="ip-geo-block-wp-info"></div>',
1336
+ )
1337
+ );
1338
+
1339
  }
1340
 
1341
  /**
1345
  public static function note_target() {
1346
  echo
1347
  '<ul class="ip-geo-block-note">', "\n",
1348
+ '<li>', __( 'To enhance the protection ability, please refer to &#8220;<a rel="noreferrer" href="http://www.ipgeoblock.com/codex/the-best-practice-for-target-settings.html" title="The best practice for target settings | IP Geo Block">The best practice for target settings</a>&#8221;.', 'ip-geo-block' ), '</li>', "\n",
1349
+ '<li>', __( 'If you have any troubles with these, please check FAQ at <a rel="noreferrer" href="https://wordpress.org/plugins/ip-geo-block/faq/" title="IP Geo Block &mdash; WordPress Plugins">WordPress.org</a> and <a rel="noreferrer" href="http://www.ipgeoblock.com/codex/#faq" title="Codex | IP Geo Block">Codex</a>.', 'ip-geo-block' ), '</li>', "\n",
1350
  '</ul>', "\n";
1351
  }
1352
 
1358
  '</ul>', "\n";
1359
  }
1360
 
1361
+ public static function note_public() {
1362
+ echo
1363
+ '<ul class="ip-geo-block-note">', "\n",
1364
+ '<li>', __( 'Please refer to the document &#8220;<a rel="noreferrer" href="http://www.ipgeoblock.com/codex/#blocking-on-front-end" title="Codex | IP Geo Block">Blocking on front-end</a>&#8221; for details, including restrictions on cache plugin.', 'ip-geo-block' ), '</li>', "\n",
1365
+ '<li>', __( 'If you find any issues or have something to suggest, please feel free to open an issue at <a rel="noreferrer" href="https://wordpress.org/support/plugin/ip-geo-block" title="WordPress &#8250; Support &raquo; IP Geo Block">support forum</a>.', 'ip-geo-block' ), '</li>', "\n",
1366
+ '</ul>', "\n";
1367
+ }
1368
+
1369
+ public static function note_record() {
1370
+ echo
1371
+ '<ul class="ip-geo-block-note">', "\n",
1372
+ '<li>', __( 'Please refer to the document &#8220;<a rel="noreferrer" href="http://www.ipgeoblock.com/codex/record-settings-and-logs.html" title="Codex | IP Geo Block">Record settings and logs</a>&#8221; for details.', 'ip-geo-block' ), '</li>', "\n",
1373
+ '</ul>', "\n";
1374
+ }
1375
+
1376
  }
admin/includes/tab-statistics.php CHANGED
@@ -73,7 +73,7 @@ if ( $options['save_statistics'] ) :
73
  $html = '<div id="'.$plugin_slug.'-chart-daily"><table id="'.$plugin_slug.'-targets">';
74
 
75
  $prev = 0;
76
- $targets = array( 'comment', 'xmlrpc', 'login', 'admin' );
77
  foreach ( $statistics['daystats'] as $key => $val ) {
78
  while( $prev && $key - $prev > DAY_IN_SECONDS ) {
79
  $prev += DAY_IN_SECONDS;
@@ -226,28 +226,26 @@ endif;
226
  foreach ( $cache as $key => $val ) {
227
  if ( $options['anonymize'] )
228
  $key = preg_replace( '/\d{1,3}$/', '***', $key );
229
- // if ( empty( $val['auth'] ) || $debug ) { // hide authenticated user
230
- $html .= '<tr><td>' . esc_html( $key ) . '</td>';
231
- $html .= '<td>' . esc_html( $val['code'] ) . ' / ';
232
- $html .= '<small>' . esc_html( $val['hook'] ) . '</small></td>';
233
- $html .= '<td>' . ( $time - (int)$val['time'] ) . ' / ';
234
- $html .= $options['save_statistics'] ? (int)$val['call'] : '-';
235
- if ( $debug ) {
236
- $user = get_user_by( 'id', intval( $val['auth'] ) );
237
- $html .= ' ' . esc_html( $user ? $user->get( 'user_login' ) : '' );
238
- $html .= ' / fail:' . intval( $val['fail'] );
239
- }
240
- $html .= '</td></tr>';
241
- if ( ++$count >= $options['cache_hold'] )
242
- break;
243
- // }
244
  }
245
  }
246
 
247
  $html .= '</tbody></table>';
248
 
249
  if ( ! empty( $count ) )
250
- $html .= '<p style="text-align:right">[ ' . $count . ' / ' . count( $cache ) . ' ]</p>';
251
 
252
  add_settings_field(
253
  $option_name.'_'.$field,
73
  $html = '<div id="'.$plugin_slug.'-chart-daily"><table id="'.$plugin_slug.'-targets">';
74
 
75
  $prev = 0;
76
+ $targets = array( 'comment', 'xmlrpc', 'login', 'admin', 'public' );
77
  foreach ( $statistics['daystats'] as $key => $val ) {
78
  while( $prev && $key - $prev > DAY_IN_SECONDS ) {
79
  $prev += DAY_IN_SECONDS;
226
  foreach ( $cache as $key => $val ) {
227
  if ( $options['anonymize'] )
228
  $key = preg_replace( '/\d{1,3}$/', '***', $key );
229
+ $html .= '<tr><td>' . esc_html( $key ) . '</td>';
230
+ $html .= '<td>' . esc_html( $val['code'] ) . ' / ';
231
+ $html .= '<small>' . esc_html( $val['hook'] ) . '</small></td>';
232
+ $html .= '<td>' . ( $time - (int)$val['time'] ) . ' / ';
233
+ $html .= $options['save_statistics'] ? (int)$val['call'] : '-';
234
+ if ( $debug ) {
235
+ $user = get_user_by( 'id', intval( $val['auth'] ) );
236
+ $html .= ' ' . esc_html( $user ? $user->get( 'user_login' ) : '' );
237
+ $html .= ' / fail:' . intval( $val['fail'] );
238
+ }
239
+ $html .= '</td></tr>';
240
+ if ( ++$count >= $options['cache_hold'] )
241
+ break;
 
 
242
  }
243
  }
244
 
245
  $html .= '</tbody></table>';
246
 
247
  if ( ! empty( $count ) )
248
+ $html .= '<span style="float:right">[ ' . $count . ' / ' . count( $cache ) . ' ]</span>';
249
 
250
  add_settings_field(
251
  $option_name.'_'.$field,
admin/js/admin.js CHANGED
@@ -1,7 +1,7 @@
1
  /*jslint white: true */
2
  /*!
3
  * Project: WordPress IP Geo Block
4
- * Copyright (c) 2015-2016 tokkonopapa (tokkonopapa@yahoo.com)
5
  * This software is released under the MIT License.
6
  */
7
  var ip_geo_block_time = new Date();
@@ -17,7 +17,7 @@ var ip_geo_block_time = new Date();
17
  '$': 'ip-geo-block-',
18
  '%': 'ip_geo_block_'
19
  };
20
- return id ? keys[selector] + id : keys.$ + selector;
21
  }
22
 
23
  function sanitize(str) {
@@ -47,11 +47,11 @@ var ip_geo_block_time = new Date();
47
  }
48
 
49
  function warning(status, msg) {
50
- window.alert(sanitize(status + ' ' + msg));
51
  }
52
 
53
  function notice_html5() {
54
- warning('Notice:', 'This feature is available with HTML5 compliant browsers.');
55
  }
56
 
57
  function redirect(page, tab) {
@@ -125,6 +125,17 @@ var ip_geo_block_time = new Date();
125
  }
126
  }
127
 
 
 
 
 
 
 
 
 
 
 
 
128
  // Show/Hide folding list
129
  function show_folding_list($this, element, field, mask) {
130
  var stat = false;
@@ -132,22 +143,19 @@ var ip_geo_block_time = new Date();
132
  stat |= (0 === $this.prop('type').indexOf('select' ) && '0' !== $this.val());
133
 
134
  element.nextAll('.' + field + '_folding').each(function (i, obj) {
135
- obj = $(obj);
136
-
137
- // completely hide
138
- // obj.css('display', mask ? 'block' : 'none');
139
-
140
- // fold the contents
141
- if (stat && mask) {
142
- obj.removeClass('folding-disable');
143
- } else {
144
- obj.children('li').hide();
145
- obj.addClass('folding-disable');
146
- obj.removeClass(ID('dropdown')).addClass(ID('dropup'));
147
- }
148
  });
149
  }
150
 
 
 
 
 
 
 
 
 
 
151
  // Encode/Decode to prevent blocking before post ajax
152
  function base64_encode(str) {
153
  return window.btoa(str);
@@ -183,11 +191,28 @@ var ip_geo_block_time = new Date();
183
  }
184
  };
185
  reader.onerror = function (event) {
186
- warning('Error: ', event.target.error.code);
187
  };
188
  reader.readAsText(file);
189
  }
190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  /**
192
  * jQuery deserialize plugin based on https://gist.github.com/nissuk/835256
193
  *
@@ -204,7 +229,7 @@ var ip_geo_block_time = new Date();
204
  name = decodeURIComponent(key);
205
  value = decodeURIComponent(json[key]);
206
 
207
- if (!(name in data)) { // !data.hasOwnProperty(name)
208
  data[name] = [];
209
  }
210
 
@@ -233,9 +258,15 @@ var ip_geo_block_time = new Date();
233
  $(ID('@', key)).trigger('change');
234
  });
235
 
 
 
 
236
  // Additional edge case
237
  var i = ID('%', 'settings[providers][IPInfoDB]');
238
  $(ID('@', 'providers_IPInfoDB')).prop('checked', json[i] ? true : false);
 
 
 
239
  }
240
  }
241
 
@@ -291,6 +322,7 @@ var ip_geo_block_time = new Date();
291
  self.dataLine.addColumn('number', 'xmlrpc');
292
  self.dataLine.addColumn('number', 'login');
293
  self.dataLine.addColumn('number', 'admin');
 
294
  var i, j, k, m, n, cells, arr = [],
295
  tr = $(ID('#', 'targets tr'));
296
  for (m = tr.length, i = 0; i < m; i++) {
@@ -327,6 +359,42 @@ var ip_geo_block_time = new Date();
327
  }
328
  };
329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  function add_hidden_form(cmd) {
331
  $('body').append(
332
  '<div style="display:none">' +
@@ -343,19 +411,13 @@ var ip_geo_block_time = new Date();
343
  }
344
 
345
  $(function () {
346
- // processing time for the browser's performance
347
- ip_geo_block_time = new Date() - ip_geo_block_time;
348
-
349
- // Get tab number and check wpCookies in wp-includes/js/utils.js
350
- var cookie = ('undefined' !== typeof wpCookies && wpCookies.getHash(ID('%', 'admin'))) || {},
351
- tabIndex = [0, 8, 9],
352
- tabNo = /&tab=(\d)/.exec(window.location.href);
353
-
354
- tabNo = Number(tabNo && tabNo[1]);
355
-
356
  // Make form style with fieldset and legend
357
  var fieldset = $('<fieldset class="' + ID('field') + '"></fieldset>'),
358
- legend = $('<legend></legend>');
 
 
 
 
359
 
360
  $('.form-table').each(function (index) {
361
  var $this = $(this),
@@ -371,8 +433,7 @@ var ip_geo_block_time = new Date();
371
 
372
  // Initialize show/hide form-table on tab 0, 1
373
  if (tabNo <= 1) {
374
- index += tabIndex[tabNo];
375
- if ('undefined' === typeof cookie[index] || cookie[index]) { // 'undefined' or 'o'
376
  title.addClass(ID('dropdown')).parent().nextAll().show();
377
  } else {
378
  title.addClass(ID('dropup')).parent().nextAll().hide();
@@ -380,34 +441,10 @@ var ip_geo_block_time = new Date();
380
  }
381
  });
382
 
383
- var drawChart = function () {
384
- if ($(ID('#', 'chart-countries')).length) {
385
- chart.drawChart();
386
- }
387
- };
388
-
389
- // Click event handler to show/hide form-table
390
- var toggle_section = function (title) {
391
- var index = title.closest('fieldset').data('ip-geo-block');
392
-
393
- // Show/Hide
394
- title.parent().nextAll().toggle();
395
- title.toggleClass(ID('dropup')).toggleClass(ID('dropdown'));
396
-
397
- // Save cookie
398
- if ('undefined' !== typeof wpCookies) {
399
- cookie[index + tabIndex[tabNo]] = title.hasClass(ID('dropdown')) ? 'o' : '';
400
- wpCookies.setHash(ID('%', 'admin'), cookie, new Date(Date.now() + 2592000000));
401
- }
402
-
403
- // redraw google chart
404
- drawChart();
405
- };
406
-
407
  // Click event handler to show/hide form-table
408
  if (tabNo <= 1) {
409
  $('form').on('click', 'h2,h3', function (event) {
410
- toggle_section($(this));
411
  return false;
412
  });
413
 
@@ -427,13 +464,11 @@ var ip_geo_block_time = new Date();
427
  $this.parent().nextAll().toggle(n ? false : true);
428
  $this.removeClass(id.join(' '))
429
  .addClass(n ? id[1] : id[0]);
430
- cookie[i + tabIndex[tabNo]] = n ? '' : 'o';
431
  });
432
 
433
  // Save cookie
434
- if ('undefined' !== typeof wpCookies) {
435
- wpCookies.setHash(ID('%', 'admin'), cookie, new Date(Date.now() + 2592000000));
436
- }
437
 
438
  // redraw google chart
439
  drawChart();
@@ -454,10 +489,13 @@ var ip_geo_block_time = new Date();
454
  *----------------------------------------*/
455
  case 0:
456
  // Scan your country code
457
- $(ID('#', 'scan-code')).on('click', function (event) {
458
- var parent = $(this).parent();
459
- ajax_post('scanning', {
460
- cmd: 'scan-code'
 
 
 
461
  }, function (data) {
462
  if (!parent.children('ul').length) {
463
  parent.append('<ul id="' + ID('code-list') + '"></ul>');
@@ -541,6 +579,12 @@ var ip_geo_block_time = new Date();
541
  return false;
542
  }).trigger('change');
543
 
 
 
 
 
 
 
544
  // Export / Import settings
545
  add_hidden_form('validate');
546
 
@@ -597,7 +641,7 @@ var ip_geo_block_time = new Date();
597
 
598
  // Import pre-defined settings
599
  $(ID('#', 'default')).on('click', function (event) {
600
- confirm('Import settings ?', function () {
601
  ajax_post('pre-defined', {
602
  cmd: 'import-default'
603
  }, deserialize_json);
@@ -610,7 +654,7 @@ var ip_geo_block_time = new Date();
610
  });
611
 
612
  $(ID('#', 'preferred')).on('click', function (event) {
613
- confirm('Import settings ?', function () {
614
  ajax_post('pre-defined', {
615
  cmd: 'import-preferred'
616
  }, deserialize_json);
@@ -620,21 +664,21 @@ var ip_geo_block_time = new Date();
620
 
621
  // Manipulate DB table for validation logs
622
  $(ID('@', 'create_table')).on('click', function (event) {
623
- confirm('Create table ?', function () {
624
  ajax_table('create-table');
625
  });
626
  return false;
627
  });
628
 
629
  $(ID('@', 'delete_table')).on('click', function (event) {
630
- confirm('Delete table ?', function () {
631
  ajax_table('delete-table');
632
  });
633
  return false;
634
  });
635
 
636
  // Folding list
637
- $('ul.' + name + '_folding dfn').on('click', function (event) {
638
  var $this = $(this).parent();
639
  $this.children('li').toggle();
640
  $this.toggleClass(ID('dropup')).toggleClass(ID('dropdown'));
@@ -653,16 +697,96 @@ var ip_geo_block_time = new Date();
653
  return false;
654
  });
655
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
  // Submit
657
  $('#submit').on('click', function (event) {
658
  var elm = $(ID('@', 'signature')),
659
  str = elm.val();
660
- if (str.search(/,/) !== -1) {
661
  elm.val(encode_str(str));
662
  }
663
  return true;
664
  });
665
-
666
  break;
667
 
668
  /*----------------------------------------
@@ -681,7 +805,7 @@ var ip_geo_block_time = new Date();
681
 
682
  // Statistics
683
  $(ID('@', 'clear_statistics')).on('click', function (event) {
684
- confirm('Clear statistics ?', function () {
685
  ajax_clear('statistics', null);
686
  });
687
  return false;
@@ -689,7 +813,7 @@ var ip_geo_block_time = new Date();
689
 
690
  // Statistics
691
  $(ID('@', 'clear_cache')).on('click', function (event) {
692
- confirm('Clear cache ?', function () {
693
  ajax_clear('cache', null);
694
  });
695
  return false;
@@ -828,7 +952,7 @@ var ip_geo_block_time = new Date();
828
  ajax_post('logs', {
829
  cmd: 'restore',
830
  which: null,
831
- time: ip_geo_block_time
832
  }, function (data) {
833
  var key;
834
  for (key in data) {
@@ -851,9 +975,15 @@ var ip_geo_block_time = new Date();
851
  });
852
  }
853
 
 
 
 
 
 
 
854
  // Validation logs
855
  $(ID('@', 'clear_logs')).on('click', function (event) {
856
- confirm('Clear logs ?', function () {
857
  ajax_clear('logs', null);
858
  });
859
  return false;
@@ -862,7 +992,7 @@ var ip_geo_block_time = new Date();
862
  // Export / Import settings
863
  add_hidden_form('export-logs');
864
 
865
- // Export settings
866
  $(ID('#', 'export-logs')).on('click', function (event) {
867
  $(ID('#', 'export-form')).trigger('submit');
868
  return false;
1
  /*jslint white: true */
2
  /*!
3
  * Project: WordPress IP Geo Block
4
+ * Copyright (c) 2015-2017 tokkonopapa (tokkonopapa@yahoo.com)
5
  * This software is released under the MIT License.
6
  */
7
  var ip_geo_block_time = new Date();
17
  '$': 'ip-geo-block-',
18
  '%': 'ip_geo_block_'
19
  };
20
+ return 'undefined' !== typeof id ? keys[selector] + id : keys.$ + selector;
21
  }
22
 
23
  function sanitize(str) {
47
  }
48
 
49
  function warning(status, msg) {
50
+ window.alert(status ? sanitize(status + ': ' + msg) : sanitize(msg));
51
  }
52
 
53
  function notice_html5() {
54
+ warning(null, IP_GEO_BLOCK.msg[6]);
55
  }
56
 
57
  function redirect(page, tab) {
125
  }
126
  }
127
 
128
+ // Fold the contents
129
+ function fold_elements(obj, stat) { // obj: ul object
130
+ if (stat) {
131
+ obj.removeClass('folding-disable');
132
+ } else {
133
+ obj.children('li').hide();
134
+ obj.addClass('folding-disable');
135
+ obj.removeClass(ID('dropdown')).addClass(ID('dropup'));
136
+ }
137
+ }
138
+
139
  // Show/Hide folding list
140
  function show_folding_list($this, element, field, mask) {
141
  var stat = false;
143
  stat |= (0 === $this.prop('type').indexOf('select' ) && '0' !== $this.val());
144
 
145
  element.nextAll('.' + field + '_folding').each(function (i, obj) {
146
+ fold_elements($(obj), stat && mask);
 
 
 
 
 
 
 
 
 
 
 
 
147
  });
148
  }
149
 
150
+ // Show / Hide Exceptions
151
+ function show_folding_ajax(elem) {
152
+ var id = ID('@', 'validation_ajax_');
153
+ fold_elements(
154
+ elem.closest('ul').next(),
155
+ $(id + '1').is(':checked') || $(id + '2').is(':checked')
156
+ );
157
+ }
158
+
159
  // Encode/Decode to prevent blocking before post ajax
160
  function base64_encode(str) {
161
  return window.btoa(str);
191
  }
192
  };
193
  reader.onerror = function (event) {
194
+ warning('Error', event.target.error.code);
195
  };
196
  reader.readAsText(file);
197
  }
198
 
199
+ // Enable / Disable at front-end target settings
200
+ function set_front_end($this) {
201
+ var field = ID('%', 'settings'),
202
+ checked = $this.is(':checked'),
203
+ select = $(ID('@', 'public_target_rule')),
204
+ parent = $this.closest('tr').nextAll('tr');
205
+
206
+ // Enable / Disable descendent items
207
+ parent.find('[name^="' + field + '"]').prop('disabled', !checked);
208
+
209
+ // Enable / Disable description
210
+ parent.find(ID('.', 'desc')).css('opacity', checked ? 1.0 : 0.5);
211
+
212
+ // Show / Hide validation target
213
+ show_folding_list($this, select, field, '1' === select.val() ? true : false);
214
+ }
215
+
216
  /**
217
  * jQuery deserialize plugin based on https://gist.github.com/nissuk/835256
218
  *
229
  name = decodeURIComponent(key);
230
  value = decodeURIComponent(json[key]);
231
 
232
+ if (!data.hasOwnProperty(name)) { // !(name in data)
233
  data[name] = [];
234
  }
235
 
258
  $(ID('@', key)).trigger('change');
259
  });
260
 
261
+ // Public facing pages
262
+ set_front_end($(ID('@', 'validation_public')));
263
+
264
  // Additional edge case
265
  var i = ID('%', 'settings[providers][IPInfoDB]');
266
  $(ID('@', 'providers_IPInfoDB')).prop('checked', json[i] ? true : false);
267
+
268
+ // Exceptions
269
+ $(ID('@', 'exception_admin')).trigger('change');
270
  }
271
  }
272
 
322
  self.dataLine.addColumn('number', 'xmlrpc');
323
  self.dataLine.addColumn('number', 'login');
324
  self.dataLine.addColumn('number', 'admin');
325
+ self.dataLine.addColumn('number', 'public');
326
  var i, j, k, m, n, cells, arr = [],
327
  tr = $(ID('#', 'targets tr'));
328
  for (m = tr.length, i = 0; i < m; i++) {
359
  }
360
  };
361
 
362
+ // google chart
363
+ function drawChart() {
364
+ if ($(ID('#', 'chart-countries')).length) {
365
+ chart.drawChart();
366
+ }
367
+ }
368
+
369
+ // Load / Save cookie using wpCookies in wp-includes/js/utils.js
370
+ function loadCookie(id) {
371
+ return ('undefined' !== typeof wpCookies && wpCookies.getHash(ID('$', id))) || {};
372
+ }
373
+
374
+ // setHash( name, value, expires, path, domain, secure )
375
+ function saveCookie(id, cookie) {
376
+ if ('undefined' !== typeof wpCookies) {
377
+ var path = 'undefined' !== typeof IP_GEO_BLOCK_AUTH ? IP_GEO_BLOCK_AUTH.home + IP_GEO_BLOCK_AUTH.admin : '';
378
+ wpCookies.setHash(ID('$', id), cookie, new Date(Date.now() + 2592000000), path);
379
+ }
380
+ }
381
+
382
+ // Click event handler to show/hide form-table
383
+ function toggleSection(title, id, cookie) {
384
+ var index = title.closest('fieldset').data('ip-geo-block');
385
+
386
+ // Show/Hide
387
+ title.parent().nextAll().toggle();
388
+ title.toggleClass(ID('dropup')).toggleClass(ID('dropdown'));
389
+
390
+ cookie[index] = title.hasClass(ID('dropdown')) ? 'o' : 'x';
391
+ saveCookie(id, cookie); // Save cookie
392
+
393
+ // redraw google chart
394
+ drawChart();
395
+ }
396
+
397
+ // form for export / import
398
  function add_hidden_form(cmd) {
399
  $('body').append(
400
  '<div style="display:none">' +
411
  }
412
 
413
  $(function () {
 
 
 
 
 
 
 
 
 
 
414
  // Make form style with fieldset and legend
415
  var fieldset = $('<fieldset class="' + ID('field') + '"></fieldset>'),
416
+ legend = $('<legend></legend>'),
417
+
418
+ // Get tab number and cookie
419
+ tabNo = Number(IP_GEO_BLOCK.tab) || 0,
420
+ cookie = loadCookie(tabNo);
421
 
422
  $('.form-table').each(function (index) {
423
  var $this = $(this),
433
 
434
  // Initialize show/hide form-table on tab 0, 1
435
  if (tabNo <= 1) {
436
+ if ('undefined' === typeof cookie[index] || 'o' === cookie[index]) { // 'undefined', 'x' or 'o'
 
437
  title.addClass(ID('dropdown')).parent().nextAll().show();
438
  } else {
439
  title.addClass(ID('dropup')).parent().nextAll().hide();
441
  }
442
  });
443
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
  // Click event handler to show/hide form-table
445
  if (tabNo <= 1) {
446
  $('form').on('click', 'h2,h3', function (event) {
447
+ toggleSection($(this), tabNo, cookie);
448
  return false;
449
  });
450
 
464
  $this.parent().nextAll().toggle(n ? false : true);
465
  $this.removeClass(id.join(' '))
466
  .addClass(n ? id[1] : id[0]);
467
+ cookie[i] = n ? 'x' : 'o';
468
  });
469
 
470
  // Save cookie
471
+ saveCookie(tabNo, cookie);
 
 
472
 
473
  // redraw google chart
474
  drawChart();
489
  *----------------------------------------*/
490
  case 0:
491
  // Scan your country code
492
+ $('[id^="' + ID('$', 'scan-') + '"]').on('click', function (event) {
493
+ var $this = $(this),
494
+ id = $this.attr('id'),
495
+ parent = $this.parent();
496
+ ajax_post(id.replace(/^.*(?:scan)/, 'scanning'), {
497
+ cmd: 'scan-code',
498
+ which: id.replace(ID('$', 'scan-'), '')
499
  }, function (data) {
500
  if (!parent.children('ul').length) {
501
  parent.append('<ul id="' + ID('code-list') + '"></ul>');
579
  return false;
580
  }).trigger('change');
581
 
582
+ // Enable / Disable for Public facing pages
583
+ $(ID('@', 'validation_public')).on('change', function (event) {
584
+ set_front_end($(this));
585
+ return false;
586
+ }).trigger('change');
587
+
588
  // Export / Import settings
589
  add_hidden_form('validate');
590
 
641
 
642
  // Import pre-defined settings
643
  $(ID('#', 'default')).on('click', function (event) {
644
+ confirm(IP_GEO_BLOCK.msg[0], function () {
645
  ajax_post('pre-defined', {
646
  cmd: 'import-default'
647
  }, deserialize_json);
654
  });
655
 
656
  $(ID('#', 'preferred')).on('click', function (event) {
657
+ confirm(IP_GEO_BLOCK.msg[0], function () {
658
  ajax_post('pre-defined', {
659
  cmd: 'import-preferred'
660
  }, deserialize_json);
664
 
665
  // Manipulate DB table for validation logs
666
  $(ID('@', 'create_table')).on('click', function (event) {
667
+ confirm(IP_GEO_BLOCK.msg[1], function () {
668
  ajax_table('create-table');
669
  });
670
  return false;
671
  });
672
 
673
  $(ID('@', 'delete_table')).on('click', function (event) {
674
+ confirm(IP_GEO_BLOCK.msg[2], function () {
675
  ajax_table('delete-table');
676
  });
677
  return false;
678
  });
679
 
680
  // Folding list
681
+ $('ul.' + name + '_folding>dfn').on('click', function (event) {
682
  var $this = $(this).parent();
683
  $this.children('li').toggle();
684
  $this.toggleClass(ID('dropup')).toggleClass(ID('dropdown'));
697
  return false;
698
  });
699
 
700
+ // Response message and Redirect URL
701
+ $(ID('@', 'response_code')).on('change', function (event) {
702
+ var res = parseInt($(this).val() / 100, 10),
703
+ elm = $(this).closest('tr').nextAll('tr');
704
+ if (res <= 3) { // 2xx, 3xx
705
+ elm.each(function (index) {
706
+ if (0 === index) { $(this).show(); } // redirect_uri
707
+ else if (1 === index) { $(this).hide(); } // response_msg
708
+ });
709
+ }
710
+ else { // 4xx, 5xx
711
+ elm.each(function (index) {
712
+ if (0 === index) { $(this).hide(); } // redirect_uri
713
+ else if (1 === index) { $(this).show(); } // response_msg
714
+ });
715
+ }
716
+ }).trigger('change');
717
+
718
+ // Show WordPress installation info
719
+ $(ID('#', 'show-info')).on('click', function (event) {
720
+ $(ID('#', 'wp-info')).empty();
721
+ ajax_post('wp-info', {
722
+ cmd: 'show-info'
723
+ }, function (data) {
724
+ var key, res = [];
725
+ for (key in data) {
726
+ if (data.hasOwnProperty(key)) {
727
+ res.push('- ' + key + ' ' + data[key]);
728
+ }
729
+ }
730
+
731
+ // response should be escaped at server side
732
+ $(ID('#', 'wp-info')).html('<textarea rows="' + res.length + '">' + /*sanitize*/(res.join("\n")) + '</textarea>').find('textarea').select();
733
+ return false;
734
+ });
735
+ });
736
+
737
+ // Exceptions for Admin ajax/post
738
+ $(ID('@', 'exception_admin')).on('change', function (event) {
739
+ var actions = $.grep($(this).val().split(','), function (e){
740
+ return '' !== e.replace(/^\s+|\s+$/g, ''); // remove empty element
741
+ });
742
+
743
+ $(ID('#', 'actions')).find('input').each(function (i, e) {
744
+ var $this = $(this),
745
+ action = $this.attr('id').replace(ID('%', ''), '');
746
+ if (-1 !== $.inArray(action, actions)) {
747
+ $this.prop('checked',true);
748
+ } else {
749
+ $this.prop('checked',false);
750
+ }
751
+ });
752
+ }).trigger('change');
753
+
754
+ // Candidate actions
755
+ $(ID('#', 'actions')).on('click', 'input', function (event) {
756
+ var i, $this = $(this),
757
+ action = $this.attr('id').replace(ID('%', ''), ''),
758
+ $admin = $(ID('@', 'exception_admin')),
759
+ actions = $.grep($admin.val().split(','), function (e){
760
+ return '' !== e.replace(/^\s+|\s+$/g, ''); // remove empty element
761
+ });
762
+
763
+ // find the action
764
+ i = $.inArray(action, actions);
765
+
766
+ if (-1 === i) {
767
+ actions.push(action);
768
+ } else {
769
+ actions.splice(i, 1);
770
+ }
771
+
772
+ $admin.val(actions.join(',')).change();
773
+ });
774
+
775
+ // Enable / Disable Exceptions
776
+ show_folding_ajax($(ID('@', 'validation_ajax_1')));
777
+ $('input[id^="' + ID('%', 'settings_validation_ajax_') + '"]').on('click', function (event) {
778
+ show_folding_ajax($(this));
779
+ });
780
+
781
  // Submit
782
  $('#submit').on('click', function (event) {
783
  var elm = $(ID('@', 'signature')),
784
  str = elm.val();
785
+ if (str.indexOf(',') !== -1) {
786
  elm.val(encode_str(str));
787
  }
788
  return true;
789
  });
 
790
  break;
791
 
792
  /*----------------------------------------
805
 
806
  // Statistics
807
  $(ID('@', 'clear_statistics')).on('click', function (event) {
808
+ confirm(IP_GEO_BLOCK.msg[3], function () {
809
  ajax_clear('statistics', null);
810
  });
811
  return false;
813
 
814
  // Statistics
815
  $(ID('@', 'clear_cache')).on('click', function (event) {
816
+ confirm(IP_GEO_BLOCK.msg[4], function () {
817
  ajax_clear('cache', null);
818
  });
819
  return false;
952
  ajax_post('logs', {
953
  cmd: 'restore',
954
  which: null,
955
+ time: new Date() - ip_geo_block_time
956
  }, function (data) {
957
  var key;
958
  for (key in data) {
975
  });
976
  }
977
 
978
+ // Clear filter logs
979
+ $(ID('#', 'reset-filter')).on('click', function (event) {
980
+ $('.footable').trigger('footable_clear_filter');
981
+ return false;
982
+ });
983
+
984
  // Validation logs
985
  $(ID('@', 'clear_logs')).on('click', function (event) {
986
+ confirm(IP_GEO_BLOCK.msg[5], function () {
987
  ajax_clear('logs', null);
988
  });
989
  return false;
992
  // Export / Import settings
993
  add_hidden_form('export-logs');
994
 
995
+ // Export logs
996
  $(ID('#', 'export-logs')).on('click', function (event) {
997
  $(ID('#', 'export-form')).trigger('submit');
998
  return false;
admin/js/admin.min.js CHANGED
@@ -1,6 +1,6 @@
1
- /*!
2
- * Project: WordPress IP Geo Block
3
- * Copyright (c) 2015-2016 tokkonopapa (tokkonopapa@yahoo.com)
4
- * This software is released under the MIT License.
5
- */
6
- var ip_geo_block_time=new Date;(function(b,h,u){function a(a,b){var c={".":".ip-geo-block-","#":"#ip-geo-block-","@":"#ip_geo_block_settings_",$:"ip-geo-block-","%":"ip_geo_block_"};return b?c[a]+b:c.$+a}function e(a){return a?a.toString().replace(/[&<>"']/g,function(a){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[a]}):""}function v(c,l){l?b(a("#",c)).addClass(a("loading")):b(a("#",c)).removeClass(a("loading"))}function n(a,b){h.confirm(e(a))&&b()}function A(){h.alert(e("Notice: This feature is available with HTML5 compliant browsers."))}function x(a,b){if(-1!==location.href.indexOf(a)){var c=e(a)+(b?"&"+e(b):"");"undefined"===typeof IP_GEO_BLOCK_ZEP?h.location.href=c:IP_GEO_BLOCK_ZEP.redirect(c)}}function m(a,l,f,r){a&&v(a,!0);l.action=IP_GEO_BLOCK.action;l.nonce=IP_GEO_BLOCK.nonce;b.post(IP_GEO_BLOCK.url,l).done(function(a,b,c){f(a)}).fail(function(a,b,c){h.alert(e(b+" "+a.responseText))}).always(function(){a&&(r?b.when.apply(b,r).then(function(){v(a,!1)}):v(a,!1))})}function y(a,b){m(a,{cmd:"clear-"+a,which:b},function(a){x(a.page,a.tab)})}function B(a){m(a,{cmd:a},function(a){x(a.page,a.tab)})}function C(c,l,f,r){var e=!1,e=e|(0===c.prop("type").indexOf("checkbox")&&c.is(":checked")),e=e|(0===c.prop("type").indexOf("select")&&"0"!==c.val());l.nextAll("."+f+"_folding").each(function(c,f){f=b(f);e&&r?f.removeClass("folding-disable"):(f.children("li").hide(),f.addClass("folding-disable"),f.removeClass(a("dropdown")).addClass(a("dropup")))})}function w(a){return String(a).replace(/[a-z]/gi,function(a){return String.fromCharCode(a.charCodeAt(0)+("n">a.toLowerCase()?13:-13))})}function F(a,b){var c=new FileReader;c.onload=function(a){b&&b(a.target.result)};c.onerror=function(a){h.alert(e("Error: "+a.target.error.code))};c.readAsText(a)}function z(c){if(c){"string"===typeof c&&(c=JSON.parse(c));b(a("#","import")).closest("form").deserialize(c);b.each(["matching_rule","validation_login","validation_plugins","validation_themes"],function(c,e){b(a("@",e)).trigger("change")});var e=a("%","settings[providers][IPInfoDB]");b(a("@","providers_IPInfoDB")).prop("checked",c[e]?!0:!1)}}function D(c){b("body").append('<div style="display:none"><form method="POST" id="'+a("export-form")+'" action="'+IP_GEO_BLOCK.url.replace("ajax.php","post.php")+'"><input type="hidden" name="action" value="'+IP_GEO_BLOCK.action+'" /><input type="hidden" name="nonce" value="'+IP_GEO_BLOCK.nonce+'" /><input type="hidden" name="cmd" value="'+c+'" /><input type="hidden" name="data" value="" id="'+a("export-data")+'"/><input type="submit" value="submit" /></form><input type="file" name="settings" id="'+a("file-dialog")+'" /></div>')}b.fn.deserialize=function(a,e){return this.each(function(){var c,e,l,h=this,k={};for(c in a)a.hasOwnProperty(c)&&(e=decodeURIComponent(c),l=decodeURIComponent(a[c]),e in k||(k[e]=[]),k[e].push(l));b.each(k,function(a,d){b('[name="'+a+'"]:input',h).val(d)})})};var E={self:this,drawChart:function(){this.drawPie();this.drawLine()},dataPie:null,viewPie:null,drawPie:function(){if(!self.dataPie){self.dataPie=new google.visualization.DataTable;self.dataPie.addColumn("string","Country");self.dataPie.addColumn("number","Requests");var c;b(a("#","countries li")).each(function(){c=b(this).text().split(":");self.dataPie.addRow([c[0]||"",Number(c[1])])})}self.viewPie||(self.viewPie=new google.visualization.PieChart(u.getElementById(a("chart-countries"))));b(a("#","chart-countries")).width()&&self.viewPie.draw(self.dataPie,{backgroundColor:"#f1f1f1",chartArea:{left:0,top:"5%",width:"100%",height:"90%"},sliceVisibilityThreshold:.015})},dataLine:null,viewLine:null,drawLine:function(){if(!self.dataLine){self.dataLine=new google.visualization.DataTable;self.dataLine.addColumn("date","Date");self.dataLine.addColumn("number","comment");self.dataLine.addColumn("number","xmlrpc");self.dataLine.addColumn("number","login");self.dataLine.addColumn("number","admin");var c,e,f,h,m,n,k=[],q=b(a("#","targets tr"));h=q.length;for(c=0;c<h;c++)for(k[c]=[],n=q.eq(c).children(),m=n.length,e=0;e<m;e++)f=n.eq(e).text(),k[c].push(e?Number(f):new Date(f));self.dataLine.addRows(k)}self.viewLine||(self.viewLine=new google.visualization.LineChart(u.getElementById(a("chart-daily"))));if(c=b(a("#","chart-daily")).width())c=320<c?!0:!1,self.viewLine.draw(self.dataLine,{backgroundColor:"#f1f1f1",legend:{position:"bottom"},hAxis:{format:"MM/dd"},vAxis:{textPosition:c?"out":"in"},chartArea:{left:c?"10%":0,top:"5%",width:"100%",height:"75%"}})}};b(function(){ip_geo_block_time=new Date-ip_geo_block_time;var c="undefined"!==typeof wpCookies&&wpCookies.getHash(a("%","admin"))||{},l=[0,8,9],f=/&tab=(\d)/.exec(h.location.href),f=Number(f&&f[1]),r=b('<fieldset class="'+a("field")+'"></fieldset>'),v=b("<legend></legend>");b(".form-table").each(function(d){var g=b(this),p=g.prevAll("h2,h3:first"),t=p.nextUntil(g);g.wrap(r).parent().attr("id",a("settings-"+d)).data("ip-geo-block",d).prepend(p.wrap(v).parent());t.insertBefore(g);1>=f&&(d+=l[f],"undefined"===typeof c[d]||c[d]?p.addClass(a("dropdown")).parent().nextAll().show():p.addClass(a("dropup")).parent().nextAll().hide())});var u=function(){b(a("#","chart-countries")).length&&E.drawChart()};1>=f&&(b("form").on("click","h2,h3",function(d){d=b(this);var g=d.closest("fieldset").data("ip-geo-block");d.parent().nextAll().toggle();d.toggleClass(a("dropup")).toggleClass(a("dropdown"));"undefined"!==typeof wpCookies&&(c[g+l[f]]=d.hasClass(a("dropdown"))?"o":"",wpCookies.setHash(a("%","admin"),c,new Date(Date.now()+2592E6)));u();return!1}),b(a("#","toggle-sections")).on("click",function(d){var g,p=0,t=[a("dropdown"),a("dropup")];d=b(a(".","field")).find("h2,h3");d.each(function(a){p+=b(this).hasClass(t[0])});d.each(function(a){g=b(this);g.parent().nextAll().toggle(p?!1:!0);g.removeClass(t.join(" ")).addClass(p?t[1]:t[0]);c[a+l[f]]=p?"":"o"});"undefined"!==typeof wpCookies&&wpCookies.setHash(a("%","admin"),c,new Date(Date.now()+2592E6));u();return!1}));b(a("#","inhibit")).on("submit",function(){return!1});switch(f){case 0:b(a("#","scan-code")).on("click",function(d){var c=b(this).parent();m("scanning",{cmd:"scan-code"},function(b){c.children("ul").length||c.append('<ul id="'+a("code-list")+'"></ul>');c=c.children("ul").empty();var d,g;for(d in b)b.hasOwnProperty(d)&&(d=e(d),"string"===typeof b[d]?g=e(b[d]):(g=e(b[d].code),d='<abbr title="'+e(b[d].type)+'">'+d+"</abbr>"),c.append("<li>"+d+' : <span class="'+a("notice")+'">'+g+"</span></li>"));c.show("slow")});return!1});b(a("@","matching_rule")).on("change",function(){b(a("@","white_list")).closest("tr").toggle("0"===this.value);b(a("@","black_list")).closest("tr").toggle("1"===this.value);return!1}).trigger("change");b(a("@","public_matching_rule")).on("change",function(){b(a("@","public_white_list")).closest("tr").toggle("0"===this.value);b(a("@","public_black_list")).closest("tr").toggle("1"===this.value);return!1}).trigger("change");b(a("@","update")).on("click",function(d){m("download",{cmd:"download"},function(d){var c,g,f;for(c in d)if(d.hasOwnProperty(c))for(g in f=d[c],f)f.hasOwnProperty(g)&&(g=e(g),f[g].filename&&b(a("@",c+"_"+g+"_path")).val(e(f[g].filename)),f[g].message&&b(a("#",c+"-"+g)).text(e(f[g].message)))});return!1});var k=a("%","settings");b(a("@","validation_login")).on("change",function(a){a=b(this);C(a,a,k,!0);return!1}).trigger("change");b('select[name^="'+k+'"]').on("change",function(d){d=b(this);var c,e=a(".","desc");d.next(e).empty();(c=d.children("option:selected").data("desc"))&&d.next(e).html(b.parseHTML(c));C(d,d,k,!0);return!1}).trigger("change");D("validate");b(a("#","export")).on("click",function(d){if("undefined"===typeof JSON)return A(),!1;var c=k,e={};b.each(b(this).closest("form").serializeArray(),function(a,b){-1!==b.name.indexOf(c)&&(e[b.name]=b.value)});e[c+="[signature]"]=h.btoa(w(e[c]));b(a("#","export-data")).val(JSON.stringify(e));b(a("#","export-form")).trigger("submit");return!1});b(a("#","file-dialog")).on("change",function(a){if("undefined"===typeof FileReader)return A(),!1;var b;(a=a.target.files[0])&&F(a,function(a){a=JSON.parse(a);b=k+"[signature]";"undefined"!==typeof a[b]&&(a[b]=h.btoa(w(a[b])));m("export-import",{cmd:"validate",data:JSON.stringify(a)},z)});return!1});b(a("#","import")).on("click",function(c){b(a("#","file-dialog")).trigger("click");return!1});b(a("#","default")).on("click",function(a){n("Import settings ?",function(){m("pre-defined",{cmd:"import-default"},z)});return!1});b(a("#","preferred")).on("click",function(a){n("Import settings ?",function(){m("pre-defined",{cmd:"import-preferred"},z)});return!1});b(a("@","create_table")).on("click",function(a){n("Create table ?",function(){B("create-table")});return!1});b(a("@","delete_table")).on("click",function(a){n("Delete table ?",function(){B("delete-table")});return!1});b("ul."+k+"_folding dfn").on("click",function(c){c=b(this).parent();c.children("li").toggle();c.toggleClass(a("dropup")).toggleClass(a("dropdown"));return!1});b(a("#","decode")).on("click",function(c){c=b(a("@","signature"));var d=c.val();-1===d.search(/,/)?c.val(w(h.atob(d))):c.val(h.btoa(w(d)));return!1});b("#submit").on("click",function(c){c=b(a("@","signature"));var d=c.val();-1!==d.search(/,/)&&c.val(h.btoa(w(d)));return!0});break;case 1:b(a("#","chart-countries")).length&&"object"===typeof google&&google.load("visualization","1",{packages:["corechart"],callback:function(){E.drawChart()}});b(a("@","clear_statistics")).on("click",function(a){n("Clear statistics ?",function(){y("statistics",null)});return!1});b(a("@","clear_cache")).on("click",function(a){n("Clear cache ?",function(){y("cache",null)});return!1});break;case 2:b(h).on(a("gmap-error"),function(){m(null,{cmd:"gmap-error"},function(a){x(a.page,a.tab)})});var q=b(a("#","map"));"object"===typeof google?q.each(function(){b(this).GmapRS()}):q.each(function(){b(this).empty().html('<iframe src="//maps.google.com/maps?output=embed" frameborder="0" style="width:100%; height:400px; border:0" allowfullscreen></iframe>')});b(a("@","get_location")).on("click",function(c){var d=b(a("#","whois")),f=b(a("@","ip_address")).val();f&&(d.hide().empty(),c=b.whois(f,function(c){var e,f="";for(e=0;e<c.length;e++)f+="<tr><td>"+c[e].name+"</td><td>"+c[e].value+"</td></tr>";d.html('<fieldset class="'+a("field")+'"><legend><h2 id="'+a("whois-title")+'" class="'+a("dropdown")+'">Whois</h2></legend><table class="'+a("table")+'">'+f+"</table><fieldset>").fadeIn("slow");b(a("#","whois-title")).on("click",function(c){c=b(this);c.parent().nextAll().toggle();c.toggleClass(a("dropup")).toggleClass(a("dropdown"));return!1})}),m("loading",{cmd:"search",ip:f,which:b(a("@","service")).val()},function(b){var c,d="",g=e(b.latitude||"0"),h=e(b.longitude||"0"),k=b.latitude||b.longitude?8:2;for(c in b)b.hasOwnProperty(c)&&(c=e(c),d+='<li><span class="'+a("title")+'">'+c+' : </span><span class="'+a("result")+'">'+e(b[c])+"</span></li>");"object"===typeof google?q.GmapRS("addMarker",{latitude:g,longitude:h,title:f,content:"<ul>"+d+"</ul>",show:!0,zoom:k}):q.css({height:"600px",backgroundColor:"transparent"}).empty().html('<ul style="margin-top:0; margin-left:1em;"><li><span class="'+a("title")+'">IP address : </span><span class="'+a("result")+'">'+e(f)+"</span></li>"+d+'</ul><iframe src="//maps.google.com/maps?q='+g+","+h+"&z="+k+'&output=embed" frameborder="0" style="width:100%; height:400px; border:0" allowfullscreen></iframe>')},[c]));return!1});b(a("@","ip_address")).val()&&b(a("@","get_location")).trigger("click");break;case 4:b(a(".","log")).hide().length&&m("logs",{cmd:"restore",which:null,time:ip_geo_block_time},function(c){for(var d in c)c.hasOwnProperty(d)&&(d=e(d),b(a("#","log-"+d)).html(c[d]));"function"===typeof b.fn.footable&&b(a(".","log")).fadeIn("slow").footable();b('tbody[id^="'+a("$","log-")+'"]').on("click","a",function(a){h.open(h.location.href.replace(/tab=\d/,"tab=2")+"&ip="+b(this).text().replace(/[^\w\.\:\*]/,""));return!1})}),b(a("@","clear_logs")).on("click",function(a){n("Clear logs ?",function(){y("logs",null)});return!1}),D("export-logs"),b(a("#","export-logs")).on("click",function(c){b(a("#","export-form")).trigger("submit");return!1})}})})(jQuery,window,document);
1
+ /*
2
+ Project: WordPress IP Geo Block
3
+ Copyright (c) 2015-2017 tokkonopapa (tokkonopapa@yahoo.com)
4
+ This software is released under the MIT License.
5
+ */
6
+ var ip_geo_block_time=new Date;(function(a,k,A){function b(a,b){var c={".":".ip-geo-block-","#":"#ip-geo-block-","@":"#ip_geo_block_settings_",$:"ip-geo-block-","%":"ip_geo_block_"};return"undefined"!==typeof b?c[a]+b:c.$+a}function f(a){return a?a.toString().replace(/[&<>"']/g,function(a){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[a]}):""}function v(c,e){e?a(b("#",c)).addClass(b("loading")):a(b("#",c)).removeClass(b("loading"))}function p(a,b){k.confirm(f(a))&&b()}function t(a,b){k.alert(a?f(a+": "+b):f(b))}function w(a,b){if(-1!==location.href.indexOf(a)){var c=f(a)+(b?"&"+f(b):"");"undefined"===typeof IP_GEO_BLOCK_ZEP?k.location.href=c:IP_GEO_BLOCK_ZEP.redirect(c)}}function m(b,e,n,l){b&&v(b,!0);e.action=IP_GEO_BLOCK.action;e.nonce=IP_GEO_BLOCK.nonce;a.post(IP_GEO_BLOCK.url,e).done(function(a,b,d){n(a)}).fail(function(a,b,d){t(b,a.responseText)}).always(function(){b&&(l?a.when.apply(a,l).then(function(){v(b,!1)}):v(b,!1))})}function x(a,b){m(a,{cmd:"clear-"+a,which:b},function(a){w(a.page,a.tab)})}function B(a){m(a,{cmd:a},function(a){w(a.page,a.tab)})}function C(a,e){e?a.removeClass("folding-disable"):(a.children("li").hide(),a.addClass("folding-disable"),a.removeClass(b("dropdown")).addClass(b("dropup")))}function y(b,e,n,l){var c=!1,c=c|(0===b.prop("type").indexOf("checkbox")&&b.is(":checked")),c=c|(0===b.prop("type").indexOf("select")&&"0"!==b.val());e.nextAll("."+n+"_folding").each(function(b,d){C(a(d),c&&l)})}function D(c){var e=b("@","validation_ajax_");C(c.closest("ul").next(),a(e+"1").is(":checked")||a(e+"2").is(":checked"))}function r(a){return String(a).replace(/[a-z]/gi,function(a){return String.fromCharCode(a.charCodeAt(0)+("n">a.toLowerCase()?13:-13))})}function J(a,b){var c=new FileReader;c.onload=function(a){b&&b(a.target.result)};c.onerror=function(a){t("Error",a.target.error.code)};c.readAsText(a)}function E(c){var e=b("%","settings"),n=c.is(":checked"),l=a(b("@","public_target_rule")),f=c.closest("tr").nextAll("tr");f.find('[name^="'+e+'"]').prop("disabled",!n);f.find(b(".","desc")).css("opacity",n?1:.5);y(c,l,e,"1"===l.val()?!0:!1)}function z(c){if(c){"string"===typeof c&&(c=JSON.parse(c));a(b("#","import")).closest("form").deserialize(c);a.each(["matching_rule","validation_login","validation_plugins","validation_themes"],function(c,e){a(b("@",e)).trigger("change")});E(a(b("@","validation_public")));var e=b("%","settings[providers][IPInfoDB]");a(b("@","providers_IPInfoDB")).prop("checked",c[e]?!0:!1);a(b("@","exception_admin")).trigger("change")}}function F(){a(b("#","chart-countries")).length&&G.drawChart()}function H(a,e){if("undefined"!==typeof wpCookies){var c="undefined"!==typeof IP_GEO_BLOCK_AUTH?IP_GEO_BLOCK_AUTH.home+IP_GEO_BLOCK_AUTH.admin:"";wpCookies.setHash(b("$",a),e,new Date(Date.now()+2592E6),c)}}function I(c){a("body").append('<div style="display:none"><form method="POST" id="'+b("export-form")+'" action="'+IP_GEO_BLOCK.url.replace("ajax.php","post.php")+'"><input type="hidden" name="action" value="'+IP_GEO_BLOCK.action+'" /><input type="hidden" name="nonce" value="'+IP_GEO_BLOCK.nonce+'" /><input type="hidden" name="cmd" value="'+c+'" /><input type="hidden" name="data" value="" id="'+b("export-data")+'"/><input type="submit" value="submit" /></form><input type="file" name="settings" id="'+b("file-dialog")+'" /></div>')}a.fn.deserialize=function(b,e){return this.each(function(){var c,e=this,f={};for(c in b)if(b.hasOwnProperty(c)){var k=decodeURIComponent(c);var d=decodeURIComponent(b[c]);f.hasOwnProperty(k)||(f[k]=[]);f[k].push(d)}a.each(f,function(b,d){a('[name="'+b+'"]:input',e).val(d)})})};var G={self:this,drawChart:function(){this.drawPie();this.drawLine()},dataPie:null,viewPie:null,drawPie:function(){if(!self.dataPie){self.dataPie=new google.visualization.DataTable;self.dataPie.addColumn("string","Country");self.dataPie.addColumn("number","Requests");var c;a(b("#","countries li")).each(function(){c=a(this).text().split(":");self.dataPie.addRow([c[0]||"",Number(c[1])])})}self.viewPie||(self.viewPie=new google.visualization.PieChart(A.getElementById(b("chart-countries"))));a(b("#","chart-countries")).width()&&self.viewPie.draw(self.dataPie,{backgroundColor:"#f1f1f1",chartArea:{left:0,top:"5%",width:"100%",height:"90%"},sliceVisibilityThreshold:.015})},dataLine:null,viewLine:null,drawLine:function(){if(!self.dataLine){self.dataLine=new google.visualization.DataTable;self.dataLine.addColumn("date","Date");self.dataLine.addColumn("number","comment");self.dataLine.addColumn("number","xmlrpc");self.dataLine.addColumn("number","login");self.dataLine.addColumn("number","admin");self.dataLine.addColumn("number","public");var c,e,f=[],l=a(b("#","targets tr"));var k=l.length;for(c=0;c<k;c++){f[c]=[];var m=l.eq(c).children();var d=m.length;for(e=0;e<d;e++){var h=m.eq(e).text();f[c].push(e?Number(h):new Date(h))}}self.dataLine.addRows(f)}self.viewLine||(self.viewLine=new google.visualization.LineChart(A.getElementById(b("chart-daily"))));if(c=a(b("#","chart-daily")).width())c=320<c?!0:!1,self.viewLine.draw(self.dataLine,{backgroundColor:"#f1f1f1",legend:{position:"bottom"},hAxis:{format:"MM/dd"},vAxis:{textPosition:c?"out":"in"},chartArea:{left:c?"10%":0,top:"5%",width:"100%",height:"75%"}})}};a(function(){var c=a('<fieldset class="'+b("field")+'"></fieldset>'),e=a("<legend></legend>"),n=Number(IP_GEO_BLOCK.tab)||0,l="undefined"!==typeof wpCookies&&wpCookies.getHash(b("$",n))||{};a(".form-table").each(function(d){var h=a(this),g=h.prevAll("h2,h3:first"),K=g.nextUntil(h);h.wrap(c).parent().attr("id",b("settings-"+d)).data("ip-geo-block",d).prepend(g.wrap(e).parent());K.insertBefore(h);1>=n&&("undefined"===typeof l[d]||"o"===l[d]?g.addClass(b("dropdown")).parent().nextAll().show():g.addClass(b("dropup")).parent().nextAll().hide())});1>=n&&(a("form").on("click","h2,h3",function(d){d=a(this);var h=d.closest("fieldset").data("ip-geo-block");d.parent().nextAll().toggle();d.toggleClass(b("dropup")).toggleClass(b("dropdown"));l[h]=d.hasClass(b("dropdown"))?"o":"x";H(n,l);F();return!1}),a(b("#","toggle-sections")).on("click",function(d){var h,g=0,c=[b("dropdown"),b("dropup")];d=a(b(".","field")).find("h2,h3");d.each(function(b){g+=a(this).hasClass(c[0])});d.each(function(b){h=a(this);h.parent().nextAll().toggle(g?!1:!0);h.removeClass(c.join(" ")).addClass(g?c[1]:c[0]);l[b]=g?"x":"o"});H(n,l);F();return!1}));a(b("#","inhibit")).on("submit",function(){return!1});switch(n){case 0:a('[id^="'+b("$","scan-")+'"]').on("click",function(d){d=a(this);var c=d.attr("id"),g=d.parent();m(c.replace(/^.*(?:scan)/,"scanning"),{cmd:"scan-code",which:c.replace(b("$","scan-"),"")},function(a){g.children("ul").length||g.append('<ul id="'+b("code-list")+'"></ul>');g=g.children("ul").empty();for(d in a)if(a.hasOwnProperty(d)){var d=f(d);if("string"===typeof a[d])var c=f(a[d]);else c=f(a[d].code),d='<abbr title="'+f(a[d].type)+'">'+d+"</abbr>";g.append("<li>"+d+' : <span class="'+b("notice")+'">'+c+"</span></li>")}g.show("slow")});return!1});a(b("@","matching_rule")).on("change",function(){a(b("@","white_list")).closest("tr").toggle("0"===this.value);a(b("@","black_list")).closest("tr").toggle("1"===this.value);return!1}).trigger("change");a(b("@","public_matching_rule")).on("change",function(){a(b("@","public_white_list")).closest("tr").toggle("0"===this.value);a(b("@","public_black_list")).closest("tr").toggle("1"===this.value);return!1}).trigger("change");a(b("@","update")).on("click",function(d){m("download",{cmd:"download"},function(d){var c;for(c in d)if(d.hasOwnProperty(c)){var h=d[c];for(e in h)if(h.hasOwnProperty(e)){var e=f(e);h[e].filename&&a(b("@",c+"_"+e+"_path")).val(f(h[e].filename));h[e].message&&a(b("#",c+"-"+e)).text(f(h[e].message))}}});return!1});var q=b("%","settings");a(b("@","validation_login")).on("change",function(b){b=a(this);y(b,b,q,!0);return!1}).trigger("change");a('select[name^="'+q+'"]').on("change",function(d){d=a(this);var c,g=b(".","desc");d.next(g).empty();(c=d.children("option:selected").data("desc"))&&d.next(g).html(a.parseHTML(c));y(d,d,q,!0);return!1}).trigger("change");a(b("@","validation_public")).on("change",function(b){E(a(this));return!1}).trigger("change");I("validate");a(b("#","export")).on("click",function(d){if("undefined"===typeof JSON)return t(null,IP_GEO_BLOCK.msg[6]),!1;var c=q,g={};a.each(a(this).closest("form").serializeArray(),function(a,b){-1!==b.name.indexOf(c)&&(g[b.name]=b.value)});g[c+="[signature]"]=k.btoa(r(g[c]));a(b("#","export-data")).val(JSON.stringify(g));a(b("#","export-form")).trigger("submit");return!1});a(b("#","file-dialog")).on("change",function(a){if("undefined"===typeof FileReader)return t(null,IP_GEO_BLOCK.msg[6]),!1;var b;(a=a.target.files[0])&&J(a,function(a){a=JSON.parse(a);b=q+"[signature]";"undefined"!==typeof a[b]&&(a[b]=k.btoa(r(a[b])));m("export-import",{cmd:"validate",data:JSON.stringify(a)},z)});return!1});a(b("#","import")).on("click",function(d){a(b("#","file-dialog")).trigger("click");return!1});a(b("#","default")).on("click",function(a){p(IP_GEO_BLOCK.msg[0],function(){m("pre-defined",{cmd:"import-default"},z)});return!1});a(b("#","preferred")).on("click",function(a){p(IP_GEO_BLOCK.msg[0],function(){m("pre-defined",{cmd:"import-preferred"},z)});return!1});a(b("@","create_table")).on("click",function(a){p(IP_GEO_BLOCK.msg[1],function(){B("create-table")});return!1});a(b("@","delete_table")).on("click",function(a){p(IP_GEO_BLOCK.msg[2],function(){B("delete-table")});return!1});a("ul."+q+"_folding>dfn").on("click",function(d){d=a(this).parent();d.children("li").toggle();d.toggleClass(b("dropup")).toggleClass(b("dropdown"));return!1});a(b("#","decode")).on("click",function(d){d=a(b("@","signature"));var c=d.val();-1===c.search(/,/)?d.val(r(k.atob(c))):d.val(k.btoa(r(c)));return!1});a(b("@","response_code")).on("change",function(b){b=parseInt(a(this).val()/100,10);var d=a(this).closest("tr").nextAll("tr");3>=b?d.each(function(b){0===b?a(this).show():1===b&&a(this).hide()}):d.each(function(b){0===b?a(this).hide():1===b&&a(this).show()})}).trigger("change");a(b("#","show-info")).on("click",function(d){a(b("#","wp-info")).empty();m("wp-info",{cmd:"show-info"},function(d){var c,e=[];for(c in d)d.hasOwnProperty(c)&&e.push("- "+c+" "+d[c]);a(b("#","wp-info")).html('<textarea rows="'+e.length+'">'+e.join("\n")+"</textarea>").find("textarea").select();return!1})});a(b("@","exception_admin")).on("change",function(d){var c=a.grep(a(this).val().split(","),function(a){return""!==a.replace(/^\s+|\s+$/g,"")});a(b("#","actions")).find("input").each(function(d,e){var h=a(this),g=h.attr("id").replace(b("%",""),"");-1!==a.inArray(g,c)?h.prop("checked",!0):h.prop("checked",!1)})}).trigger("change");a(b("#","actions")).on("click","input",function(d){var c=a(this).attr("id").replace(b("%",""),""),e=a(b("@","exception_admin")),f=a.grep(e.val().split(","),function(a){return""!==a.replace(/^\s+|\s+$/g,"")});d=a.inArray(c,f);-1===d?f.push(c):f.splice(d,1);e.val(f.join(",")).change()});D(a(b("@","validation_ajax_1")));a('input[id^="'+b("%","settings_validation_ajax_")+'"]').on("click",function(b){D(a(this))});a("#submit").on("click",function(c){c=a(b("@","signature"));var d=c.val();-1!==d.indexOf(",")&&c.val(k.btoa(r(d)));return!0});break;case 1:a(b("#","chart-countries")).length&&"object"===typeof google&&google.load("visualization","1",{packages:["corechart"],callback:function(){G.drawChart()}});a(b("@","clear_statistics")).on("click",function(a){p(IP_GEO_BLOCK.msg[3],function(){x("statistics",null)});return!1});a(b("@","clear_cache")).on("click",function(a){p(IP_GEO_BLOCK.msg[4],function(){x("cache",null)});return!1});break;case 2:a(k).on(b("gmap-error"),function(){m(null,{cmd:"gmap-error"},function(a){w(a.page,a.tab)})});var u=a(b("#","map"));"object"===typeof google?u.each(function(){a(this).GmapRS()}):u.each(function(){a(this).empty().html('<iframe src="//maps.google.com/maps?output=embed" frameborder="0" style="width:100%; height:400px; border:0" allowfullscreen></iframe>')});a(b("@","get_location")).on("click",function(c){var d=a(b("#","whois")),e=a(b("@","ip_address")).val();e&&(d.hide().empty(),c=a.whois(e,function(c){var e,f="";for(e=0;e<c.length;e++)f+="<tr><td>"+c[e].name+"</td><td>"+c[e].value+"</td></tr>";d.html('<fieldset class="'+b("field")+'"><legend><h2 id="'+b("whois-title")+'" class="'+b("dropdown")+'">Whois</h2></legend><table class="'+b("table")+'">'+f+"</table><fieldset>").fadeIn("slow");a(b("#","whois-title")).on("click",function(c){c=a(this);c.parent().nextAll().toggle();c.toggleClass(b("dropup")).toggleClass(b("dropdown"));return!1})}),m("loading",{cmd:"search",ip:e,which:a(b("@","service")).val()},function(a){var c="",d=f(a.latitude||"0"),h=f(a.longitude||"0"),g=a.latitude||a.longitude?8:2;for(k in a)if(a.hasOwnProperty(k)){var k=f(k);c+='<li><span class="'+b("title")+'">'+k+' : </span><span class="'+b("result")+'">'+f(a[k])+"</span></li>"}"object"===typeof google?u.GmapRS("addMarker",{latitude:d,longitude:h,title:e,content:"<ul>"+c+"</ul>",show:!0,zoom:g}):u.css({height:"600px",backgroundColor:"transparent"}).empty().html('<ul style="margin-top:0; margin-left:1em;"><li><span class="'+b("title")+'">IP address : </span><span class="'+b("result")+'">'+f(e)+"</span></li>"+c+'</ul><iframe src="//maps.google.com/maps?q='+d+","+h+"&z="+g+'&output=embed" frameborder="0" style="width:100%; height:400px; border:0" allowfullscreen></iframe>')},[c]));return!1});a(b("@","ip_address")).val()&&a(b("@","get_location")).trigger("click");break;case 4:a(b(".","log")).hide().length&&m("logs",{cmd:"restore",which:null,time:new Date-ip_geo_block_time},function(c){for(var d in c)c.hasOwnProperty(d)&&(d=f(d),a(b("#","log-"+d)).html(c[d]));"function"===typeof a.fn.footable&&a(b(".","log")).fadeIn("slow").footable();a('tbody[id^="'+b("$","log-")+'"]').on("click","a",function(b){k.open(k.location.href.replace(/tab=\d/,"tab=2")+"&ip="+a(this).text().replace(/[^\w\.\:\*]/,""));return!1})}),a(b("#","reset-filter")).on("click",function(b){a(".footable").trigger("footable_clear_filter");return!1}),a(b("@","clear_logs")).on("click",function(a){p(IP_GEO_BLOCK.msg[5],function(){x("logs",null)});return!1}),I("export-logs"),a(b("#","export-logs")).on("click",function(c){a(b("#","export-form")).trigger("submit");return!1})}})})(jQuery,window,document);
admin/js/authenticate.js CHANGED
@@ -1,7 +1,7 @@
1
  /*jslint white: true */
2
  /*!
3
  * Project: WP-ZEP - Zero-day exploit Prevention for wp-admin
4
- * Copyright (c) 2015-2016 tokkonopapa (tokkonopapa@yahoo.com)
5
  * This software is released under the MIT License.
6
  */
7
  // utility object
@@ -24,21 +24,23 @@ var IP_GEO_BLOCK_ZEP = {
24
  'use strict';
25
 
26
  // produce safe text for HTML
27
- function sanitize(str) {
28
- return str ? str.toString().replace(/[&<>"']/g, function (match) {
 
 
29
  return {
30
- '&': '&amp;',
31
- '<': '&lt;',
32
- '>': '&gt;',
33
  '"': '&quot;',
34
  "'": '&#39;'
35
  }[match];
36
- }) : '';
 
 
37
  }
38
 
39
  // Parse a URL and return its components
40
  function parse_uri(uri) {
41
- uri = decodeURIComponent(uri ? uri.toString() : '');
 
42
 
43
  var m = uri.match(
44
  // https://tools.ietf.org/html/rfc3986#appendix-B
@@ -121,14 +123,14 @@ var IP_GEO_BLOCK_ZEP = {
121
  // returns the absloute path as a string
122
  return real.join('/').replace(/\/\//g, '/');
123
  }
124
-
125
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
126
  function encodeURIComponentRFC3986(str) {
127
  return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
128
  return '%' + c.charCodeAt(0).toString(16);
129
  });
130
  }
131
-
132
  // append the nonce as query strings to the uri
133
  function add_query_nonce(uri, nonce) {
134
  if (typeof uri !== 'object') { // `string` or `undefined`
@@ -146,7 +148,7 @@ var IP_GEO_BLOCK_ZEP = {
146
  }
147
  }
148
 
149
- data.push(IP_GEO_BLOCK_ZEP.auth + '=' + encodeURIComponentRFC3986(nonce));
150
  uri.query = data.join('&');
151
 
152
  return compose_uri(uri);
@@ -163,14 +165,16 @@ var IP_GEO_BLOCK_ZEP = {
163
  // check the URI where the nonce is needed
164
  function is_admin(uri) {
165
  // parse uri and get real path
166
- uri = parse_uri(uri ? uri.toString().toLowerCase() : location.pathname);
 
167
 
168
  // get absolute path with flattening `./`, `../`, `//`
169
  var path = realpath(uri);
170
 
171
  // possibly scheme is `javascript` and path is `void(0);`
172
- if (/https?/.test(uri.scheme) || !uri.scheme) {
173
  // external domain (`http://example` or `www.example`)
 
174
  if (uri.authority && uri.authority !== location.host.toLowerCase()) {
175
  return -1; // external
176
  }
@@ -188,7 +192,7 @@ var IP_GEO_BLOCK_ZEP = {
188
  var theme_featured = function (data) {
189
  var i = data.length;
190
  while (i-- > 0) {
191
- if (data[i].indexOf('request%5Bbrowse%5D=ip-geo-block-auth') === 0) {
192
  data[i] = 'request%5Bbrowse%5D=featured'; // correct the parameter
193
  break;
194
  }
@@ -200,7 +204,7 @@ var IP_GEO_BLOCK_ZEP = {
200
  var media_library = function (data) {
201
  var i = data.length;
202
  while (i-- > 0) {
203
- if (data[i].indexOf('query%5Bip-geo-block-auth-nonce%5D=' + IP_GEO_BLOCK_AUTH.nonce) === 0) {
204
  delete data[i];
205
  break;
206
  }
@@ -224,7 +228,9 @@ var IP_GEO_BLOCK_ZEP = {
224
  // embed a nonce before an Ajax request is sent
225
  $(document).ajaxSend(function (event, jqxhr, settings) {
226
  var nonce = IP_GEO_BLOCK_ZEP.nonce;
227
- if (nonce && is_admin(settings.url) === 1) {
 
 
228
  // multipart/form-data (XMLHttpRequest Level 2)
229
  // IE10+, Firefox 4+, Safari 5+, Android 3+
230
  if (typeof window.FormData !== 'undefined' && settings.data instanceof FormData) {
@@ -247,7 +253,7 @@ var IP_GEO_BLOCK_ZEP = {
247
  if (callback) {
248
  data = callback(data);
249
  }
250
- data.push(IP_GEO_BLOCK_ZEP.auth + '=' + encodeURIComponentRFC3986(nonce));
251
  settings.data = data.join('&');
252
  }
253
  }
@@ -274,7 +280,7 @@ var IP_GEO_BLOCK_ZEP = {
274
  function moveEventHandlers($elems, eventsString, isDelegate) {
275
  var events = eventsString.split(/\s+/);
276
  $elems.each(function(i) {
277
- for (i = 0; i < events.length; i++) {
278
  var pureEventName = $.trim(events[i]).match(/[^\.]+/i)[0];
279
  moveHandlerToTop($(this), pureEventName, isDelegate);
280
  }
@@ -303,6 +309,10 @@ var IP_GEO_BLOCK_ZEP = {
303
  };
304
  }
305
 
 
 
 
 
306
  function attach_nonce() {
307
  var nonce = IP_GEO_BLOCK_ZEP.nonce;
308
  if (nonce) {
@@ -317,29 +327,39 @@ var IP_GEO_BLOCK_ZEP = {
317
  }
318
  });
319
 
320
- $body.onFirst('click', 'a', function (event) {
321
  // attr() returns 'string' or 'undefined'
322
  var $this = $(this),
323
- href = $this.attr('href'),
324
- rel = $this.attr('rel'),
325
  admin = "undefined" !== typeof href ? is_admin(href) : 0;
326
 
327
- // if admin area (except in comment) then add a nonce
328
  if (admin === 1) {
329
  $this.attr('href', add_query_nonce(
330
- href, (!rel || rel.indexOf('nofollow') < 0 ? nonce : 'nofollow')
331
  ));
332
  }
333
 
334
  // if external then redirect with no referrer not to leak out the nonce
335
- else if (admin === -1) {
 
 
 
336
  var w = window.open();
337
  w.document.write(
 
338
  '<meta name="referrer" content="never" />' +
339
  '<meta name="referrer" content="no-referrer" />' +
340
- '<meta http-equiv="refresh" content="0; url=' + sanitize(this.href) + '" />'
 
341
  );
342
  w.document.close();
 
 
 
 
 
343
  return false;
344
  }
345
  });
@@ -355,11 +375,11 @@ var IP_GEO_BLOCK_ZEP = {
355
  });
356
 
357
  // Restore post revisions (wp-admin/revisions.php @since 2.6.0)
358
- if ("undefined" !== typeof _wpRevisionsSettings) {
359
- var i, data = _wpRevisionsSettings.revisionData, n = data.length;
360
- for (i = 0; i < n; i++) {
361
  if (-1 === data[i].restoreUrl.indexOf(IP_GEO_BLOCK_ZEP.auth)) {
362
- _wpRevisionsSettings.revisionData[i].restoreUrl = add_query_nonce(data[i].restoreUrl, nonce);
363
  }
364
  }
365
  }
@@ -367,6 +387,16 @@ var IP_GEO_BLOCK_ZEP = {
367
  }
368
 
369
  $(function () {
 
 
 
 
 
 
 
 
 
 
370
  attach_nonce();
371
  IP_GEO_BLOCK_ZEP.init = true;
372
  });
1
  /*jslint white: true */
2
  /*!
3
  * Project: WP-ZEP - Zero-day exploit Prevention for wp-admin
4
+ * Copyright (c) 2015-2017 tokkonopapa (tokkonopapa@yahoo.com)
5
  * This software is released under the MIT License.
6
  */
7
  // utility object
24
  'use strict';
25
 
26
  // produce safe text for HTML
27
+ function escapeHTML(html) {
28
+ var elem = document.createElement('div');
29
+ elem.appendChild(document.createTextNode(html));
30
+ html = elem.innerHTML.replace(/["']/g, function (match) {
31
  return {
 
 
 
32
  '"': '&quot;',
33
  "'": '&#39;'
34
  }[match];
35
+ });
36
+ elem = '';
37
+ return html;
38
  }
39
 
40
  // Parse a URL and return its components
41
  function parse_uri(uri) {
42
+ // avoid malformed URI error when uri includes '%'
43
+ uri = /*decodeURIComponent*/(uri ? uri.toString() : '');
44
 
45
  var m = uri.match(
46
  // https://tools.ietf.org/html/rfc3986#appendix-B
123
  // returns the absloute path as a string
124
  return real.join('/').replace(/\/\//g, '/');
125
  }
126
+ /*
127
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
128
  function encodeURIComponentRFC3986(str) {
129
  return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
130
  return '%' + c.charCodeAt(0).toString(16);
131
  });
132
  }
133
+ */
134
  // append the nonce as query strings to the uri
135
  function add_query_nonce(uri, nonce) {
136
  if (typeof uri !== 'object') { // `string` or `undefined`
148
  }
149
  }
150
 
151
+ data.push(IP_GEO_BLOCK_ZEP.auth + '=' + encodeURIComponent(nonce));//RFC3986
152
  uri.query = data.join('&');
153
 
154
  return compose_uri(uri);
165
  // check the URI where the nonce is needed
166
  function is_admin(uri) {
167
  // parse uri and get real path
168
+ uri = uri || location.pathname;
169
+ uri = parse_uri(uri.toLowerCase());
170
 
171
  // get absolute path with flattening `./`, `../`, `//`
172
  var path = realpath(uri);
173
 
174
  // possibly scheme is `javascript` and path is `void(0);`
175
+ if (!uri.scheme || /^https?$/.test(uri.scheme)) {
176
  // external domain (`http://example` or `www.example`)
177
+ // https://tools.ietf.org/html/rfc6454#section-4
178
  if (uri.authority && uri.authority !== location.host.toLowerCase()) {
179
  return -1; // external
180
  }
192
  var theme_featured = function (data) {
193
  var i = data.length;
194
  while (i-- > 0) {
195
+ if (data[i].indexOf('request%5Bbrowse%5D=ip-geo-block-auth') !== -1) {
196
  data[i] = 'request%5Bbrowse%5D=featured'; // correct the parameter
197
  break;
198
  }
204
  var media_library = function (data) {
205
  var i = data.length;
206
  while (i-- > 0) {
207
+ if (data[i].indexOf('query%5Bip-geo-block-auth-nonce%5D=') !== -1) {
208
  delete data[i];
209
  break;
210
  }
228
  // embed a nonce before an Ajax request is sent
229
  $(document).ajaxSend(function (event, jqxhr, settings) {
230
  var nonce = IP_GEO_BLOCK_ZEP.nonce;
231
+
232
+ // POST to async-upload.php causes an error in https://wordpress.org/plugins/mammoth-docx-converter/
233
+ if (nonce && is_admin(settings.url) === 1 && !settings.url.match(/async-upload\.php$/)) {
234
  // multipart/form-data (XMLHttpRequest Level 2)
235
  // IE10+, Firefox 4+, Safari 5+, Android 3+
236
  if (typeof window.FormData !== 'undefined' && settings.data instanceof FormData) {
253
  if (callback) {
254
  data = callback(data);
255
  }
256
+ data.push(IP_GEO_BLOCK_ZEP.auth + '=' + encodeURIComponent(nonce));//RFC3986
257
  settings.data = data.join('&');
258
  }
259
  }
280
  function moveEventHandlers($elems, eventsString, isDelegate) {
281
  var events = eventsString.split(/\s+/);
282
  $elems.each(function(i) {
283
+ for (i = 0; i < events.length; ++i) {
284
  var pureEventName = $.trim(events[i]).match(/[^\.]+/i)[0];
285
  moveHandlerToTop($(this), pureEventName, isDelegate);
286
  }
309
  };
310
  }
311
 
312
+ function is_back_end() {
313
+ return (is_admin(location.pathname) === 1 || location.search.indexOf(IP_GEO_BLOCK_ZEP.auth) >= 0);
314
+ }
315
+
316
  function attach_nonce() {
317
  var nonce = IP_GEO_BLOCK_ZEP.nonce;
318
  if (nonce) {
327
  }
328
  });
329
 
330
+ $body.onFirst('click contextmenu', 'a', function (event) {
331
  // attr() returns 'string' or 'undefined'
332
  var $this = $(this),
333
+ href = $this.attr('href'),
334
+ rel = $this.attr('rel' ),
335
  admin = "undefined" !== typeof href ? is_admin(href) : 0;
336
 
337
+ // if admin area (except in comment with nofollow) then add a nonce
338
  if (admin === 1) {
339
  $this.attr('href', add_query_nonce(
340
+ href, (!rel || rel.indexOf('nofollow') < 0) ? nonce : 'nofollow'
341
  ));
342
  }
343
 
344
  // if external then redirect with no referrer not to leak out the nonce
345
+ else if (admin === -1 && is_back_end()) {
346
+ href = escapeHTML(decodeURIComponent(this.href));
347
+ href = href.split(';', 2).shift(); // avoid `url=...;url=javascript:...`
348
+
349
  var w = window.open();
350
  w.document.write(
351
+ '<!DOCTYPE html><html><head>' +
352
  '<meta name="referrer" content="never" />' +
353
  '<meta name="referrer" content="no-referrer" />' +
354
+ '<meta http-equiv="refresh" content="0; url=' + href + '" />' +
355
+ '<script>window.location.replace("' + href + '")</script></head></html>'
356
  );
357
  w.document.close();
358
+
359
+ // stop event propagation
360
+ event.stopImmediatePropagation();
361
+
362
+ // automatically call event.stopPropagation() and event.preventDefault()
363
  return false;
364
  }
365
  });
375
  });
376
 
377
  // Restore post revisions (wp-admin/revisions.php @since 2.6.0)
378
+ if ('undefined' !== typeof window._wpRevisionsSettings) {
379
+ var i, data = window._wpRevisionsSettings.revisionData, n = data.length;
380
+ for (i = 0; i < n; ++i) {
381
  if (-1 === data[i].restoreUrl.indexOf(IP_GEO_BLOCK_ZEP.auth)) {
382
+ window._wpRevisionsSettings.revisionData[i].restoreUrl = add_query_nonce(data[i].restoreUrl, nonce);
383
  }
384
  }
385
  }
387
  }
388
 
389
  $(function () {
390
+ // avoid conflict with "Open external links in a new window"
391
+ if (is_back_end()) {
392
+ $('a').each(function () {
393
+ if(!this.hasAttribute('onClick') && is_admin(this.getAttribute('href')) === -1) {
394
+ this.setAttribute('onClick', 'javascript:void(0);return false;');
395
+ }
396
+ });
397
+ }
398
+
399
+ // attach event to add nonce
400
  attach_nonce();
401
  IP_GEO_BLOCK_ZEP.init = true;
402
  });
admin/js/authenticate.min.js CHANGED
@@ -1,6 +1,6 @@
1
- /*!
2
- * Project: WP-ZEP - Zero-day exploit Prevention for wp-admin
3
- * Copyright (c) 2015-2016 tokkonopapa (tokkonopapa@yahoo.com)
4
- * This software is released under the MIT License.
5
- */
6
- var IP_GEO_BLOCK_ZEP={init:!1,auth:"ip-geo-block-auth-nonce",nonce:IP_GEO_BLOCK_AUTH.nonce||"",redirect:function(e){-1!==location.href.indexOf(e)&&(this.nonce&&(e+=(0<=e.indexOf("?")?"&":"?")+this.auth+"="+this.nonce),window.location.href=e)}};(function(e,t){function u(a){return a?a.toString().replace(/[&<>"']/g,function(a){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[a]}):""}function h(a){a=decodeURIComponent(a?a.toString():"");a=a.match(/^(?:([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/);return{scheme:a[1]||"",relative:a[2]||"",authority:a[3]||"",path:a[4]||"",query:a[5]||"",fragment:a[6]||""}}function m(a){return encodeURIComponent(a).replace(/[!'()*]/g,function(a){return"%"+a.charCodeAt(0).toString(16)})}function g(a,b){"object"!==typeof a&&(a=h(a||location.href));for(var c=a.query?a.query.split("&"):[],d=c.length;0<d--;)if(0===c[d].indexOf(IP_GEO_BLOCK_ZEP.auth)){c.splice(d,1);break}c.push(IP_GEO_BLOCK_ZEP.auth+"="+m(b));a.query=c.join("&");return(a.scheme?a.scheme+":":"")+(a.relative+a.path)+(a.query?"?"+a.query:"")+(a.fragment?"#"+a.fragment:"")}function k(a){a=h(a?a.toString().toLowerCase():location.pathname);var b,c=a,d=[];"object"!==typeof c&&(c=h(c));c=c.path;"/"!==c.charAt(0)&&(b=window.location.pathname,c=b.substring(0,b.lastIndexOf("/")+1)+c);c=c.split("/");""===c[c.length-1]&&(c.pop(),c[c.length-1]+="/");for(b in c)c.hasOwnProperty(b)&&"."!==c[b]&&(".."===c[b]?0<d.length&&d.pop():(1>d.length||""!==c[b])&&d.push(c[b]));b=d.join("/").replace(/\/\//g,"/");if(/https?/.test(a.scheme)||!a.scheme){if(a.authority&&a.authority!==location.host.toLowerCase())return-1;if((a.scheme||a.path||a.query)&&v.test(b))return 1}return 0}function n(a,b,c){var d=b.split(/\s+/);a.each(function(a){for(a=0;a<d.length;a++){var b=e.trim(d[a]).match(/[^\.]+/i)[0],f=e(this),l=b,b=c,f=e._data(f[0]).events[l],l=b?f.splice(f.delegateCount-1,1)[0]:f.pop();f.splice(b?0:f.delegateCount||0,0,l)}})}function p(){var a=IP_GEO_BLOCK_ZEP.nonce;if(a){var b=e("body");b.find("img").each(function(b){b=e(this).attr("src");1===k(b)&&e(this).attr("src",g(b,a))});b.onFirst("click","a",function(b){b=e(this);var c=b.attr("href"),d=b.attr("rel"),f="undefined"!==typeof c?k(c):0;if(1===f)b.attr("href",g(c,!d||0>d.indexOf("nofollow")?a:"nofollow"));else if(-1===f)return b=window.open(),b.document.write('<meta name="referrer" content="never" /><meta name="referrer" content="no-referrer" /><meta http-equiv="refresh" content="0; url='+u(this.href)+'" />'),b.document.close(),!1});b.onFirst("submit","form",function(b){b=e(this);var c=b.attr("action");1===k(c)&&b.attr("action",g(c,a))});if("undefined"!==typeof _wpRevisionsSettings)for(var c=_wpRevisionsSettings.revisionData,d=c.length,b=0;b<d;b++)-1===c[b].restoreUrl.indexOf(IP_GEO_BLOCK_ZEP.auth)&&(_wpRevisionsSettings.revisionData[b].restoreUrl=g(c[b].restoreUrl,a))}}var v=new RegExp("^(?:"+(IP_GEO_BLOCK_AUTH.home||"")+IP_GEO_BLOCK_AUTH.admin+"|"+(IP_GEO_BLOCK_AUTH.home||"")+IP_GEO_BLOCK_AUTH.plugins+"|"+(IP_GEO_BLOCK_AUTH.home||"")+IP_GEO_BLOCK_AUTH.themes+")(?:.*.php|.*/)?$"),q=function(a){for(var b=a.length;0<b--;)if(0===a[b].indexOf("request%5Bbrowse%5D=ip-geo-block-auth")){a[b]="request%5Bbrowse%5D=featured";break}return a},r={"upload.php":function(a){for(var b=a.length;0<b--;)if(0===a[b].indexOf("query%5Bip-geo-block-auth-nonce%5D="+IP_GEO_BLOCK_AUTH.nonce)){delete a[b];break}return a},"theme-install.php":q,"network/theme-install.php":q};e(t).ajaxSend(function(a,b,c){if((a=IP_GEO_BLOCK_ZEP.nonce)&&1===k(c.url))if("undefined"!==typeof window.FormData&&c.data instanceof FormData)c.data.append(IP_GEO_BLOCK_ZEP.auth,a);else if(b=h(c.url),"undefined"===typeof c.data||b.query)c.url=g(b,a);else{b=c.data?c.data.split("&"):[];var d;d=location.pathname;d=d.replace(IP_GEO_BLOCK_AUTH.home+IP_GEO_BLOCK_AUTH.admin,"");(d=r.hasOwnProperty(d)?r[d]:null)&&(b=d(b));b.push(IP_GEO_BLOCK_ZEP.auth+"="+m(a));c.data=b.join("&")}});"undefined"===typeof e.fn.onFirst&&(e.fn.onFirst=function(a,b){var c,d=e(this),f="string"===typeof b;e.fn.on.apply(d,arguments);if("object"===typeof a)for(c in a)a.hasOwnProperty(c)&&n(d,c,f);else"string"===typeof a&&n(d,a,f);return d});e(function(){p();IP_GEO_BLOCK_ZEP.init=!0});e(window).on("error",function(){IP_GEO_BLOCK_ZEP.init||p()})})(jQuery,document);
1
+ /*
2
+ Project: WP-ZEP - Zero-day exploit Prevention for wp-admin
3
+ Copyright (c) 2015-2017 tokkonopapa (tokkonopapa@yahoo.com)
4
+ This software is released under the MIT License.
5
+ */
6
+ var IP_GEO_BLOCK_ZEP={init:!1,auth:"ip-geo-block-auth-nonce",nonce:IP_GEO_BLOCK_AUTH.nonce||"",redirect:function(e){-1!==location.href.indexOf(e)&&(this.nonce&&(e+=(0<=e.indexOf("?")?"&":"?")+this.auth+"="+this.nonce),window.location.href=e)}};(function(e,m){function u(a){var b=m.createElement("div");b.appendChild(m.createTextNode(a));a=b.innerHTML.replace(/["']/g,function(a){return{'"':"&quot;","'":"&#39;"}[a]});b="";return a}function g(a){a=a?a.toString():"";a=a.match(/^(?:([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/);return{scheme:a[1]||"",relative:a[2]||"",authority:a[3]||"",path:a[4]||"",query:a[5]||"",fragment:a[6]||""}}function l(a,b){"object"!==typeof a&&(a=g(a||location.href));for(var d=a.query?a.query.split("&"):[],c=d.length;0<c--;)if(0===d[c].indexOf(IP_GEO_BLOCK_ZEP.auth)){d.splice(c,1);break}d.push(IP_GEO_BLOCK_ZEP.auth+"="+encodeURIComponent(b));a.query=d.join("&");return(a.scheme?a.scheme+":":"")+(a.relative+a.path)+(a.query?"?"+a.query:"")+(a.fragment?"#"+a.fragment:"")}function k(a){a=a||location.pathname;a=g(a.toLowerCase());var b=a,d=[];"object"!==typeof b&&(b=g(b));b=b.path;if("/"!==b.charAt(0)){var c=window.location.pathname;b=c.substring(0,c.lastIndexOf("/")+1)+b}b=b.split("/");""===b[b.length-1]&&(b.pop(),b[b.length-1]+="/");for(c in b)b.hasOwnProperty(c)&&"."!==b[c]&&(".."===b[c]?0<d.length&&d.pop():(1>d.length||""!==b[c])&&d.push(b[c]));c=d.join("/").replace(/\/\//g,"/");if(!a.scheme||/^https?$/.test(a.scheme)){if(a.authority&&a.authority!==location.host.toLowerCase())return-1;if((a.scheme||a.path||a.query)&&v.test(c))return 1}return 0}function n(a,b,d){var c=b.split(/\s+/);a.each(function(a){for(a=0;a<c.length;++a){var b=e.trim(c[a]).match(/[^\.]+/i)[0],h=e(this),f=b,b=d,h=e._data(h[0]).events[f],f=b?h.splice(h.delegateCount-1,1)[0]:h.pop();h.splice(b?0:h.delegateCount||0,0,f)}})}function p(){return 1===k(location.pathname)||0<=location.search.indexOf(IP_GEO_BLOCK_ZEP.auth)}function q(){var a=IP_GEO_BLOCK_ZEP.nonce;if(a){var b=e("body");b.find("img").each(function(b){b=e(this).attr("src");1===k(b)&&e(this).attr("src",l(b,a))});b.onFirst("click contextmenu","a",function(b){var d=e(this),c=d.attr("href"),f=d.attr("rel"),g="undefined"!==typeof c?k(c):0;if(1===g)d.attr("href",l(c,!f||0>f.indexOf("nofollow")?a:"nofollow"));else if(-1===g&&p())return c=u(decodeURIComponent(this.href)),c=c.split(";",2).shift(),d=window.open(),d.document.write('<!DOCTYPE html><html><head><meta name="referrer" content="never" /><meta name="referrer" content="no-referrer" /><meta http-equiv="refresh" content="0; url='+c+'" /><script>window.location.replace("'+c+'")\x3c/script></head></html>'),d.document.close(),b.stopImmediatePropagation(),!1});b.onFirst("submit","form",function(b){b=e(this);var c=b.attr("action");1===k(c)&&b.attr("action",l(c,a))});if("undefined"!==typeof window._wpRevisionsSettings)for(var d=window._wpRevisionsSettings.revisionData,c=d.length,b=0;b<c;++b)-1===d[b].restoreUrl.indexOf(IP_GEO_BLOCK_ZEP.auth)&&(window._wpRevisionsSettings.revisionData[b].restoreUrl=l(d[b].restoreUrl,a))}}var v=new RegExp("^(?:"+(IP_GEO_BLOCK_AUTH.home||"")+IP_GEO_BLOCK_AUTH.admin+"|"+(IP_GEO_BLOCK_AUTH.home||"")+IP_GEO_BLOCK_AUTH.plugins+"|"+(IP_GEO_BLOCK_AUTH.home||"")+IP_GEO_BLOCK_AUTH.themes+")(?:.*.php|.*/)?$"),r=function(a){for(var b=a.length;0<b--;)if(-1!==a[b].indexOf("request%5Bbrowse%5D=ip-geo-block-auth")){a[b]="request%5Bbrowse%5D=featured";break}return a},t={"upload.php":function(a){for(var b=a.length;0<b--;)if(-1!==a[b].indexOf("query%5Bip-geo-block-auth-nonce%5D=")){delete a[b];break}return a},"theme-install.php":r,"network/theme-install.php":r};e(m).ajaxSend(function(a,b,d){if((a=IP_GEO_BLOCK_ZEP.nonce)&&1===k(d.url)&&!d.url.match(/async-upload\.php$/))if("undefined"!==typeof window.FormData&&d.data instanceof FormData)d.data.append(IP_GEO_BLOCK_ZEP.auth,a);else if(b=g(d.url),"undefined"===typeof d.data||b.query)d.url=l(b,a);else{b=d.data?d.data.split("&"):[];var c=location.pathname;c=c.replace(IP_GEO_BLOCK_AUTH.home+IP_GEO_BLOCK_AUTH.admin,"");(c=t.hasOwnProperty(c)?t[c]:null)&&(b=c(b));b.push(IP_GEO_BLOCK_ZEP.auth+"="+encodeURIComponent(a));d.data=b.join("&")}});"undefined"===typeof e.fn.onFirst&&(e.fn.onFirst=function(a,b){var d,c=e(this),f="string"===typeof b;e.fn.on.apply(c,arguments);if("object"===typeof a)for(d in a)a.hasOwnProperty(d)&&n(c,d,f);else"string"===typeof a&&n(c,a,f);return c});e(function(){p()&&e("a").each(function(){this.hasAttribute("onClick")||-1!==k(this.getAttribute("href"))||this.setAttribute("onClick","javascript:void(0);return false;")});q();IP_GEO_BLOCK_ZEP.init=!0});e(window).on("error",function(){IP_GEO_BLOCK_ZEP.init||q()})})(jQuery,document);
admin/js/footable.min.js CHANGED
@@ -12,7 +12,7 @@
12
  * Date: 11 Nov 2014
13
  *
14
  * This is a customized version for IP Geo Block.
15
- * footable.js + footable.paginate.js + footable.sort.js + footable.striping.js
16
  * https://github.com/fooplugins/FooTable/issues/298
17
  */
18
  (function(d,m,w){function t(){var d=this;d.id=null;d.busy=!1;d.start=function(g,h){d.busy||(d.stop(),d.id=setTimeout(function(){g();d.id=null;d.busy=!1},h),d.busy=!0)};d.stop=function(){null!==d.id&&(clearTimeout(d.id),d.id=null,d.busy=!1)}}function v(a,g,h){var b=this;b.id=h;b.table=a;b.options=g;b.breakpoints=[];b.breakpointNames="";b.columns={};b.plugins=m.footable.plugins.load(b);var l=b.options,e=l.classes,n=l.events,k=l.triggers,r=0;b.timers={resize:new t,register:function(c){b.timers[c]=new t;return b.timers[c]}};b.init=function(){var c=d(m),f=d(b.table);m.footable.plugins.init(b);if(f.hasClass(e.loaded))b.raise(n.alreadyInitialized);else{b.raise(n.initializing);f.addClass(e.loading);f.find(l.columnDataSelector).each(function(){var c=b.getColumnData(this);b.columns[c.index]=c});for(var a in l.breakpoints)b.breakpoints.push({name:a,width:l.breakpoints[a]}),b.breakpointNames+=a+" ";b.breakpoints.sort(function(b,c){return b.width-c.width});f.unbind(k.initialize).bind(k.initialize,function(){f.removeData("footable_info");f.data("breakpoint","");f.trigger(k.resize);f.removeClass(e.loading);f.addClass(e.loaded).addClass(e.main);b.raise(n.initialized)}).unbind(k.redraw).bind(k.redraw,function(){b.redraw()}).unbind(k.resize).bind(k.resize,function(){b.resize()}).unbind(k.expandFirstRow).bind(k.expandFirstRow,function(){f.find(l.toggleSelector).first().not("."+e.detailShow).trigger(k.toggleRow)}).unbind(k.expandAll).bind(k.expandAll,function(){f.find(l.toggleSelector).not("."+e.detailShow).trigger(k.toggleRow)}).unbind(k.collapseAll).bind(k.collapseAll,function(){f.find("."+e.detailShow).trigger(k.toggleRow)});f.trigger(k.initialize);c.bind("resize.footable",function(){b.timers.resize.stop();b.timers.resize.start(function(){b.raise(k.resize)},l.delay)})}};b.addRowToggle=function(){if(l.addRowToggle){var c=d(b.table);c.find("span."+e.toggle).remove();for(var f in b.columns){var a=b.columns[f];if(a.toggle){c=c.find("> tbody");a="> tr:not(."+e.detail+",."+e.disabled+") > td:nth-child("+(parseInt(a.index,10)+1)+"),> tr:not(."+e.detail+",."+e.disabled+") > th:nth-child("+(parseInt(a.index,10)+1)+")";c.find(a).not("."+e.detailCell).prepend(d(l.toggleHTMLElement).addClass(e.toggle));return}}c.find("> tbody > tr:not(."+e.detail+",."+e.disabled+") > td:first-child").add("> tbody > tr:not(."+e.detail+",."+e.disabled+") > th:first-child").not("."+e.detailCell).prepend(d(l.toggleHTMLElement).addClass(e.toggle))}};b.setColumnClasses=function(){var c=d(b.table),f;for(f in b.columns){var a=b.columns[f];if(null!==a.className){var q="",p=!0;d.each(a.matches,function(b,c){p||(q+=", ");q+="> tbody > tr:not(."+e.detail+") > td:nth-child("+(parseInt(c,10)+1)+")";p=!1});c.find(q).not("."+e.detailCell).addClass(a.className)}}};b.bindToggleSelectors=function(){var c=d(b.table);b.hasAnyBreakpointColumn()&&(c.find(l.toggleSelector).unbind(k.toggleRow).bind(k.toggleRow,function(c){c=d(this).is("tr")?d(this):d(this).parents("tr:first");b.toggleDetail(c)}),c.find(l.toggleSelector).unbind("click.footable").bind("click.footable",function(b){c.is(".breakpoint")&&d(b.target).is("td,th,."+e.toggle)&&d(this).trigger(k.toggleRow)}))};b.parse=function(b,f){return(l.parsers[f.type]||l.parsers.alpha)(b)};b.getColumnData=function(c){var f=d(c),a=f.data("hide"),e=f.index(),a=jQuery.map((a||"").split(","),function(b){return jQuery.trim(b)}),e={index:e,hide:{},type:f.data("type")||"alpha",name:f.data("name")||d.trim(f.text()),ignore:f.data("ignore")||!1,toggle:f.data("toggle")||!1,className:f.data("class")||null,matches:[],names:{},group:f.data("group")||null,groupName:null,isEditable:f.data("editable")};if(null!==e.group){var p=d(b.table).find('> thead > tr.footable-group-row > th[data-group="'+e.group+'"], > thead > tr.footable-group-row > td[data-group="'+e.group+'"]').first();e.groupName=b.parse(p,{type:"alpha"})}p=parseInt(f.prev().attr("colspan")||0,10);r+=1<p?p-1:0;var p=parseInt(f.attr("colspan")||0,10),g=e.index+r;if(1<p)for(var h=f.data("names"),h=(h||"").split(","),k=0;k<p;k++)e.matches.push(k+g),k<h.length&&(e.names[k+g]=h[k]);else e.matches.push(g);e.hide["default"]="all"===f.data("hide")||0<=d.inArray("default",a);var p=!1,m;for(m in l.breakpoints)e.hide[m]="all"===f.data("hide")||0<=d.inArray(m,a),p=p||e.hide[m];e.hasBreakpoint=p;return b.raise(n.columnData,{column:{data:e,th:c}}).column.data};b.getViewportWidth=function(){return window.innerWidth||(document.body?document.body.offsetWidth:0)};b.calculateWidth=function(b,f){if(jQuery.isFunction(l.calculateWidthOverride))return l.calculateWidthOverride(b,f);f.viewportWidth<f.width&&(f.width=f.viewportWidth);f.parentWidth<f.width&&(f.width=f.parentWidth);return f};b.hasBreakpointColumn=function(c){for(var f in b.columns)if(b.columns[f].hide[c]&&!b.columns[f].ignore)return!0;return!1};b.hasAnyBreakpointColumn=function(){for(var c in b.columns)if(b.columns[c].hasBreakpoint)return!0;return!1};b.resize=function(){var c=d(b.table);if(c.is(":visible"))if(b.hasAnyBreakpointColumn()){var f={width:c.width(),viewportWidth:b.getViewportWidth(),parentWidth:c.parent().width()},f=b.calculateWidth(c,f),a=c.data("footable_info");c.data("footable_info",f);b.raise(n.resizing,{old:a,info:f});if(!a||a&&a.width&&a.width!==f.width){for(var e=null,g,h=0;h<b.breakpoints.length;h++)if((g=b.breakpoints[h])&&g.width&&f.width<=g.width){e=g;break}e=null===e?"default":e.name;g=b.hasBreakpointColumn(e);h=c.data("breakpoint");c.data("breakpoint",e).removeClass("default breakpoint").removeClass(b.breakpointNames).addClass(e+(g?" breakpoint":""));e!==h&&(c.trigger(k.redraw),b.raise(n.breakpoint,{breakpoint:e,info:f}))}b.raise(n.resized,{old:a,info:f})}else c.trigger(k.redraw)};b.redraw=function(){b.addRowToggle();b.bindToggleSelectors();b.setColumnClasses();var c=d(b.table),f=c.data("breakpoint"),a=b.hasBreakpointColumn(f);c.find("> tbody > tr:not(."+e.detail+")").data("detail_created",!1).end().find("> thead > tr:last-child > th").each(function(){var a=b.columns[d(this).index()],g="",h=!0;d.each(a.matches,function(b,c){h||(g+=", ");var a=c+1;g+="> tbody > tr:not(."+e.detail+") > td:nth-child("+a+")";g+=", > tfoot > tr:not(."+e.detail+") > td:nth-child("+a+")";g+=", > colgroup > col:nth-child("+a+")";h=!1});var g=g+(', > thead > tr[data-group-row="true"] > th[data-group="'+a.group+'"]'),k=c.find(g).add(this);""!==f&&(!1===a.hide[f]?k.addClass("footable-visible").show():k.removeClass("footable-visible").hide());if(1===c.find("> thead > tr.footable-group-row").length){var k=c.find('> thead > tr:last-child > th[data-group="'+a.group+'"]:visible, > thead > tr:last-child > th[data-group="'+a.group+'"]:visible'),a=c.find('> thead > tr.footable-group-row > th[data-group="'+a.group+'"], > thead > tr.footable-group-row > td[data-group="'+a.group+'"]'),l=0;d.each(k,function(){l+=parseInt(d(this).attr("colspan")||1,10)});0<l?a.attr("colspan",l).show():a.hide()}}).end().find("> tbody > tr."+e.detailShow).each(function(){b.createOrUpdateDetailRow(this)});c.find("[data-bind-name]").each(function(){b.toggleInput(this)});c.find("> tbody > tr."+e.detailShow+":visible").each(function(){var b=d(this).next();b.hasClass(e.detail)&&(a?b.show():b.hide())});c.find("> thead > tr > th.footable-last-column, > tbody > tr > td.footable-last-column").removeClass("footable-last-column");c.find("> thead > tr > th.footable-first-column, > tbody > tr > td.footable-first-column").removeClass("footable-first-column");c.find("> thead > tr, > tbody > tr").find("> th.footable-visible:last, > td.footable-visible:last").addClass("footable-last-column").end().find("> th.footable-visible:first, > td.footable-visible:first").addClass("footable-first-column");b.raise(n.redrawn)};b.toggleDetail=function(c){c=c.jquery?c:d(c);var a=c.next();c.hasClass(e.detailShow)?(c.removeClass(e.detailShow),a.hasClass(e.detail)&&a.hide(),b.raise(n.rowCollapsed,{row:c[0]})):(b.createOrUpdateDetailRow(c[0]),c.addClass(e.detailShow).next().show(),b.raise(n.rowExpanded,{row:c[0]}))};b.removeRow=function(c){c=c.jquery?c:d(c);c.hasClass(e.detail)&&(c=c.prev());var a=c.next();!0===c.data("detail_created")&&a.remove();c.remove();b.raise(n.rowRemoved)};b.appendRow=function(c){c=c.jquery?c:d(c);d(b.table).find("tbody").append(c);b.redraw()};b.getColumnFromTdIndex=function(c){var a=null,e;for(e in b.columns)if(0<=d.inArray(c,b.columns[e].matches)){a=b.columns[e];break}return a};b.createOrUpdateDetailRow=function(c){c=d(c);var a=c.next(),g,h=[];if(!0===c.data("detail_created"))return!0;if(c.is(":hidden"))return!1;b.raise(n.rowDetailUpdating,{row:c,detail:a});c.find("> td:hidden").each(function(){var c=d(this).index(),a=b.getColumnFromTdIndex(c),f=a.name;if(!0===a.ignore)return!0;c in a.names&&(f=a.names[c]);var g=d(this).attr("data-bind-name");if(null!=g&&d(this).is(":empty")){var k=d("."+e.detailInnerValue+'[data-bind-value="'+g+'"]');d(this).html(d(k).contents().detach())}var l;!1!==a.isEditable&&(a.isEditable||0<d(this).find(":input").length)&&(null==g&&(g="bind-"+d.now()+"-"+c,d(this).attr("data-bind-name",g)),l=d(this).contents().detach());l||(l=d(this).contents().clone(!0,!0));h.push({name:f,value:b.parse(this,a),display:l,group:a.group,groupName:a.groupName,bindName:g});return!0});if(0===h.length)return!1;g=c.find("> td:visible").length;var k=a.hasClass(e.detail);k||(a=d('<tr class="'+e.detail+'"><td class="'+e.detailCell+'"><div class="'+e.detailInner+'"></div></td></tr>'),c.after(a));a.find("> td:first").attr("colspan",g);g=a.find("."+e.detailInner).empty();l.createDetail(g,h,l.createGroupedDetail,l.detailSeparator,e);c.data("detail_created",!0);b.raise(n.rowDetailUpdated,{row:c,detail:a});return!k};b.raise=function(a,e){!0===b.options.debug&&d.isFunction(b.options.log)&&b.options.log(a,"event");e=e||{};var g={ft:b};d.extend(!0,g,e);var h=d.Event(a,g);h.ft||d.extend(!0,h,g);d(b.table).trigger(h);return h};b.reset=function(){var a=d(b.table);a.removeData("footable_info").data("breakpoint","").removeClass(e.loading).removeClass(e.loaded);a.find(l.toggleSelector).unbind(k.toggleRow).unbind("click.footable");a.find("> tbody > tr").removeClass(e.detailShow);a.find("> tbody > tr."+e.detail).remove();b.raise(n.reset)};b.toggleInput=function(b){var a=d(b).attr("data-bind-name");null!=a&&(a=d("."+e.detailInnerValue+'[data-bind-value="'+a+'"]'),null!=a&&(d(b).is(":visible")?d(a).is(":empty")||d(b).html(d(a).contents().detach()):d(b).is(":empty")||d(a).html(d(b).contents().detach())))};b.init();return b}m.footable={options:{delay:100,breakpoints:{phone:480,tablet:1024},parsers:{alpha:function(a){return d(a).data("value")||d.trim(d(a).text())},numeric:function(a){a=d(a).data("value")||d(a).text().replace(/[^0-9.\-]/g,"");a=parseFloat(a);isNaN(a)&&(a=0);return a}},addRowToggle:!0,calculateWidthOverride:null,toggleSelector:" > tbody > tr:not(.footable-row-detail)",columnDataSelector:"> thead > tr:last-child > th, > thead > tr:last-child > td",detailSeparator:":",toggleHTMLElement:"<span />",createGroupedDetail:function(a){for(var d={_none:{name:null,data:[]}},h=0;h<a.length;h++){var b=a[h].group;null!==b?(b in d||(d[b]={name:a[h].groupName||a[h].group,data:[]}),d[b].data.push(a[h])):d._none.data.push(a[h])}return d},createDetail:function(a,g,h,b,l){g=h(g);for(var e in g)if(0!==g[e].data.length)for("_none"!==e&&a.append('<div class="'+l.detailInnerGroup+'">'+g[e].name+"</div>"),h=0;h<g[e].data.length;h++){var m=g[e].data[h].name?b:"";a.append(d("<div></div>").addClass(l.detailInnerRow).append(d("<div></div>").addClass(l.detailInnerName).append(g[e].data[h].name+m)).append(d("<div></div>").addClass(l.detailInnerValue).attr("data-bind-value",g[e].data[h].bindName).append(g[e].data[h].display)))}},classes:{main:"footable",loading:"footable-loading",loaded:"footable-loaded",toggle:"footable-toggle",disabled:"footable-disabled",detail:"footable-row-detail",detailCell:"footable-row-detail-cell",detailInner:"footable-row-detail-inner",detailInnerRow:"footable-row-detail-row",detailInnerGroup:"footable-row-detail-group",detailInnerName:"footable-row-detail-name",detailInnerValue:"footable-row-detail-value",detailShow:"footable-detail-show"},triggers:{initialize:"footable_initialize",resize:"footable_resize",redraw:"footable_redraw",toggleRow:"footable_toggle_row",expandFirstRow:"footable_expand_first_row",expandAll:"footable_expand_all",collapseAll:"footable_collapse_all"},events:{alreadyInitialized:"footable_already_initialized",initializing:"footable_initializing",initialized:"footable_initialized",resizing:"footable_resizing",resized:"footable_resized",redrawn:"footable_redrawn",breakpoint:"footable_breakpoint",columnData:"footable_column_data",rowDetailUpdating:"footable_row_detail_updating",rowDetailUpdated:"footable_row_detail_updated",rowCollapsed:"footable_row_collapsed",rowExpanded:"footable_row_expanded",rowRemoved:"footable_row_removed",reset:"footable_reset"},debug:!1,log:null},version:{major:0,minor:5,toString:function(){return m.footable.version.major+"."+m.footable.version.minor},parse:function(a){a=/(\d+)\.?(\d+)?\.?(\d+)?/.exec(a);return{major:parseInt(a[1],10)||0,minor:parseInt(a[2],10)||0,patch:parseInt(a[3],10)||0}}},plugins:{_validate:function(a){if(!d.isFunction(a))return!0===m.footable.options.debug&&console.error('Validation failed, expected type "function", received type "{0}".',typeof a),!1;a=new a;if("string"!==typeof a.name)return!0===m.footable.options.debug&&console.error('Validation failed, plugin does not implement a string property called "name".',a),!1;if(!d.isFunction(a.init))return!0===m.footable.options.debug&&console.error('Validation failed, plugin "'+a.name+'" does not implement a function called "init".',a),!1;!0===m.footable.options.debug&&console.log('Validation succeeded for plugin "'+a.name+'".',a);return!0},registered:[],register:function(a,g){m.footable.plugins._validate(a)&&(m.footable.plugins.registered.push(a),"object"===typeof g&&d.extend(!0,m.footable.options,g))},load:function(a){var d=[],h,b;for(b=0;b<m.footable.plugins.registered.length;b++)try{h=m.footable.plugins.registered[b],d.push(new h(a))}catch(l){!0===m.footable.options.debug&&console.error(l)}return d},init:function(a){for(var d=0;d<a.plugins.length;d++)try{a.plugins[d].init(a)}catch(h){!0===m.footable.options.debug&&console.error(h)}}}};var u=0;d.fn.footable=function(a){a=a||{};var g=d.extend(!0,{},m.footable.options,a);return this.each(function(){u++;var a=new v(this,g,u);d(this).data("footable",a)})}})(jQuery,window);
@@ -21,4 +21,6 @@
21
  /* sort */
22
  (function(t,e,undefined){function a(){var e=this;e.name="Footable Sortable",e.init=function(a){e.footable=a,a.options.sort===!0&&t(a.table).unbind(".sorting").bind({"footable_initialized.sorting":function(){var i,o,n=t(a.table),r=(n.find("> tbody"),a.options.classes.sort);if(n.data("sort")!==!1){n.find("> thead > tr:last-child > th, > thead > tr:last-child > td").each(function(){var e=t(this),i=a.columns[e.index()];i.sort.ignore===!0||e.hasClass(r.sortable)||(e.addClass(r.sortable),t("<span />").addClass(r.indicator).appendTo(e))}),n.find("> thead > tr:last-child > th."+r.sortable+", > thead > tr:last-child > td."+r.sortable).unbind("click.footable").bind("click.footable",function(a){a.preventDefault(),o=t(this);var i=!o.hasClass(r.sorted);return e.doSort(o.index(),i),!1});var l=!1;for(var s in a.columns)if(i=a.columns[s],i.sort.initial){var d="descending"!==i.sort.initial;e.doSort(i.index,d);break}l&&a.bindToggleSelectors()}},"footable_redrawn.sorting":function(){var i=t(a.table),o=a.options.classes.sort;i.data("sorted")>=0&&i.find("> thead > tr:last-child > th").each(function(a){var i=t(this);return i.hasClass(o.sorted)||i.hasClass(o.descending)?(e.doSort(a),undefined):undefined})},"footable_column_data.sorting":function(e){var a=t(e.column.th);e.column.data.sort=e.column.data.sort||{},e.column.data.sort.initial=a.data("sort-initial")||!1,e.column.data.sort.ignore=a.data("sort-ignore")||!1,e.column.data.sort.selector=a.data("sort-selector")||null;var i=a.data("sort-match")||0;i>=e.column.data.matches.length&&(i=0),e.column.data.sort.match=e.column.data.matches[i]}}).data("footable-sort",e)},e.doSort=function(a,i){var o=e.footable;if(t(o.table).data("sort")!==!1){var n=t(o.table),r=n.find("> tbody"),l=o.columns[a],s=n.find("> thead > tr:last-child > th:eq("+a+")"),d=o.options.classes.sort,f=o.options.events.sort;if(i=i===undefined?s.hasClass(d.sorted):"toggle"===i?!s.hasClass(d.sorted):i,l.sort.ignore===!0)return!0;var u=o.raise(f.sorting,{column:l,direction:i?"ASC":"DESC"});u&&u.result===!1||(n.data("sorted",l.index),n.find("> thead > tr:last-child > th, > thead > tr:last-child > td").not(s).removeClass(d.sorted+" "+d.descending),i===undefined&&(i=s.hasClass(d.sorted)),i?s.removeClass(d.descending).addClass(d.sorted):s.removeClass(d.sorted).addClass(d.descending),e.sort(o,r,l,i),o.bindToggleSelectors(),o.raise(f.sorted,{column:l,direction:i?"ASC":"DESC"}))}},e.rows=function(e,a,i){var o=[];return a.find("> tr").each(function(){var a=t(this),n=null;if(a.hasClass(e.options.classes.detail))return!0;a.next().hasClass(e.options.classes.detail)&&(n=a.next().get(0));var r={row:a,detail:n};return i!==undefined&&(r.value=e.parse(this.cells[i.sort.match],i)),o.push(r),!0}).detach(),o},e.sort=function(t,a,i,o){var n=e.rows(t,a,i),r=t.options.sorters[i.type]||t.options.sorters.alpha;n.sort(function(t,e){return o?r(t.value,e.value):r(e.value,t.value)});for(var l=0;n.length>l;l++)a.append(n[l].row),null!==n[l].detail&&a.append(n[l].detail)}}if(e.footable===undefined||null===e.footable)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={sort:!0,sorters:{alpha:function(t,e){return"string"==typeof t&&(t=t.toLowerCase()),"string"==typeof e&&(e=e.toLowerCase()),t===e?0:e>t?-1:1},numeric:function(t,e){return t-e}},classes:{sort:{sortable:"footable-sortable",sorted:"footable-sorted",descending:"footable-sorted-desc",indicator:"footable-sort-indicator"}},events:{sort:{sorting:"footable_sorting",sorted:"footable_sorted"}}};e.footable.plugins.register(a,i)})(jQuery,window);
23
  /* striping */
24
- (function(t,e,undefined){function a(){var e=this;e.name="Footable Striping",e.init=function(a){e.footable=a,t(a.table).unbind("striping").bind({"footable_initialized.striping footable_row_removed.striping footable_redrawn.striping footable_sorted.striping footable_filtered.striping":function(){t(this).data("striping")!==!1&&e.setupStriping(a)}})},e.setupStriping=function(e){var a=0;t(e.table).find("> tbody > tr:not(.footable-row-detail)").each(function(){var i=t(this);i.removeClass(e.options.classes.striping.even).removeClass(e.options.classes.striping.odd),0===a%2?i.addClass(e.options.classes.striping.even):i.addClass(e.options.classes.striping.odd),a++})}}if(e.footable===undefined||null===e.foobox)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={striping:{enabled:!0},classes:{striping:{odd:"footable-odd",even:"footable-even"}}};e.footable.plugins.register(a,i)})(jQuery,window);
 
 
12
  * Date: 11 Nov 2014
13
  *
14
  * This is a customized version for IP Geo Block.
15
+ * footable.js + footable.paginate.js + footable.sort.js + footable.striping.js + footable.filter.js
16
  * https://github.com/fooplugins/FooTable/issues/298
17
  */
18
  (function(d,m,w){function t(){var d=this;d.id=null;d.busy=!1;d.start=function(g,h){d.busy||(d.stop(),d.id=setTimeout(function(){g();d.id=null;d.busy=!1},h),d.busy=!0)};d.stop=function(){null!==d.id&&(clearTimeout(d.id),d.id=null,d.busy=!1)}}function v(a,g,h){var b=this;b.id=h;b.table=a;b.options=g;b.breakpoints=[];b.breakpointNames="";b.columns={};b.plugins=m.footable.plugins.load(b);var l=b.options,e=l.classes,n=l.events,k=l.triggers,r=0;b.timers={resize:new t,register:function(c){b.timers[c]=new t;return b.timers[c]}};b.init=function(){var c=d(m),f=d(b.table);m.footable.plugins.init(b);if(f.hasClass(e.loaded))b.raise(n.alreadyInitialized);else{b.raise(n.initializing);f.addClass(e.loading);f.find(l.columnDataSelector).each(function(){var c=b.getColumnData(this);b.columns[c.index]=c});for(var a in l.breakpoints)b.breakpoints.push({name:a,width:l.breakpoints[a]}),b.breakpointNames+=a+" ";b.breakpoints.sort(function(b,c){return b.width-c.width});f.unbind(k.initialize).bind(k.initialize,function(){f.removeData("footable_info");f.data("breakpoint","");f.trigger(k.resize);f.removeClass(e.loading);f.addClass(e.loaded).addClass(e.main);b.raise(n.initialized)}).unbind(k.redraw).bind(k.redraw,function(){b.redraw()}).unbind(k.resize).bind(k.resize,function(){b.resize()}).unbind(k.expandFirstRow).bind(k.expandFirstRow,function(){f.find(l.toggleSelector).first().not("."+e.detailShow).trigger(k.toggleRow)}).unbind(k.expandAll).bind(k.expandAll,function(){f.find(l.toggleSelector).not("."+e.detailShow).trigger(k.toggleRow)}).unbind(k.collapseAll).bind(k.collapseAll,function(){f.find("."+e.detailShow).trigger(k.toggleRow)});f.trigger(k.initialize);c.bind("resize.footable",function(){b.timers.resize.stop();b.timers.resize.start(function(){b.raise(k.resize)},l.delay)})}};b.addRowToggle=function(){if(l.addRowToggle){var c=d(b.table);c.find("span."+e.toggle).remove();for(var f in b.columns){var a=b.columns[f];if(a.toggle){c=c.find("> tbody");a="> tr:not(."+e.detail+",."+e.disabled+") > td:nth-child("+(parseInt(a.index,10)+1)+"),> tr:not(."+e.detail+",."+e.disabled+") > th:nth-child("+(parseInt(a.index,10)+1)+")";c.find(a).not("."+e.detailCell).prepend(d(l.toggleHTMLElement).addClass(e.toggle));return}}c.find("> tbody > tr:not(."+e.detail+",."+e.disabled+") > td:first-child").add("> tbody > tr:not(."+e.detail+",."+e.disabled+") > th:first-child").not("."+e.detailCell).prepend(d(l.toggleHTMLElement).addClass(e.toggle))}};b.setColumnClasses=function(){var c=d(b.table),f;for(f in b.columns){var a=b.columns[f];if(null!==a.className){var q="",p=!0;d.each(a.matches,function(b,c){p||(q+=", ");q+="> tbody > tr:not(."+e.detail+") > td:nth-child("+(parseInt(c,10)+1)+")";p=!1});c.find(q).not("."+e.detailCell).addClass(a.className)}}};b.bindToggleSelectors=function(){var c=d(b.table);b.hasAnyBreakpointColumn()&&(c.find(l.toggleSelector).unbind(k.toggleRow).bind(k.toggleRow,function(c){c=d(this).is("tr")?d(this):d(this).parents("tr:first");b.toggleDetail(c)}),c.find(l.toggleSelector).unbind("click.footable").bind("click.footable",function(b){c.is(".breakpoint")&&d(b.target).is("td,th,."+e.toggle)&&d(this).trigger(k.toggleRow)}))};b.parse=function(b,f){return(l.parsers[f.type]||l.parsers.alpha)(b)};b.getColumnData=function(c){var f=d(c),a=f.data("hide"),e=f.index(),a=jQuery.map((a||"").split(","),function(b){return jQuery.trim(b)}),e={index:e,hide:{},type:f.data("type")||"alpha",name:f.data("name")||d.trim(f.text()),ignore:f.data("ignore")||!1,toggle:f.data("toggle")||!1,className:f.data("class")||null,matches:[],names:{},group:f.data("group")||null,groupName:null,isEditable:f.data("editable")};if(null!==e.group){var p=d(b.table).find('> thead > tr.footable-group-row > th[data-group="'+e.group+'"], > thead > tr.footable-group-row > td[data-group="'+e.group+'"]').first();e.groupName=b.parse(p,{type:"alpha"})}p=parseInt(f.prev().attr("colspan")||0,10);r+=1<p?p-1:0;var p=parseInt(f.attr("colspan")||0,10),g=e.index+r;if(1<p)for(var h=f.data("names"),h=(h||"").split(","),k=0;k<p;k++)e.matches.push(k+g),k<h.length&&(e.names[k+g]=h[k]);else e.matches.push(g);e.hide["default"]="all"===f.data("hide")||0<=d.inArray("default",a);var p=!1,m;for(m in l.breakpoints)e.hide[m]="all"===f.data("hide")||0<=d.inArray(m,a),p=p||e.hide[m];e.hasBreakpoint=p;return b.raise(n.columnData,{column:{data:e,th:c}}).column.data};b.getViewportWidth=function(){return window.innerWidth||(document.body?document.body.offsetWidth:0)};b.calculateWidth=function(b,f){if(jQuery.isFunction(l.calculateWidthOverride))return l.calculateWidthOverride(b,f);f.viewportWidth<f.width&&(f.width=f.viewportWidth);f.parentWidth<f.width&&(f.width=f.parentWidth);return f};b.hasBreakpointColumn=function(c){for(var f in b.columns)if(b.columns[f].hide[c]&&!b.columns[f].ignore)return!0;return!1};b.hasAnyBreakpointColumn=function(){for(var c in b.columns)if(b.columns[c].hasBreakpoint)return!0;return!1};b.resize=function(){var c=d(b.table);if(c.is(":visible"))if(b.hasAnyBreakpointColumn()){var f={width:c.width(),viewportWidth:b.getViewportWidth(),parentWidth:c.parent().width()},f=b.calculateWidth(c,f),a=c.data("footable_info");c.data("footable_info",f);b.raise(n.resizing,{old:a,info:f});if(!a||a&&a.width&&a.width!==f.width){for(var e=null,g,h=0;h<b.breakpoints.length;h++)if((g=b.breakpoints[h])&&g.width&&f.width<=g.width){e=g;break}e=null===e?"default":e.name;g=b.hasBreakpointColumn(e);h=c.data("breakpoint");c.data("breakpoint",e).removeClass("default breakpoint").removeClass(b.breakpointNames).addClass(e+(g?" breakpoint":""));e!==h&&(c.trigger(k.redraw),b.raise(n.breakpoint,{breakpoint:e,info:f}))}b.raise(n.resized,{old:a,info:f})}else c.trigger(k.redraw)};b.redraw=function(){b.addRowToggle();b.bindToggleSelectors();b.setColumnClasses();var c=d(b.table),f=c.data("breakpoint"),a=b.hasBreakpointColumn(f);c.find("> tbody > tr:not(."+e.detail+")").data("detail_created",!1).end().find("> thead > tr:last-child > th").each(function(){var a=b.columns[d(this).index()],g="",h=!0;d.each(a.matches,function(b,c){h||(g+=", ");var a=c+1;g+="> tbody > tr:not(."+e.detail+") > td:nth-child("+a+")";g+=", > tfoot > tr:not(."+e.detail+") > td:nth-child("+a+")";g+=", > colgroup > col:nth-child("+a+")";h=!1});var g=g+(', > thead > tr[data-group-row="true"] > th[data-group="'+a.group+'"]'),k=c.find(g).add(this);""!==f&&(!1===a.hide[f]?k.addClass("footable-visible").show():k.removeClass("footable-visible").hide());if(1===c.find("> thead > tr.footable-group-row").length){var k=c.find('> thead > tr:last-child > th[data-group="'+a.group+'"]:visible, > thead > tr:last-child > th[data-group="'+a.group+'"]:visible'),a=c.find('> thead > tr.footable-group-row > th[data-group="'+a.group+'"], > thead > tr.footable-group-row > td[data-group="'+a.group+'"]'),l=0;d.each(k,function(){l+=parseInt(d(this).attr("colspan")||1,10)});0<l?a.attr("colspan",l).show():a.hide()}}).end().find("> tbody > tr."+e.detailShow).each(function(){b.createOrUpdateDetailRow(this)});c.find("[data-bind-name]").each(function(){b.toggleInput(this)});c.find("> tbody > tr."+e.detailShow+":visible").each(function(){var b=d(this).next();b.hasClass(e.detail)&&(a?b.show():b.hide())});c.find("> thead > tr > th.footable-last-column, > tbody > tr > td.footable-last-column").removeClass("footable-last-column");c.find("> thead > tr > th.footable-first-column, > tbody > tr > td.footable-first-column").removeClass("footable-first-column");c.find("> thead > tr, > tbody > tr").find("> th.footable-visible:last, > td.footable-visible:last").addClass("footable-last-column").end().find("> th.footable-visible:first, > td.footable-visible:first").addClass("footable-first-column");b.raise(n.redrawn)};b.toggleDetail=function(c){c=c.jquery?c:d(c);var a=c.next();c.hasClass(e.detailShow)?(c.removeClass(e.detailShow),a.hasClass(e.detail)&&a.hide(),b.raise(n.rowCollapsed,{row:c[0]})):(b.createOrUpdateDetailRow(c[0]),c.addClass(e.detailShow).next().show(),b.raise(n.rowExpanded,{row:c[0]}))};b.removeRow=function(c){c=c.jquery?c:d(c);c.hasClass(e.detail)&&(c=c.prev());var a=c.next();!0===c.data("detail_created")&&a.remove();c.remove();b.raise(n.rowRemoved)};b.appendRow=function(c){c=c.jquery?c:d(c);d(b.table).find("tbody").append(c);b.redraw()};b.getColumnFromTdIndex=function(c){var a=null,e;for(e in b.columns)if(0<=d.inArray(c,b.columns[e].matches)){a=b.columns[e];break}return a};b.createOrUpdateDetailRow=function(c){c=d(c);var a=c.next(),g,h=[];if(!0===c.data("detail_created"))return!0;if(c.is(":hidden"))return!1;b.raise(n.rowDetailUpdating,{row:c,detail:a});c.find("> td:hidden").each(function(){var c=d(this).index(),a=b.getColumnFromTdIndex(c),f=a.name;if(!0===a.ignore)return!0;c in a.names&&(f=a.names[c]);var g=d(this).attr("data-bind-name");if(null!=g&&d(this).is(":empty")){var k=d("."+e.detailInnerValue+'[data-bind-value="'+g+'"]');d(this).html(d(k).contents().detach())}var l;!1!==a.isEditable&&(a.isEditable||0<d(this).find(":input").length)&&(null==g&&(g="bind-"+d.now()+"-"+c,d(this).attr("data-bind-name",g)),l=d(this).contents().detach());l||(l=d(this).contents().clone(!0,!0));h.push({name:f,value:b.parse(this,a),display:l,group:a.group,groupName:a.groupName,bindName:g});return!0});if(0===h.length)return!1;g=c.find("> td:visible").length;var k=a.hasClass(e.detail);k||(a=d('<tr class="'+e.detail+'"><td class="'+e.detailCell+'"><div class="'+e.detailInner+'"></div></td></tr>'),c.after(a));a.find("> td:first").attr("colspan",g);g=a.find("."+e.detailInner).empty();l.createDetail(g,h,l.createGroupedDetail,l.detailSeparator,e);c.data("detail_created",!0);b.raise(n.rowDetailUpdated,{row:c,detail:a});return!k};b.raise=function(a,e){!0===b.options.debug&&d.isFunction(b.options.log)&&b.options.log(a,"event");e=e||{};var g={ft:b};d.extend(!0,g,e);var h=d.Event(a,g);h.ft||d.extend(!0,h,g);d(b.table).trigger(h);return h};b.reset=function(){var a=d(b.table);a.removeData("footable_info").data("breakpoint","").removeClass(e.loading).removeClass(e.loaded);a.find(l.toggleSelector).unbind(k.toggleRow).unbind("click.footable");a.find("> tbody > tr").removeClass(e.detailShow);a.find("> tbody > tr."+e.detail).remove();b.raise(n.reset)};b.toggleInput=function(b){var a=d(b).attr("data-bind-name");null!=a&&(a=d("."+e.detailInnerValue+'[data-bind-value="'+a+'"]'),null!=a&&(d(b).is(":visible")?d(a).is(":empty")||d(b).html(d(a).contents().detach()):d(b).is(":empty")||d(a).html(d(b).contents().detach())))};b.init();return b}m.footable={options:{delay:100,breakpoints:{phone:480,tablet:1024},parsers:{alpha:function(a){return d(a).data("value")||d.trim(d(a).text())},numeric:function(a){a=d(a).data("value")||d(a).text().replace(/[^0-9.\-]/g,"");a=parseFloat(a);isNaN(a)&&(a=0);return a}},addRowToggle:!0,calculateWidthOverride:null,toggleSelector:" > tbody > tr:not(.footable-row-detail)",columnDataSelector:"> thead > tr:last-child > th, > thead > tr:last-child > td",detailSeparator:":",toggleHTMLElement:"<span />",createGroupedDetail:function(a){for(var d={_none:{name:null,data:[]}},h=0;h<a.length;h++){var b=a[h].group;null!==b?(b in d||(d[b]={name:a[h].groupName||a[h].group,data:[]}),d[b].data.push(a[h])):d._none.data.push(a[h])}return d},createDetail:function(a,g,h,b,l){g=h(g);for(var e in g)if(0!==g[e].data.length)for("_none"!==e&&a.append('<div class="'+l.detailInnerGroup+'">'+g[e].name+"</div>"),h=0;h<g[e].data.length;h++){var m=g[e].data[h].name?b:"";a.append(d("<div></div>").addClass(l.detailInnerRow).append(d("<div></div>").addClass(l.detailInnerName).append(g[e].data[h].name+m)).append(d("<div></div>").addClass(l.detailInnerValue).attr("data-bind-value",g[e].data[h].bindName).append(g[e].data[h].display)))}},classes:{main:"footable",loading:"footable-loading",loaded:"footable-loaded",toggle:"footable-toggle",disabled:"footable-disabled",detail:"footable-row-detail",detailCell:"footable-row-detail-cell",detailInner:"footable-row-detail-inner",detailInnerRow:"footable-row-detail-row",detailInnerGroup:"footable-row-detail-group",detailInnerName:"footable-row-detail-name",detailInnerValue:"footable-row-detail-value",detailShow:"footable-detail-show"},triggers:{initialize:"footable_initialize",resize:"footable_resize",redraw:"footable_redraw",toggleRow:"footable_toggle_row",expandFirstRow:"footable_expand_first_row",expandAll:"footable_expand_all",collapseAll:"footable_collapse_all"},events:{alreadyInitialized:"footable_already_initialized",initializing:"footable_initializing",initialized:"footable_initialized",resizing:"footable_resizing",resized:"footable_resized",redrawn:"footable_redrawn",breakpoint:"footable_breakpoint",columnData:"footable_column_data",rowDetailUpdating:"footable_row_detail_updating",rowDetailUpdated:"footable_row_detail_updated",rowCollapsed:"footable_row_collapsed",rowExpanded:"footable_row_expanded",rowRemoved:"footable_row_removed",reset:"footable_reset"},debug:!1,log:null},version:{major:0,minor:5,toString:function(){return m.footable.version.major+"."+m.footable.version.minor},parse:function(a){a=/(\d+)\.?(\d+)?\.?(\d+)?/.exec(a);return{major:parseInt(a[1],10)||0,minor:parseInt(a[2],10)||0,patch:parseInt(a[3],10)||0}}},plugins:{_validate:function(a){if(!d.isFunction(a))return!0===m.footable.options.debug&&console.error('Validation failed, expected type "function", received type "{0}".',typeof a),!1;a=new a;if("string"!==typeof a.name)return!0===m.footable.options.debug&&console.error('Validation failed, plugin does not implement a string property called "name".',a),!1;if(!d.isFunction(a.init))return!0===m.footable.options.debug&&console.error('Validation failed, plugin "'+a.name+'" does not implement a function called "init".',a),!1;!0===m.footable.options.debug&&console.log('Validation succeeded for plugin "'+a.name+'".',a);return!0},registered:[],register:function(a,g){m.footable.plugins._validate(a)&&(m.footable.plugins.registered.push(a),"object"===typeof g&&d.extend(!0,m.footable.options,g))},load:function(a){var d=[],h,b;for(b=0;b<m.footable.plugins.registered.length;b++)try{h=m.footable.plugins.registered[b],d.push(new h(a))}catch(l){!0===m.footable.options.debug&&console.error(l)}return d},init:function(a){for(var d=0;d<a.plugins.length;d++)try{a.plugins[d].init(a)}catch(h){!0===m.footable.options.debug&&console.error(h)}}}};var u=0;d.fn.footable=function(a){a=a||{};var g=d.extend(!0,{},m.footable.options,a);return this.each(function(){u++;var a=new v(this,g,u);d(this).data("footable",a)})}})(jQuery,window);
21
  /* sort */
22
  (function(t,e,undefined){function a(){var e=this;e.name="Footable Sortable",e.init=function(a){e.footable=a,a.options.sort===!0&&t(a.table).unbind(".sorting").bind({"footable_initialized.sorting":function(){var i,o,n=t(a.table),r=(n.find("> tbody"),a.options.classes.sort);if(n.data("sort")!==!1){n.find("> thead > tr:last-child > th, > thead > tr:last-child > td").each(function(){var e=t(this),i=a.columns[e.index()];i.sort.ignore===!0||e.hasClass(r.sortable)||(e.addClass(r.sortable),t("<span />").addClass(r.indicator).appendTo(e))}),n.find("> thead > tr:last-child > th."+r.sortable+", > thead > tr:last-child > td."+r.sortable).unbind("click.footable").bind("click.footable",function(a){a.preventDefault(),o=t(this);var i=!o.hasClass(r.sorted);return e.doSort(o.index(),i),!1});var l=!1;for(var s in a.columns)if(i=a.columns[s],i.sort.initial){var d="descending"!==i.sort.initial;e.doSort(i.index,d);break}l&&a.bindToggleSelectors()}},"footable_redrawn.sorting":function(){var i=t(a.table),o=a.options.classes.sort;i.data("sorted")>=0&&i.find("> thead > tr:last-child > th").each(function(a){var i=t(this);return i.hasClass(o.sorted)||i.hasClass(o.descending)?(e.doSort(a),undefined):undefined})},"footable_column_data.sorting":function(e){var a=t(e.column.th);e.column.data.sort=e.column.data.sort||{},e.column.data.sort.initial=a.data("sort-initial")||!1,e.column.data.sort.ignore=a.data("sort-ignore")||!1,e.column.data.sort.selector=a.data("sort-selector")||null;var i=a.data("sort-match")||0;i>=e.column.data.matches.length&&(i=0),e.column.data.sort.match=e.column.data.matches[i]}}).data("footable-sort",e)},e.doSort=function(a,i){var o=e.footable;if(t(o.table).data("sort")!==!1){var n=t(o.table),r=n.find("> tbody"),l=o.columns[a],s=n.find("> thead > tr:last-child > th:eq("+a+")"),d=o.options.classes.sort,f=o.options.events.sort;if(i=i===undefined?s.hasClass(d.sorted):"toggle"===i?!s.hasClass(d.sorted):i,l.sort.ignore===!0)return!0;var u=o.raise(f.sorting,{column:l,direction:i?"ASC":"DESC"});u&&u.result===!1||(n.data("sorted",l.index),n.find("> thead > tr:last-child > th, > thead > tr:last-child > td").not(s).removeClass(d.sorted+" "+d.descending),i===undefined&&(i=s.hasClass(d.sorted)),i?s.removeClass(d.descending).addClass(d.sorted):s.removeClass(d.sorted).addClass(d.descending),e.sort(o,r,l,i),o.bindToggleSelectors(),o.raise(f.sorted,{column:l,direction:i?"ASC":"DESC"}))}},e.rows=function(e,a,i){var o=[];return a.find("> tr").each(function(){var a=t(this),n=null;if(a.hasClass(e.options.classes.detail))return!0;a.next().hasClass(e.options.classes.detail)&&(n=a.next().get(0));var r={row:a,detail:n};return i!==undefined&&(r.value=e.parse(this.cells[i.sort.match],i)),o.push(r),!0}).detach(),o},e.sort=function(t,a,i,o){var n=e.rows(t,a,i),r=t.options.sorters[i.type]||t.options.sorters.alpha;n.sort(function(t,e){return o?r(t.value,e.value):r(e.value,t.value)});for(var l=0;n.length>l;l++)a.append(n[l].row),null!==n[l].detail&&a.append(n[l].detail)}}if(e.footable===undefined||null===e.footable)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={sort:!0,sorters:{alpha:function(t,e){return"string"==typeof t&&(t=t.toLowerCase()),"string"==typeof e&&(e=e.toLowerCase()),t===e?0:e>t?-1:1},numeric:function(t,e){return t-e}},classes:{sort:{sortable:"footable-sortable",sorted:"footable-sorted",descending:"footable-sorted-desc",indicator:"footable-sort-indicator"}},events:{sort:{sorting:"footable_sorting",sorted:"footable_sorted"}}};e.footable.plugins.register(a,i)})(jQuery,window);
23
  /* striping */
24
+ (function(t,e,undefined){function a(){var e=this;e.name="Footable Striping",e.init=function(a){e.footable=a,t(a.table).unbind("striping").bind({"footable_initialized.striping footable_row_removed.striping footable_redrawn.striping footable_sorted.striping footable_filtered.striping":function(){t(this).data("striping")!==!1&&e.setupStriping(a)}})},e.setupStriping=function(e){var a=0;t(e.table).find("> tbody > tr:not(.footable-row-detail)").each(function(){var i=t(this);i.removeClass(e.options.classes.striping.even).removeClass(e.options.classes.striping.odd),0===a%2?i.addClass(e.options.classes.striping.even):i.addClass(e.options.classes.striping.odd),a++})}}if(e.footable===undefined||null===e.foobox)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={striping:{enabled:!0},classes:{striping:{odd:"footable-odd",even:"footable-even"}}};e.footable.plugins.register(a,i)})(jQuery,window);
25
+ /* filter */
26
+ (function(t,e,undefined){function a(){var e=this;e.name="Footable Filter",e.init=function(a){if(e.footable=a,a.options.filter.enabled===!0){if(t(a.table).data("filter")===!1)return;a.timers.register("filter"),t(a.table).unbind(".filtering").bind({"footable_initialized.filtering":function(){var i=t(a.table),o={input:i.data("filter")||a.options.filter.input,timeout:i.data("filter-timeout")||a.options.filter.timeout,minimum:i.data("filter-minimum")||a.options.filter.minimum,disableEnter:i.data("filter-disable-enter")||a.options.filter.disableEnter};o.disableEnter&&t(o.input).keypress(function(t){return window.event?13!==window.event.keyCode:13!==t.which}),i.bind("footable_clear_filter",function(){t(o.input).val(""),e.clearFilter()}),i.bind("footable_filter",function(t,a){e.filter(a.filter)}),t(o.input).keyup(function(i){a.timers.filter.stop(),27===i.which&&t(o.input).val(""),a.timers.filter.start(function(){var a=t(o.input).val()||"";e.filter(a)},o.timeout)})},"footable_redrawn.filtering":function(){var i=t(a.table),o=i.data("filter-string");o&&e.filter(o)}}).data("footable-filter",e)}},e.filter=function(a){var i=e.footable,o=t(i.table),n=o.data("filter-minimum")||i.options.filter.minimum,r=!a,l=i.raise("footable_filtering",{filter:a,clear:r});if(!(l&&l.result===!1||l.filter&&n>l.filter.length))if(l.clear)e.clearFilter();else{var d=l.filter.split(" ");o.find("> tbody > tr").hide().addClass("footable-filtered");var s=o.find("> tbody > tr:not(.footable-row-detail)");t.each(d,function(t,e){e&&e.length>0&&(o.data("current-filter",e),s=s.filter(i.options.filter.filterFunction))}),s.each(function(){e.showRow(this,i),t(this).removeClass("footable-filtered")}),o.data("filter-string",l.filter),i.raise("footable_filtered",{filter:l.filter,clear:!1})}},e.clearFilter=function(){var a=e.footable,i=t(a.table);i.find("> tbody > tr:not(.footable-row-detail)").removeClass("footable-filtered").each(function(){e.showRow(this,a)}),i.removeData("filter-string"),a.raise("footable_filtered",{clear:!0})},e.showRow=function(e,a){var i=t(e),o=i.next(),n=t(a.table);i.is(":visible")||(n.hasClass("breakpoint")&&i.hasClass("footable-detail-show")&&o.hasClass("footable-row-detail")?(i.add(o).show(),a.createOrUpdateDetailRow(e)):i.show())}}if(e.footable===undefined||null===e.footable)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={filter:{enabled:!0,input:".footable-filter",timeout:300,minimum:2,disableEnter:!1,filterFunction:function(){var e=t(this),a=e.parents("table:first"),i=a.data("current-filter").toUpperCase(),o=e.find("td").text();return a.data("filter-text-only")||e.find("td[data-value]").each(function(){o+=t(this).data("value")}),o.toUpperCase().indexOf(i)>=0}}};e.footable.plugins.register(a,i)})(jQuery,window);
admin/js/gmap.js CHANGED
@@ -1,8 +1,8 @@
1
- /**
2
  * Project: GmapRS - google map for WordPress IP Geo Block
3
  * Description: A really simple google map plugin based on jQuery-boilerplate.
4
  * Version: 0.2.4
5
- * Copyright (c) 2013-2016 tokkonopapa (tokkonopapa@yahoo.com)
6
  * This software is released under the MIT License.
7
  */
8
  // https://developers.google.com/maps/documentation/javascript/events?hl=en#auth-errors
1
+ /*!
2
  * Project: GmapRS - google map for WordPress IP Geo Block
3
  * Description: A really simple google map plugin based on jQuery-boilerplate.
4
  * Version: 0.2.4
5
+ * Copyright (c) 2013-2017 tokkonopapa (tokkonopapa@yahoo.com)
6
  * This software is released under the MIT License.
7
  */
8
  // https://developers.google.com/maps/documentation/javascript/events?hl=en#auth-errors
admin/js/gmap.min.js CHANGED
@@ -1,8 +1,8 @@
1
- /**
2
- * Project: GmapRS - google map for WordPress IP Geo Block
3
- * Description: A really simple google map plugin based on jQuery-boilerplate.
4
- * Version: 0.2.4
5
- * Copyright (c) 2013-2016 tokkonopapa (tokkonopapa@yahoo.com)
6
- * This software is released under the MIT License.
7
- */
8
  function gm_authFailure(){jQuery(window).trigger("ip-geo-block-gmap-error")}(function(f){f(function(d){var f={zoom:2,latitude:0,longitude:0},e=google.maps,g=function(a){this.o=d.extend({},f);this.q=[]};g.prototype={init:function(a){d.extend(this.o,a);this.c=new e.LatLng(this.o.latitude,this.o.longitude);this.m=new e.Map(this.e.get(0),{zoom:this.o.zoom,center:this.c,mapTypeId:e.MapTypeId.ROADMAP})},destroy:function(){this.deleteMarkers();this.e.data("plugin_GmapRS",null)},setCenter:function(){if(2<=arguments.length){var a=new e.LatLng(this.o.latitude=arguments[0],this.o.longitude=arguments[1]);delete this.c;this.c=a}this.m.setCenter(this.c);return this.e},setZoom:function(a){this.m.setZoom(a||this.o.zoom);return this.e},showMarker:function(a,c){var b=this.q[a];b&&b.w&&(!1===c?b.w.close():b.w.open(this.m,b.m))},addMarker:function(a){var c,b,d;c=new e.LatLng(a.latitude||this.o.latitude,a.longitude||this.o.longitude);b=new e.Marker({position:c,map:this.m,title:a.title||""});a.content&&(d=new e.InfoWindow({content:a.content}),e.event.addListener(b,"click",function(){d.open(b.getMap(),b)}));this.q.push({p:c,w:d,m:b});this.m.setCenter(c);this.m.setZoom(a.zoom);a.show&&this.showMarker(this.q.length-1);return this.e},deleteMarkers:function(){var a,c;for(a in this.q)this.q.hasOwnProperty(a)&&(c=this.q[a],c.m.setMap(null));this.q.length=0;return this.e}};d.fn.GmapRS=function(a){var c,b;this.data("plugin_GmapRS")instanceof g||this.data("plugin_GmapRS",new g(this));b=this.data("plugin_GmapRS");b.e=this;if("undefined"===typeof a||"object"===typeof a)"function"===typeof b.init&&b.init(a);else{if("string"===typeof a&&"function"===typeof b[a])return c=Array.prototype.slice.call(arguments,1),b[a].apply(b,c);d.error("Method "+a+" does not exist.GmapRS")}}})})(jQuery);
1
+ /*
2
+ Project: GmapRS - google map for WordPress IP Geo Block
3
+ Description: A really simple google map plugin based on jQuery-boilerplate.
4
+ Version: 0.2.4
5
+ Copyright (c) 2013-2017 tokkonopapa (tokkonopapa@yahoo.com)
6
+ This software is released under the MIT License.
7
+ */
8
  function gm_authFailure(){jQuery(window).trigger("ip-geo-block-gmap-error")}(function(f){f(function(d){var f={zoom:2,latitude:0,longitude:0},e=google.maps,g=function(a){this.o=d.extend({},f);this.q=[]};g.prototype={init:function(a){d.extend(this.o,a);this.c=new e.LatLng(this.o.latitude,this.o.longitude);this.m=new e.Map(this.e.get(0),{zoom:this.o.zoom,center:this.c,mapTypeId:e.MapTypeId.ROADMAP})},destroy:function(){this.deleteMarkers();this.e.data("plugin_GmapRS",null)},setCenter:function(){if(2<=arguments.length){var a=new e.LatLng(this.o.latitude=arguments[0],this.o.longitude=arguments[1]);delete this.c;this.c=a}this.m.setCenter(this.c);return this.e},setZoom:function(a){this.m.setZoom(a||this.o.zoom);return this.e},showMarker:function(a,c){var b=this.q[a];b&&b.w&&(!1===c?b.w.close():b.w.open(this.m,b.m))},addMarker:function(a){var c,b,d;c=new e.LatLng(a.latitude||this.o.latitude,a.longitude||this.o.longitude);b=new e.Marker({position:c,map:this.m,title:a.title||""});a.content&&(d=new e.InfoWindow({content:a.content}),e.event.addListener(b,"click",function(){d.open(b.getMap(),b)}));this.q.push({p:c,w:d,m:b});this.m.setCenter(c);this.m.setZoom(a.zoom);a.show&&this.showMarker(this.q.length-1);return this.e},deleteMarkers:function(){var a,c;for(a in this.q)this.q.hasOwnProperty(a)&&(c=this.q[a],c.m.setMap(null));this.q.length=0;return this.e}};d.fn.GmapRS=function(a){var c,b;this.data("plugin_GmapRS")instanceof g||this.data("plugin_GmapRS",new g(this));b=this.data("plugin_GmapRS");b.e=this;if("undefined"===typeof a||"object"===typeof a)"function"===typeof b.init&&b.init(a);else{if("string"===typeof a&&"function"===typeof b[a])return c=Array.prototype.slice.call(arguments,1),b[a].apply(b,c);d.error("Method "+a+" does not exist.GmapRS")}}})})(jQuery);
admin/js/whois.min.js CHANGED
@@ -1,8 +1,8 @@
1
- /*!
2
- * Project: whois.js - get whois infomation
3
- * Description: A jQuery plugin to get whois infomation from RIPE NCC database.
4
- * Version: 0.1
5
- * Copyright (c) 2016 tokkonopapa (tokkonopapa@yahoo.com)
6
- * This software is released under the MIT License.
7
- */
8
  (function(g){g.extend({whois:function(l,e){function b(b){return b?b.toString().replace(/[&<>"']/g,function(b){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[b]}):""}var f=[];return g.ajax({url:'https://query.yahooapis.com/v1/public/yql?q=select * from xml where url="%URL%"&format=json&jsonCompat=new'.replace(/%URL%/,"https://rest.db.ripe.net/search%3fflags=no-filtering%26flags=resource%26query-string="+l),method:"GET",dataType:"json"}).done(function(c,d,e){function k(c,a){if(a&&"object"===typeof a)if(a.errormessage){var d=a.errormessage,e=d.text.split(/\n+/);f.push({name:b(d.severity),value:b(e[1].replace(/%s/,d.args.value))})}else a.href?(a.href=b(a.href),f.push({name:b(c),value:'<a href="'+a.href+'.json" target=_blank>'+a.href+"</a>"})):a.name&&a.value?(a.link?a.value='<a href="'+b(a.link.href)+'.json" target=_blank>'+b(a.value)+"</a>":"remarks"===a.name&&(a.value=b(a.value),a.value=a.value.replace(/(https?:\/\/[^\s]+)/gi,'<a href="$1" target=_blank>$1</a>')),f.push({name:b(a.name),value:a.value})):"primary-key"!==c&&g.each(a,function(a,b){k(a,b)})}var h;c=c.query.results;d=[];for(h in c)if(c.hasOwnProperty(h)){d=c[h];break}k(null,d)}).fail(function(c,d,e){f.push({name:b(d),value:b(e)})}).always(function(){f.push({name:"copyright",value:'<a href="https://apps.db.ripe.net/search/query.html" title="Database Query - RIPE Network Coordination Centre">RIPE NCC</a>'});e&&e(f)})}})})(jQuery);
1
+ /*
2
+ Project: whois.js - get whois infomation
3
+ Description: A jQuery plugin to get whois infomation from RIPE NCC database.
4
+ Version: 0.1
5
+ Copyright (c) 2016 tokkonopapa (tokkonopapa@yahoo.com)
6
+ This software is released under the MIT License.
7
+ */
8
  (function(g){g.extend({whois:function(l,e){function b(b){return b?b.toString().replace(/[&<>"']/g,function(b){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[b]}):""}var f=[];return g.ajax({url:'https://query.yahooapis.com/v1/public/yql?q=select * from xml where url="%URL%"&format=json&jsonCompat=new'.replace(/%URL%/,"https://rest.db.ripe.net/search%3fflags=no-filtering%26flags=resource%26query-string="+l),method:"GET",dataType:"json"}).done(function(c,d,e){function k(c,a){if(a&&"object"===typeof a)if(a.errormessage){var d=a.errormessage,e=d.text.split(/\n+/);f.push({name:b(d.severity),value:b(e[1].replace(/%s/,d.args.value))})}else a.href?(a.href=b(a.href),f.push({name:b(c),value:'<a href="'+a.href+'.json" target=_blank>'+a.href+"</a>"})):a.name&&a.value?(a.link?a.value='<a href="'+b(a.link.href)+'.json" target=_blank>'+b(a.value)+"</a>":"remarks"===a.name&&(a.value=b(a.value),a.value=a.value.replace(/(https?:\/\/[^\s]+)/gi,'<a href="$1" target=_blank>$1</a>')),f.push({name:b(a.name),value:a.value})):"primary-key"!==c&&g.each(a,function(a,b){k(a,b)})}var h;c=c.query.results;d=[];for(h in c)if(c.hasOwnProperty(h)){d=c[h];break}k(null,d)}).fail(function(c,d,e){f.push({name:b(d),value:b(e)})}).always(function(){f.push({name:"copyright",value:'<a href="https://apps.db.ripe.net/search/query.html" title="Database Query - RIPE Network Coordination Centre">RIPE NCC</a>'});e&&e(f)})}})})(jQuery);
classes/class-ip-geo-block-actv.php CHANGED
@@ -6,15 +6,15 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2016 tokkonopapa
10
  */
11
 
12
  // Stuff for resources
13
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-util.php' );
14
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php' );
15
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php' );
16
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php' );
17
- require_once( IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-rewrite.php' );
18
 
19
  class IP_Geo_Block_Activate {
20
 
@@ -26,11 +26,12 @@ class IP_Geo_Block_Activate {
26
 
27
  // initialize main blog
28
  public static function init_main_blog() {
29
- if ( is_user_logged_in() && current_user_can( 'manage_options' ) ) {
30
  $settings = IP_Geo_Block::get_option();
31
 
32
  // kick off a cron job to download database immediately
33
  IP_Geo_Block_Cron::start_update_db( $settings );
 
34
 
35
  // activate rewrite rules
36
  IP_Geo_Block_Admin_Rewrite::activate_rewrite_all( $settings['rewrite'] );
@@ -46,7 +47,7 @@ class IP_Geo_Block_Activate {
46
  */
47
  public static function activate( $network_wide = FALSE ) {
48
  if ( ! function_exists( 'is_plugin_active_for_network' ) )
49
- require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
50
 
51
  if ( is_plugin_active_for_network( IP_GEO_BLOCK_BASE ) ) {
52
  global $wpdb;
@@ -65,7 +66,9 @@ class IP_Geo_Block_Activate {
65
  self::activate_blog();
66
  }
67
 
68
- self::init_main_blog(); // should be called with high priority
 
 
69
  }
70
 
71
  /**
@@ -75,6 +78,7 @@ class IP_Geo_Block_Activate {
75
  public static function deactivate( $network_wide = FALSE ) {
76
  // cancel schedule
77
  IP_Geo_Block_Cron::stop_update_db();
 
78
 
79
  // deactivate rewrite rules
80
  IP_Geo_Block_Admin_Rewrite::deactivate_rewrite_all();
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2017 tokkonopapa
10
  */
11
 
12
  // Stuff for resources
13
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-util.php';
14
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php';
15
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php';
16
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php';
17
+ require_once IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-rewrite.php';
18
 
19
  class IP_Geo_Block_Activate {
20
 
26
 
27
  // initialize main blog
28
  public static function init_main_blog() {
29
+ if ( current_user_can( 'manage_options' ) ) {
30
  $settings = IP_Geo_Block::get_option();
31
 
32
  // kick off a cron job to download database immediately
33
  IP_Geo_Block_Cron::start_update_db( $settings );
34
+ IP_Geo_Block_Cron::start_cache_gc( $settings );
35
 
36
  // activate rewrite rules
37
  IP_Geo_Block_Admin_Rewrite::activate_rewrite_all( $settings['rewrite'] );
47
  */
48
  public static function activate( $network_wide = FALSE ) {
49
  if ( ! function_exists( 'is_plugin_active_for_network' ) )
50
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
51
 
52
  if ( is_plugin_active_for_network( IP_GEO_BLOCK_BASE ) ) {
53
  global $wpdb;
66
  self::activate_blog();
67
  }
68
 
69
+ // only after 'init' action hook for is_user_logged_in().
70
+ if ( did_action( 'init' ) && is_user_logged_in() )
71
+ self::init_main_blog(); // should be called with high priority
72
  }
73
 
74
  /**
78
  public static function deactivate( $network_wide = FALSE ) {
79
  // cancel schedule
80
  IP_Geo_Block_Cron::stop_update_db();
81
+ IP_Geo_Block_Cron::stop_cache_gc();
82
 
83
  // deactivate rewrite rules
84
  IP_Geo_Block_Admin_Rewrite::deactivate_rewrite_all();
classes/class-ip-geo-block-apis.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2013-2016 tokkonopapa
10
  */
11
 
12
  /**
@@ -446,74 +446,54 @@ class IP_Geo_Block_API_IPInfoDB extends IP_Geo_Block_API {
446
  /**
447
  * Class for Cache
448
  *
449
- * URL : http://codex.wordpress.org/Transients_API
450
  * Input type : IP address (IPv4, IPv6)
451
  * Output type : array
452
  */
453
  class IP_Geo_Block_API_Cache extends IP_Geo_Block_API {
454
 
 
 
 
455
  public static function update_cache( $hook, $validate, $settings ) {
456
- $time = $_SERVER['REQUEST_TIME']; // time();
457
- $num = ! empty( $settings['cache_hold'] ) ? $settings['cache_hold'] : 10;
458
- $exp = ! empty( $settings['cache_time'] ) ? $settings['cache_time'] : HOUR_IN_SECONDS;
459
-
460
- // unset expired elements
461
- if ( FALSE !== ( $cache = get_transient( IP_Geo_Block::CACHE_NAME ) ) ) {
462
- foreach ( $cache as $key => $val ) {
463
- if ( $time - $val['time'] > $exp )
464
- unset( $cache[ $key ] );
465
- }
466
- }
467
 
468
- // $validate['fail'] is set in auth_fail()
469
- if ( isset( $cache[ $ip = $validate['ip'] ] ) ) {
470
- $fail = $cache[ $ip ]['fail'] + (int)isset( $validate['fail'] );
471
- $call = $cache[ $ip ]['call'] + (int)empty( $validate['fail'] );
472
  } else { // if new cache then reset these values
473
- $call = 1;
474
  $fail = 0;
 
475
  }
476
 
477
  // update elements
478
- $cache[ $ip ] = array(
479
- 'time' => $time,
 
480
  'hook' => $hook,
481
  'code' => $validate['code'],
482
  'auth' => $validate['auth'], // get_current_user_id() > 0
483
- 'fail' => $validate['auth'] ? 0 : $fail,
484
  'call' => $settings['save_statistics'] ? $call : 0,
485
  'host' => isset( $validate['host'] ) ? $validate['host'] : NULL,
486
- );
487
 
488
- // sort by 'time'
489
- foreach ( $cache as $key => $val )
490
- $hash[ $key ] = $val['time'];
491
- array_multisort( $hash, SORT_DESC, $cache );
492
-
493
- // keep the maximum number of entries, except for hidden elements
494
- $time = 0;
495
- foreach ( $cache as $key => $val ) {
496
- if ( ! $val['auth'] && ++$time > $num ) {
497
- --$time;
498
- unset( $cache[ $key ] );
499
- }
500
- }
501
-
502
- set_transient( IP_Geo_Block::CACHE_NAME, $cache, $exp ); // @since 2.8
503
- return $cache[ $ip ];
504
  }
505
 
506
  public static function clear_cache() {
507
- delete_transient( IP_Geo_Block::CACHE_NAME ); // @since 2.8
 
508
  }
509
 
510
  public static function get_cache_all() {
511
- return get_transient( IP_Geo_Block::CACHE_NAME );
512
  }
513
 
514
  public static function get_cache( $ip ) {
515
- $cache = get_transient( IP_Geo_Block::CACHE_NAME );
516
- return $cache && isset( $cache[ $ip ] ) ? $cache[ $ip ] : NULL;
 
 
517
  }
518
 
519
  public function get_location( $ip, $args = array() ) {
@@ -539,43 +519,43 @@ class IP_Geo_Block_Provider {
539
  'freegeoip.net' => array(
540
  'key' => NULL,
541
  'type' => 'IPv4, IPv6 / free',
542
- 'link' => '<a class="ip-geo-block-link" href="http://freegeoip.net/" title="freegeoip.net: FREE IP Geolocation Web Service" rel=noreferrer target=_blank>http://freegeoip.net/</a>&nbsp;(IPv4, IPv6 / free)',
543
  ),
544
 
545
  'ipinfo.io' => array(
546
  'key' => NULL,
547
  'type' => 'IPv4, IPv6 / free',
548
- 'link' => '<a class="ip-geo-block-link" href="http://ipinfo.io/" title="ip address information including geolocation, hostname and network details" rel=noreferrer target=_blank>http://ipinfo.io/</a>&nbsp;(IPv4, IPv6 / free)',
549
  ),
550
 
551
  'Nekudo' => array(
552
  'key' => NULL,
553
  'type' => 'IPv4, IPv6 / free',
554
- 'link' => '<a class="ip-geo-block-link" href="http://geoip.nekudo.com/" title="geoip.nekudo.com | Free IP to geolocation API" rel=noreferrer target=_blank>http://geoip.nekudo.com/</a>&nbsp;(IPv4, IPv6 / free)',
555
  ),
556
 
557
  'Xhanch' => array(
558
  'key' => NULL,
559
  'type' => 'IPv4 / free',
560
- 'link' => '<a class="ip-geo-block-link" href="http://xhanch.com/xhanch-api-ip-get-detail/" title="Xhanch API &#8211; IP Get Detail | Xhanch Studio" rel=noreferrer target=_blank>http://xhanch.com/</a>&nbsp;(IPv4 / free)',
561
  ),
562
 
563
  'GeoIPLookup' => array(
564
  'key' => NULL,
565
  'type' => 'IPv4, IPv6 / free',
566
- 'link' => '<a class="ip-geo-block-link" href="http://geoiplookup.net/" title="What Is My IP Address | GeoIP Lookup" rel=noreferrer target=_blank>GeoIPLookup.net</a>&nbsp;(IPv4, IPv6 / free)',
567
  ),
568
 
569
  'ip-api.com' => array(
570
  'key' => FALSE,
571
  'type' => 'IPv4, IPv6 / free for non-commercial use',
572
- 'link' => '<a class="ip-geo-block-link" href="http://ip-api.com/" title="IP-API.com - Free Geolocation API" rel=noreferrer target=_blank>http://ip-api.com/</a>&nbsp;(IPv4, IPv6 / free for non-commercial use)',
573
  ),
574
 
575
  'IPInfoDB' => array(
576
  'key' => '',
577
  'type' => 'IPv4, IPv6 / free for registered user',
578
- 'link' => '<a class="ip-geo-block-link" href="http://ipinfodb.com/" title="IPInfoDB | Free IP Address Geolocation Tools" rel=noreferrer target=_blank>http://ipinfodb.com/</a>&nbsp;(IPv4, IPv6 / free for registered user)',
579
  ),
580
  );
581
 
@@ -663,15 +643,12 @@ class IP_Geo_Block_Provider {
663
  if ( ( NULL === $val && ! isset( $settings[ $key ] ) ) ||
664
  ( FALSE === $val && ! empty( $settings[ $key ] ) ) ||
665
  ( is_string( $val ) && ! empty( $settings[ $key ] ) ) ) {
666
- $field++;
667
  }
668
  }
669
 
670
  if ( 0 === $field )
671
- return __(
672
- 'You need to select at least one IP geolocation service. Otherwise <strong>you\'ll be blocked</strong> after the cache expires.',
673
- 'ip-geo-block'
674
- );
675
 
676
  return NULL;
677
  }
@@ -703,7 +680,7 @@ if ( class_exists( 'IP_Geo_Block' ) ) {
703
  $exclude = array( '.', '..' );
704
  foreach ( $plugins as $plugin ) {
705
  if ( ! in_array( $plugin, $exclude, TRUE ) && is_dir( $dir.$plugin ) ) {
706
- @include( $dir.$plugin.'/class-'.$plugin.'.php' );
707
  }
708
  }
709
  }
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
  */
11
 
12
  /**
446
  /**
447
  * Class for Cache
448
  *
 
449
  * Input type : IP address (IPv4, IPv6)
450
  * Output type : array
451
  */
452
  class IP_Geo_Block_API_Cache extends IP_Geo_Block_API {
453
 
454
+ // memory cache
455
+ protected static $memcache = array();
456
+
457
  public static function update_cache( $hook, $validate, $settings ) {
458
+ $cache = self::get_cache( $ip = $validate['ip'] );
 
 
 
 
 
 
 
 
 
 
459
 
460
+ if ( $cache ) {
461
+ $fail = $cache['fail'] + ( empty( $validate['fail'] ) ? 0 : 1 );
462
+ $call = $cache['call'] + ( empty( $validate['fail'] ) ? 1 : 0 );
 
463
  } else { // if new cache then reset these values
 
464
  $fail = 0;
465
+ $call = 1;
466
  }
467
 
468
  // update elements
469
+ IP_Geo_Block_Logs::update_cache( $cache = array(
470
+ 'time' => $_SERVER['REQUEST_TIME'],
471
+ 'ip' => $ip,
472
  'hook' => $hook,
473
  'code' => $validate['code'],
474
  'auth' => $validate['auth'], // get_current_user_id() > 0
475
+ 'fail' => $fail, // $validate['auth'] ? 0 : $fail,
476
  'call' => $settings['save_statistics'] ? $call : 0,
477
  'host' => isset( $validate['host'] ) ? $validate['host'] : NULL,
478
+ ) );
479
 
480
+ return self::$memcache[ $ip ] = $cache;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  }
482
 
483
  public static function clear_cache() {
484
+ IP_Geo_Block_Logs::clear_cache();
485
+ self::$memcache = array();
486
  }
487
 
488
  public static function get_cache_all() {
489
+ return IP_Geo_Block_Logs::restore_cache();
490
  }
491
 
492
  public static function get_cache( $ip ) {
493
+ if ( ! empty( self::$memcache[ $ip ] ) )
494
+ return self::$memcache[ $ip ];
495
+ else
496
+ return self::$memcache[ $ip ] = IP_Geo_Block_Logs::search_cache( $ip );
497
  }
498
 
499
  public function get_location( $ip, $args = array() ) {
519
  'freegeoip.net' => array(
520
  'key' => NULL,
521
  'type' => 'IPv4, IPv6 / free',
522
+ 'link' => '<a rel="noreferrer" href="http://freegeoip.net/" title="freegeoip.net: FREE IP Geolocation Web Service">http://freegeoip.net/</a>&nbsp;(IPv4, IPv6 / free)',
523
  ),
524
 
525
  'ipinfo.io' => array(
526
  'key' => NULL,
527
  'type' => 'IPv4, IPv6 / free',
528
+ 'link' => '<a rel="noreferrer" href="http://ipinfo.io/" title="ip address information including geolocation, hostname and network details">http://ipinfo.io/</a>&nbsp;(IPv4, IPv6 / free)',
529
  ),
530
 
531
  'Nekudo' => array(
532
  'key' => NULL,
533
  'type' => 'IPv4, IPv6 / free',
534
+ 'link' => '<a rel="noreferrer" href="http://geoip.nekudo.com/" title="geoip.nekudo.com | Free IP to geolocation API">http://geoip.nekudo.com/</a>&nbsp;(IPv4, IPv6 / free)',
535
  ),
536
 
537
  'Xhanch' => array(
538
  'key' => NULL,
539
  'type' => 'IPv4 / free',
540
+ 'link' => '<a rel="noreferrer" href="http://xhanch.com/xhanch-api-ip-get-detail/" title="Xhanch API &#8211; IP Get Detail | Xhanch Studio">http://xhanch.com/</a>&nbsp;(IPv4 / free)',
541
  ),
542
 
543
  'GeoIPLookup' => array(
544
  'key' => NULL,
545
  'type' => 'IPv4, IPv6 / free',
546
+ 'link' => '<a rel="noreferrer" href="http://geoiplookup.net/" title="What Is My IP Address | GeoIP Lookup">GeoIPLookup.net</a>&nbsp;(IPv4, IPv6 / free)',
547
  ),
548
 
549
  'ip-api.com' => array(
550
  'key' => FALSE,
551
  'type' => 'IPv4, IPv6 / free for non-commercial use',
552
+ 'link' => '<a rel="noreferrer" href="http://ip-api.com/" title="IP-API.com - Free Geolocation API">http://ip-api.com/</a>&nbsp;(IPv4, IPv6 / free for non-commercial use)',
553
  ),
554
 
555
  'IPInfoDB' => array(
556
  'key' => '',
557
  'type' => 'IPv4, IPv6 / free for registered user',
558
+ 'link' => '<a rel="noreferrer" href="http://ipinfodb.com/" title="IPInfoDB | Free IP Address Geolocation Tools">http://ipinfodb.com/</a>&nbsp;(IPv4, IPv6 / free for registered user)',
559
  ),
560
  );
561
 
643
  if ( ( NULL === $val && ! isset( $settings[ $key ] ) ) ||
644
  ( FALSE === $val && ! empty( $settings[ $key ] ) ) ||
645
  ( is_string( $val ) && ! empty( $settings[ $key ] ) ) ) {
646
+ ++$field;
647
  }
648
  }
649
 
650
  if ( 0 === $field )
651
+ return __( 'You need to select at least one IP geolocation service. Otherwise <strong>you\'ll be blocked</strong> after the cache expires.', 'ip-geo-block' );
 
 
 
652
 
653
  return NULL;
654
  }
680
  $exclude = array( '.', '..' );
681
  foreach ( $plugins as $plugin ) {
682
  if ( ! in_array( $plugin, $exclude, TRUE ) && is_dir( $dir.$plugin ) ) {
683
+ @include $dir.$plugin.'/class-'.$plugin.'.php';
684
  }
685
  }
686
  }
classes/class-ip-geo-block-cron.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2013-2016 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block_Cron {
@@ -73,7 +73,7 @@ class IP_Geo_Block_Cron {
73
 
74
  // if blocking may happen then disable validation
75
  if ( -1 !== (int)$settings['matching_rule'] && 'passed' !== $validate['result'] &&
76
- FALSE === strpos( $_SERVER['HTTP_X_REQUESTED_FROM'], 'InfiniteWP' ) ) {
77
  $settings['matching_rule'] = -1;
78
  }
79
 
@@ -101,7 +101,7 @@ class IP_Geo_Block_Cron {
101
  */
102
  private static function update_settings( $src, $keys = array() ) {
103
  if ( ! function_exists( 'is_plugin_active_for_network' ) )
104
- require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
105
 
106
  // for multisite
107
  if ( is_plugin_active_for_network( IP_GEO_BLOCK_BASE ) ) {
@@ -144,7 +144,11 @@ class IP_Geo_Block_Cron {
144
  *
145
  */
146
  public static function start_update_db( $settings ) {
147
- if ( has_action( 'activate_' . IP_GEO_BLOCK_BASE ) ) {
 
 
 
 
148
  set_transient( IP_Geo_Block::CRON_NAME, IP_Geo_Block::get_ip_address(), MINUTE_IN_SECONDS );
149
  self::schedule_cron_job( $settings['update'], NULL, TRUE );
150
  }
@@ -154,4 +158,221 @@ class IP_Geo_Block_Cron {
154
  wp_clear_scheduled_hook( IP_Geo_Block::CRON_NAME, array( FALSE ) ); // @since 2.1.0
155
  }
156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block_Cron {
73
 
74
  // if blocking may happen then disable validation
75
  if ( -1 !== (int)$settings['matching_rule'] && 'passed' !== $validate['result'] &&
76
+ ( empty( $_SERVER['HTTP_X_REQUESTED_FROM'] ) || FALSE === strpos( $_SERVER['HTTP_X_REQUESTED_FROM'], 'InfiniteWP' ) ) ) {
77
  $settings['matching_rule'] = -1;
78
  }
79
 
101
  */
102
  private static function update_settings( $src, $keys = array() ) {
103
  if ( ! function_exists( 'is_plugin_active_for_network' ) )
104
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
105
 
106
  // for multisite
107
  if ( is_plugin_active_for_network( IP_GEO_BLOCK_BASE ) ) {
144
  *
145
  */
146
  public static function start_update_db( $settings ) {
147
+ if ( ! function_exists( 'is_plugin_active' ) )
148
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
149
+
150
+ // the status is still inactive when this plugin is activated on dashboard.
151
+ if ( ! is_plugin_active( IP_GEO_BLOCK_BASE ) ) {
152
  set_transient( IP_Geo_Block::CRON_NAME, IP_Geo_Block::get_ip_address(), MINUTE_IN_SECONDS );
153
  self::schedule_cron_job( $settings['update'], NULL, TRUE );
154
  }
158
  wp_clear_scheduled_hook( IP_Geo_Block::CRON_NAME, array( FALSE ) ); // @since 2.1.0
159
  }
160
 
161
+ /**
162
+ * Kick off a cron job to garbage collection for IP address cache.
163
+ *
164
+ * Note: When the init action occurs in /wp-settings.php, wp_cron() runs.
165
+ */
166
+ public static function exec_cache_gc( $settings ) {
167
+ IP_Geo_Block_Logs::delete_expired_cache( $settings['cache_time'] );
168
+ self::stop_cache_gc();
169
+ self::start_cache_gc( $settings );
170
+ }
171
+
172
+ public static function start_cache_gc( $settings ) {
173
+ if ( ! wp_next_scheduled( IP_Geo_Block::CACHE_NAME ) )
174
+ wp_schedule_single_event( time() + $settings['cache_time_gc'], IP_Geo_Block::CACHE_NAME );
175
+ }
176
+
177
+ public static function stop_cache_gc() {
178
+ wp_clear_scheduled_hook( IP_Geo_Block::CACHE_NAME ); // @since 2.1.0
179
+ }
180
+
181
+ /**
182
+ * Download zip/gz file, uncompress and save it to specified file
183
+ *
184
+ * @param string $url URL of remote file to be downloaded.
185
+ * @param array $args request headers.
186
+ * @param string $filename full path to the downloaded file.
187
+ * @param int $modified time of last modified on the remote server.
188
+ * @return array status message.
189
+ */
190
+ public static function download_zip( $url, $args, $filename, $modified ) {
191
+ if ( ! function_exists( 'download_url' ) )
192
+ require_once ABSPATH . 'wp-admin/includes/file.php';
193
+
194
+ // if the name of src file is changed, then update the dst
195
+ if ( basename( $filename ) !== ( $base = pathinfo( $url, PATHINFO_FILENAME ) ) ) {
196
+ $filename = dirname( $filename ) . '/' . $base;
197
+ }
198
+
199
+ // check file
200
+ if ( ! file_exists( $filename ) )
201
+ $modified = 0;
202
+
203
+ // set 'If-Modified-Since' request header
204
+ $args += array(
205
+ 'headers' => array(
206
+ 'If-Modified-Since' => gmdate( DATE_RFC1123, (int)$modified ),
207
+ ),
208
+ );
209
+
210
+ // fetch file and get response code & message
211
+ $src = wp_remote_head( ( $url = esc_url_raw( $url ) ), $args );
212
+
213
+ if ( is_wp_error( $src ) )
214
+ return array(
215
+ 'code' => $src->get_error_code(),
216
+ 'message' => $src->get_error_message(),
217
+ );
218
+
219
+ $code = wp_remote_retrieve_response_code ( $src );
220
+ $mssg = wp_remote_retrieve_response_message( $src );
221
+ $data = wp_remote_retrieve_header( $src, 'last-modified' );
222
+ $modified = $data ? strtotime( $data ) : $modified;
223
+
224
+ if ( 304 == $code )
225
+ return array(
226
+ 'code' => $code,
227
+ 'message' => __( 'Your database file is up-to-date.', 'ip-geo-block' ),
228
+ 'filename' => $filename,
229
+ 'modified' => $modified,
230
+ );
231
+
232
+ elseif ( 200 != $code )
233
+ return array(
234
+ 'code' => $code,
235
+ 'message' => $code.' '.$mssg,
236
+ );
237
+
238
+ // downloaded and unzip
239
+ try {
240
+ // download file
241
+ $src = download_url( $url );
242
+
243
+ if ( is_wp_error( $src ) )
244
+ throw new Exception(
245
+ $src->get_error_code() . ' ' . $src->get_error_message()
246
+ );
247
+
248
+ // get extension
249
+ $args = strtolower( pathinfo( $url, PATHINFO_EXTENSION ) );
250
+
251
+ // unzip file
252
+ if ( 'gz' === $args && function_exists( 'gzopen' ) ) {
253
+ if ( FALSE === ( $gz = gzopen( $src, 'r' ) ) )
254
+ throw new Exception(
255
+ sprintf( __( 'Unable to read %s. Please check the permission.', 'ip-geo-block' ), $src )
256
+ );
257
+
258
+ if ( FALSE === ( $fp = @fopen( $filename, 'cb' ) ) )
259
+ throw new Exception(
260
+ sprintf( __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), $filename )
261
+ );
262
+
263
+ if ( ! flock( $fp, LOCK_EX ) )
264
+ throw new Exception(
265
+ sprintf( __( 'Can\'t lock %s. Please try again after a while.', 'ip-geo-block' ), $filename )
266
+ );
267
+
268
+ ftruncate( $fp, 0 ); // truncate file
269
+
270
+ // same block size in wp-includes/class-http.php
271
+ while ( $data = gzread( $gz, 4096 ) ) {
272
+ fwrite( $fp, $data, strlen( $data ) );
273
+ }
274
+ }
275
+
276
+ elseif ( 'zip' === $args && class_exists( 'ZipArchive' ) ) {
277
+ // https://codex.wordpress.org/Function_Reference/unzip_file
278
+ WP_Filesystem();
279
+ $tmp = get_temp_dir(); // @since 2.5
280
+ $ret = unzip_file( $src, $tmp ); // @since 2.5
281
+
282
+ if ( is_wp_error( $ret ) ) {
283
+ /* try fallback instead of throwing error
284
+ throw new Exception(
285
+ $ret->get_error_code() . ' ' . $ret->get_error_message()
286
+ );*/
287
+
288
+ // https://wordpress.org/support/topic/deactivated-after-updte-why/#post-6994655
289
+ $zip = new ZipArchive;
290
+ if ( TRUE !== $zip->open( $src ) )
291
+ throw new Exception(
292
+ sprintf(
293
+ __( 'Unable to read %s. Please check permission.', 'ip-geo-block' ),
294
+ $src
295
+ )
296
+ );
297
+
298
+ if ( FALSE === @$zip->extractTo( $tmp ) ) {
299
+ $zip->close();
300
+ throw new Exception(
301
+ sprintf(
302
+ __( 'Unable to write %s. Please check permission.', 'ip-geo-block' ),
303
+ $tmp . basename( $filename )
304
+ )
305
+ );
306
+ }
307
+
308
+ $zip->close();
309
+ }
310
+
311
+ if ( FALSE === ( $gz = @fopen( $tmp .= basename( $filename ), 'r' ) ) )
312
+ throw new Exception(
313
+ sprintf( __( 'Unable to read %s. Please check the permission.', 'ip-geo-block' ), $src )
314
+ );
315
+
316
+ if ( FALSE === ( $fp = @fopen( $filename, 'cb' ) ) )
317
+ throw new Exception(
318
+ sprintf( __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), $filename )
319
+ );
320
+
321
+ if ( ! flock( $fp, LOCK_EX ) )
322
+ throw new Exception(
323
+ sprintf( __( 'Can\'t lock %s. Please try again after a while.', 'ip-geo-block' ), $filename )
324
+ );
325
+
326
+ ftruncate( $fp, 0 ); // truncate file
327
+
328
+ // same block size in wp-includes/class-http.php
329
+ while ( $data = fread( $gz, 4096 ) ) {
330
+ fwrite( $fp, $data, strlen( $data ) );
331
+ }
332
+ }
333
+
334
+ else {
335
+ throw new Exception( __( 'gz or zip is not supported on your system.', 'ip-geo-block' ) );
336
+ }
337
+
338
+ if ( ! empty( $fp ) ) {
339
+ fflush( $fp ); // flush output before releasing the lock
340
+ flock ( $fp, LOCK_UN ); // release the lock
341
+ fclose( $fp );
342
+ }
343
+
344
+ ! empty( $gz ) and gzclose( $gz );
345
+ ! empty( $tmp ) && @is_file( $tmp ) and @unlink( $tmp );
346
+ ! is_wp_error( $src ) && @is_file( $src ) and @unlink( $src );
347
+ }
348
+
349
+ // error handler
350
+ catch ( Exception $e ) {
351
+ if ( ! empty( $fp ) ) {
352
+ fflush( $fp ); // flush output before releasing the lock
353
+ flock ( $fp, LOCK_UN ); // release the lock
354
+ fclose( $fp );
355
+ }
356
+
357
+ ! empty( $gz ) and gzclose( $gz );
358
+ ! empty( $tmp ) && @is_file( $tmp ) and @unlink( $tmp );
359
+ ! is_wp_error( $src ) && @is_file( $src ) and @unlink( $src );
360
+
361
+ return array(
362
+ 'code' => $e->getCode(),
363
+ 'message' => $e->getMessage(),
364
+ );
365
+ }
366
+
367
+ return array(
368
+ 'code' => $code,
369
+ 'message' => sprintf(
370
+ __( 'Last update: %s', 'ip-geo-block' ),
371
+ IP_Geo_Block_Util::localdate( $modified )
372
+ ),
373
+ 'filename' => $filename,
374
+ 'modified' => $modified,
375
+ );
376
+ }
377
+
378
  }
classes/class-ip-geo-block-lkup.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2016 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block_Lkup {
@@ -14,43 +14,42 @@ class IP_Geo_Block_Lkup {
14
  /**
15
  * Converts IP address to in_addr representation
16
  *
 
17
  */
18
- public static function inet_pton( $ip ) {
19
- // available on Windows platforms after PHP 5.3.0
20
- if ( function_exists( 'inet_pton' ) )
21
- return inet_pton( $ip );
22
-
23
- // http://stackoverflow.com/questions/14459041/inet-pton-replacement-function-for-php-5-2-17-in-windows
24
- else {
25
- // ipv4
26
- if ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
27
- if ( FALSE === strpos( $ip, ':' ) ) {
28
- $ip = pack( 'N', ip2long( $ip ) );
29
- } else {
30
- $ip = explode( ':', $ip );
31
- $ip = pack( 'N', ip2long( $ip[ count( $ip ) - 1 ] ) );
32
- }
33
- }
34
 
35
- // ipv6
36
- elseif ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
 
 
 
37
  $ip = explode( ':', $ip );
38
- $parts = 8 - count( $ip );
39
- $res = '';
40
- $replaced = 0;
41
- foreach ( $ip as $seg ) {
42
- if ( $seg != '' ) {
43
- $res .= str_pad( $seg, 4, '0', STR_PAD_LEFT );
44
- } elseif ( $replaced == 0 ) {
45
- for ( $i = 0; $i <= $parts; $i++ )
46
- $res .= '0000';
47
- $replaced = 1;
48
- } elseif ( $replaced == 1 ) {
 
 
 
 
49
  $res .= '0000';
50
  }
 
 
 
51
  }
52
- $ip = pack( 'H' . strlen( $res ), $res );
53
  }
 
54
  }
55
 
56
  return $ip;
@@ -63,7 +62,7 @@ class IP_Geo_Block_Lkup {
63
  public static function gethostbyaddr( $ip ) {
64
  // available on Windows platforms after PHP 5.3.0
65
  if ( function_exists( 'gethostbyaddr' ) )
66
- $host = gethostbyaddr( $ip );
67
 
68
  // if not available
69
  if ( empty( $host ) ) {
@@ -88,7 +87,7 @@ class IP_Geo_Block_Lkup {
88
  // on some operating systems, try the PEAR class Net_DNS
89
  if ( empty( $host ) ) {
90
  set_include_path( IP_GEO_BLOCK_PATH . 'includes' . PATH_SEPARATOR . get_include_path() );
91
- require_once( IP_GEO_BLOCK_PATH . 'includes/Net/DNS2.php' );
92
 
93
  // use google public dns
94
  $r = new Net_DNS2_Resolver(
@@ -115,4 +114,14 @@ class IP_Geo_Block_Lkup {
115
  return isset( $host ) ? $host : $ip;
116
  }
117
 
 
 
 
 
 
 
 
 
 
 
118
  }
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2016-2017 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block_Lkup {
14
  /**
15
  * Converts IP address to in_addr representation
16
  *
17
+ * @link http://stackoverflow.com/questions/14459041/inet-pton-replacement-function-for-php-5-2-17-in-windows
18
  */
19
+ private static function inet_pton( $ip ) {
20
+ // available on Windows platforms after PHP 5.3.0, need IPv6 support by PHP
21
+ if ( function_exists( 'inet_pton' ) && ( $ip = @inet_pton( $ip ) ) )
22
+ return $ip;
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ // ipv4
25
+ elseif ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
26
+ if ( FALSE === strpos( $ip, ':' ) ) {
27
+ $ip = pack( 'N', ip2long( $ip ) );
28
+ } else {
29
  $ip = explode( ':', $ip );
30
+ $ip = pack( 'N', ip2long( $ip[ count( $ip ) - 1 ] ) );
31
+ }
32
+ }
33
+
34
+ // ipv6
35
+ elseif ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
36
+ $ip = explode( ':', $ip );
37
+ $parts = 8 - count( $ip );
38
+ $res = '';
39
+ $replaced = 0;
40
+ foreach ( $ip as $seg ) {
41
+ if ( $seg != '' ) {
42
+ $res .= str_pad( $seg, 4, '0', STR_PAD_LEFT );
43
+ } elseif ( $replaced == 0 ) {
44
+ for ( $i = 0; $i <= $parts; ++$i ) {
45
  $res .= '0000';
46
  }
47
+ $replaced = 1;
48
+ } elseif ( $replaced == 1 ) {
49
+ $res .= '0000';
50
  }
 
51
  }
52
+ $ip = pack( 'H' . strlen( $res ), $res );
53
  }
54
 
55
  return $ip;
62
  public static function gethostbyaddr( $ip ) {
63
  // available on Windows platforms after PHP 5.3.0
64
  if ( function_exists( 'gethostbyaddr' ) )
65
+ $host = @gethostbyaddr( $ip );
66
 
67
  // if not available
68
  if ( empty( $host ) ) {
87
  // on some operating systems, try the PEAR class Net_DNS
88
  if ( empty( $host ) ) {
89
  set_include_path( IP_GEO_BLOCK_PATH . 'includes' . PATH_SEPARATOR . get_include_path() );
90
+ require_once IP_GEO_BLOCK_PATH . 'includes/Net/DNS2.php';
91
 
92
  // use google public dns
93
  $r = new Net_DNS2_Resolver(
114
  return isset( $host ) ? $host : $ip;
115
  }
116
 
117
+ /**
118
+ * https://codex.wordpress.org/WordPress_Feeds
119
+ *
120
+ */
121
+ public static function is_feed( $request_uri ) {
122
+ return isset( $_GET['feed'] ) ?
123
+ ( preg_match( '!(?:comments-)?(?:feed|rss|rss2|rdf|atom)$!', $_GET['feed'] ) ? TRUE : FALSE ) :
124
+ ( preg_match( '!(?:comments/)?(?:feed|rss|rss2|rdf|atom)/?$!', $request_uri ) ? TRUE : FALSE );
125
+ }
126
+
127
  }
classes/class-ip-geo-block-load.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2016 tokkonopapa
10
  */
11
 
12
  /**
@@ -126,32 +126,32 @@ class IP_Geo_Block_Loader {
126
  public function run() {
127
 
128
  /**
129
- * This part will be executed at the very beginning of WordPress core.
130
- * Execute callbacks that are specified by the component with 'init'.
131
  */
132
- if ( ! IP_Geo_Block_Util::may_be_logged_in() ) {
133
  foreach ( $this->actions as $index => $hook ) {
134
- if ( in_array( $hook['hook'], array( 'init', 'wp_loaded' ) ) ) {
135
- // Execute callback directly
136
- call_user_func( $hook['callback'], $hook['accepted_args'] );
137
 
138
- // To avoid duplicated execution, delete this hook
139
- unset( $this->actions[ $index ] );
140
- }
141
  }
142
  }
143
 
144
  /**
145
- * This part will be executed after loading this plugin.
146
- * Register all the rest of the action and filter hooks.
147
  */
148
  else {
149
- foreach ( $this->filters as $hook ) {
150
- add_filter( $hook['hook'], $hook['callback'], $hook['priority'], $hook['accepted_args'] );
151
- }
 
 
 
 
 
152
 
153
- foreach ( $this->actions as $hook ) {
154
- add_action( $hook['hook'], $hook['callback'], $hook['priority'], $hook['accepted_args'] );
155
  }
156
  }
157
 
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2016-2017 tokkonopapa
10
  */
11
 
12
  /**
126
  public function run() {
127
 
128
  /**
129
+ * This part will be executed after loading this plugin.
130
+ * Register all the rest of the action and filter hooks.
131
  */
132
+ if ( IP_Geo_Block_Util::is_user_logged_in() ) {
133
  foreach ( $this->actions as $index => $hook ) {
134
+ add_action( $hook['hook'], $hook['callback'], $hook['priority'], $hook['accepted_args'] );
 
 
135
 
136
+ unset( $this->actions[ $index ] );
 
 
137
  }
138
  }
139
 
140
  /**
141
+ * This part will be executed at the very beginning of WordPress core.
142
+ * Execute callbacks that are specified by the component with 'init'.
143
  */
144
  else {
145
+ foreach ( $this->actions as $index => $hook ) { /* admin ajax/post needs to be deferred */
146
+ if ( 'init' === $hook['hook'] || ( 'wp_loaded' === $hook['hook'] && ( ! defined( 'WP_ADMIN' ) || ! WP_ADMIN ) ) ) {
147
+ // Execute callback directly
148
+ call_user_func( $hook['callback'], $hook['accepted_args'] );
149
+ }
150
+ else {
151
+ add_action( $hook['hook'], $hook['callback'], $hook['priority'], $hook['accepted_args'] );
152
+ }
153
 
154
+ unset( $this->actions[ $index ] );
 
155
  }
156
  }
157
 
classes/class-ip-geo-block-logs.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2013-2016 tokkonopapa
10
  */
11
 
12
  // varchar can not be exceeded over 255 before MySQL-5.0.3.
@@ -32,7 +32,7 @@ class IP_Geo_Block_Logs {
32
  /**
33
  * Create
34
  *
35
- * @note creating mixed storage engine may cause troubles with some plugins.
36
  */
37
  public static function create_tables() {
38
  global $wpdb;
@@ -59,10 +59,10 @@ class IP_Geo_Block_Logs {
59
  `user_agent` varchar(" . IP_GEO_BLOCK_MAX_STR_LEN . ") NULL,
60
  `headers` varchar(" . IP_GEO_BLOCK_MAX_TXT_LEN . ") NULL,
61
  `data` text NULL,
62
- PRIMARY KEY (`No`),
63
  KEY `time` (`time`),
64
  KEY `hook` (`hook`)
65
- ) CHARACTER SET " . $charset
66
  ) ) or self::error( __LINE__ ); // utf8mb4 ENGINE=InnoDB or MyISAM
67
 
68
  // for statistics
@@ -70,8 +70,8 @@ class IP_Geo_Block_Logs {
70
  $result &= ( FALSE !== $wpdb->query( "CREATE TABLE IF NOT EXISTS `$table` (
71
  `No` tinyint(4) unsigned NOT NULL AUTO_INCREMENT,
72
  `data` longtext NULL,
73
- PRIMARY KEY (`No`)
74
- ) CHARACTER SET " . $charset
75
  ) ) or self::error( __LINE__ ); // utf8mb4 ENGINE=InnoDB or MyISAM
76
 
77
  // Create 1 record if not exists
@@ -80,20 +80,57 @@ class IP_Geo_Block_Logs {
80
  ON DUPLICATE KEY UPDATE No = No", 1, serialize( self::$default )
81
  ) and $wpdb->query( $sql );
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  return $result;
84
  }
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  /**
87
  * Delete
88
  *
89
  */
90
- public static function delete_tables() {
91
  global $wpdb;
92
- $tables = array( self::TABLE_LOGS, self::TABLE_STAT );
93
 
94
  foreach ( $tables as $table ) {
95
- $table = $wpdb->prefix . $table;
96
- $wpdb->query( "DROP TABLE IF EXISTS `$table`" ) or self::error( __LINE__ );
 
 
97
  }
98
  }
99
 
@@ -103,7 +140,7 @@ class IP_Geo_Block_Logs {
103
  */
104
  public static function diag_tables() {
105
  global $wpdb;
106
- $tables = array( self::TABLE_LOGS, self::TABLE_STAT );
107
 
108
  foreach ( $tables as $table ) {
109
  $table = $wpdb->prefix . $table;
@@ -158,43 +195,33 @@ class IP_Geo_Block_Logs {
158
  * Record statistics data.
159
  *
160
  */
161
- public static function record_stat( $statistics ) {
162
  global $wpdb;
163
  $table = $wpdb->prefix . self::TABLE_STAT;
164
 
165
- if ( ! is_array( $statistics ) ) {
166
- $statistics = self::$default;
167
  }
168
 
169
  $sql = $wpdb->prepare(
170
- "UPDATE `$table` SET `data` = '%s'", serialize( $statistics )
171
- // "REPLACE INTO `$table` (`No`, `data`) VALUES (%d, %s)", 1, serialize( $statistics )
172
- ) and $data = $wpdb->query( $sql ) or self::error( __LINE__ );
173
-
174
- return empty( $data ) ? FALSE : TRUE;
175
  }
176
 
177
  /**
178
- * Limit the number of rows to send to the user agent
179
  *
180
  */
181
  public static function limit_rows( $time ) {
182
- $time = intval( $time );
183
  $options = IP_Geo_Block::get_option();
184
-
185
- if ( $time < 80 /* msec */ )
186
- return (int)$options['validation']['maxlogs'];
187
-
188
- elseif ( $time < 200 /* msec */ )
189
- return (int)($options['validation']['maxlogs'] / 2);
190
-
191
- return (int)($options['validation']['maxlogs'] / 5);
192
  }
193
 
194
  /**
195
  * Validate string whether utf8
196
  *
197
- * @note code from wp_check_invalid_utf8() in wp-includes/formatting.php
198
  * @link https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php
199
  */
200
  private static function validate_utf8( $str ) {
@@ -275,9 +302,9 @@ class IP_Geo_Block_Logs {
275
 
276
  // truncate extra characters
277
  $len = min( $length, 6 );
278
- for ( $i = 0; $i < $len; $i++ ) {
279
  $c = ord( $str[$length-1 - $i] );
280
- for ( $j = $i; $j < 6; $j++ ) {
281
  if ( ( $c & $code[$j][0] ) == $code[$j][1] ) {
282
  mbstring_binary_safe_encoding(); // @since 3.7.0
283
  $str = substr( $str, 0, $length - (int)($j > 0) - $i );
@@ -341,10 +368,11 @@ class IP_Geo_Block_Logs {
341
 
342
  // XML-RPC
343
  if ( 'xmlrpc' === $hook ) {
344
- // mask the password
345
  $posts = self::truncate_utf8(
346
  file_get_contents( 'php://input' ), '!\s*([<>])\s*!', '$1', IP_GEO_BLOCK_MAX_STR_LEN
347
  );
 
 
348
  if ( $mask_pwd &&
349
  preg_match_all( '/<string>(\S*?)<\/string>/', $posts, $matches ) >= 2 &&
350
  strpos( $matches[1][1], home_url() ) !== 0 ) { // except pingback
@@ -387,7 +415,7 @@ class IP_Geo_Block_Logs {
387
  /**
388
  * Backup the validation log to text files
389
  *
390
- * @notice $path should not be in the public_html.
391
  */
392
  private static function backup_logs( $hook, $validate, $method, $agent, $heads, $posts, $path ) {
393
  // $path should be absolute path to the directory
@@ -492,16 +520,13 @@ class IP_Geo_Block_Logs {
492
  * Restore the validation log
493
  *
494
  * @param string $hook type of log name
495
- * return array log data
496
  */
497
  public static function restore_logs( $hook = NULL ) {
498
  global $wpdb;
499
  $table = $wpdb->prefix . self::TABLE_LOGS;
500
 
501
- $sql = ( "SELECT
502
- `hook`, `time`, `ip`, `code`, `result`, `method`, `user_agent`, `headers`, `data`
503
- FROM `$table`"
504
- );
505
 
506
  if ( ! $hook )
507
  $sql .= " ORDER BY `hook`, `No` DESC";
@@ -511,52 +536,155 @@ class IP_Geo_Block_Logs {
511
  return $sql ? $wpdb->get_results( $sql, ARRAY_N ) : array();
512
  }
513
 
 
 
 
 
 
 
 
 
514
  /**
515
  * Update statistics.
516
  *
517
  */
518
  public static function update_stat( $hook, $validate, $settings ) {
519
  // Restore statistics.
520
- if ( $statistics = self::restore_stat() ) {
521
 
522
  $provider = isset( $validate['provider'] ) ? $validate['provider'] : 'ZZ';
523
- if ( empty( $statistics['providers'][ $provider ] ) )
524
- $statistics['providers'][ $provider ] = array( 'count' => 0, 'time' => 0.0 );
525
 
526
- $statistics['providers'][ $provider ]['count']++; // undefined in auth_fail()
527
- $statistics['providers'][ $provider ]['time'] += (float)@$validate['time'];
528
 
529
  if ( 'passed' !== $validate['result'] ) {
530
  // Blocked by type of IP address
531
  if ( filter_var( $validate['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) )
532
- $statistics['IPv4']++;
533
  elseif ( filter_var( $validate['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) )
534
- $statistics['IPv6']++;
535
 
536
- @$statistics['blocked' ]++;
537
- @$statistics['countries'][ $validate['code'] ]++;
538
- @$statistics['daystats' ][ mktime( 0, 0, 0 ) ][ $hook ]++;
539
  }
540
 
541
- if ( count( $statistics['daystats'] ) > max( 30, min( 365, (int)@$settings['validation']['recdays'] ) ) ) {
542
- reset( $statistics['daystats'] );
543
- unset( $statistics['daystats'][ key( $statistics['daystats'] ) ] );
544
  }
545
 
546
  // Record statistics.
547
- self::record_stat( $statistics );
548
  }
549
  }
550
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
  /**
552
  * SQL Error handling
553
  *
554
  */
555
  private static function error( $line ) {
556
- if ( class_exists( 'IP_Geo_Block_Admin' ) ) {
557
- global $wpdb;
558
- if ( $wpdb->last_error )
559
  IP_Geo_Block_Admin::add_admin_notice( 'error', __FILE__ . ' (' . $line . ') ' . $wpdb->last_error );
 
 
 
560
  }
561
  }
 
562
  }
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
  */
11
 
12
  // varchar can not be exceeded over 255 before MySQL-5.0.3.
32
  /**
33
  * Create
34
  *
35
+ * @internal creating mixed storage engine may cause troubles with some plugins.
36
  */
37
  public static function create_tables() {
38
  global $wpdb;
59
  `user_agent` varchar(" . IP_GEO_BLOCK_MAX_STR_LEN . ") NULL,
60
  `headers` varchar(" . IP_GEO_BLOCK_MAX_TXT_LEN . ") NULL,
61
  `data` text NULL,
62
+ PRIMARY KEY (`No`),
63
  KEY `time` (`time`),
64
  KEY `hook` (`hook`)
65
+ ) CHARACTER SET $charset"
66
  ) ) or self::error( __LINE__ ); // utf8mb4 ENGINE=InnoDB or MyISAM
67
 
68
  // for statistics
70
  $result &= ( FALSE !== $wpdb->query( "CREATE TABLE IF NOT EXISTS `$table` (
71
  `No` tinyint(4) unsigned NOT NULL AUTO_INCREMENT,
72
  `data` longtext NULL,
73
+ PRIMARY KEY (`No`)
74
+ ) CHARACTER SET $charset"
75
  ) ) or self::error( __LINE__ ); // utf8mb4 ENGINE=InnoDB or MyISAM
76
 
77
  // Create 1 record if not exists
80
  ON DUPLICATE KEY UPDATE No = No", 1, serialize( self::$default )
81
  ) and $wpdb->query( $sql );
82
 
83
+ // for IP address cache
84
+ $table = $wpdb->prefix . IP_Geo_Block::CACHE_NAME;
85
+ $result &= ( FALSE !== $wpdb->query( "CREATE TABLE IF NOT EXISTS `$table` (
86
+ `No` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
87
+ `time` int(10) unsigned NOT NULL DEFAULT 0,
88
+ `ip` varchar(40) NOT NULL,
89
+ `hook` varchar(8) NOT NULL,
90
+ `auth` int(10) unsigned NOT NULL DEFAULT 0,
91
+ `code` varchar(2) NOT NULL DEFAULT 'ZZ',
92
+ `fail` int(10) unsigned NOT NULL DEFAULT 0,
93
+ `call` int(10) unsigned NOT NULL DEFAULT 0,
94
+ `host` tinytext NOT NULL,
95
+ PRIMARY KEY (`No`),
96
+ UNIQUE KEY (`ip`)
97
+ ) CHARACTER SET $charset"
98
+ ) ) or self::error( __LINE__ ); // utf8mb4 ENGINE=InnoDB or MyISAM
99
+
100
  return $result;
101
  }
102
 
103
+ /**
104
+ * Search table by specific IP address
105
+ *
106
+ */
107
+ private static function search_table( $table, $ip, $type = FALSE ) {
108
+ global $wpdb;
109
+ $table = $wpdb->prefix . $table;
110
+
111
+ $sql = $wpdb->prepare(
112
+ "SELECT * FROM `$table` WHERE `ip` = '%s'", $ip
113
+ ) and $result = $wpdb->get_results( $sql, ARRAY_A ) or self::error( __LINE__ );
114
+
115
+ if ( ! $type )
116
+ return ! empty( $result[0] ) ? $result[0] : NULL; // for cache
117
+ else
118
+ return ! empty( $result ) ? $result : array(); // for logs
119
+ }
120
+
121
  /**
122
  * Delete
123
  *
124
  */
125
+ public static function delete_tables( $which = 'all' ) {
126
  global $wpdb;
127
+ $tables = array( self::TABLE_LOGS, self::TABLE_STAT, IP_Geo_Block::CACHE_NAME );
128
 
129
  foreach ( $tables as $table ) {
130
+ if ( 'all' === $which || $table === $which ) {
131
+ $table = $wpdb->prefix . $table;
132
+ $wpdb->query( "DROP TABLE IF EXISTS `$table`" ) or self::error( __LINE__ );
133
+ }
134
  }
135
  }
136
 
140
  */
141
  public static function diag_tables() {
142
  global $wpdb;
143
+ $tables = array( self::TABLE_LOGS, self::TABLE_STAT, IP_Geo_Block::CACHE_NAME );
144
 
145
  foreach ( $tables as $table ) {
146
  $table = $wpdb->prefix . $table;
195
  * Record statistics data.
196
  *
197
  */
198
+ public static function record_stat( $stat ) {
199
  global $wpdb;
200
  $table = $wpdb->prefix . self::TABLE_STAT;
201
 
202
+ if ( ! is_array( $stat ) ) {
203
+ $stat = self::$default;
204
  }
205
 
206
  $sql = $wpdb->prepare(
207
+ "UPDATE `$table` SET `data` = '%s'", serialize( $stat )
208
+ // "REPLACE INTO `$table` (`No`, `data`) VALUES (%d, %s)", 1, serialize( $stat )
209
+ ) and $wpdb->query( $sql ) or self::error( __LINE__ );
 
 
210
  }
211
 
212
  /**
213
+ * Limit the number of rows to send to the user agent according the processing time [msec]
214
  *
215
  */
216
  public static function limit_rows( $time ) {
 
217
  $options = IP_Geo_Block::get_option();
218
+ return (int)( $options['validation']['maxlogs'] / (wp_is_mobile() ? 2 : 1) );
 
 
 
 
 
 
 
219
  }
220
 
221
  /**
222
  * Validate string whether utf8
223
  *
224
+ * @see wp_check_invalid_utf8() in wp-includes/formatting.php
225
  * @link https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php
226
  */
227
  private static function validate_utf8( $str ) {
302
 
303
  // truncate extra characters
304
  $len = min( $length, 6 );
305
+ for ( $i = 0; $i < $len; ++$i ) {
306
  $c = ord( $str[$length-1 - $i] );
307
+ for ( $j = $i; $j < 6; ++$j ) {
308
  if ( ( $c & $code[$j][0] ) == $code[$j][1] ) {
309
  mbstring_binary_safe_encoding(); // @since 3.7.0
310
  $str = substr( $str, 0, $length - (int)($j > 0) - $i );
368
 
369
  // XML-RPC
370
  if ( 'xmlrpc' === $hook ) {
 
371
  $posts = self::truncate_utf8(
372
  file_get_contents( 'php://input' ), '!\s*([<>])\s*!', '$1', IP_GEO_BLOCK_MAX_STR_LEN
373
  );
374
+
375
+ // mask the password
376
  if ( $mask_pwd &&
377
  preg_match_all( '/<string>(\S*?)<\/string>/', $posts, $matches ) >= 2 &&
378
  strpos( $matches[1][1], home_url() ) !== 0 ) { // except pingback
415
  /**
416
  * Backup the validation log to text files
417
  *
418
+ * Note: $path should not be within the public_html.
419
  */
420
  private static function backup_logs( $hook, $validate, $method, $agent, $heads, $posts, $path ) {
421
  // $path should be absolute path to the directory
520
  * Restore the validation log
521
  *
522
  * @param string $hook type of log name
523
+ * @return array log data
524
  */
525
  public static function restore_logs( $hook = NULL ) {
526
  global $wpdb;
527
  $table = $wpdb->prefix . self::TABLE_LOGS;
528
 
529
+ $sql = "SELECT `hook`, `time`, `ip`, `code`, `result`, `method`, `user_agent`, `headers`, `data` FROM `$table`";
 
 
 
530
 
531
  if ( ! $hook )
532
  $sql .= " ORDER BY `hook`, `No` DESC";
536
  return $sql ? $wpdb->get_results( $sql, ARRAY_N ) : array();
537
  }
538
 
539
+ /**
540
+ * Search logs by specific IP address
541
+ *
542
+ */
543
+ public static function search_logs( $ip ) {
544
+ return self::search_table( self::TABLE_LOGS, $ip, TRUE );
545
+ }
546
+
547
  /**
548
  * Update statistics.
549
  *
550
  */
551
  public static function update_stat( $hook, $validate, $settings ) {
552
  // Restore statistics.
553
+ if ( $stat = self::restore_stat() ) {
554
 
555
  $provider = isset( $validate['provider'] ) ? $validate['provider'] : 'ZZ';
556
+ if ( empty( $stat['providers'][ $provider ] ) )
557
+ $stat['providers'][ $provider ] = array( 'count' => 0, 'time' => 0.0 );
558
 
559
+ $stat['providers'][ $provider ]['count']++; // undefined in auth_fail()
560
+ $stat['providers'][ $provider ]['time' ] += (float)@$validate['time'];
561
 
562
  if ( 'passed' !== $validate['result'] ) {
563
  // Blocked by type of IP address
564
  if ( filter_var( $validate['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) )
565
+ ++$stat['IPv4'];
566
  elseif ( filter_var( $validate['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) )
567
+ ++$stat['IPv6'];
568
 
569
+ @$stat['blocked' ]++;
570
+ @$stat['countries'][ $validate['code'] ]++;
571
+ @$stat['daystats' ][ mktime( 0, 0, 0 ) ][ $hook ]++;
572
  }
573
 
574
+ if ( count( $stat['daystats'] ) > max( 30, min( 365, (int)@$settings['validation']['recdays'] ) ) ) {
575
+ reset( $stat['daystats'] );
576
+ unset( $stat['daystats'][ key( $stat['daystats'] ) ] );
577
  }
578
 
579
  // Record statistics.
580
+ self::record_stat( $stat );
581
  }
582
  }
583
 
584
+ /**
585
+ * Clear IP address cache.
586
+ *
587
+ */
588
+ public static function clear_cache() {
589
+ global $wpdb;
590
+ $table = $wpdb->prefix . IP_Geo_Block::CACHE_NAME;
591
+ $wpdb->query( "TRUNCATE TABLE `$table`" ) or self::error( __LINE__ );
592
+ }
593
+
594
+ /**
595
+ * Search cache by specific IP address
596
+ *
597
+ */
598
+ public static function search_cache( $ip ) {
599
+ return self::search_table( IP_Geo_Block::CACHE_NAME, $ip );
600
+ }
601
+
602
+ /**
603
+ * Restore cache
604
+ *
605
+ */
606
+ public static function restore_cache() {
607
+ global $wpdb;
608
+ $table = $wpdb->prefix . IP_Geo_Block::CACHE_NAME;
609
+ $result = $wpdb->get_results( "SELECT * FROM `$table`", ARRAY_A ) or self::error( __LINE__ );
610
+
611
+ // transform DB to cache format
612
+ $cache = $hash = array();
613
+ foreach ( $result as $key => $val ) {
614
+ $ip = $val['ip'];
615
+ unset( $val['ip'] );
616
+ $cache[ $ip ] = $val;
617
+ }
618
+
619
+ // sort by 'time'
620
+ foreach ( $cache as $key => $val )
621
+ $hash[ $key ] = $val['time'];
622
+
623
+ array_multisort( $hash, SORT_DESC, $cache );
624
+
625
+ return $cache;
626
+ }
627
+
628
+ /**
629
+ * Update cache
630
+ *
631
+ */
632
+ public static function update_cache( $cache ) {
633
+ global $wpdb;
634
+ $table = $wpdb->prefix . IP_Geo_Block::CACHE_NAME;
635
+
636
+ $sql = $wpdb->prepare(
637
+ "INSERT INTO `$table`
638
+ (`time`, `ip`, `hook`, `auth`, `code`, `fail`, `call`, `host`)
639
+ VALUES (%d, %s, %s, %d, %s, %d, %d, %s)
640
+ ON DUPLICATE KEY UPDATE
641
+ `time` = VALUES(`time`),
642
+ `hook` = VALUES(`hook`),
643
+ `auth` = VALUES(`auth`),
644
+ `code` = VALUES(`code`),
645
+ `fail` = VALUES(`fail`),
646
+ `call` = VALUES(`call`),
647
+ `host` = VALUES(`host`)",
648
+ $cache['time'],
649
+ $cache['ip' ],
650
+ $cache['hook'],
651
+ $cache['auth'],
652
+ $cache['code'],
653
+ $cache['fail'],
654
+ $cache['call'],
655
+ $cache['host']
656
+ ) and $wpdb->query( $sql ) or self::error( __LINE__ );
657
+ }
658
+
659
+ /**
660
+ * Delete expired cache
661
+ *
662
+ */
663
+ public static function delete_expired_cache( $cache_time ) {
664
+ global $wpdb;
665
+ $table = $wpdb->prefix . IP_Geo_Block::CACHE_NAME;
666
+
667
+ $sql = $wpdb->prepare(
668
+ "DELETE FROM `$table` WHERE `time` < %d",
669
+ $_SERVER['REQUEST_TIME'] - $cache_time
670
+ ) and $result = $wpdb->query( $sql ) or self::error( __LINE__ );
671
+
672
+ return $result;
673
+ }
674
+
675
  /**
676
  * SQL Error handling
677
  *
678
  */
679
  private static function error( $line ) {
680
+ global $wpdb;
681
+ if ( $wpdb->last_error ) {
682
+ if ( class_exists( 'IP_Geo_Block_Admin' ) )
683
  IP_Geo_Block_Admin::add_admin_notice( 'error', __FILE__ . ' (' . $line . ') ' . $wpdb->last_error );
684
+
685
+ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG )
686
+ error_log( __FILE__ . ' (' . $line . ') ' . $wpdb->last_error );
687
  }
688
  }
689
+
690
  }
classes/class-ip-geo-block-opts.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2013-2016 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block_Opts {
@@ -16,7 +16,7 @@ class IP_Geo_Block_Opts {
16
  *
17
  */
18
  private static $option_table = array(
19
- 'version' => '2.2.9', // Version of this table (not package)
20
  // since version 1.0
21
  'providers' => array(), // List of providers and API keys
22
  'comment' => array( // Message on the comment form
@@ -33,10 +33,12 @@ class IP_Geo_Block_Opts {
33
  // since version 1.1
34
  'cache_hold' => 10, // Max entries in cache
35
  'cache_time' => HOUR_IN_SECONDS, // @since 3.5
 
 
36
  // since version 1.2, 1.3
37
  'login_fails' => 5, // Limited number of login attempts
38
  'validation' => array( // Action hook for validation
39
- 'comment' => TRUE, // Validate on comment post
40
  'login' => 1, // Validate on login
41
  'admin' => 1, // Validate on admin (1:country 2:ZEP)
42
  'ajax' => 0, // Validate on ajax/post (1:country 2:ZEP)
@@ -53,6 +55,11 @@ class IP_Geo_Block_Opts {
53
  // since version 2.2.9
54
  'timing' => 0, // 0:init, 1:mu-plugins, 2:drop-in
55
  'recdays' => 30, // Number of days for recording logs
 
 
 
 
 
56
  ),
57
  'update' => array( // Updating IP address DB
58
  'auto' => TRUE, // Auto updating of DB file
@@ -71,6 +78,11 @@ class IP_Geo_Block_Opts {
71
  'rewrite' => array( // Apply rewrite rule
72
  'plugins' => FALSE, // for wp-content/plugins
73
  'themes' => FALSE, // for wp-content/themes
 
 
 
 
 
74
  ),
75
  'Maxmind' => array( // Maxmind
76
  // since version 2.2.2
@@ -94,6 +106,15 @@ class IP_Geo_Block_Opts {
94
  'exception' => array( // list of exceptional
95
  'plugins' => array(), // for pliugins
96
  'themes' => array(), // for themes
 
 
 
 
 
 
 
 
 
97
  ),
98
  // since version 2.2.7
99
  'api_key' => array( // API key
@@ -107,6 +128,22 @@ class IP_Geo_Block_Opts {
107
  'lostpassword' => TRUE,
108
  'postpass' => TRUE,
109
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  );
111
 
112
  /**
@@ -225,12 +262,29 @@ class IP_Geo_Block_Opts {
225
  $settings['validation']['recdays'] = $default['validation']['recdays'];
226
  }
227
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  // save package version number
229
  $settings['version'] = IP_Geo_Block::VERSION;
230
  }
231
 
232
- // install addons for IP Geolocation database API
233
- if ( ! $settings['api_dir'] || version_compare( $version, '2.2.9' ) < 0 )
234
  $settings['api_dir'] = self::install_api( $settings );
235
 
236
  // update option table
@@ -336,10 +390,7 @@ class IP_Geo_Block_Opts {
336
  }
337
 
338
  public static function get_validation_timing() {
339
- if ( file_exists( WPMU_PLUGIN_DIR . '/ip-geo-block-mu.php' ) )
340
- return 1; // mu-plugins
341
-
342
- return 0;
343
  }
344
 
345
  public static function setup_validation_timing( $settings = NULL ) {
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block_Opts {
16
  *
17
  */
18
  private static $option_table = array(
19
+ 'version' => '3.0.0', // Version of this table (not package)
20
  // since version 1.0
21
  'providers' => array(), // List of providers and API keys
22
  'comment' => array( // Message on the comment form
33
  // since version 1.1
34
  'cache_hold' => 10, // Max entries in cache
35
  'cache_time' => HOUR_IN_SECONDS, // @since 3.5
36
+ // since version 3.0.0
37
+ 'cache_time_gc' => 900, // Cache garbage collection time
38
  // since version 1.2, 1.3
39
  'login_fails' => 5, // Limited number of login attempts
40
  'validation' => array( // Action hook for validation
41
+ 'comment' => FALSE, // Validate on comment post
42
  'login' => 1, // Validate on login
43
  'admin' => 1, // Validate on admin (1:country 2:ZEP)
44
  'ajax' => 0, // Validate on ajax/post (1:country 2:ZEP)
55
  // since version 2.2.9
56
  'timing' => 0, // 0:init, 1:mu-plugins, 2:drop-in
57
  'recdays' => 30, // Number of days for recording logs
58
+ // since version 3.0.0
59
+ 'includes' => 3, // for wp-includes/
60
+ 'uploads' => 3, // for UPLOADS/uploads
61
+ 'languages' => 3, // for WP_CONTENT_DIR/language
62
+ 'public' => 0, // Validate on public facing pages
63
  ),
64
  'update' => array( // Updating IP address DB
65
  'auto' => TRUE, // Auto updating of DB file
78
  'rewrite' => array( // Apply rewrite rule
79
  'plugins' => FALSE, // for wp-content/plugins
80
  'themes' => FALSE, // for wp-content/themes
81
+ // since version 3.0.0
82
+ 'public' => FALSE, // for public facing pages
83
+ 'includes' => FALSE, // for wp-includes/
84
+ 'uploads' => FALSE, // for UPLOADS/uploads
85
+ 'languages' => FALSE, // for wp-content/language
86
  ),
87
  'Maxmind' => array( // Maxmind
88
  // since version 2.2.2
106
  'exception' => array( // list of exceptional
107
  'plugins' => array(), // for pliugins
108
  'themes' => array(), // for themes
109
+ // since version 3.0.0
110
+ 'admin' => array(), // for wp-admin
111
+ 'public' => array( // for public facing pages
112
+ 'bbp-new-topic', 'bbp-edit-topic',
113
+ 'bbp-new-reply', 'bbp-edit-reply',
114
+ ),
115
+ 'includes' => array(), // for wp-includes/
116
+ 'uploads' => array(), // for UPLOADS/uploads
117
+ 'languages' => array(), // for wp-content/language
118
  ),
119
  // since version 2.2.7
120
  'api_key' => array( // API key
128
  'lostpassword' => TRUE,
129
  'postpass' => TRUE,
130
  ),
131
+ // since version 3.0.0
132
+ 'response_msg' => 'Sorry, your request cannot be accepted.', // message on blocking
133
+ 'redirect_uri' => 'http://blackhole.webpagetest.org/', // redirection on blocking
134
+ 'network_wide' => FALSE, // settings page on network dashboard
135
+ 'public' => array(
136
+ 'matching_rule' => -1, // -1:follow, 0:white list, 1:black list
137
+ 'white_list' => NULL, // Comma separeted country code
138
+ 'black_list' => 'ZZ', // Comma separeted country code
139
+ 'target_rule' => 0, // 0:all requests, 1:specify the target
140
+ 'target_pages' => array(), // blocking target of pages
141
+ 'target_posts' => array(), // blocking target of post types
142
+ 'target_cates' => array(), // blocking target of categories
143
+ 'target_tags' => array(), // blocking target of tags
144
+ 'ua_list' => "Google:HOST,bot:HOST,slurp:HOST\nspider:HOST,archive:HOST,*:FEED\n*:HOST=embed.ly,Twitterbot:US,Facebot:US",
145
+ 'simulate' => FALSE, // just simulate, never block
146
+ ),
147
  );
148
 
149
  /**
262
  $settings['validation']['recdays'] = $default['validation']['recdays'];
263
  }
264
 
265
+ if ( version_compare( $version, '3.0.0' ) < 0 ) {
266
+ foreach ( array( 'cache_time_gc', 'response_msg', 'redirect_uri', 'network_wide', 'public' ) as $tmp ) {
267
+ $settings[ $tmp ] = $default[ $tmp ];
268
+ }
269
+
270
+ foreach ( array( 'public', 'includes', 'uploads', 'languages' ) as $tmp ) {
271
+ $settings['validation'][ $tmp ] = $default['validation'][ $tmp ];
272
+ $settings['rewrite' ][ $tmp ] = $default['rewrite' ][ $tmp ];
273
+ $settings['exception' ][ $tmp ] = $default['exception' ][ $tmp ];
274
+ }
275
+
276
+ $settings['exception']['admin'] = $default['exception']['admin'];
277
+ }
278
+
279
+ if ( version_compare( $version, '3.0.1' ) < 0 )
280
+ delete_transient( IP_Geo_Block::CACHE_NAME ); // @since 2.8
281
+
282
  // save package version number
283
  $settings['version'] = IP_Geo_Block::VERSION;
284
  }
285
 
286
+ // install addons for IP Geolocation database API ver. 1.1.8
287
+ if ( ! $settings['api_dir'] || version_compare( $version, '3.0.3' ) < 0 )
288
  $settings['api_dir'] = self::install_api( $settings );
289
 
290
  // update option table
390
  }
391
 
392
  public static function get_validation_timing() {
393
+ return file_exists( WPMU_PLUGIN_DIR . '/ip-geo-block-mu.php' ) ? 1 : 0;
 
 
 
394
  }
395
 
396
  public static function setup_validation_timing( $settings = NULL ) {
classes/class-ip-geo-block-util.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2013-2016 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block_Util {
@@ -31,137 +31,31 @@ class IP_Geo_Block_Util {
31
  /**
32
  * Download zip/gz file, uncompress and save it to specified file
33
  *
34
- * @param string $url URL of remote file to be downloaded.
35
- * @param array $args request headers.
36
- * @param string $filename full path to the downloaded file.
37
- * @param int $modified time of last modified on the remote server.
38
- * @return array status message.
39
  */
40
  public static function download_zip( $url, $args, $filename, $modified ) {
41
- if ( ! function_exists( 'download_url' ) )
42
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
43
-
44
- // if the name of src file is changed, then update the dst
45
- if ( basename( $filename ) !== ( $base = pathinfo( $url, PATHINFO_FILENAME ) ) ) {
46
- $filename = dirname( $filename ) . '/' . $base;
47
- }
48
-
49
- // check file
50
- if ( ! file_exists( $filename ) )
51
- $modified = 0;
52
-
53
- // set 'If-Modified-Since' request header
54
- $args += array(
55
- 'headers' => array(
56
- 'If-Modified-Since' => gmdate( DATE_RFC1123, (int)$modified ),
57
- ),
58
- );
59
-
60
- // fetch file and get response code & message
61
- $src = wp_remote_head( ( $url = esc_url_raw( $url ) ), $args );
62
-
63
- if ( is_wp_error( $src ) )
64
- return array(
65
- 'code' => $src->get_error_code(),
66
- 'message' => $src->get_error_message(),
67
- );
68
-
69
- $code = wp_remote_retrieve_response_code ( $src );
70
- $mssg = wp_remote_retrieve_response_message( $src );
71
- $data = wp_remote_retrieve_header( $src, 'last-modified' );
72
- $modified = $data ? strtotime( $data ) : $modified;
73
-
74
- if ( 304 == $code )
75
- return array(
76
- 'code' => $code,
77
- 'message' => __( 'Your database file is up-to-date.', 'ip-geo-block' ),
78
- 'filename' => $filename,
79
- 'modified' => $modified,
80
- );
81
-
82
- elseif ( 200 != $code )
83
- return array(
84
- 'code' => $code,
85
- 'message' => $code.' '.$mssg,
86
- );
87
-
88
- // downloaded and unzip
89
- try {
90
- // download file
91
- $src = download_url( $url );
92
-
93
- if ( is_wp_error( $src ) )
94
- throw new Exception(
95
- $src->get_error_code() . ' ' . $src->get_error_message()
96
- );
97
-
98
- // get extension
99
- $args = strtolower( pathinfo( $url, PATHINFO_EXTENSION ) );
100
-
101
- // unzip file
102
- if ( 'gz' === $args && function_exists( 'gzopen' ) ) {
103
- if ( FALSE === ( $gz = gzopen( $src, 'r' ) ) )
104
- throw new Exception(
105
- sprintf(
106
- __( 'Unable to read %s. Please check the permission.', 'ip-geo-block' ),
107
- $src
108
- )
109
- );
110
-
111
- if ( FALSE === ( $fp = @fopen( $filename, 'wb' ) ) )
112
- throw new Exception(
113
- sprintf(
114
- __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ),
115
- $filename
116
- )
117
- );
118
-
119
- // same block size in wp-includes/class-http.php
120
- while ( $data = gzread( $gz, 4096 ) )
121
- fwrite( $fp, $data, strlen( $data ) );
122
-
123
- gzclose( $gz );
124
- fclose ( $fp );
125
- }
126
-
127
- elseif ( 'zip' === $args && class_exists( 'ZipArchive' ) ) {
128
- // https://codex.wordpress.org/Function_Reference/unzip_file
129
- WP_Filesystem();
130
- $ret = unzip_file( $src, dirname( $filename ) ); // @since 2.5
131
-
132
- if ( is_wp_error( $ret ) )
133
- throw new Exception(
134
- $ret->get_error_code() . ' ' . $ret->get_error_message()
135
- );
136
- }
137
-
138
- @unlink( $src );
139
- }
140
 
141
- // error handler
142
- catch ( Exception $e ) {
143
- if ( 'gz' === $args && function_exists( 'gzopen' ) ) {
144
- ! empty( $gz ) and gzclose( $gz );
145
- ! empty( $fp ) and fclose ( $fp );
146
- }
 
147
 
148
- ! is_wp_error( $src ) and @unlink( $src );
 
 
149
 
150
- return array(
151
- 'code' => $e->getCode(),
152
- 'message' => $e->getMessage(),
153
- );
154
- }
155
 
156
- return array(
157
- 'code' => $code,
158
- 'message' => sprintf(
159
- __( 'Last update: %s', 'ip-geo-block' ),
160
- self::localdate( $modified )
161
- ),
162
- 'filename' => $filename,
163
- 'modified' => $modified,
164
- );
165
  }
166
 
167
  /**
@@ -175,8 +69,10 @@ class IP_Geo_Block_Util {
175
  /**
176
  * HTML/XHTML filter that only allows some elements and attributes
177
  *
 
178
  */
179
  public static function kses( $str, $allow_tags = TRUE ) {
 
180
  return wp_kses( $str, $allow_tags ? $GLOBALS['allowedtags'] : array() );
181
  }
182
 
@@ -195,7 +91,7 @@ class IP_Geo_Block_Util {
195
  }
196
 
197
  public static function trace_nonce( $nonce ) {
198
- if ( self::may_be_logged_in() && empty( $_REQUEST[ $nonce ] ) &&
199
  self::retrieve_nonce( $nonce ) && 'GET' === $_SERVER['REQUEST_METHOD'] ) {
200
  // add nonce at add_admin_nonce() to handle the client side redirection.
201
  self::redirect( esc_url_raw( $_SERVER['REQUEST_URI'] ), 302 );
@@ -208,13 +104,11 @@ class IP_Geo_Block_Util {
208
  *
209
  */
210
  public static function rebuild_nonce( $location, $status = 302 ) {
211
- $key = IP_Geo_Block::PLUGIN_NAME . '-auth-nonce';
212
-
213
- if ( $nonce = self::retrieve_nonce( $key ) ) { // must be sanitized
214
- $host = parse_url( $location, PHP_URL_HOST );
215
-
216
- // check if the location is internal
217
- if ( ! $host || $host === parse_url( home_url(), PHP_URL_HOST ) ) {
218
  $location = esc_url_raw( add_query_arg(
219
  array(
220
  $key => false, // delete onece
@@ -229,13 +123,13 @@ class IP_Geo_Block_Util {
229
  }
230
 
231
  /**
232
- * WP alternative function for mu-plugins
233
  *
234
  * Creates a cryptographic tied to the action, user, session, and time.
235
- * @source: wp-includes/pluggable.php
236
  */
237
- public static function create_nonce( $action = -1, $ip_addr = NULL ) {
238
- $uid = self::get_current_user( $ip_addr );
239
  $tok = self::get_session_token();
240
  $exp = self::nonce_tick();
241
 
@@ -243,13 +137,13 @@ class IP_Geo_Block_Util {
243
  }
244
 
245
  /**
246
- * WP alternative function for mu-plugins
247
  *
248
  * Verify that correct nonce was used with time limit.
249
- * @source: wp-includes/pluggable.php
250
  */
251
- public static function verify_nonce( $nonce, $action = -1, $ip_addr = NULL ) {
252
- $uid = self::get_current_user( $ip_addr );
253
  $tok = self::get_session_token();
254
  $exp = self::nonce_tick();
255
 
@@ -270,10 +164,10 @@ class IP_Geo_Block_Util {
270
  }
271
 
272
  /**
273
- * WP alternative function for mu-plugins
274
  *
275
  * Get hash of given string for nonce.
276
- * @source: wp-includes/pluggable.php
277
  */
278
  private static function hash_nonce( $data ) {
279
  return self::hash_hmac( 'md5', $data, NONCE_KEY . NONCE_SALT );
@@ -283,7 +177,7 @@ class IP_Geo_Block_Util {
283
  * WP alternative function for mu-plugins
284
  *
285
  * Retrieve the current session token from the logged_in cookie.
286
- * @source: wp-includes/user.php
287
  */
288
  private static function get_session_token() {
289
  // Arrogating logged_in cookie never cause the privilege escalation.
@@ -294,13 +188,13 @@ class IP_Geo_Block_Util {
294
  /**
295
  * WP alternative function for mu-plugins
296
  *
297
- * Parse a cookie into its components.
298
- * @source: wp-includes/pluggable.php
299
  */
300
  private static function parse_auth_cookie( $scheme ) {
301
- static $cookie = NULL;
302
 
303
- if ( NULL === $cookie ) {
304
  foreach ( array_keys( $_COOKIE ) as $key ) {
305
  if ( FALSE !== strpos( $key, $scheme ) ) {
306
  if ( count( $elements = explode( '|', $_COOKIE[ $key ] ) ) === 4 ) {
@@ -318,58 +212,19 @@ class IP_Geo_Block_Util {
318
  * WP alternative function for mu-plugins
319
  *
320
  * Get the time-dependent variable for nonce creation.
321
- * @source: wp-includes/pluggable.php
322
  */
323
  private static function nonce_tick() {
324
  return ceil( time() / ( DAY_IN_SECONDS / 2 ) );
325
  }
326
 
327
  /**
328
- * WP alternative function for mu-plugins
329
- *
330
- * Retrieve the current user identification.
331
- * @source: wp-includes/user.php
332
- */
333
- private static function get_current_user( $ip_addr ) {
334
- if ( $ip_addr ) {
335
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-lkup.php' );
336
-
337
- $num = '';
338
- $sum = 0;
339
-
340
- foreach ( unpack( 'C*', IP_Geo_Block_Lkup::inet_pton( $ip_addr ) ) as $byte ) {
341
- $sum += $byte;
342
- $num .= (string)( $byte % 10 );
343
- }
344
-
345
- $num += $sum;
346
- }
347
-
348
- elseif ( isset( $_COOKIE ) ) {
349
- foreach ( array_keys( $_COOKIE ) as $key ) {
350
- if ( 0 === strpos( $key, 'wp-settings-' ) ) {
351
- $num = substr( $key, 12 ); // get numerical characters
352
- break;
353
- }
354
- }
355
- }
356
- /*
357
- // add something which a visitor can't control
358
- $num .= substr( SECURE_AUTH_KEY, 1, 6 ); // @since 2.6
359
-
360
- // add something unique
361
- if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && is_string( $_SERVER['HTTP_USER_AGENT'] ) )
362
- $num .= preg_replace( '/[^-,:!*+\.\/\w\s]/', '', $_SERVER['HTTP_USER_AGENT'] );
363
- */
364
- return isset( $num ) ? $num : '0';
365
- }
366
-
367
- /**
368
- * WP alternative function for mu-plugins
369
  *
370
  * Timing attack safe string comparison.
371
- * @source: http://php.net/manual/en/function.hash-equals.php#115635
372
- * @reference: wp-includes/compat.php
 
373
  */
374
  private static function hash_equals( $a, $b ) {
375
  // PHP 5 >= 5.6.0 or wp-includes/compat.php
@@ -379,20 +234,21 @@ class IP_Geo_Block_Util {
379
  if( ( $i = strlen( $a ) ) !== strlen( $b ) )
380
  return FALSE;
381
 
382
- $exp = $a ^ $b; // 1 === strlen( 'a' ^ 'ab' )
383
  $ret = 0;
384
 
385
- while ( --$i >= 0 )
386
  $ret |= ord( $exp[ $i ] );
 
387
 
388
  return ! $ret;
389
  }
390
 
391
  /**
392
- * WP alternative function for mu-plugins
393
  *
394
  * Generate a keyed hash value using the HMAC method.
395
- * @source: http://php.net/manual/en/function.hash-hmac.php#93440
396
  */
397
  private static function hash_hmac( $algo, $data, $key, $raw_output = FALSE ) {
398
  // PHP 5 >= 5.1.2, PECL hash >= 1.1 or wp-includes/compat.php
@@ -420,16 +276,16 @@ class IP_Geo_Block_Util {
420
  }
421
 
422
  /**
423
- * WP alternative function for mu-plugins
424
  *
425
  * Sanitizes a URL for use in a redirect.
426
- * @source: wp-includes/pluggable.php
427
  */
428
  private static function sanitize_utf8_in_redirect( $matches ) {
429
  return urlencode( $matches[0] );
430
  }
431
 
432
- private static function sanitize_redirect($location) {
433
  $regex = '/
434
  (
435
  (?: [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
@@ -452,38 +308,51 @@ class IP_Geo_Block_Util {
452
  }
453
 
454
  /**
455
- * WP alternative function for mu-plugins
456
  *
457
  * Redirects to another page.
458
- * @source: wp-includes/pluggable.php
459
  */
460
  public static function redirect( $location, $status = 302 ) {
461
- $_is_apache = (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false || strpos($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') !== false);
462
- $_is_IIS = !$_is_apache && (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false || strpos($_SERVER['SERVER_SOFTWARE'], 'ExpressionDevServer') !== false);
463
-
464
  // retrieve nonce from referer and add it to the location
465
  $location = self::rebuild_nonce( $location, $status );
466
  $location = self::sanitize_redirect( $location );
467
 
468
  if ( $location ) {
469
- if ( ! $_is_IIS && PHP_SAPI != 'cgi-fcgi' )
470
  status_header( $status ); // This causes problems on IIS and some FastCGI setups
471
 
472
  header( "Location: $location", true, $status );
473
 
474
- return true;
475
  }
476
 
477
  else {
478
- return false;
479
  }
480
  }
481
 
482
  /**
483
- * WP alternative function for mu-plugins
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  *
485
  * Validates a URL for use in a redirect.
486
- * @source: wp-includes/pluggable.php
487
  */
488
  private static function validate_redirect( $location, $default = '' ) {
489
  // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//'
@@ -497,7 +366,7 @@ class IP_Geo_Block_Util {
497
  $lp = @parse_url( $test );
498
 
499
  // Give up if malformed URL
500
- if ( false === $lp )
501
  return $default;
502
 
503
  // Allow only http and https schemes. No data:, etc.
@@ -518,6 +387,7 @@ class IP_Geo_Block_Util {
518
 
519
  // Filters the whitelist of hosts to redirect to.
520
  $allowed_hosts = (array) apply_filters( 'allowed_redirect_hosts', array( $wpp['host'] ), isset( $lp['host'] ) ? $lp['host'] : '' );
 
521
 
522
  if ( isset( $lp['host'] ) && ( ! in_array( $lp['host'], $allowed_hosts ) && $lp['host'] != strtolower( $wpp['host'] ) ) )
523
  $location = $default;
@@ -526,11 +396,11 @@ class IP_Geo_Block_Util {
526
  }
527
 
528
  /**
529
- * WP alternative function for mu-plugins
530
  *
531
  * Retrieves unvalidated referer from '_wp_http_referer' or HTTP referer.
532
- * @source: wp-includes/functions.php
533
- * @note: wp_unslash() can be replaced with stripslashes() in this context because the target value is 'string'.
534
  */
535
  private static function get_raw_referer() {
536
  if ( ! empty( $_REQUEST['_wp_http_referer'] ) )
@@ -539,46 +409,66 @@ class IP_Geo_Block_Util {
539
  elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) )
540
  return /*wp_unslash*/ stripslashes( $_SERVER['HTTP_REFERER'] ); // wp-includes/formatting.php
541
 
542
- return false;
543
  }
544
 
545
  /**
546
- * WP alternative function for mu-plugins
547
  *
548
  * Retrieve referer from '_wp_http_referer' or HTTP referer.
549
- * @source: wp-includes/functions.php
550
  */
551
  public static function get_referer() {
552
  $ref = self::get_raw_referer(); // wp-includes/functions.php
553
  $req = /*wp_unslash*/ stripslashes( $_SERVER['REQUEST_URI'] );
554
 
555
  if ( $ref && $ref !== $req && $ref !== home_url() . $req )
556
- return self::validate_redirect( $ref, false );
557
 
558
- return false;
559
  }
560
 
561
  /**
562
- * WP alternative function for mu-plugins
563
  *
564
  * Checks if the current visitor is a logged in user.
565
- * @source: wp-includes/pluggable.php
566
  */
567
- public static function may_be_logged_in() {
568
  // possibly logged in but should be verified after 'init' hook is fired.
569
  return did_action( 'init' ) ? is_user_logged_in() : ( self::parse_auth_cookie( 'logged_in' ) ? TRUE : FALSE );
570
  }
571
 
 
 
 
 
 
 
572
  public static function get_current_user_id() {
573
- // unavailale before 'init' hook.
574
- return did_action( 'init' ) ? get_current_user_id() : 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
575
  }
576
 
577
  /**
578
  * WP alternative function for advanced-cache.php
579
  *
580
  * Add / Remove slash at the end of string.
581
- * @source: wp-includes/formatting.php
582
  */
583
  public static function unslashit( $string ) {
584
  return rtrim( $string, '/\\' );
@@ -589,10 +479,10 @@ class IP_Geo_Block_Util {
589
  }
590
 
591
  /**
592
- * WP alternative function for advanced-cache.php
593
  *
594
  * Removes any NULL characters in $string.
595
- * @source: wp-includes/kses.php
596
  */
597
  private static function kses_no_null( $string ) {
598
  $string = preg_replace( '/[\x00-\x08\x0B\x0C\x0E-\x1F]/', '', $string );
@@ -602,11 +492,11 @@ class IP_Geo_Block_Util {
602
  }
603
 
604
  /**
605
- * WP alternative function for advanced-cache.php
606
  *
607
  * Perform a deep string replace operation to ensure the values in $search are no longer present.
608
  * e.g. $subject = '%0%0%0DDD', $search ='%0D', $result ='' rather than the '%0%0DD' that str_replace would return
609
- * @source: wp-includes/formatting.php
610
  */
611
  private static function deep_replace( $search, $subject ) {
612
  $subject = (string) $subject;
@@ -619,4 +509,29 @@ class IP_Geo_Block_Util {
619
  return $subject;
620
  }
621
 
622
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block_Util {
31
  /**
32
  * Download zip/gz file, uncompress and save it to specified file
33
  *
 
 
 
 
 
34
  */
35
  public static function download_zip( $url, $args, $filename, $modified ) {
36
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php';
37
+ return IP_Geo_Block_Cron::download_zip( $url, $args, $filename, $modified );
38
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ /**
41
+ * Simple comparison of urls
42
+ *
43
+ */
44
+ public static function compare_url( $a, $b ) {
45
+ if ( ! ( $a = @parse_url( $a ) ) ) return FALSE;
46
+ if ( ! ( $b = @parse_url( $b ) ) ) return FALSE;
47
 
48
+ // leave scheme to site configuration because is_ssl() doesn’t work behind some load balancers.
49
+ unset( $a['scheme'] );
50
+ unset( $b['scheme'] );
51
 
52
+ // $_SERVER['HTTP_HOST'] can't be available in case of malicious url.
53
+ $key = isset( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : '';
54
+ if ( empty( $a['host'] ) ) $a['host'] = $key;
55
+ if ( empty( $b['host'] ) ) $b['host'] = $key;
 
56
 
57
+ $key = array_diff( $a, $b );
58
+ return empty( $key ) ? TRUE : FALSE;
 
 
 
 
 
 
 
59
  }
60
 
61
  /**
69
  /**
70
  * HTML/XHTML filter that only allows some elements and attributes
71
  *
72
+ * @see wp-includes/kses.php
73
  */
74
  public static function kses( $str, $allow_tags = TRUE ) {
75
+ // wp_kses() is unavailable on advanced-cache.php
76
  return wp_kses( $str, $allow_tags ? $GLOBALS['allowedtags'] : array() );
77
  }
78
 
91
  }
92
 
93
  public static function trace_nonce( $nonce ) {
94
+ if ( self::is_user_logged_in() && empty( $_REQUEST[ $nonce ] ) &&
95
  self::retrieve_nonce( $nonce ) && 'GET' === $_SERVER['REQUEST_METHOD'] ) {
96
  // add nonce at add_admin_nonce() to handle the client side redirection.
97
  self::redirect( esc_url_raw( $_SERVER['REQUEST_URI'] ), 302 );
104
  *
105
  */
106
  public static function rebuild_nonce( $location, $status = 302 ) {
107
+ // check if the location is internal
108
+ $host = parse_url( $location, PHP_URL_HOST );
109
+ if ( ! $host || $host === parse_url( home_url(), PHP_URL_HOST ) ) {
110
+ // it doesn't care about valid nonce or invalid nonce (must be sanitized)
111
+ if ( $nonce = self::retrieve_nonce( $key = IP_Geo_Block::PLUGIN_NAME . '-auth-nonce' ) ) {
 
 
112
  $location = esc_url_raw( add_query_arg(
113
  array(
114
  $key => false, // delete onece
123
  }
124
 
125
  /**
126
+ * WP alternative function of wp_create_nonce() for mu-plugins
127
  *
128
  * Creates a cryptographic tied to the action, user, session, and time.
129
+ * @source wp-includes/pluggable.php
130
  */
131
+ public static function create_nonce( $action = -1 ) {
132
+ $uid = self::get_current_user_id();
133
  $tok = self::get_session_token();
134
  $exp = self::nonce_tick();
135
 
137
  }
138
 
139
  /**
140
+ * WP alternative function of wp_verify_nonce() for mu-plugins
141
  *
142
  * Verify that correct nonce was used with time limit.
143
+ * @source wp-includes/pluggable.php
144
  */
145
+ public static function verify_nonce( $nonce, $action = -1 ) {
146
+ $uid = self::get_current_user_id();
147
  $tok = self::get_session_token();
148
  $exp = self::nonce_tick();
149
 
164
  }
165
 
166
  /**
167
+ * WP alternative function of wp_hash() for mu-plugins
168
  *
169
  * Get hash of given string for nonce.
170
+ * @source wp-includes/pluggable.php
171
  */
172
  private static function hash_nonce( $data ) {
173
  return self::hash_hmac( 'md5', $data, NONCE_KEY . NONCE_SALT );
177
  * WP alternative function for mu-plugins
178
  *
179
  * Retrieve the current session token from the logged_in cookie.
180
+ * @source wp-includes/user.php
181
  */
182
  private static function get_session_token() {
183
  // Arrogating logged_in cookie never cause the privilege escalation.
188
  /**
189
  * WP alternative function for mu-plugins
190
  *
191
+ * Parse a cookie into its components. It assumes the key including $scheme.
192
+ * @source wp-includes/pluggable.php (after muplugins_loaded, it would be initialized)
193
  */
194
  private static function parse_auth_cookie( $scheme ) {
195
+ static $cookie = FALSE;
196
 
197
+ if ( FALSE === $cookie ) {
198
  foreach ( array_keys( $_COOKIE ) as $key ) {
199
  if ( FALSE !== strpos( $key, $scheme ) ) {
200
  if ( count( $elements = explode( '|', $_COOKIE[ $key ] ) ) === 4 ) {
212
  * WP alternative function for mu-plugins
213
  *
214
  * Get the time-dependent variable for nonce creation.
215
+ * @source wp-includes/pluggable.php
216
  */
217
  private static function nonce_tick() {
218
  return ceil( time() / ( DAY_IN_SECONDS / 2 ) );
219
  }
220
 
221
  /**
222
+ * WP alternative function of hash_equals() for mu-plugins
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  *
224
  * Timing attack safe string comparison.
225
+ * @source http://php.net/manual/en/function.hash-equals.php#115635
226
+ * @see http://php.net/manual/en/language.operators.increment.php
227
+ * @see wp-includes/compat.php
228
  */
229
  private static function hash_equals( $a, $b ) {
230
  // PHP 5 >= 5.6.0 or wp-includes/compat.php
234
  if( ( $i = strlen( $a ) ) !== strlen( $b ) )
235
  return FALSE;
236
 
237
+ $exp = $a ^ $b; // length of both $a and $b are same
238
  $ret = 0;
239
 
240
+ while ( --$i >= 0 ) {
241
  $ret |= ord( $exp[ $i ] );
242
+ }
243
 
244
  return ! $ret;
245
  }
246
 
247
  /**
248
+ * WP alternative function of hash_hmac() for mu-plugins
249
  *
250
  * Generate a keyed hash value using the HMAC method.
251
+ * @source http://php.net/manual/en/function.hash-hmac.php#93440
252
  */
253
  private static function hash_hmac( $algo, $data, $key, $raw_output = FALSE ) {
254
  // PHP 5 >= 5.1.2, PECL hash >= 1.1 or wp-includes/compat.php
276
  }
277
 
278
  /**
279
+ * WP alternative function of wp_sanitize_redirect() for mu-plugins
280
  *
281
  * Sanitizes a URL for use in a redirect.
282
+ * @source wp-includes/pluggable.php
283
  */
284
  private static function sanitize_utf8_in_redirect( $matches ) {
285
  return urlencode( $matches[0] );
286
  }
287
 
288
+ private static function sanitize_redirect( $location ) {
289
  $regex = '/
290
  (
291
  (?: [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
308
  }
309
 
310
  /**
311
+ * WP alternative function of wp_redirect() for mu-plugins
312
  *
313
  * Redirects to another page.
314
+ * @source wp-includes/pluggable.php
315
  */
316
  public static function redirect( $location, $status = 302 ) {
 
 
 
317
  // retrieve nonce from referer and add it to the location
318
  $location = self::rebuild_nonce( $location, $status );
319
  $location = self::sanitize_redirect( $location );
320
 
321
  if ( $location ) {
322
+ if ( ! self::is_IIS() && PHP_SAPI != 'cgi-fcgi' )
323
  status_header( $status ); // This causes problems on IIS and some FastCGI setups
324
 
325
  header( "Location: $location", true, $status );
326
 
327
+ return TRUE;
328
  }
329
 
330
  else {
331
+ return FALSE;
332
  }
333
  }
334
 
335
  /**
336
+ * WP alternative function of wp_redirect() for mu-plugins
337
+ *
338
+ * Performs a safe (local) redirect, using redirect().
339
+ * @source wp-includes/pluggable.php
340
+ */
341
+ public static function safe_redirect( $location, $status = 302 ) {
342
+ // Need to look at the URL the way it will end up in wp_redirect()
343
+ $location = self::sanitize_redirect( $location );
344
+
345
+ // Filters the redirect fallback URL for when the provided redirect is not safe (local).
346
+ $location = self::validate_redirect( $location, apply_filters( 'wp_safe_redirect_fallback', admin_url(), $status ) );
347
+
348
+ self::redirect( $location, $status );
349
+ }
350
+
351
+ /**
352
+ * WP alternative function of wp_validate_redirect() for mu-plugins
353
  *
354
  * Validates a URL for use in a redirect.
355
+ * @source wp-includes/pluggable.php
356
  */
357
  private static function validate_redirect( $location, $default = '' ) {
358
  // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//'
366
  $lp = @parse_url( $test );
367
 
368
  // Give up if malformed URL
369
+ if ( FALSE === $lp )
370
  return $default;
371
 
372
  // Allow only http and https schemes. No data:, etc.
387
 
388
  // Filters the whitelist of hosts to redirect to.
389
  $allowed_hosts = (array) apply_filters( 'allowed_redirect_hosts', array( $wpp['host'] ), isset( $lp['host'] ) ? $lp['host'] : '' );
390
+ $allowed_hosts[] = 'blackhole.webpagetest.org';
391
 
392
  if ( isset( $lp['host'] ) && ( ! in_array( $lp['host'], $allowed_hosts ) && $lp['host'] != strtolower( $wpp['host'] ) ) )
393
  $location = $default;
396
  }
397
 
398
  /**
399
+ * WP alternative function of wp_get_raw_referer() for mu-plugins
400
  *
401
  * Retrieves unvalidated referer from '_wp_http_referer' or HTTP referer.
402
+ * @source wp-includes/functions.php
403
+ * @uses wp_unslash() can be replaced with stripslashes() in this context because the target value is 'string'.
404
  */
405
  private static function get_raw_referer() {
406
  if ( ! empty( $_REQUEST['_wp_http_referer'] ) )
409
  elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) )
410
  return /*wp_unslash*/ stripslashes( $_SERVER['HTTP_REFERER'] ); // wp-includes/formatting.php
411
 
412
+ return FALSE;
413
  }
414
 
415
  /**
416
+ * WP alternative function of wp_get_referer() for mu-plugins
417
  *
418
  * Retrieve referer from '_wp_http_referer' or HTTP referer.
419
+ * @source wp-includes/functions.php
420
  */
421
  public static function get_referer() {
422
  $ref = self::get_raw_referer(); // wp-includes/functions.php
423
  $req = /*wp_unslash*/ stripslashes( $_SERVER['REQUEST_URI'] );
424
 
425
  if ( $ref && $ref !== $req && $ref !== home_url() . $req )
426
+ return self::validate_redirect( $ref, FALSE );
427
 
428
+ return FALSE;
429
  }
430
 
431
  /**
432
+ * WP alternative function of is_user_logged_in() for mu-plugins
433
  *
434
  * Checks if the current visitor is a logged in user.
435
+ * @source wp-includes/pluggable.php
436
  */
437
+ public static function is_user_logged_in() {
438
  // possibly logged in but should be verified after 'init' hook is fired.
439
  return did_action( 'init' ) ? is_user_logged_in() : ( self::parse_auth_cookie( 'logged_in' ) ? TRUE : FALSE );
440
  }
441
 
442
+ /**
443
+ * WP alternative function of get_current_user_id() for mu-plugins
444
+ *
445
+ * Get the current user's ID.
446
+ * @source wp-includes/user.php
447
+ */
448
  public static function get_current_user_id() {
449
+ static $uid = 0;
450
+
451
+ if ( ! $uid ) {
452
+ $uid = did_action( 'init' ) ? get_current_user_id() : 0;
453
+
454
+ if ( ! $uid && isset( $_COOKIE ) ) {
455
+ foreach ( array_keys( $_COOKIE ) as $key ) {
456
+ if ( 0 === strpos( $key, 'wp-settings-' ) ) {
457
+ $uid = substr( $key, strrpos( $key, '-' ) + 1 ); // get numerical characters
458
+ break;
459
+ }
460
+ }
461
+ }
462
+ }
463
+
464
+ return $uid;
465
  }
466
 
467
  /**
468
  * WP alternative function for advanced-cache.php
469
  *
470
  * Add / Remove slash at the end of string.
471
+ * @source wp-includes/formatting.php
472
  */
473
  public static function unslashit( $string ) {
474
  return rtrim( $string, '/\\' );
479
  }
480
 
481
  /**
482
+ * WP alternative function of wp_kses_no_null() for advanced-cache.php
483
  *
484
  * Removes any NULL characters in $string.
485
+ * @source wp-includes/kses.php
486
  */
487
  private static function kses_no_null( $string ) {
488
  $string = preg_replace( '/[\x00-\x08\x0B\x0C\x0E-\x1F]/', '', $string );
492
  }
493
 
494
  /**
495
+ * WP alternative function of _deep_replace() for advanced-cache.php
496
  *
497
  * Perform a deep string replace operation to ensure the values in $search are no longer present.
498
  * e.g. $subject = '%0%0%0DDD', $search ='%0D', $result ='' rather than the '%0%0DD' that str_replace would return
499
+ * @source wp-includes/formatting.php
500
  */
501
  private static function deep_replace( $search, $subject ) {
502
  $subject = (string) $subject;
509
  return $subject;
510
  }
511
 
512
+ /**
513
+ * Whether the server software is IIS or something else
514
+ *
515
+ * @source wp-includes/vers.php
516
+ */
517
+ private static function is_IIS() {
518
+ $_is_apache = ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) !== FALSE || strpos( $_SERVER['SERVER_SOFTWARE'], 'LiteSpeed' ) !== FALSE );
519
+ $_is_IIS = ! $_is_apache && ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) !== FALSE || strpos( $_SERVER['SERVER_SOFTWARE'], 'ExpressionDevServer' ) !== FALSE );
520
+
521
+ if ( $_is_IIS )
522
+ $_is_IIS = substr( $_SERVER['SERVER_SOFTWARE'], strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/' ) + 14 );
523
+
524
+ return $_is_IIS;
525
+ }
526
+
527
+ /**
528
+ * Check the IP address is private or not
529
+ *
530
+ * @link https://en.wikipedia.org/wiki/Localhost
531
+ * @link https://en.wikipedia.org/wiki/Private_network
532
+ */
533
+ public static function is_private_ip( $ip ) {
534
+ return ( 0 === strpos( $ip, '127.0.0.' ) || 0 === strpos( $ip, '10.0.0.' ) || '::1' === $ip );
535
+ }
536
+
537
+ }
classes/class-ip-geo-block.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2013-2016 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block {
@@ -15,7 +15,7 @@ class IP_Geo_Block {
15
  * Unique identifier for this plugin.
16
  *
17
  */
18
- const VERSION = '2.2.9.1';
19
  const GEOAPI_NAME = 'ip-geo-api';
20
  const PLUGIN_NAME = 'ip-geo-block';
21
  const OPTION_NAME = 'ip_geo_block_settings';
@@ -30,7 +30,6 @@ class IP_Geo_Block {
30
 
31
  // Globals in this class
32
  public static $wp_path;
33
- private $query = '';
34
  private $pagenow = NULL;
35
  private $request_uri = NULL;
36
  private $target_type = NULL;
@@ -41,18 +40,17 @@ class IP_Geo_Block {
41
  *
42
  */
43
  private function __construct() {
44
- require( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-util.php' );
45
- require( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-load.php' );
46
- require( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-apis.php' );
47
- require( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php' );
48
-
49
  $settings = self::get_option();
50
- $priority = $settings['priority'];
51
  $validate = $settings['validation'];
52
  $loader = new IP_Geo_Block_Loader();
53
 
54
  // include drop in if it exists
55
- @include( IP_Geo_Block_Util::unslashit( $settings['api_dir'] ) . '/drop-in.php' );
 
 
 
56
 
57
  // the action hook which will be fired by cron job
58
  if ( $settings['update']['auto'] )
@@ -66,15 +64,14 @@ class IP_Geo_Block {
66
  $key = preg_replace( array( '!\.+/!', '!//+!' ), '/', $_SERVER['REQUEST_URI'] );
67
  $this->request_uri = @parse_url( $key, PHP_URL_PATH ) or $this->request_uri = $key;
68
  $this->pagenow = ! empty( $GLOBALS['pagenow'] ) ? $GLOBALS['pagenow'] : basename( $_SERVER['SCRIPT_NAME'] );
69
- $this->query = strtolower( urldecode( serialize( array_values( $_GET + $_POST ) ) ) );
70
 
71
  // setup the content folders
72
  self::$wp_path = array( 'home' => IP_Geo_Block_Util::unslashit( parse_url( site_url(), PHP_URL_PATH ) ) ); // @since 2.6.0
73
  $len = strlen( self::$wp_path['home'] );
74
  $list = array(
75
- 'admin' => 'admin_url', // @since 2.6.0
76
- 'plugins' => 'plugins_url', // @since 2.6.0
77
- 'themes' => 'get_theme_root_uri', // @since 1.5.0
78
  );
79
 
80
  // analize the validation target (admin|plugins|themes|includes)
@@ -107,7 +104,17 @@ class IP_Geo_Block {
107
  $loader->add_action( 'init', array( $this, 'validate_' . $list[ $this->pagenow ] ), $priority );
108
  }
109
 
 
 
 
 
 
 
110
  else {
 
 
 
 
111
  // message text on comment form
112
  if ( $settings['comment']['pos'] ) {
113
  $key = ( 1 === (int)$settings['comment']['pos'] ? '_top' : '' );
@@ -115,6 +122,10 @@ class IP_Geo_Block {
115
  }
116
 
117
  if ( $validate['comment'] ) {
 
 
 
 
118
  // bbPress: prevent creating topic/relpy and rendering form
119
  add_action( 'bbp_post_request_bbp-new-topic', array( $this, 'validate_comment' ), $priority );
120
  add_action( 'bbp_post_request_bbp-new-reply', array( $this, 'validate_comment' ), $priority );
@@ -125,12 +136,16 @@ class IP_Geo_Block {
125
  if ( $validate['login'] ) {
126
  // for hide/rename wp-login.php, BuddyPress: prevent registration and rendering form
127
  add_action( 'login_init', array( $this, 'validate_login' ), $priority );
128
- add_action( 'bp_core_screen_signup', array( $this, 'validate_login' ), $priority );
129
- add_action( 'bp_signup_pre_validate', array( $this, 'validate_login' ), $priority );
 
 
 
 
130
  }
131
  }
132
 
133
- // force to change the redirect URL at logout to remove nonce, embed a nonce into pages
134
  add_filter( 'wp_redirect', array( $this, 'logout_redirect' ), 20, 2 ); // logout_redirect @4.2
135
  add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_nonce' ), $priority );
136
 
@@ -160,7 +175,7 @@ class IP_Geo_Block {
160
  *
161
  */
162
  public static function get_default() {
163
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php' );
164
  return IP_Geo_Block_Opts::get_default();
165
  }
166
 
@@ -187,12 +202,11 @@ class IP_Geo_Block {
187
  }
188
 
189
  /**
190
- * Remove the redirecting URL at logout not to be blocked by WP-ZEP.
191
  *
192
  */
193
  public function logout_redirect( $uri ) {
194
- if ( FALSE !== stripos( $uri, self::$wp_path['admin'] ) &&
195
- isset( $_REQUEST['action'] ) && 'logout' === $_REQUEST['action'] )
196
  return esc_url_raw( add_query_arg( array( 'loggedout' => 'true' ), wp_login_url() ) );
197
  else
198
  return $uri;
@@ -215,11 +229,11 @@ class IP_Geo_Block {
215
  *
216
  */
217
  public static function get_ip_address() {
218
- return apply_filters( self::PLUGIN_NAME . '-ip-addr', $_SERVER['REMOTE_ADDR'] );
219
  }
220
 
221
  /**
222
- * Render a text message at the comment form.
223
  *
224
  */
225
  public function comment_form_message() {
@@ -248,9 +262,9 @@ class IP_Geo_Block {
248
  * @return array $result country code and so on
249
  */
250
  public static function get_geolocation( $ip = NULL, $providers = array(), $callback = 'get_country' ) {
251
- // make valid providers list
252
  $settings = self::get_option();
253
- if ( empty( $providers ) )
 
254
  $providers = IP_Geo_Block_Provider::get_valid_providers( $settings['providers'] );
255
 
256
  $result = self::_get_geolocation( $ip ? $ip : self::get_ip_address(), $settings, $providers, $callback );
@@ -266,6 +280,10 @@ class IP_Geo_Block {
266
  *
267
  */
268
  private static function _get_geolocation( $ip, $settings, $providers, $callback = 'get_country' ) {
 
 
 
 
269
  // set arguments for wp_remote_get()
270
  $args = self::get_request_headers( $settings );
271
 
@@ -288,16 +306,18 @@ class IP_Geo_Block {
288
  *
289
  */
290
  public static function validate_country( $hook, $validate, $settings, $block = TRUE ) {
291
- if ( $block && 0 === (int)$settings['matching_rule'] ) {
292
- // 'ZZ' will be blocked if it's not in the $list.
293
- if ( ( $list = $settings['white_list'] ) && FALSE === strpos( $list, $validate['code'] ) )
294
- return $validate + array( 'result' => 'blocked' ); // can't overwrite existing result
295
- }
 
296
 
297
- elseif( $block && 1 === (int)$settings['matching_rule'] ) {
298
- // 'ZZ' will NOT be blocked if it's not in the $list.
299
- if ( ( $list = $settings['black_list'] ) && FALSE !== strpos( $list, $validate['code'] ) )
300
- return $validate + array( 'result' => 'blocked' ); // can't overwrite existing result
 
301
  }
302
 
303
  return $validate + array( 'result' => 'passed' ); // can't overwrite existing result
@@ -307,39 +327,53 @@ class IP_Geo_Block {
307
  * Send response header with http status code and reason.
308
  *
309
  */
310
- public function send_response( $hook, $code ) {
 
 
311
  // prevent caching (WP Super Cache, W3TC, Wordfence, Comet Cache)
312
  if ( ! defined( 'DONOTCACHEPAGE' ) )
313
  define( 'DONOTCACHEPAGE', TRUE );
314
 
315
- $code = (int )apply_filters( self::PLUGIN_NAME . '-'.$hook.'-status', (int)$code );
316
- $mesg = (string)apply_filters( self::PLUGIN_NAME . '-'.$hook.'-reason', get_status_header_desc( $code ) );
 
 
 
317
 
318
- nocache_headers(); // nocache and response code
 
 
 
 
 
 
 
319
 
320
  switch ( (int)substr( (string)$code, 0, 1 ) ) {
321
- case 2: // 2xx Success
322
- header( 'Refresh: 0; url=' . home_url(), TRUE, $code ); // @since 3.0
323
  exit;
324
 
325
- case 3: // 3xx Redirection
326
- IP_Geo_Block_Util::redirect( 'http://blackhole.webpagetest.org/', $code );
327
  exit;
328
 
329
  default: // 4xx Client Error, 5xx Server Error
330
- // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag
331
- 'login' === $hook and header( 'X-Robots-Tag: noindex, nofollow', FALSE );
332
  status_header( $code ); // @since 2.0.0
333
 
 
 
 
334
  if ( function_exists( 'trackback_response' ) )
335
  trackback_response( $code, IP_Geo_Block_Util::kses( $mesg ) ); // @since 0.71
336
 
 
337
  elseif ( ! defined( 'DOING_AJAX' ) && ! defined( 'XMLRPC_REQUEST' ) ) {
338
- $hook = IP_Geo_Block_Util::may_be_logged_in() && 'admin' === $this->target_type;
339
- FALSE !== ( @include( get_stylesheet_directory() .'/'.$code.'.php' ) ) or // child theme
340
- FALSE !== ( @include( get_template_directory() .'/'.$code.'.php' ) ) or // parent theme
341
  wp_die( // get_dashboard_url() @since 3.1.0
342
- IP_Geo_Block_Util::kses( $mesg ) . ( $hook ? "\n<p><a href='" . esc_url( get_dashboard_url() ) . "'>&laquo; " . __( 'Dashboard' ) . "</a></p>" : '' ),
343
  '', array( 'response' => $code, 'back_link' => ! $hook )
344
  );
345
  }
@@ -350,9 +384,11 @@ class IP_Geo_Block {
350
  /**
351
  * Validate ip address.
352
  *
353
- * @param string $hook a name to identify action hook applied in this call.
354
- * @param array $settings option settings
355
- * @param boolean $die send http response and die if validation fails
 
 
356
  */
357
  public function validate_ip( $hook, $settings, $block = TRUE, $die = TRUE, $auth = TRUE ) {
358
  // set IP address to be validated
@@ -370,18 +406,26 @@ class IP_Geo_Block {
370
  }
371
 
372
  // register auxiliary validation functions
 
 
 
 
 
 
 
 
373
  $var = self::PLUGIN_NAME . '-' . $hook;
374
- $auth and add_filter( $var, array( $this, 'check_auth' ), 9, 2 );
375
- $auth and add_filter( $var, array( $this, 'check_fail' ), 8, 2 );
376
  $settings['extra_ips'] = apply_filters( self::PLUGIN_NAME . '-extra-ips', $settings['extra_ips'], $hook );
377
- $settings['extra_ips']['white_list'] and add_filter( $var, array( $this, 'check_ips_white' ), 7, 2 );
378
- $settings['extra_ips']['black_list'] and add_filter( $var, array( $this, 'check_ips_black' ), 7, 2 );
 
 
379
 
380
  // make valid provider name list
381
  $providers = IP_Geo_Block_Provider::get_valid_providers( $settings['providers'] );
382
 
383
  // apply custom filter for validation
384
- // @usage add_filter( 'ip-geo-block-$hook', 'my_validation', 10, 2 );
385
  // @param $validate = array(
386
  // 'ip' => $ip, /* validated ip address */
387
  // 'auth' => $auth, /* authenticated or not */
@@ -401,42 +445,35 @@ class IP_Geo_Block {
401
  break;
402
  }
403
 
404
- // record log (0:no, 1:blocked, 2:passed, 3:unauth, 4:auth, 5:all)
405
- $var = (int)apply_filters( self::PLUGIN_NAME . '-record-logs', $settings['validation']['reclogs'], $hook, $validate );
406
- $block = ( 'passed' !== $validate['result'] );
407
- if ( ( 1 === $var && $block ) || // blocked
408
- ( 2 === $var && ! $block ) || // passed
409
- ( 3 === $var && ! $validate['auth'] ) || // unauthenticated
410
- ( 4 === $var && $validate['auth'] ) || // authenticated
411
- ( 5 === $var ) ) { // all
412
- IP_Geo_Block_Logs::record_logs( $hook, $validate, $settings );
413
- }
 
414
 
415
- // update cache
416
- IP_Geo_Block_API_Cache::update_cache( $hook, $validate, $settings );
417
 
418
- // update statistics
419
- if ( $auth && $settings['save_statistics'] )
420
- IP_Geo_Block_Logs::update_stat( $hook, $validate, $settings );
421
 
422
- // send response code to refuse
423
- if ( $block && $die )
424
- $this->send_response( $hook, $settings['response_code'] );
 
425
 
426
  return $validate;
427
  }
428
 
429
  /**
430
- * Validate at frontend.
431
- *
432
- */
433
- public function validate_front( $can_access = TRUE ) {
434
- $validate = $this->validate_ip( 'comment', self::get_option(), TRUE, FALSE );
435
- return ( 'passed' === $validate['result'] ? $can_access : FALSE );
436
- }
437
-
438
- /**
439
- * Validate at comment.
440
  *
441
  */
442
  public function validate_comment( $comment = NULL ) {
@@ -447,15 +484,20 @@ class IP_Geo_Block {
447
  return $comment;
448
  }
449
 
 
 
 
 
 
450
  /**
451
- * Validate at xmlrpc.
452
  *
453
  */
454
  public function validate_xmlrpc() {
455
  $settings = self::get_option();
456
 
457
  if ( 2 === (int)$settings['validation']['xmlrpc'] ) // Completely close
458
- add_filter( self::PLUGIN_NAME . '-xmlrpc', array( $this, 'close_xmlrpc' ), 6, 2 );
459
 
460
  else // wp-includes/class-wp-xmlrpc-server.php @since 3.5.0
461
  add_filter( 'xmlrpc_login_error', array( $this, 'auth_fail' ), $settings['priority'] );
@@ -468,7 +510,7 @@ class IP_Geo_Block {
468
  }
469
 
470
  /**
471
- * Validate at login.
472
  *
473
  */
474
  public function validate_login() {
@@ -482,23 +524,32 @@ class IP_Geo_Block {
482
  $action = 'resetpass';
483
 
484
  $settings = self::get_option();
485
- $actions = $settings['login_action'];
486
 
487
- // the same rule is applied to login / logout
488
- if ( ! empty( $actions['login'] ) )
489
- $actions += array( 'logout' => 1 );
490
 
491
  // wp-includes/pluggable.php @since 2.5.0
492
  add_action( 'wp_login_failed', array( $this, 'auth_fail' ), $settings['priority'] );
493
 
494
- // enables to skip validation of country at login/out except BuddyPress signup
495
- $this->validate_ip( 'login', $settings,
496
- ! empty( $actions[ $action ] ) || 'bp_' === substr( current_filter(), 0, 3 )
497
- );
498
  }
499
 
500
  /**
501
- * Validate at admin area.
 
 
 
 
 
 
 
 
 
 
 
 
502
  *
503
  */
504
  public function validate_admin() {
@@ -512,77 +563,89 @@ class IP_Geo_Block {
512
  case 'admin-ajax.php':
513
  // if the request has an action for no privilege user, skip WP-ZEP
514
  $zep = ! has_action( 'wp_ajax_nopriv_'.$action );
515
- $type = (int)$settings['validation']['ajax'];
516
  break;
517
 
518
  case 'admin-post.php':
519
  // if the request has an action for no privilege user, skip WP-ZEP
520
  $zep = ! has_action( 'admin_post_nopriv' . ($action ? '_'.$action : '') );
521
- $type = (int)$settings['validation']['ajax'];
522
  break;
523
 
524
  default:
525
  // if the request has no page and no action, skip WP-ZEP
526
  $zep = ( $page || $action ) ? TRUE : FALSE;
527
- $type = (int)$settings['validation']['admin'];
528
  }
529
 
530
- // list of request with a specific query to bypass WP-ZEP
531
- $list = apply_filters( self::PLUGIN_NAME . '-bypass-admins', array(
532
- 'save-widget', 'wordfence_testAjax', 'wordfence_doScan', 'wp-compression-test', // wp-admin/includes/template.php
533
- 'upload-attachment', 'imgedit-preview', 'bp_avatar_upload', // pluploader won't fire an event in "Media Library"
534
- 'jetpack', 'authorize', 'jetpack_modules', 'atd_settings', 'bulk-activate', 'bulk-deactivate', // jetpack page & action
535
- ) );
 
 
536
 
537
- $in_action = in_array( $action, $list, TRUE );
538
- $in_page = in_array( $page, $list, TRUE );
 
539
 
540
  // combination with vulnerable keys should be prevented to bypass WP-ZEP
541
- if ( ( ( $action xor $page ) && ( ! $in_action and ! $in_page ) ) ||
542
- ( ( $action and $page ) && ( ! $in_action or ! $in_page ) ) ) {
543
- if ( ( 2 & $type ) && $zep ) {
544
  // redirect if valid nonce in referer, otherwise register WP-ZEP (2: WP-ZEP)
545
  IP_Geo_Block_Util::trace_nonce( self::PLUGIN_NAME . '-auth-nonce' );
546
  add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_nonce' ), 5, 2 );
547
  }
548
-
549
- // register validation of malicious signature (except in the comment and post)
550
- if ( ! IP_Geo_Block_Util::may_be_logged_in() || ! in_array( $this->pagenow, array( 'comment.php', 'post.php' ), TRUE ) )
551
- add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_signature' ), 6, 2 );
552
  }
553
 
 
 
 
 
554
  // validate country by IP address (1: Block by country)
555
- $this->validate_ip( 'admin', $settings, 1 & $type );
556
  }
557
 
558
  /**
559
- * Validate at plugins/themes area.
560
  *
561
  */
562
  public function validate_direct() {
563
  // analyze target in wp-includes, wp-content/(plugins|themes|language|uploads)
564
  $path = preg_quote( self::$wp_path[ $type = $this->target_type ], '/' );
565
- $target = ( 'plugins' === $type || 'themes' === $type ? '[^\?\&\/]*' : '[^\?\&]*' );
566
- preg_match( "/($path)($target)/", $this->request_uri, $target );
567
- $target = empty( $target[2] ) ? $target[1] : $target[2];
568
 
569
- // set validation type by target (0: Bypass, 1: Block by country, 2: WP-ZEP)
 
 
 
570
  $settings = self::get_option();
571
- $path = apply_filters( self::PLUGIN_NAME . "-bypass-{$type}", $settings['exception'][ $type ] );
572
- $type = (int)$settings['validation'][ $type ];
573
 
574
- if ( ! in_array( $target, $path, TRUE ) ) {
575
- // register validation of nonce (2: WP-ZEP)
576
- if ( 2 & $type )
577
- add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_nonce' ), 5, 2 );
578
 
579
- // register validation of malicious signature
580
- if ( ! IP_Geo_Block_Util::may_be_logged_in() )
581
- add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_signature' ), 6, 2 );
 
 
 
 
 
 
 
582
  }
583
 
 
 
 
 
584
  // validate country by IP address (1: Block by country)
585
- $validate = $this->validate_ip( 'admin', $settings, 1 & $type );
586
 
587
  // if the validation is successful, execute the requested uri via rewrite.php
588
  if ( class_exists( 'IP_Geo_Block_Rewrite' ) )
@@ -603,23 +666,27 @@ class IP_Geo_Block {
603
  'provider' => 'Cache',
604
  ) );
605
 
 
 
 
 
 
606
  // validate xmlrpc system.multicall
607
- if ( defined( 'XMLRPC_REQUEST' ) && FALSE !== stripos( file_get_contents( 'php://input' ), 'system.multicall' ) )
608
  $validate['result'] = 'multi';
609
 
610
- $settings = self::get_option();
611
- $cache = IP_Geo_Block_API_Cache::update_cache( $cache['hook'], $validate, $settings ); // update 'fail'
612
 
613
  // (1) blocked, (3) unauthenticated, (5) all
614
  if ( 1 & (int)$settings['validation']['reclogs'] )
615
- IP_Geo_Block_Logs::record_logs( $cache['hook'], $validate, $settings );
616
 
617
  // send response code to refuse immediately
618
- if ( $cache['fail'] > max( 0, (int)$settings['login_fails'] ) || 'multi' === $validate['result'] ) {
619
  if ( $settings['save_statistics'] )
620
- IP_Geo_Block_Logs::update_stat( $cache['hook'], $validate, $settings );
621
 
622
- $this->send_response( $cache['hook'], $settings['response_code'] );
623
  }
624
  }
625
 
@@ -627,15 +694,9 @@ class IP_Geo_Block {
627
  }
628
 
629
  public function check_fail( $validate, $settings ) {
 
630
  $cache = IP_Geo_Block_API_Cache::get_cache( $validate['ip'] );
631
-
632
- // if a number of fails is exceeded, then fail
633
- if ( $cache && $cache['fail'] > max( 0, (int)$settings['login_fails'] ) ) {
634
- if ( empty( $validate['result'] ) || 'passed' === $validate['result'] )
635
- $validate['result'] = 'failed'; // can't overwrite existing result
636
- }
637
-
638
- return $validate;
639
  }
640
 
641
  public function check_auth( $validate, $settings ) {
@@ -644,33 +705,24 @@ class IP_Geo_Block {
644
  }
645
 
646
  public function check_nonce( $validate, $settings ) {
647
- $action = self::PLUGIN_NAME . '-auth-nonce';
648
- $nonce = IP_Geo_Block_Util::retrieve_nonce( $action );
649
-
650
- if ( ! IP_Geo_Block_Util::verify_nonce( $nonce, $action ) ) {
651
- if ( empty( $validate['result'] ) || 'passed' === $validate['result'] )
652
- $validate['result'] = 'wp-zep'; // can't overwrite existing result
653
- }
654
-
655
- return $validate;
656
  }
657
 
658
  public function check_signature( $validate, $settings ) {
659
  $score = 0.0;
 
660
 
661
  foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $settings['signature'] ) as $sig ) {
662
  $val = explode( ':', $sig, 2 );
663
 
664
- if ( ( $sig = trim( $val[0] ) ) && FALSE !== strpos( $this->query, $sig ) ) {
665
  if ( ( $score += ( empty( $val[1] ) ? 1.0 : (float)$val[1] ) ) > 0.99 )
666
  return $validate + array( 'result' => 'badsig' ); // can't overwrite existing result
667
  }
668
  }
669
 
670
- // validate malicious tags
671
- if ( preg_match( '!<(script|svg|iframe|object|applet)[^>]*>\W*\w+[^<]*<\\\\*/\1[^>]*>!', $this->query ) )
672
- return $validate + array( 'result' => 'badtag' );
673
-
674
  return $validate;
675
  }
676
 
@@ -688,7 +740,7 @@ class IP_Geo_Block {
688
 
689
  private function check_ips( $validate, $ips, $which ) {
690
  if ( filter_var( $ip = $validate['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
691
- require_once( IP_GEO_BLOCK_PATH . 'includes/Net/IPv4.php' );
692
 
693
  foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $ips ) as $i ) {
694
  $j = explode( '/', $i, 2 );
@@ -701,7 +753,7 @@ class IP_Geo_Block {
701
  }
702
 
703
  elseif ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
704
- require_once( IP_GEO_BLOCK_PATH . 'includes/Net/IPv6.php' );
705
 
706
  foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $ips ) as $i ) {
707
  $j = explode( '/', $i, 2 );
@@ -716,13 +768,151 @@ class IP_Geo_Block {
716
  return $validate;
717
  }
718
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
719
  /**
720
  * Handlers of cron job
721
  *
722
  */
723
  public function update_database( $immediate = FALSE ) {
724
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php' );
725
  return IP_Geo_Block_Cron::exec_job( $immediate );
726
  }
727
 
 
 
 
 
 
728
  }
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
  */
11
 
12
  class IP_Geo_Block {
15
  * Unique identifier for this plugin.
16
  *
17
  */
18
+ const VERSION = '3.0.2.2';
19
  const GEOAPI_NAME = 'ip-geo-api';
20
  const PLUGIN_NAME = 'ip-geo-block';
21
  const OPTION_NAME = 'ip_geo_block_settings';
30
 
31
  // Globals in this class
32
  public static $wp_path;
 
33
  private $pagenow = NULL;
34
  private $request_uri = NULL;
35
  private $target_type = NULL;
40
  *
41
  */
42
  private function __construct() {
43
+ // setup loader to configure validation function
 
 
 
 
44
  $settings = self::get_option();
45
+ $priority = $settings['priority' ];
46
  $validate = $settings['validation'];
47
  $loader = new IP_Geo_Block_Loader();
48
 
49
  // include drop in if it exists
50
+ file_exists( $key = IP_Geo_Block_Util::unslashit( $settings['api_dir'] ) . '/drop-in.php' ) and include( $key );
51
+
52
+ // Garbage collection for IP address cache
53
+ add_action( self::CACHE_NAME, array( $this, 'exec_cache_gc' ) );
54
 
55
  // the action hook which will be fired by cron job
56
  if ( $settings['update']['auto'] )
64
  $key = preg_replace( array( '!\.+/!', '!//+!' ), '/', $_SERVER['REQUEST_URI'] );
65
  $this->request_uri = @parse_url( $key, PHP_URL_PATH ) or $this->request_uri = $key;
66
  $this->pagenow = ! empty( $GLOBALS['pagenow'] ) ? $GLOBALS['pagenow'] : basename( $_SERVER['SCRIPT_NAME'] );
 
67
 
68
  // setup the content folders
69
  self::$wp_path = array( 'home' => IP_Geo_Block_Util::unslashit( parse_url( site_url(), PHP_URL_PATH ) ) ); // @since 2.6.0
70
  $len = strlen( self::$wp_path['home'] );
71
  $list = array(
72
+ 'admin' => 'admin_url', // @since 2.6.0 /wp-admin/
73
+ 'plugins' => 'plugins_url', // @since 2.6.0 /wp-content/plugins/
74
+ 'themes' => 'get_theme_root_uri', // @since 1.5.0 /wp-content/themes/
75
  );
76
 
77
  // analize the validation target (admin|plugins|themes|includes)
104
  $loader->add_action( 'init', array( $this, 'validate_' . $list[ $this->pagenow ] ), $priority );
105
  }
106
 
107
+ // alternative of trackback
108
+ elseif ( 'POST' === $_SERVER['REQUEST_METHOD'] && 'trackback' === basename( $this->request_uri ) ) {
109
+ if ( $validate['comment'] )
110
+ $loader->add_action( 'init', array( $this, 'validate_comment' ), $priority );
111
+ }
112
+
113
  else {
114
+ // public facing pages
115
+ if ( $validate['public'] /* && 'index.php' === $this->pagenow */ )
116
+ $loader->add_action( 'init', array( $this, 'validate_public' ), $priority );
117
+
118
  // message text on comment form
119
  if ( $settings['comment']['pos'] ) {
120
  $key = ( 1 === (int)$settings['comment']['pos'] ? '_top' : '' );
122
  }
123
 
124
  if ( $validate['comment'] ) {
125
+ add_action( 'pre_comment_on_post', array( $this, 'validate_comment' ), $priority ); // wp-comments-post.php @since 2.8.0
126
+ add_action( 'pre_trackback_post', array( $this, 'validate_comment' ), $priority ); // wp-trackback.php @since 4.7.0
127
+ add_filter( 'preprocess_comment', array( $this, 'validate_comment' ), $priority ); // wp-includes/comment.php @since 1.5.0
128
+
129
  // bbPress: prevent creating topic/relpy and rendering form
130
  add_action( 'bbp_post_request_bbp-new-topic', array( $this, 'validate_comment' ), $priority );
131
  add_action( 'bbp_post_request_bbp-new-reply', array( $this, 'validate_comment' ), $priority );
136
  if ( $validate['login'] ) {
137
  // for hide/rename wp-login.php, BuddyPress: prevent registration and rendering form
138
  add_action( 'login_init', array( $this, 'validate_login' ), $priority );
139
+
140
+ // only when block on front-end is disabled
141
+ if ( ! $validate['public'] ) {
142
+ add_action( 'bp_core_screen_signup', array( $this, 'validate_login' ), $priority );
143
+ add_action( 'bp_signup_pre_validate', array( $this, 'validate_login' ), $priority );
144
+ }
145
  }
146
  }
147
 
148
+ // force to change the redirect URL on logout to remove nonce, embed a nonce into pages
149
  add_filter( 'wp_redirect', array( $this, 'logout_redirect' ), 20, 2 ); // logout_redirect @4.2
150
  add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_nonce' ), $priority );
151
 
175
  *
176
  */
177
  public static function get_default() {
178
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php';
179
  return IP_Geo_Block_Opts::get_default();
180
  }
181
 
202
  }
203
 
204
  /**
205
+ * Remove the redirecting URL on logout not to be blocked by WP-ZEP.
206
  *
207
  */
208
  public function logout_redirect( $uri ) {
209
+ if ( isset( $_REQUEST['action'] ) && 'logout' === $_REQUEST['action'] && FALSE !== stripos( $uri, self::$wp_path['admin'] ) )
 
210
  return esc_url_raw( add_query_arg( array( 'loggedout' => 'true' ), wp_login_url() ) );
211
  else
212
  return $uri;
229
  *
230
  */
231
  public static function get_ip_address() {
232
+ return apply_filters( self::PLUGIN_NAME . '-ip-addr', empty( $_SERVER['REMOTE_ADDR'] ) ? '' : $_SERVER['REMOTE_ADDR'] );
233
  }
234
 
235
  /**
236
+ * Render a text message on the comment form.
237
  *
238
  */
239
  public function comment_form_message() {
262
  * @return array $result country code and so on
263
  */
264
  public static function get_geolocation( $ip = NULL, $providers = array(), $callback = 'get_country' ) {
 
265
  $settings = self::get_option();
266
+
267
+ if ( empty( $providers ) ) // make valid providers list
268
  $providers = IP_Geo_Block_Provider::get_valid_providers( $settings['providers'] );
269
 
270
  $result = self::_get_geolocation( $ip ? $ip : self::get_ip_address(), $settings, $providers, $callback );
280
  *
281
  */
282
  private static function _get_geolocation( $ip, $settings, $providers, $callback = 'get_country' ) {
283
+ // check loop back / private address
284
+ if ( IP_Geo_Block_Util::is_private_ip( $ip ) )
285
+ return self::make_validation( $ip, array( 'time' => 0, 'provider' => 'Loopback', 'code' => 'XX' ) );
286
+
287
  // set arguments for wp_remote_get()
288
  $args = self::get_request_headers( $settings );
289
 
306
  *
307
  */
308
  public static function validate_country( $hook, $validate, $settings, $block = TRUE ) {
309
+ if ( 'XX' !== $validate['code'] ) { // 'XX' is for localhost or inside of load balancer etc
310
+ if ( $block && 0 === (int)$settings['matching_rule'] ) {
311
+ // 'ZZ' will be blocked if it's not in the $list.
312
+ if ( ( $list = $settings['white_list'] ) && FALSE === strpos( $list, $validate['code'] ) )
313
+ return $validate + array( 'result' => 'blocked' ); // can't overwrite existing result
314
+ }
315
 
316
+ elseif( $block && 1 === (int)$settings['matching_rule'] ) {
317
+ // 'ZZ' will NOT be blocked if it's not in the $list.
318
+ if ( ( $list = $settings['black_list'] ) && FALSE !== strpos( $list, $validate['code'] ) )
319
+ return $validate + array( 'result' => 'blocked' ); // can't overwrite existing result
320
+ }
321
  }
322
 
323
  return $validate + array( 'result' => 'passed' ); // can't overwrite existing result
327
  * Send response header with http status code and reason.
328
  *
329
  */
330
+ public function send_response( $hook, $validate, $settings ) {
331
+ require_once ABSPATH . WPINC . '/functions.php'; // for get_status_header_desc() @since 2.3.0
332
+
333
  // prevent caching (WP Super Cache, W3TC, Wordfence, Comet Cache)
334
  if ( ! defined( 'DONOTCACHEPAGE' ) )
335
  define( 'DONOTCACHEPAGE', TRUE );
336
 
337
+ $code = (int )apply_filters( self::PLUGIN_NAME . '-'.$hook.'-status', $settings['response_code'] );
338
+ $mesg = (string)apply_filters( self::PLUGIN_NAME . '-'.$hook.'-reason', $settings['response_msg' ] ? $settings['response_msg'] : get_status_header_desc( $code ) );
339
+
340
+ // custom action (for fail2ban) @since 1.2.0
341
+ do_action( self::PLUGIN_NAME . '-send-response', $hook, $code, $validate );
342
 
343
+ // Set the headers to prevent caching for the different browsers.
344
+ nocache_headers(); // wp-includes/functions.php @since 2.0.0
345
+
346
+ if ( defined( 'XMLRPC_REQUEST' ) && 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
347
+ status_header( 405 );
348
+ header( 'Content-Type: text/plain' );
349
+ die( 'XML-RPC server accepts POST requests only.' );
350
+ }
351
 
352
  switch ( (int)substr( (string)$code, 0, 1 ) ) {
353
+ case 2: // 2xx Success (HTTP header injection should be avoided)
354
+ header( 'Refresh: 0; url=' . esc_url_raw( $settings['redirect_uri'] ? $settings['redirect_uri'] : home_url( '/' ) ), TRUE, $code ); // @since 2.8
355
  exit;
356
 
357
+ case 3: // 3xx Redirection (HTTP header injection should be avoided)
358
+ IP_Geo_Block_Util::safe_redirect( esc_url_raw( $settings['redirect_uri'] ? $settings['redirect_uri'] : home_url( '/' ) ), $code ); // @since 2.8
359
  exit;
360
 
361
  default: // 4xx Client Error, 5xx Server Error
 
 
362
  status_header( $code ); // @since 2.0.0
363
 
364
+ // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag
365
+ 'public' !== $hook and header( 'X-Robots-Tag: noindex, nofollow', FALSE );
366
+
367
  if ( function_exists( 'trackback_response' ) )
368
  trackback_response( $code, IP_Geo_Block_Util::kses( $mesg ) ); // @since 0.71
369
 
370
+ // Show human readable page
371
  elseif ( ! defined( 'DOING_AJAX' ) && ! defined( 'XMLRPC_REQUEST' ) ) {
372
+ $hook = IP_Geo_Block_Util::is_user_logged_in() && 'admin' === $this->target_type;
373
+ FALSE !== ( @include get_stylesheet_directory() .'/'.$code.'.php' ) or // child theme
374
+ FALSE !== ( @include get_template_directory() .'/'.$code.'.php' ) or // parent theme
375
  wp_die( // get_dashboard_url() @since 3.1.0
376
+ IP_Geo_Block_Util::kses( $mesg ) . ( $hook ? "\n<p><a rel='nofollow' href='" . esc_url( get_dashboard_url() ) . "'>&laquo; " . __( 'Dashboard' ) . "</a></p>" : '' ),
377
  '', array( 'response' => $code, 'back_link' => ! $hook )
378
  );
379
  }
384
  /**
385
  * Validate ip address.
386
  *
387
+ * @param string $hook a name to identify action hook applied in this call.
388
+ * @param array $settings option settings
389
+ * @param boolean $block block if validation fails (for simulate)
390
+ * @param boolean $die send http response and die if validation fails (for validate_front )
391
+ * @param boolean $auth save log and block if validation fails (for admin dashboard)
392
  */
393
  public function validate_ip( $hook, $settings, $block = TRUE, $die = TRUE, $auth = TRUE ) {
394
  // set IP address to be validated
406
  }
407
 
408
  // register auxiliary validation functions
409
+ // priority high 4 close_xmlrpc
410
+ // 5 check_nonce
411
+ // 6 check_signature
412
+ // 7 check_auth
413
+ // 8 check_fail
414
+ // 9 check_ips_black
415
+ // 9 check_ips_white
416
+ // priority low 10 validate_country
417
  $var = self::PLUGIN_NAME . '-' . $hook;
 
 
418
  $settings['extra_ips'] = apply_filters( self::PLUGIN_NAME . '-extra-ips', $settings['extra_ips'], $hook );
419
+ $settings['extra_ips']['black_list'] and add_filter( $var, array( $this, 'check_ips_black' ), 9, 2 );
420
+ $settings['extra_ips']['white_list'] and add_filter( $var, array( $this, 'check_ips_white' ), 9, 2 );
421
+ $settings['login_fails'] >= 0 and add_filter( $var, array( $this, 'check_fail' ), 8, 2 );
422
+ $auth and add_filter( $var, array( $this, 'check_auth' ), 7, 2 );
423
 
424
  // make valid provider name list
425
  $providers = IP_Geo_Block_Provider::get_valid_providers( $settings['providers'] );
426
 
427
  // apply custom filter for validation
428
+ // @example add_filter( 'ip-geo-block-$hook', 'my_validation', 10, 2 );
429
  // @param $validate = array(
430
  // 'ip' => $ip, /* validated ip address */
431
  // 'auth' => $auth, /* authenticated or not */
445
  break;
446
  }
447
 
448
+ if ( $auth ) {
449
+ // record log (0:no, 1:blocked, 2:passed, 3:unauth, 4:auth, 5:all)
450
+ $var = (int)apply_filters( self::PLUGIN_NAME . '-record-logs', $settings['validation']['reclogs'], $hook, $validate );
451
+ $block = ( 'passed' !== $validate['result'] );
452
+ if ( ( 1 === $var && $block ) || // blocked
453
+ ( 2 === $var && ! $block ) || // passed
454
+ ( 3 === $var && ! $validate['auth'] ) || // unauthenticated
455
+ ( 4 === $var && $validate['auth'] ) || // authenticated
456
+ ( 5 === $var ) ) { // all
457
+ IP_Geo_Block_Logs::record_logs( $hook, $validate, $settings );
458
+ }
459
 
460
+ // update cache
461
+ IP_Geo_Block_API_Cache::update_cache( $hook, $validate, $settings );
462
 
463
+ // update statistics
464
+ if ( $settings['save_statistics'] )
465
+ IP_Geo_Block_Logs::update_stat( $hook, $validate, $settings );
466
 
467
+ // send response code to refuse
468
+ if ( $block && $die )
469
+ $this->send_response( $hook, $validate, $settings );
470
+ }
471
 
472
  return $validate;
473
  }
474
 
475
  /**
476
+ * Validate on comment.
 
 
 
 
 
 
 
 
 
477
  *
478
  */
479
  public function validate_comment( $comment = NULL ) {
484
  return $comment;
485
  }
486
 
487
+ public function validate_front( $can_access = TRUE ) {
488
+ $validate = $this->validate_ip( 'comment', self::get_option(), TRUE, FALSE, FALSE );
489
+ return ( 'passed' === $validate['result'] ? $can_access : FALSE );
490
+ }
491
+
492
  /**
493
+ * Validate on xmlrpc.
494
  *
495
  */
496
  public function validate_xmlrpc() {
497
  $settings = self::get_option();
498
 
499
  if ( 2 === (int)$settings['validation']['xmlrpc'] ) // Completely close
500
+ add_filter( self::PLUGIN_NAME . '-xmlrpc', array( $this, 'close_xmlrpc' ), 4, 2 );
501
 
502
  else // wp-includes/class-wp-xmlrpc-server.php @since 3.5.0
503
  add_filter( 'xmlrpc_login_error', array( $this, 'auth_fail' ), $settings['priority'] );
510
  }
511
 
512
  /**
513
+ * Validate on login.
514
  *
515
  */
516
  public function validate_login() {
524
  $action = 'resetpass';
525
 
526
  $settings = self::get_option();
527
+ $list = $settings['login_action'];
528
 
529
+ // the same rule should be applied to login and logout
530
+ ! empty( $list['login'] ) and $list['logout'] = TRUE;
 
531
 
532
  // wp-includes/pluggable.php @since 2.5.0
533
  add_action( 'wp_login_failed', array( $this, 'auth_fail' ), $settings['priority'] );
534
 
535
+ // enables to skip validation of country on login/out except BuddyPress signup
536
+ $this->validate_ip( 'login', $settings, ! empty( $list[ $action ] ) || 'bp_' === substr( current_filter(), 0, 3 ) );
 
 
537
  }
538
 
539
  /**
540
+ * Check exceptions
541
+ *
542
+ */
543
+ private function check_exceptions( $action, $page, $exceptions = array() ) {
544
+ $in_action = in_array( $action, $exceptions, TRUE );
545
+ $in_page = in_array( $page, $exceptions, TRUE );
546
+
547
+ return ( ( $action xor $page ) && ( ! $in_action and ! $in_page ) ) ||
548
+ ( ( $action and $page ) && ( ! $in_action or ! $in_page ) ) ? FALSE : TRUE;
549
+ }
550
+
551
+ /**
552
+ * Validate in admin area.
553
  *
554
  */
555
  public function validate_admin() {
563
  case 'admin-ajax.php':
564
  // if the request has an action for no privilege user, skip WP-ZEP
565
  $zep = ! has_action( 'wp_ajax_nopriv_'.$action );
566
+ $rule = (int)$settings['validation']['ajax'];
567
  break;
568
 
569
  case 'admin-post.php':
570
  // if the request has an action for no privilege user, skip WP-ZEP
571
  $zep = ! has_action( 'admin_post_nopriv' . ($action ? '_'.$action : '') );
572
+ $rule = (int)$settings['validation']['ajax'];
573
  break;
574
 
575
  default:
576
  // if the request has no page and no action, skip WP-ZEP
577
  $zep = ( $page || $action ) ? TRUE : FALSE;
578
+ $rule = (int)$settings['validation']['admin'];
579
  }
580
 
581
+ // list of request for specific action or page to bypass WP-ZEP
582
+ $list = array_merge(
583
+ apply_filters( self::PLUGIN_NAME . '-bypass-admins', array() ),
584
+ array( 'save-widget', 'wp-compression-test', 'upload-attachment', 'imgedit-preview', // in wp-admin js/widget.js, includes/template.php, async-upload.php
585
+ 'wordfence_testAjax', 'wordfence_doScan', 'bp_avatar_upload', 'GOTMLS_logintime', // Wordfence, bbPress, Anti-Malware Security and Brute-Force Firewall
586
+ 'jetpack', 'authorize', 'jetpack_modules', 'atd_settings', 'bulk-activate', 'bulk-deactivate', // jetpack page & action
587
+ )
588
+ );
589
 
590
+ // skip validation of country code and WP-ZEP if exceptions matches action or page
591
+ if ( ( $page || $action ) && $this->check_exceptions( $action, $page, $settings['exception']['admin'] ) )
592
+ $rule &= ~ ( $zep ? 2 : 3 ); // 2: WP-ZEP, 1: Block by country (validation of bad signature is still in effective)
593
 
594
  // combination with vulnerable keys should be prevented to bypass WP-ZEP
595
+ elseif ( ! $this->check_exceptions( $action, $page, $list ) ) {
596
+ if ( ( 2 & $rule ) && $zep ) {
 
597
  // redirect if valid nonce in referer, otherwise register WP-ZEP (2: WP-ZEP)
598
  IP_Geo_Block_Util::trace_nonce( self::PLUGIN_NAME . '-auth-nonce' );
599
  add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_nonce' ), 5, 2 );
600
  }
 
 
 
 
601
  }
602
 
603
+ // register validation of malicious signature (except in the comment and post)
604
+ if ( ! IP_Geo_Block_Util::is_user_logged_in() || ! in_array( $this->pagenow, array( 'comment.php', 'post.php' ), TRUE ) )
605
+ add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_signature' ), 6, 2 );
606
+
607
  // validate country by IP address (1: Block by country)
608
+ $this->validate_ip( 'admin', $settings, 1 & $rule );
609
  }
610
 
611
  /**
612
+ * Validate in plugins/themes area.
613
  *
614
  */
615
  public function validate_direct() {
616
  // analyze target in wp-includes, wp-content/(plugins|themes|language|uploads)
617
  $path = preg_quote( self::$wp_path[ $type = $this->target_type ], '/' );
618
+ $name = ( 'plugins' === $type || 'themes' === $type ? '[^\?\&\/]*' : '[^\?\&]*' );
 
 
619
 
620
+ preg_match( "/($path)($name)/", $this->request_uri, $name );
621
+ $name = empty( $name[2] ) ? $name[1] : $name[2];
622
+
623
+ // set validation rule by target (0: Bypass, 1: Block by country, 2: WP-ZEP)
624
  $settings = self::get_option();
625
+ $rule = (int)$settings['validation'][ $type ];
 
626
 
627
+ // list of request for specific action or page to bypass WP-ZEP
628
+ $path = array( 'includes' => array( 'ms-files.php', 'js/tinymce/wp-tinymce.php', ), /* for wp-includes */ );
629
+ $path = apply_filters( self::PLUGIN_NAME . "-bypass-{$type}", isset( $path[ $type ] ) ? $path[ $type ] : array() );
 
630
 
631
+ // skip validation of country code if exceptions matches action or page
632
+ if ( in_array( $name, $settings['exception'][ $type ], TRUE ) )
633
+ $rule = 0;
634
+
635
+ elseif ( ! in_array( $name, $path, TRUE ) ) {
636
+ if ( 2 & $rule ) {
637
+ // redirect if valid nonce in referer, otherwise register WP-ZEP (2: WP-ZEP)
638
+ IP_Geo_Block_Util::trace_nonce( self::PLUGIN_NAME . '-auth-nonce' );
639
+ add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_nonce' ), 5, 2 );
640
+ }
641
  }
642
 
643
+ // register validation of malicious signature
644
+ if ( ! IP_Geo_Block_Util::is_user_logged_in() )
645
+ add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_signature' ), 6, 2 );
646
+
647
  // validate country by IP address (1: Block by country)
648
+ $validate = $this->validate_ip( 'admin', $settings, 1 & $rule );
649
 
650
  // if the validation is successful, execute the requested uri via rewrite.php
651
  if ( class_exists( 'IP_Geo_Block_Rewrite' ) )
666
  'provider' => 'Cache',
667
  ) );
668
 
669
+ $settings = self::get_option();
670
+
671
+ if ( $cache['fail'] > max( 0, (int)$settings['login_fails'] ) )
672
+ $validate['result'] = 'limited';
673
+
674
  // validate xmlrpc system.multicall
675
+ elseif ( defined( 'XMLRPC_REQUEST' ) && FALSE !== stripos( file_get_contents( 'php://input' ), 'system.multicall' ) )
676
  $validate['result'] = 'multi';
677
 
678
+ $cache = IP_Geo_Block_API_Cache::update_cache( 'login', $validate, $settings ); // count up 'fail'
 
679
 
680
  // (1) blocked, (3) unauthenticated, (5) all
681
  if ( 1 & (int)$settings['validation']['reclogs'] )
682
+ IP_Geo_Block_Logs::record_logs( 'login', $validate, $settings );
683
 
684
  // send response code to refuse immediately
685
+ if ( 'failed' !== $validate['result'] ) {
686
  if ( $settings['save_statistics'] )
687
+ IP_Geo_Block_Logs::update_stat( 'login', $validate, $settings );
688
 
689
+ $this->send_response( 'login', $validate, $settings );
690
  }
691
  }
692
 
694
  }
695
 
696
  public function check_fail( $validate, $settings ) {
697
+ // check if number of fails reaches the limit. can't overwrite existing result.
698
  $cache = IP_Geo_Block_API_Cache::get_cache( $validate['ip'] );
699
+ return $cache && $cache['fail'] >= max( 0, (int)$settings['login_fails'] ) ? $validate + array( 'result' => 'limited' ) : $validate;
 
 
 
 
 
 
 
700
  }
701
 
702
  public function check_auth( $validate, $settings ) {
705
  }
706
 
707
  public function check_nonce( $validate, $settings ) {
708
+ // should be passed when nonce is valid. can't overwrite existing result
709
+ $nonce = IP_Geo_Block_Util::retrieve_nonce( $action = self::PLUGIN_NAME . '-auth-nonce' );
710
+ return $validate + array( 'result' => IP_Geo_Block_Util::verify_nonce( $nonce, $action ) ? 'passed' : 'wp-zep' );
 
 
 
 
 
 
711
  }
712
 
713
  public function check_signature( $validate, $settings ) {
714
  $score = 0.0;
715
+ $query = strtolower( urldecode( serialize( array_values( $_GET + $_POST ) ) ) );
716
 
717
  foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $settings['signature'] ) as $sig ) {
718
  $val = explode( ':', $sig, 2 );
719
 
720
+ if ( ( $sig = trim( $val[0] ) ) && FALSE !== strpos( $query, $sig ) ) {
721
  if ( ( $score += ( empty( $val[1] ) ? 1.0 : (float)$val[1] ) ) > 0.99 )
722
  return $validate + array( 'result' => 'badsig' ); // can't overwrite existing result
723
  }
724
  }
725
 
 
 
 
 
726
  return $validate;
727
  }
728
 
740
 
741
  private function check_ips( $validate, $ips, $which ) {
742
  if ( filter_var( $ip = $validate['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
743
+ require_once IP_GEO_BLOCK_PATH . 'includes/Net/IPv4.php';
744
 
745
  foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $ips ) as $i ) {
746
  $j = explode( '/', $i, 2 );
753
  }
754
 
755
  elseif ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
756
+ require_once IP_GEO_BLOCK_PATH . 'includes/Net/IPv6.php';
757
 
758
  foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $ips ) as $i ) {
759
  $j = explode( '/', $i, 2 );
768
  return $validate;
769
  }
770
 
771
+ /**
772
+ * Validate on public facing pages.
773
+ *
774
+ */
775
+ public function validate_public() {
776
+ $settings = self::get_option();
777
+ $public = $settings['public'];
778
+
779
+ // avoid redirection loop
780
+ if ( $settings['response_code'] < 400 && IP_Geo_Block_Util::compare_url( $_SERVER['REQUEST_URI'], $settings['redirect_uri'] ? $settings['redirect_uri'] : home_url( '/' ) ) )
781
+ return; // do not block
782
+
783
+ if ( $public['target_rule'] ) {
784
+ if ( ! did_action( 'wp' ) ) { // deferred validation on 'wp' when the target is specified
785
+ add_action( 'wp', array( $this, 'validate_public' ) );
786
+ return;
787
+ }
788
+
789
+ // register filter hook to check pages and post types
790
+ add_filter( self::PLUGIN_NAME . '-public', array( $this, 'check_page' ), 10, 2 );
791
+ }
792
+
793
+ // replace "Validation rule settings"
794
+ if ( -1 !== (int)$public['matching_rule'] ) {
795
+ $settings['matching_rule'] = $public['matching_rule'];
796
+ $settings['white_list' ] = $public['white_list' ];
797
+ $settings['black_list' ] = $public['black_list' ];
798
+ }
799
+
800
+ // retrieve IP address of visitor via proxy services
801
+ add_filter( self::PLUGIN_NAME . '-ip-addr', array( $this, 'get_proxy_ip' ), 20, 1 );
802
+
803
+ // validate undesired user agent
804
+ add_filter( self::PLUGIN_NAME . '-public', array( $this, 'check_bots' ), 6, 2 );
805
+
806
+ // validate country by IP address (block: true, die: false)
807
+ $this->validate_ip( 'public', $settings, TRUE, ! $public['simulate'] );
808
+ }
809
+
810
+ public function get_proxy_ip( $ip ) {
811
+ if ( isset( $_SERVER['HTTP_VIA'] ) && FALSE !== strpos( $_SERVER['HTTP_VIA'], 'Chrome-Compression-Proxy' ) && isset( $_SERVER['HTTP_FORWARDED'] ) ) {
812
+ // require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-lkup.php';
813
+ // if ( FALSE !== strpos( 'google', IP_Geo_Block_Lkup::gethostbyaddr( $ip ) ) )
814
+ $proxy = preg_replace( '/^for=.*?([a-f\d\.:]+).*$/', '$1', $_SERVER['HTTP_FORWARDED'] );
815
+ }
816
+
817
+ return empty( $proxy ) ? $ip : $proxy;
818
+ }
819
+
820
+ public function check_page( $validate, $settings ) {
821
+ global $pagename, $post;
822
+ $public = $settings['public'];
823
+
824
+ if ( $pagename ) {
825
+ // check page
826
+ if ( isset( $public['target_pages'][ $pagename ] ) )
827
+ return $validate; // block by country
828
+ } elseif ( $post ) {
829
+ // check post type (this would not block top page)
830
+ $keys = array_keys( $public['target_posts'] );
831
+ if ( ! empty( $keys ) && is_singular( $keys ) )
832
+ return $validate; // block by country
833
+
834
+ // check category (single page or category archive)
835
+ $keys = array_keys( $public['target_cates'] );
836
+ if ( ! empty( $keys ) && in_category( $keys ) && ( is_single() || is_category() ) )
837
+ return $validate; // block by country
838
+
839
+ // check tag (single page or tag archive)
840
+ $keys = array_keys( $public['target_tags'] );
841
+ if ( ! empty( $keys ) && has_tag( $keys ) && ( is_single() || is_tag() ) )
842
+ return $validate; // block by country
843
+ }
844
+
845
+ return $validate + array( 'result' => 'passed' ); // provide content
846
+ }
847
+
848
+ public function check_bots( $validate, $settings ) {
849
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-lkup.php';
850
+
851
+ // get the name of host (from the cache if exists)
852
+ if ( empty( $validate['host'] ) && FALSE !== strpos( $settings['public']['ua_list'], 'HOST' ) )
853
+ $validate['host'] = IP_Geo_Block_Lkup::gethostbyaddr( $validate['ip'] );
854
+
855
+ // check requested url
856
+ $is_feed = IP_Geo_Block_Lkup::is_feed( $this->request_uri );
857
+ $u_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
858
+ $referer = isset( $_SERVER['HTTP_REFERER' ] ) ? $_SERVER['HTTP_REFERER' ] : '';
859
+
860
+ foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $settings['public']['ua_list'] ) as $pat ) {
861
+ list( $name, $code ) = array_pad( IP_Geo_Block_Util::multiexplode( array( ':', '#' ), $pat ), 2, '' );
862
+
863
+ if ( $name && ( '*' === $name || FALSE !== strpos( $u_agent, $name ) ) ) {
864
+ $which = ( FALSE !== strpos( $pat, '#' ) ); // 0: pass (':'), 1: block ('#')
865
+ $not = ( '!' === $code[0] ); // 0: positive, 1: negative
866
+ $code = ( $not ? substr( $code, 1 ) : $code ); // qualification identifier
867
+
868
+ if ( 'FEED' === $code ) {
869
+ if ( $not xor $is_feed )
870
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
871
+ }
872
+
873
+ elseif ( 'HOST' === $code ) {
874
+ if ( $not xor $validate['host'] !== $validate['ip'] )
875
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
876
+ }
877
+
878
+ elseif ( 0 === strncmp( 'HOST=', $code, 5 ) ) {
879
+ if ( $not xor FALSE !== strpos( $validate['host'], substr( $code, 5 ) ) )
880
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
881
+ }
882
+
883
+ elseif ( 0 === strncmp( 'REF=', $code, 4 ) ) {
884
+ if ( $not xor FALSE !== strpos( $referer, substr( $code, 4 ) ) )
885
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
886
+ }
887
+
888
+ elseif ( '*' === $code || 2 === strlen( $code ) ) {
889
+ if ( $not xor ( '*' === $code || $validate['code'] === $code ) )
890
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
891
+ }
892
+
893
+ elseif ( preg_match( '!^[a-f\d\.:/]+$!', $code = substr( $pat, strpos( $pat, $code ) ) ) ) {
894
+ $name = $this->check_ips( $validate, $code, $which );
895
+ if ( $not xor isset( $name['result'] ) )
896
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
897
+ }
898
+ }
899
+ }
900
+
901
+ return $validate;
902
+ }
903
+
904
  /**
905
  * Handlers of cron job
906
  *
907
  */
908
  public function update_database( $immediate = FALSE ) {
909
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php';
910
  return IP_Geo_Block_Cron::exec_job( $immediate );
911
  }
912
 
913
+ public function exec_cache_gc() {
914
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php';
915
+ IP_Geo_Block_Cron::exec_cache_gc( self::get_option() );
916
+ }
917
+
918
  }
includes/Net/DNS2.php CHANGED
@@ -72,7 +72,7 @@ class Net_DNS2
72
  /*
73
  * the current version of this library
74
  */
75
- const VERSION = '1.4.2';
76
 
77
  /*
78
  * the default path to a resolv.conf file
@@ -240,7 +240,7 @@ class Net_DNS2
240
  /*
241
  * local sockets
242
  */
243
- protected $sock = array('udp' => array(), 'tcp' => array());
244
 
245
  /*
246
  * if the socket extension is loaded
@@ -866,43 +866,9 @@ class Net_DNS2
866
  */
867
  public static function expandIPv6($_address)
868
  {
869
- if (strpos($_address, '::') !== false) {
870
-
871
- $part = explode('::', $_address);
872
- $part[0] = explode(':', $part[0]);
873
- $part[1] = explode(':', $part[1]);
874
-
875
- $missing = array();
876
-
877
- $x = (8 - (count($part[0]) + count($part[1])));
878
- for ($i = 0; $i < $x; $i++) {
879
-
880
- array_push($missing, '0000');
881
- }
882
-
883
- $missing = array_merge($part[0], $missing);
884
- $part = array_merge($missing, $part[1]);
885
-
886
- } else {
887
-
888
- $part = explode(':', $_address);
889
- }
890
-
891
- foreach ($part as &$p) {
892
- while (strlen($p) < 4) {
893
- $p = '0' . $p;
894
- }
895
- }
896
-
897
- unset($p);
898
 
899
- $result = implode(':', $part);
900
-
901
- if (strlen($result) == 39) {
902
- return $result;
903
- } else {
904
- return false;
905
- }
906
  }
907
 
908
  /**
@@ -1086,6 +1052,45 @@ class Net_DNS2
1086
  return $response;
1087
  }
1088
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1089
  /**
1090
  * sends a DNS request using TCP
1091
  *
@@ -1109,8 +1114,8 @@ class Net_DNS2
1109
  // see if we already have an open socket from a previous request; if so, try to use
1110
  // that instead of opening a new one.
1111
  //
1112
- if ( (!isset($this->sock['tcp'][$_ns]))
1113
- || (!($this->sock['tcp'][$_ns] instanceof Net_DNS2_Socket))
1114
  ) {
1115
 
1116
  //
@@ -1118,7 +1123,7 @@ class Net_DNS2
1118
  //
1119
  if ($this->sockets_enabled === true) {
1120
 
1121
- $this->sock['tcp'][$_ns] = new Net_DNS2_Socket_Sockets(
1122
  Net_DNS2_Socket::SOCK_STREAM, $_ns, $this->dns_port, $this->timeout
1123
  );
1124
 
@@ -1127,7 +1132,7 @@ class Net_DNS2
1127
  //
1128
  } else {
1129
 
1130
- $this->sock['tcp'][$_ns] = new Net_DNS2_Socket_Streams(
1131
  Net_DNS2_Socket::SOCK_STREAM, $_ns, $this->dns_port, $this->timeout
1132
  );
1133
  }
@@ -1137,7 +1142,7 @@ class Net_DNS2
1137
  //
1138
  if (strlen($this->local_host) > 0) {
1139
 
1140
- $this->sock['tcp'][$_ns]->bindAddress(
1141
  $this->local_host, $this->local_port
1142
  );
1143
  }
@@ -1145,11 +1150,9 @@ class Net_DNS2
1145
  //
1146
  // open the socket
1147
  //
1148
- if ($this->sock['tcp'][$_ns]->open() === false) {
1149
 
1150
- throw new Net_DNS2_Exception(
1151
- $this->sock['tcp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1152
- );
1153
  }
1154
  }
1155
 
@@ -1157,11 +1160,9 @@ class Net_DNS2
1157
  // write the data to the socket; if it fails, continue on
1158
  // the while loop
1159
  //
1160
- if ($this->sock['tcp'][$_ns]->write($_data) === false) {
1161
 
1162
- throw new Net_DNS2_Exception(
1163
- $this->sock['tcp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1164
- );
1165
  }
1166
 
1167
  //
@@ -1183,12 +1184,19 @@ class Net_DNS2
1183
  //
1184
  // read the data off the socket
1185
  //
1186
- $result = $this->sock['tcp'][$_ns]->read($size, ($this->dnssec == true) ? $this->dnssec_payload_size : Net_DNS2_Lookups::DNS_MAX_UDP_SIZE);
1187
  if ( ($result === false) || ($size < Net_DNS2_Lookups::DNS_HEADER_SIZE) ) {
1188
 
1189
- throw new Net_DNS2_Exception(
1190
- $this->sock['tcp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1191
- );
 
 
 
 
 
 
 
1192
  }
1193
 
1194
  //
@@ -1272,12 +1280,10 @@ class Net_DNS2
1272
  //
1273
  } else {
1274
 
1275
- $result = $this->sock['tcp'][$_ns]->read($size, ($this->dnssec == true) ? $this->dnssec_payload_size : Net_DNS2_Lookups::DNS_MAX_UDP_SIZE);
1276
  if ( ($result === false) || ($size < Net_DNS2_Lookups::DNS_HEADER_SIZE) ) {
1277
 
1278
- throw new Net_DNS2_Exception(
1279
- $this->sock['tcp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1280
- );
1281
  }
1282
 
1283
  //
@@ -1326,8 +1332,8 @@ class Net_DNS2
1326
  // see if we already have an open socket from a previous request; if so, try to use
1327
  // that instead of opening a new one.
1328
  //
1329
- if ( (!isset($this->sock['udp'][$_ns]))
1330
- || (!($this->sock['udp'][$_ns] instanceof Net_DNS2_Socket))
1331
  ) {
1332
 
1333
  //
@@ -1335,7 +1341,7 @@ class Net_DNS2
1335
  //
1336
  if ($this->sockets_enabled === true) {
1337
 
1338
- $this->sock['udp'][$_ns] = new Net_DNS2_Socket_Sockets(
1339
  Net_DNS2_Socket::SOCK_DGRAM, $_ns, $this->dns_port, $this->timeout
1340
  );
1341
 
@@ -1344,7 +1350,7 @@ class Net_DNS2
1344
  //
1345
  } else {
1346
 
1347
- $this->sock['udp'][$_ns] = new Net_DNS2_Socket_Streams(
1348
  Net_DNS2_Socket::SOCK_DGRAM, $_ns, $this->dns_port, $this->timeout
1349
  );
1350
  }
@@ -1354,7 +1360,7 @@ class Net_DNS2
1354
  //
1355
  if (strlen($this->local_host) > 0) {
1356
 
1357
- $this->sock['udp'][$_ns]->bindAddress(
1358
  $this->local_host, $this->local_port
1359
  );
1360
  }
@@ -1362,22 +1368,18 @@ class Net_DNS2
1362
  //
1363
  // open the socket
1364
  //
1365
- if ($this->sock['udp'][$_ns]->open() === false) {
1366
 
1367
- throw new Net_DNS2_Exception(
1368
- $this->sock['udp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1369
- );
1370
  }
1371
  }
1372
 
1373
  //
1374
  // write the data to the socket
1375
  //
1376
- if ($this->sock['udp'][$_ns]->write($_data) === false) {
1377
 
1378
- throw new Net_DNS2_Exception(
1379
- $this->sock['udp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1380
- );
1381
  }
1382
 
1383
  //
@@ -1385,12 +1387,10 @@ class Net_DNS2
1385
  //
1386
  $size = 0;
1387
 
1388
- $result = $this->sock['udp'][$_ns]->read($size, ($this->dnssec == true) ? $this->dnssec_payload_size : Net_DNS2_Lookups::DNS_MAX_UDP_SIZE);
1389
  if (( $result === false) || ($size < Net_DNS2_Lookups::DNS_HEADER_SIZE)) {
1390
 
1391
- throw new Net_DNS2_Exception(
1392
- $this->sock['udp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1393
- );
1394
  }
1395
 
1396
  //
72
  /*
73
  * the current version of this library
74
  */
75
+ const VERSION = '1.4.3';
76
 
77
  /*
78
  * the default path to a resolv.conf file
240
  /*
241
  * local sockets
242
  */
243
+ protected $sock = array(Net_DNS2_Socket::SOCK_DGRAM => array(), Net_DNS2_Socket::SOCK_STREAM => array());
244
 
245
  /*
246
  * if the socket extension is loaded
866
  */
867
  public static function expandIPv6($_address)
868
  {
869
+ $hex = unpack('H*hex', inet_pton($_address));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
870
 
871
+ return substr(preg_replace('/([A-f0-9]{4})/', "$1:", $hex['hex']), 0, -1);
 
 
 
 
 
 
872
  }
873
 
874
  /**
1052
  return $response;
1053
  }
1054
 
1055
+ /**
1056
+ * cleans up a failed socket and throws the given exception
1057
+ *
1058
+ * @param string $_proto the protocol of the socket
1059
+ * @param string $_ns the name server to use for the request
1060
+ * @param string $_error the error message to throw at the end of the function
1061
+ *
1062
+ * @throws Net_DNS2_Exception
1063
+ * @access private
1064
+ *
1065
+ */
1066
+ private function generateError($_proto, $_ns, $_error)
1067
+ {
1068
+ if (isset($this->sock[$_proto][$_ns]) == false)
1069
+ {
1070
+ throw new Net_DNS2_Exception('invalid socket referenced', Net_DNS2_Lookups::E_NS_INVALID_SOCKET);
1071
+ }
1072
+
1073
+ //
1074
+ // grab the last error message off the socket
1075
+ //
1076
+ $last_error = $this->sock[$_proto][$_ns]->last_error;
1077
+
1078
+ //
1079
+ // close it
1080
+ //
1081
+ $this->sock[$_proto][$_ns]->close();
1082
+
1083
+ //
1084
+ // remove it from the socket cache
1085
+ //
1086
+ unset($this->sock[$_proto][$_ns]);
1087
+
1088
+ //
1089
+ // throw the error provided
1090
+ //
1091
+ throw new Net_DNS2_Exception($last_error, $_error);
1092
+ }
1093
+
1094
  /**
1095
  * sends a DNS request using TCP
1096
  *
1114
  // see if we already have an open socket from a previous request; if so, try to use
1115
  // that instead of opening a new one.
1116
  //
1117
+ if ( (!isset($this->sock[Net_DNS2_Socket::SOCK_STREAM][$_ns]))
1118
+ || (!($this->sock[Net_DNS2_Socket::SOCK_STREAM][$_ns] instanceof Net_DNS2_Socket))
1119
  ) {
1120
 
1121
  //
1123
  //
1124
  if ($this->sockets_enabled === true) {
1125
 
1126
+ $this->sock[Net_DNS2_Socket::SOCK_STREAM][$_ns] = new Net_DNS2_Socket_Sockets(
1127
  Net_DNS2_Socket::SOCK_STREAM, $_ns, $this->dns_port, $this->timeout
1128
  );
1129
 
1132
  //
1133
  } else {
1134
 
1135
+ $this->sock[Net_DNS2_Socket::SOCK_STREAM][$_ns] = new Net_DNS2_Socket_Streams(
1136
  Net_DNS2_Socket::SOCK_STREAM, $_ns, $this->dns_port, $this->timeout
1137
  );
1138
  }
1142
  //
1143
  if (strlen($this->local_host) > 0) {
1144
 
1145
+ $this->sock[Net_DNS2_Socket::SOCK_STREAM][$_ns]->bindAddress(
1146
  $this->local_host, $this->local_port
1147
  );
1148
  }
1150
  //
1151
  // open the socket
1152
  //
1153
+ if ($this->sock[Net_DNS2_Socket::SOCK_STREAM][$_ns]->open() === false) {
1154
 
1155
+ $this->generateError(Net_DNS2_Socket::SOCK_STREAM, $_ns, Net_DNS2_Lookups::E_NS_SOCKET_FAILED);
 
 
1156
  }
1157
  }
1158
 
1160
  // write the data to the socket; if it fails, continue on
1161
  // the while loop
1162
  //
1163
+ if ($this->sock[Net_DNS2_Socket::SOCK_STREAM][$_ns]->write($_data) === false) {
1164
 
1165
+ $this->generateError(Net_DNS2_Socket::SOCK_STREAM, $_ns, Net_DNS2_Lookups::E_NS_SOCKET_FAILED);
 
 
1166
  }
1167
 
1168
  //
1184
  //
1185
  // read the data off the socket
1186
  //
1187
+ $result = $this->sock[Net_DNS2_Socket::SOCK_STREAM][$_ns]->read($size, ($this->dnssec == true) ? $this->dnssec_payload_size : Net_DNS2_Lookups::DNS_MAX_UDP_SIZE);
1188
  if ( ($result === false) || ($size < Net_DNS2_Lookups::DNS_HEADER_SIZE) ) {
1189
 
1190
+ //
1191
+ // if we get an error, then keeping this socket around for a future request, could cause
1192
+ // an error- for example, https://github.com/mikepultz/netdns2/issues/61
1193
+ //
1194
+ // in this case, the connection was timing out, which once it did finally respond, left
1195
+ // data on the socket, which could be captured on a subsequent request.
1196
+ //
1197
+ // since there's no way to "reset" a socket, the only thing we can do it close it.
1198
+ //
1199
+ $this->generateError(Net_DNS2_Socket::SOCK_STREAM, $_ns, Net_DNS2_Lookups::E_NS_SOCKET_FAILED);
1200
  }
1201
 
1202
  //
1280
  //
1281
  } else {
1282
 
1283
+ $result = $this->sock[Net_DNS2_Socket::SOCK_STREAM][$_ns]->read($size, ($this->dnssec == true) ? $this->dnssec_payload_size : Net_DNS2_Lookups::DNS_MAX_UDP_SIZE);
1284
  if ( ($result === false) || ($size < Net_DNS2_Lookups::DNS_HEADER_SIZE) ) {
1285
 
1286
+ $this->generateError(Net_DNS2_Socket::SOCK_STREAM, $_ns, Net_DNS2_Lookups::E_NS_SOCKET_FAILED);
 
 
1287
  }
1288
 
1289
  //
1332
  // see if we already have an open socket from a previous request; if so, try to use
1333
  // that instead of opening a new one.
1334
  //
1335
+ if ( (!isset($this->sock[Net_DNS2_Socket::SOCK_DGRAM][$_ns]))
1336
+ || (!($this->sock[Net_DNS2_Socket::SOCK_DGRAM][$_ns] instanceof Net_DNS2_Socket))
1337
  ) {
1338
 
1339
  //
1341
  //
1342
  if ($this->sockets_enabled === true) {
1343
 
1344
+ $this->sock[Net_DNS2_Socket::SOCK_DGRAM][$_ns] = new Net_DNS2_Socket_Sockets(
1345
  Net_DNS2_Socket::SOCK_DGRAM, $_ns, $this->dns_port, $this->timeout
1346
  );
1347
 
1350
  //
1351
  } else {
1352
 
1353
+ $this->sock[Net_DNS2_Socket::SOCK_DGRAM][$_ns] = new Net_DNS2_Socket_Streams(
1354
  Net_DNS2_Socket::SOCK_DGRAM, $_ns, $this->dns_port, $this->timeout
1355
  );
1356
  }
1360
  //
1361
  if (strlen($this->local_host) > 0) {
1362
 
1363
+ $this->sock[Net_DNS2_Socket::SOCK_DGRAM][$_ns]->bindAddress(
1364
  $this->local_host, $this->local_port
1365
  );
1366
  }
1368
  //
1369
  // open the socket
1370
  //
1371
+ if ($this->sock[Net_DNS2_Socket::SOCK_DGRAM][$_ns]->open() === false) {
1372
 
1373
+ $this->generateError(Net_DNS2_Socket::SOCK_DGRAM, $_ns, Net_DNS2_Lookups::E_NS_SOCKET_FAILED);
 
 
1374
  }
1375
  }
1376
 
1377
  //
1378
  // write the data to the socket
1379
  //
1380
+ if ($this->sock[Net_DNS2_Socket::SOCK_DGRAM][$_ns]->write($_data) === false) {
1381
 
1382
+ $this->generateError(Net_DNS2_Socket::SOCK_DGRAM, $_ns, Net_DNS2_Lookups::E_NS_SOCKET_FAILED);
 
 
1383
  }
1384
 
1385
  //
1387
  //
1388
  $size = 0;
1389
 
1390
+ $result = $this->sock[Net_DNS2_Socket::SOCK_DGRAM][$_ns]->read($size, ($this->dnssec == true) ? $this->dnssec_payload_size : Net_DNS2_Lookups::DNS_MAX_UDP_SIZE);
1391
  if (( $result === false) || ($size < Net_DNS2_Lookups::DNS_HEADER_SIZE)) {
1392
 
1393
+ $this->generateError(Net_DNS2_Socket::SOCK_DGRAM, $_ns, Net_DNS2_Lookups::E_NS_SOCKET_FAILED);
 
 
1394
  }
1395
 
1396
  //
includes/Net/DNS2/Cache.php CHANGED
@@ -82,6 +82,12 @@ class Net_DNS2_Cache
82
  */
83
  protected $cache_serializer;
84
 
 
 
 
 
 
 
85
  /**
86
  * returns true/false if the provided key is defined in the cache
87
  *
82
  */
83
  protected $cache_serializer;
84
 
85
+ /*
86
+ * an internal flag to make sure we don't load the cache content more
87
+ * than once per instance.
88
+ */
89
+ protected $cache_opened = false;
90
+
91
  /**
92
  * returns true/false if the provided key is defined in the cache
93
  *
includes/Net/DNS2/Cache/File.php CHANGED
@@ -83,10 +83,10 @@ class Net_DNS2_Cache_File extends Net_DNS2_Cache
83
  //
84
  // check that the file exists first
85
  //
86
- if ( (file_exists($this->cache_file) == true)
 
87
  && (filesize($this->cache_file) > 0)
88
  ) {
89
-
90
  //
91
  // open the file for reading
92
  //
@@ -135,6 +135,11 @@ class Net_DNS2_Cache_File extends Net_DNS2_Cache
135
  // clean up the data
136
  //
137
  $this->clean();
 
 
 
 
 
138
  }
139
  }
140
  }
83
  //
84
  // check that the file exists first
85
  //
86
+ if ( ($this->cache_opened == false)
87
+ && (file_exists($this->cache_file) == true)
88
  && (filesize($this->cache_file) > 0)
89
  ) {
 
90
  //
91
  // open the file for reading
92
  //
135
  // clean up the data
136
  //
137
  $this->clean();
138
+
139
+ //
140
+ // mark this so we don't read this contents more than once per instance.
141
+ //
142
+ $this->cache_opened = true;
143
  }
144
  }
145
  }
includes/Net/DNS2/Cache/Shm.php CHANGED
@@ -90,6 +90,14 @@ class Net_DNS2_Cache_Shm extends Net_DNS2_Cache
90
  $this->cache_file = $cache_file;
91
  $this->cache_serializer = $serializer;
92
 
 
 
 
 
 
 
 
 
93
  //
94
  // make sure the file exists first
95
  //
@@ -161,6 +169,11 @@ class Net_DNS2_Cache_Shm extends Net_DNS2_Cache
161
  // call clean to clean up old entries
162
  //
163
  $this->clean();
 
 
 
 
 
164
  }
165
  }
166
  }
90
  $this->cache_file = $cache_file;
91
  $this->cache_serializer = $serializer;
92
 
93
+ //
94
+ // if we've already loaded the cache data, then just return right away
95
+ //
96
+ if ($this->cache_opened == true)
97
+ {
98
+ return;
99
+ }
100
+
101
  //
102
  // make sure the file exists first
103
  //
169
  // call clean to clean up old entries
170
  //
171
  $this->clean();
172
+
173
+ //
174
+ // mark the cache as loaded, so we don't load it more than once
175
+ //
176
+ $this->cache_opened = true;
177
  }
178
  }
179
  }
includes/Net/DNS2/Header.php CHANGED
@@ -253,7 +253,9 @@ class Net_DNS2_Header
253
  */
254
  public function get(Net_DNS2_Packet &$packet)
255
  {
256
- $data = pack('n', $this->id) .
 
 
257
  chr(
258
  ($this->qr << 7) | ($this->opcode << 3) |
259
  ($this->aa << 2) | ($this->tc << 1) | ($this->rd)
@@ -261,14 +263,7 @@ class Net_DNS2_Header
261
  chr(
262
  ($this->ra << 7) | ($this->ad << 5) | ($this->cd << 4) | $this->rcode
263
  ) .
264
- chr($this->qdcount << 8) . chr($this->qdcount) .
265
- chr($this->ancount << 8) . chr($this->ancount) .
266
- chr($this->nscount << 8) . chr($this->nscount) .
267
- chr($this->arcount << 8) . chr($this->arcount);
268
-
269
- $packet->offset += Net_DNS2_Lookups::DNS_HEADER_SIZE;
270
-
271
- return $data;
272
  }
273
  }
274
 
253
  */
254
  public function get(Net_DNS2_Packet &$packet)
255
  {
256
+ $packet->offset += Net_DNS2_Lookups::DNS_HEADER_SIZE;
257
+
258
+ return pack('n', $this->id) .
259
  chr(
260
  ($this->qr << 7) | ($this->opcode << 3) |
261
  ($this->aa << 2) | ($this->tc << 1) | ($this->rd)
263
  chr(
264
  ($this->ra << 7) | ($this->ad << 5) | ($this->cd << 4) | $this->rcode
265
  ) .
266
+ pack('n4', $this->qdcount, $this->ancount, $this->nscount, $this->arcount);
 
 
 
 
 
 
 
267
  }
268
  }
269
 
includes/Net/DNS2/Lookups.php CHANGED
@@ -130,13 +130,15 @@ class Net_DNS2_Lookups
130
 
131
  // 11-15 reserved
132
 
133
- const RCODE_BADSIG = 16; // RFC 2845
 
134
  const RCODE_BADKEY = 17; // RFC 2845
135
  const RCODE_BADTIME = 18; // RFC 2845
136
  const RCODE_BADMODE = 19; // RFC 2930
137
  const RCODE_BADNAME = 20; // RFC 2930
138
  const RCODE_BADALG = 21; // RFC 2930
139
  const RCODE_BADTRUNC = 22; // RFC 4635
 
140
 
141
  /*
142
  * internal errors codes returned by the exceptions class
@@ -162,6 +164,7 @@ class Net_DNS2_Lookups
162
  const E_DNS_BADNAME = self::RCODE_BADNAME;
163
  const E_DNS_BADALG = self::RCODE_BADALG;
164
  const E_DNS_BADTRUNC = self::RCODE_BADTRUNC;
 
165
 
166
  // other error conditions
167
 
@@ -169,6 +172,7 @@ class Net_DNS2_Lookups
169
  const E_NS_INVALID_ENTRY = 201;
170
  const E_NS_FAILED = 202;
171
  const E_NS_SOCKET_FAILED = 203;
 
172
 
173
  const E_PACKET_INVALID = 300;
174
  const E_PARSE_ERROR = 301;
@@ -185,6 +189,24 @@ class Net_DNS2_Lookups
185
  const E_CACHE_SHM_FILE = 501;
186
  const E_CACHE_SHM_UNAVAIL = 502;
187
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  /*
189
  * DNSSEC Algorithms
190
  */
@@ -273,8 +295,9 @@ class Net_DNS2_Lookups
273
  'NSEC3' => 50, // RFC 5155
274
  'NSEC3PARAM' => 51, // RFC 5155
275
  'TLSA' => 52, // RFC 6698
 
276
 
277
- // 53 - 54 unassigned
278
 
279
  'HIP' => 55, // RFC 5205
280
  'NINFO' => 56, // Not implemented
@@ -282,7 +305,7 @@ class Net_DNS2_Lookups
282
  'TALINK' => 58, //
283
  'CDS' => 59, // RFC 7344
284
  'CDNSKEY' => 60, // RFC 7344
285
- 'OPENPGPKEY' => 61, // IETF (draft-ietf-dane-openpgpkey)
286
  'CSYNC' => 62, // RFC 7477
287
 
288
  // 63 - 98 unassigned
@@ -310,8 +333,9 @@ class Net_DNS2_Lookups
310
  'ANY' => 255, // RFC 1035 - we support both 'ANY' and '*'
311
  'URI' => 256, // tools.ietf.org/html/draft-faltstrom-uri-06
312
  'CAA' => 257, // tools.ietf.org/html/draft-ietf-pkix-caa-03
 
313
 
314
- // 258 - 32767 unassigned
315
 
316
  'TA' => 32768, // same as DS
317
  'DLV' => 32769 // RFC 4431
@@ -384,6 +408,7 @@ class Net_DNS2_Lookups
384
  50 => 'Net_DNS2_RR_NSEC3',
385
  51 => 'Net_DNS2_RR_NSEC3PARAM',
386
  52 => 'Net_DNS2_RR_TLSA',
 
387
  55 => 'Net_DNS2_RR_HIP',
388
  58 => 'Net_DNS2_RR_TALINK',
389
  59 => 'Net_DNS2_RR_CDS',
@@ -407,6 +432,7 @@ class Net_DNS2_Lookups
407
  255 => 'Net_DNS2_RR_ANY',
408
  256 => 'Net_DNS2_RR_URI',
409
  257 => 'Net_DNS2_RR_CAA',
 
410
  32768 => 'Net_DNS2_RR_TA',
411
  32769 => 'Net_DNS2_RR_DLV'
412
  );
130
 
131
  // 11-15 reserved
132
 
133
+ const RCODE_BADSIG = 16; // RFC 2845
134
+ const RCODE_BADVERS = 16; // RFC 6891
135
  const RCODE_BADKEY = 17; // RFC 2845
136
  const RCODE_BADTIME = 18; // RFC 2845
137
  const RCODE_BADMODE = 19; // RFC 2930
138
  const RCODE_BADNAME = 20; // RFC 2930
139
  const RCODE_BADALG = 21; // RFC 2930
140
  const RCODE_BADTRUNC = 22; // RFC 4635
141
+ const RCODE_BADCOOKIE = 23; // RFC 7873
142
 
143
  /*
144
  * internal errors codes returned by the exceptions class
164
  const E_DNS_BADNAME = self::RCODE_BADNAME;
165
  const E_DNS_BADALG = self::RCODE_BADALG;
166
  const E_DNS_BADTRUNC = self::RCODE_BADTRUNC;
167
+ const E_DNS_BADCOOKIE = self::RCODE_BADCOOKIE;
168
 
169
  // other error conditions
170
 
172
  const E_NS_INVALID_ENTRY = 201;
173
  const E_NS_FAILED = 202;
174
  const E_NS_SOCKET_FAILED = 203;
175
+ const E_NS_INVALID_SOCKET = 204;
176
 
177
  const E_PACKET_INVALID = 300;
178
  const E_PARSE_ERROR = 301;
189
  const E_CACHE_SHM_FILE = 501;
190
  const E_CACHE_SHM_UNAVAIL = 502;
191
 
192
+ /*
193
+ * EDNS0 Option Codes (OPT)
194
+ */
195
+ // 0 - Reserved
196
+ const EDNS0_OPT_LLQ = 1;
197
+ const EDNS0_OPT_UL = 2;
198
+ const EDNS0_OPT_NSID = 3;
199
+ // 4 - Reserved
200
+ const EDNS0_OPT_DAU = 5;
201
+ const EDNS0_OPT_DHU = 6;
202
+ const EDNS0_OPT_N3U = 7;
203
+ const EDNS0_OPT_CLIENT_SUBNET = 8;
204
+ const EDNS0_OPT_EXPIRE = 9;
205
+ const EDNS0_OPT_COOKIE = 10;
206
+ const EDNS0_OPT_TCP_KEEPALIVE = 11;
207
+ const EDNS0_OPT_PADDING = 12;
208
+ const EDNS0_OPT_CHAIN = 13;
209
+
210
  /*
211
  * DNSSEC Algorithms
212
  */
295
  'NSEC3' => 50, // RFC 5155
296
  'NSEC3PARAM' => 51, // RFC 5155
297
  'TLSA' => 52, // RFC 6698
298
+ 'SMIMEA' => 53, // draft-ietf-dane-smime-10
299
 
300
+ // 54 unassigned
301
 
302
  'HIP' => 55, // RFC 5205
303
  'NINFO' => 56, // Not implemented
305
  'TALINK' => 58, //
306
  'CDS' => 59, // RFC 7344
307
  'CDNSKEY' => 60, // RFC 7344
308
+ 'OPENPGPKEY' => 61, // RFC 7929
309
  'CSYNC' => 62, // RFC 7477
310
 
311
  // 63 - 98 unassigned
333
  'ANY' => 255, // RFC 1035 - we support both 'ANY' and '*'
334
  'URI' => 256, // tools.ietf.org/html/draft-faltstrom-uri-06
335
  'CAA' => 257, // tools.ietf.org/html/draft-ietf-pkix-caa-03
336
+ 'AVC' => 258, // Application Visibility and Control
337
 
338
+ // 259 - 32767 unassigned
339
 
340
  'TA' => 32768, // same as DS
341
  'DLV' => 32769 // RFC 4431
408
  50 => 'Net_DNS2_RR_NSEC3',
409
  51 => 'Net_DNS2_RR_NSEC3PARAM',
410
  52 => 'Net_DNS2_RR_TLSA',
411
+ 53 => 'Net_DNS2_RR_SMIMEA',
412
  55 => 'Net_DNS2_RR_HIP',
413
  58 => 'Net_DNS2_RR_TALINK',
414
  59 => 'Net_DNS2_RR_CDS',
432
  255 => 'Net_DNS2_RR_ANY',
433
  256 => 'Net_DNS2_RR_URI',
434
  257 => 'Net_DNS2_RR_CAA',
435
+ 258 => 'Net_DNS2_RR_AVC',
436
  32768 => 'Net_DNS2_RR_TA',
437
  32769 => 'Net_DNS2_RR_DLV'
438
  );
includes/Net/DNS2/Packet.php CHANGED
@@ -422,21 +422,6 @@ class Net_DNS2_Packet
422
 
423
  return true;
424
  }
425
-
426
- /**
427
- * formats an IPv6 IP address in the preferred format
428
- *
429
- * @param string $address The IPv6 IP address to format
430
- *
431
- * @return string The IPv6 IP address formatted in the new format
432
- * @access public
433
- * @deprecated function deprecated in 1.1.3
434
- *
435
- */
436
- public static function formatIPv6($address)
437
- {
438
- return Net_DNS2::expandIPv6($address);
439
- }
440
  }
441
 
442
  /*
422
 
423
  return true;
424
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425
  }
426
 
427
  /*
includes/Net/DNS2/Question.php CHANGED
@@ -174,7 +174,7 @@ class Net_DNS2_Question
174
  // validate it
175
  //
176
  $type_name = Net_DNS2_Lookups::$rr_types_by_id[$type];
177
- $class_name = Net_DNS2_Lookups::$classes_by_id[$class];
178
 
179
  if ( (!isset($type_name)) || (!isset($class_name)) ) {
180
 
@@ -227,7 +227,7 @@ class Net_DNS2_Question
227
 
228
  $data = $packet->compress($this->qname, $packet->offset);
229
 
230
- $data .= chr($type << 8) . chr($type) . chr($class << 8) . chr($class);
231
  $packet->offset += 4;
232
 
233
  return $data;
174
  // validate it
175
  //
176
  $type_name = Net_DNS2_Lookups::$rr_types_by_id[$type];
177
+ $class_name = Net_DNS2_Lookups::$classes_by_id[$class];
178
 
179
  if ( (!isset($type_name)) || (!isset($class_name)) ) {
180
 
227
 
228
  $data = $packet->compress($this->qname, $packet->offset);
229
 
230
+ $data .= chr($type >> 8) . chr($type) . chr($class >> 8) . chr($class);
231
  $packet->offset += 4;
232
 
233
  return $data;
includes/Net/DNS2/RR.php CHANGED
@@ -548,16 +548,18 @@ abstract class Net_DNS2_RR
548
  //
549
  foreach ($values as $value) {
550
 
551
- switch($value) {
552
  case is_numeric($value):
553
 
554
  $ttl = array_shift($values);
555
  break;
556
 
557
  //
558
- // PHP SUCKS!
 
559
  //
560
  case ($value === 0):
 
561
  $ttl = array_shift($values);
562
  break;
563
 
@@ -570,7 +572,8 @@ abstract class Net_DNS2_RR
570
 
571
  $type = strtoupper(array_shift($values));
572
  break 2;
573
- break;
 
574
  default:
575
 
576
  throw new Net_DNS2_Exception(
548
  //
549
  foreach ($values as $value) {
550
 
551
+ switch(true) {
552
  case is_numeric($value):
553
 
554
  $ttl = array_shift($values);
555
  break;
556
 
557
  //
558
+ // this is here because of a bug in is_numeric() in certain versions of
559
+ // PHP on windows.
560
  //
561
  case ($value === 0):
562
+
563
  $ttl = array_shift($values);
564
  break;
565
 
572
 
573
  $type = strtoupper(array_shift($values));
574
  break 2;
575
+ break;
576
+
577
  default:
578
 
579
  throw new Net_DNS2_Exception(
includes/Net/DNS2/RR/AVC.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2016, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2016 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.4.2
49
+ *
50
+ */
51
+
52
+ /**
53
+ * The AVC RR is implemented exactly like the TXT record, so
54
+ * for now we just extend the TXT RR and use it.
55
+ *
56
+ * @category Networking
57
+ * @package Net_DNS2
58
+ * @author Mike Pultz <mike@mikepultz.com>
59
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
60
+ * @link http://pear.php.net/package/Net_DNS2
61
+ * @see Net_DNS2_RR
62
+ *
63
+ */
64
+ class Net_DNS2_RR_AVC extends Net_DNS2_RR_TXT
65
+ {
66
+ }
67
+
68
+ /*
69
+ * Local variables:
70
+ * tab-width: 4
71
+ * c-basic-offset: 4
72
+ * c-hanging-comment-ender-p: nil
73
+ * End:
74
+ */
75
+ ?>
includes/Net/DNS2/RR/NSAP.php CHANGED
@@ -130,7 +130,7 @@ class Net_DNS2_RR_NSAP extends Net_DNS2_RR
130
  //
131
  // make sure the afi value is 47
132
  //
133
- if ($x['afi'] == 47) {
134
 
135
  $this->afi = '0x' . $x['afi'];
136
  $this->idi = $x['idi'];
@@ -169,7 +169,7 @@ class Net_DNS2_RR_NSAP extends Net_DNS2_RR
169
  //
170
  // we only support AFI 47- there arent' any others defined.
171
  //
172
- if ($this->afi == 47) {
173
 
174
  //
175
  // unpack the rest of the values
@@ -212,7 +212,7 @@ class Net_DNS2_RR_NSAP extends Net_DNS2_RR
212
  */
213
  protected function rrGet(Net_DNS2_Packet &$packet)
214
  {
215
- if ($this->afi == 0x47) {
216
 
217
  //
218
  // build the aa field
130
  //
131
  // make sure the afi value is 47
132
  //
133
+ if ($x['afi'] == '47') {
134
 
135
  $this->afi = '0x' . $x['afi'];
136
  $this->idi = $x['idi'];
169
  //
170
  // we only support AFI 47- there arent' any others defined.
171
  //
172
+ if ($this->afi == '47') {
173
 
174
  //
175
  // unpack the rest of the values
212
  */
213
  protected function rrGet(Net_DNS2_Packet &$packet)
214
  {
215
+ if ($this->afi == '0x47') {
216
 
217
  //
218
  // build the aa field
includes/Net/DNS2/RR/OPENPGPKEY.php CHANGED
@@ -115,7 +115,7 @@ class Net_DNS2_RR_OPENPGPKEY extends Net_DNS2_RR
115
  {
116
  if ($this->rdlength > 0) {
117
 
118
- $this->key = base64_encode($this->rdata);
119
 
120
  return true;
121
  }
115
  {
116
  if ($this->rdlength > 0) {
117
 
118
+ $this->key = base64_encode(substr($this->rdata, 0, $this->rdlength));
119
 
120
  return true;
121
  }
includes/Net/DNS2/RR/SMIMEA.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2016, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2016 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.4.2
49
+ *
50
+ */
51
+
52
+ /**
53
+ * The SMIMEA RR is implemented exactly like the TLSA record, so
54
+ * for now we just extend the TLSA RR and use it.
55
+ *
56
+ * @category Networking
57
+ * @package Net_DNS2
58
+ * @author Mike Pultz <mike@mikepultz.com>
59
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
60
+ * @link http://pear.php.net/package/Net_DNS2
61
+ * @see Net_DNS2_RR
62
+ *
63
+ */
64
+ class Net_DNS2_RR_SMIMEA extends Net_DNS2_RR_TLSA
65
+ {
66
+ }
67
+
68
+ /*
69
+ * Local variables:
70
+ * tab-width: 4
71
+ * c-basic-offset: 4
72
+ * c-hanging-comment-ender-p: nil
73
+ * End:
74
+ */
75
+ ?>
includes/Net/DNS2/RR/SSHFP.php CHANGED
@@ -92,12 +92,14 @@ class Net_DNS2_RR_SSHFP extends Net_DNS2_RR
92
  const SSHFP_ALGORITHM_RES = 0;
93
  const SSHFP_ALGORITHM_RSA = 1;
94
  const SSHFP_ALGORITHM_DSS = 2;
 
95
 
96
  /*
97
  * Fingerprint Types
98
  */
99
  const SSHFP_FPTYPE_RES = 0;
100
  const SSHFP_FPTYPE_SHA1 = 1;
 
101
 
102
 
103
  /**
@@ -137,15 +139,17 @@ class Net_DNS2_RR_SSHFP extends Net_DNS2_RR
137
  //
138
  if ( ($algorithm != self::SSHFP_ALGORITHM_RSA)
139
  && ($algorithm != self::SSHFP_ALGORITHM_DSS)
 
140
  ) {
141
  return false;
142
  }
143
 
144
  //
145
- // there's only one fingerprint type currently implemented, so if it's not
146
- // that, then fail.
147
  //
148
- if ($fp_type != self::SSHFP_FPTYPE_SHA1) {
 
 
149
  return false;
150
  }
151
 
@@ -178,19 +182,21 @@ class Net_DNS2_RR_SSHFP extends Net_DNS2_RR
178
  $this->fp_type = $x['fp_type'];
179
 
180
  //
181
- // There are only two algorithm's defined
182
  //
183
  if ( ($this->algorithm != self::SSHFP_ALGORITHM_RSA)
184
  && ($this->algorithm != self::SSHFP_ALGORITHM_DSS)
 
185
  ) {
186
  return false;
187
  }
188
 
189
  //
190
- // there's only one fingerprint type currently implemented,
191
- // so if it's not that, then fail.
192
  //
193
- if ($this->fp_type != self::SSHFP_FPTYPE_SHA1) {
 
 
194
  return false;
195
  }
196
 
92
  const SSHFP_ALGORITHM_RES = 0;
93
  const SSHFP_ALGORITHM_RSA = 1;
94
  const SSHFP_ALGORITHM_DSS = 2;
95
+ const SSHFP_ALGORITHM_ECDSA = 3;
96
 
97
  /*
98
  * Fingerprint Types
99
  */
100
  const SSHFP_FPTYPE_RES = 0;
101
  const SSHFP_FPTYPE_SHA1 = 1;
102
+ const SSHFP_FPTYPE_SHA256 = 2;
103
 
104
 
105
  /**
139
  //
140
  if ( ($algorithm != self::SSHFP_ALGORITHM_RSA)
141
  && ($algorithm != self::SSHFP_ALGORITHM_DSS)
142
+ && ($algorithm != self::SSHFP_ALGORITHM_ECDSA)
143
  ) {
144
  return false;
145
  }
146
 
147
  //
148
+ // there are only two fingerprints defined
 
149
  //
150
+ if ( ($fp_type != self::SSHFP_FPTYPE_SHA1)
151
+ && ($fp_type != self::SSHFP_FPTYPE_SHA256)
152
+ ) {
153
  return false;
154
  }
155
 
182
  $this->fp_type = $x['fp_type'];
183
 
184
  //
185
+ // There are only three algorithm's defined
186
  //
187
  if ( ($this->algorithm != self::SSHFP_ALGORITHM_RSA)
188
  && ($this->algorithm != self::SSHFP_ALGORITHM_DSS)
189
+ && ($this->algorithm != self::SSHFP_ALGORITHM_ECDSA)
190
  ) {
191
  return false;
192
  }
193
 
194
  //
195
+ // there are only two fingerprints defined
 
196
  //
197
+ if ( ($this->fp_type != self::SSHFP_FPTYPE_SHA1)
198
+ && ($this->fp_type != self::SSHFP_FPTYPE_SHA256)
199
+ ) {
200
  return false;
201
  }
202
 
includes/Net/DNS2/Resolver.php CHANGED
@@ -229,9 +229,9 @@ class Net_DNS2_Resolver extends Net_DNS2
229
  //
230
  foreach ($response->answer as $index => $object) {
231
 
232
- if ( (strcasecmp($object->name, $name) == 0)
233
- && ($object->type == $type)
234
- && ($object->class == $class)
235
  ) {
236
  $found = true;
237
  break;
229
  //
230
  foreach ($response->answer as $index => $object) {
231
 
232
+ if ( (strcasecmp(trim($object->name, '.'), trim($packet->question[0]->qname, '.')) == 0)
233
+ && ($object->type == $packet->question[0]->qtype)
234
+ && ($object->class == $packet->question[0]->qclass)
235
  ) {
236
  $found = true;
237
  break;
includes/Net/IPv4.php CHANGED
@@ -1,469 +1,16 @@
1
  <?php
2
  /**
3
- * Class to provide IPv4 calculations
4
- *
5
- * PHP versions 4 and 5
6
- *
7
- * LICENSE: This source file is subject to version 3.01 of the PHP license
8
- * that is available through the world-wide-web at the following URI:
9
- * http://www.php.net/license/3_01.txt. If you did not receive a copy of
10
- * the PHP License and are unable to obtain it through the web, please
11
- * send a note to license@php.net so we can mail you a copy immediately.
12
- *
13
- * @category Net
14
- * @package Net_IPv4
15
- * @author Eric Kilfoil <edk@ypass.net>
16
- * @author Marco Kaiser <bate@php.net>
17
- * @author Florian Anderiasch <fa@php.net>
18
- * @copyright 1997-2005 The PHP Group
19
- * @license http://www.php.net/license/3_01.txt PHP License 3.01
20
- * @version CVS: $Id: IPv4.php 302879 2010-08-30 06:52:41Z bate $
21
- * @link http://pear.php.net/package/Net_IPv4
22
- */
23
-
24
- //require_once 'PEAR.php';
25
- class myPEAR {
26
- public static function raiseError( $msg ) {
27
- return false;
28
- }
29
- public static function isError( $data, $msgcode ) {
30
- return false === $data;
31
- }
32
- }
33
-
34
- // {{{ GLOBALS
35
- /**
36
- * Map of bitmasks to subnets
37
  *
38
- * This array contains every valid netmask. The index of the dot quad
39
- * netmask value is the corresponding CIDR notation (bitmask).
40
  *
41
- * @global array $GLOBALS['Net_IPv4_Netmask_Map']
 
42
  */
43
- $GLOBALS['Net_IPv4_Netmask_Map'] = array(
44
- 0 => "0.0.0.0",
45
- 1 => "128.0.0.0",
46
- 2 => "192.0.0.0",
47
- 3 => "224.0.0.0",
48
- 4 => "240.0.0.0",
49
- 5 => "248.0.0.0",
50
- 6 => "252.0.0.0",
51
- 7 => "254.0.0.0",
52
- 8 => "255.0.0.0",
53
- 9 => "255.128.0.0",
54
- 10 => "255.192.0.0",
55
- 11 => "255.224.0.0",
56
- 12 => "255.240.0.0",
57
- 13 => "255.248.0.0",
58
- 14 => "255.252.0.0",
59
- 15 => "255.254.0.0",
60
- 16 => "255.255.0.0",
61
- 17 => "255.255.128.0",
62
- 18 => "255.255.192.0",
63
- 19 => "255.255.224.0",
64
- 20 => "255.255.240.0",
65
- 21 => "255.255.248.0",
66
- 22 => "255.255.252.0",
67
- 23 => "255.255.254.0",
68
- 24 => "255.255.255.0",
69
- 25 => "255.255.255.128",
70
- 26 => "255.255.255.192",
71
- 27 => "255.255.255.224",
72
- 28 => "255.255.255.240",
73
- 29 => "255.255.255.248",
74
- 30 => "255.255.255.252",
75
- 31 => "255.255.255.254",
76
- 32 => "255.255.255.255"
77
- );
78
- // }}}
79
- // {{{ Net_IPv4
80
-
81
- /**
82
- * Class to provide IPv4 calculations
83
- *
84
- * Provides methods for validating IP addresses, calculating netmasks,
85
- * broadcast addresses, network addresses, conversion routines, etc.
86
- *
87
- * @category Net
88
- * @package Net_IPv4
89
- * @author Eric Kilfoil <edk@ypass.net>
90
- * @author Marco Kaiser <bate@php.net>
91
- * @author Florian Anderiasch <fa@php.net>
92
- * @copyright 1997-2005 The PHP Group
93
- * @license http://www.php.net/license/3_01.txt PHP License 3.01
94
- * @version CVS: @package_version@
95
- * @link http://pear.php.net/package/Net_IPv4
96
- * @access public
97
- */
98
- class Net_IPv4
99
- {
100
- // {{{ properties
101
- var $ip = "";
102
- var $bitmask = false;
103
- var $netmask = "";
104
- var $network = "";
105
- var $broadcast = "";
106
- var $long = 0;
107
-
108
- // }}}
109
- // {{{ validateIP()
110
-
111
- /**
112
- * Validate the syntax of the given IP adress
113
- *
114
- * Using the PHP long2ip() and ip2long() functions, convert the IP
115
- * address from a string to a long and back. If the original still
116
- * matches the converted IP address, it's a valid address. This
117
- * function does not allow for IP addresses to be formatted as long
118
- * integers.
119
- *
120
- * @param string $ip IP address in the format x.x.x.x
121
- * @return bool true if syntax is valid, otherwise false
122
- */
123
- function validateIP($ip)
124
- {
125
- if ($ip == long2ip(ip2long($ip))) {
126
- return true;
127
- } else {
128
- return false;
129
- }
130
- }
131
-
132
- // }}}
133
- // {{{ check_ip()
134
-
135
- /**
136
- * Validate the syntax of the given IP address (compatibility)
137
- *
138
- * This function is identical to Net_IPv4::validateIP(). It is included
139
- * merely for compatibility reasons.
140
- *
141
- * @param string $ip IP address
142
- * @return bool true if syntax is valid, otherwise false
143
- */
144
- function check_ip($ip)
145
- {
146
- return $this->validateIP($ip);
147
- }
148
-
149
- // }}}
150
- // {{{ validateNetmask()
151
-
152
- /**
153
- * Validate the syntax of a four octet netmask
154
- *
155
- * There are 33 valid netmask values. This function will compare the
156
- * string passed as $netmask to the predefined 33 values and return
157
- * true or false. This is most likely much faster than performing the
158
- * calculation to determine the validity of the netmask.
159
- *
160
- * @param string $netmask Netmask
161
- * @return bool true if syntax is valid, otherwise false
162
- */
163
- function validateNetmask($netmask)
164
- {
165
- if (! in_array($netmask, $GLOBALS['Net_IPv4_Netmask_Map'])) {
166
- return false;
167
- }
168
- return true;
169
- }
170
-
171
- // }}}
172
- // {{{ parseAddress()
173
-
174
- /**
175
- * Parse a formatted IP address
176
- *
177
- * Given a network qualified IP address, attempt to parse out the parts
178
- * and calculate qualities of the address.
179
- *
180
- * The following formats are possible:
181
- *
182
- * [dot quad ip]/[ bitmask ]
183
- * [dot quad ip]/[ dot quad netmask ]
184
- * [dot quad ip]/[ hex string netmask ]
185
- *
186
- * The first would be [IP Address]/[BitMask]:
187
- * 192.168.0.0/16
188
- *
189
- * The second would be [IP Address] [Subnet Mask in dot quad notation]:
190
- * 192.168.0.0/255.255.0.0
191
- *
192
- * The third would be [IP Address] [Subnet Mask as Hex string]
193
- * 192.168.0.0/ffff0000
194
- *
195
- * Usage:
196
- *
197
- * $cidr = '192.168.0.50/16';
198
- * $net = Net_IPv4::parseAddress($cidr);
199
- * echo $net->network; // 192.168.0.0
200
- * echo $net->ip; // 192.168.0.50
201
- * echo $net->broadcast; // 192.168.255.255
202
- * echo $net->bitmask; // 16
203
- * echo $net->long; // 3232235520 (long/double version of 192.168.0.50)
204
- * echo $net->netmask; // 255.255.0.0
205
- *
206
- * @param string $ip IP address netmask combination
207
- * @return object true if syntax is valid, otherwise false
208
- */
209
- static function parseAddress($address)
210
- {
211
- $myself = new Net_IPv4;
212
- if (strchr($address, "/")) {
213
- $parts = explode("/", $address);
214
- if (! $myself->validateIP($parts[0])) {
215
- return myPEAR::raiseError("invalid IP address");
216
- }
217
- $myself->ip = $parts[0];
218
-
219
- // Check the style of netmask that was entered
220
- /*
221
- * a hexadecimal string was entered
222
- */
223
- if (preg_match("/^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i", $parts[1], $regs)) {
224
- // hexadecimal string
225
- $myself->netmask = hexdec($regs[1]) . "." . hexdec($regs[2]) . "." .
226
- hexdec($regs[3]) . "." . hexdec($regs[4]);
227
-
228
- /*
229
- * a standard dot quad netmask was entered.
230
- */
231
- } else if (strchr($parts[1], ".")) {
232
- if (! $myself->validateNetmask($parts[1])) {
233
- return myPEAR::raiseError("invalid netmask value");
234
- }
235
- $myself->netmask = $parts[1];
236
-
237
- /*
238
- * a CIDR bitmask type was entered
239
- */
240
- } else if (ctype_digit($parts[1]) && $parts[1] >= 0 && $parts[1] <= 32) {
241
- // bitmask was entered
242
- $myself->bitmask = $parts[1];
243
-
244
- /*
245
- * Some unknown format of netmask was entered
246
- */
247
- } else {
248
- return myPEAR::raiseError("invalid netmask value");
249
- }
250
- $myself->calculate();
251
- return $myself;
252
- } else if ($myself->validateIP($address)) {
253
- $myself->ip = $address;
254
- return $myself;
255
- } else {
256
- return myPEAR::raiseError("invalid IP address");
257
- }
258
- }
259
-
260
- // }}}
261
- // {{{ calculate()
262
-
263
- /**
264
- * Calculates network information based on an IP address and netmask.
265
- *
266
- * Fully populates the object properties based on the IP address and
267
- * netmask/bitmask properties. Once these two fields are populated,
268
- * calculate() will perform calculations to determine the network and
269
- * broadcast address of the network.
270
- *
271
- * @return mixed true if no errors occured, otherwise PEAR_Error object
272
- */
273
- function calculate()
274
- {
275
- $validNM = $GLOBALS['Net_IPv4_Netmask_Map'];
276
-
277
- // if (! is_a($this, "net_ipv4")) { // avoid E_STRICT in PHP 5.2 and under
278
- if (! ($this instanceof net_ipv4)) {
279
- $myself = new Net_IPv4;
280
- return myPEAR::raiseError("cannot calculate on uninstantiated Net_IPv4 class");
281
- }
282
-
283
- /* Find out if we were given an ip address in dot quad notation or
284
- * a network long ip address. Whichever was given, populate the
285
- * other field
286
- */
287
- if (strlen($this->ip)) {
288
- if (! $this->validateIP($this->ip)) {
289
- return myPEAR::raiseError("invalid IP address");
290
- }
291
- $this->long = self::ip2double($this->ip);
292
- } else if (is_numeric($this->long)) {
293
- $this->ip = long2ip($this->long);
294
- } else {
295
- return myPEAR::raiseError("ip address not specified");
296
- }
297
 
298
- /*
299
- * Check to see if we were supplied with a bitmask or a netmask.
300
- * Populate the other field as needed.
301
- */
302
- if (strlen($this->bitmask)) {
303
- $this->netmask = $validNM[$this->bitmask];
304
- } else if (strlen($this->netmask)) {
305
- $validNM_rev = array_flip($validNM);
306
- $this->bitmask = $validNM_rev[$this->netmask];
307
- } else {
308
- return myPEAR::raiseError("netmask or bitmask are required for calculation");
309
- }
310
- $this->network = long2ip(ip2long($this->ip) & ip2long($this->netmask));
311
- $this->broadcast = long2ip(ip2long($this->ip) |
312
- (ip2long($this->netmask) ^ ip2long("255.255.255.255")));
313
- return true;
314
- }
315
-
316
- // }}}
317
- // {{{ getNetmask()
318
-
319
- function getNetmask($length)
320
- {
321
- if (! myPEAR::isError($ipobj = Net_IPv4::parseAddress("0.0.0.0/" . $length))) {
322
- $mask = $ipobj->netmask;
323
- unset($ipobj);
324
- return $mask;
325
- }
326
- return false;
327
- }
328
-
329
- // }}}
330
- // {{{ getNetLength()
331
-
332
- function getNetLength($netmask)
333
- {
334
- if (! myPEAR::isError($ipobj = Net_IPv4::parseAddress("0.0.0.0/" . $netmask))) {
335
- $bitmask = $ipobj->bitmask;
336
- unset($ipobj);
337
- return $bitmask;
338
- }
339
- return false;
340
- }
341
-
342
- // }}}
343
- // {{{ getSubnet()
344
-
345
- function getSubnet($ip, $netmask)
346
- {
347
- if (! myPEAR::isError($ipobj = Net_IPv4::parseAddress($ip . "/" . $netmask))) {
348
- $net = $ipobj->network;
349
- unset($ipobj);
350
- return $net;
351
- }
352
- return false;
353
- }
354
-
355
- // }}}
356
- // {{{ inSameSubnet()
357
-
358
- function inSameSubnet($ip1, $ip2)
359
- {
360
- if (! is_object($ip1) || strcasecmp(get_class($ip1), 'net_ipv4') <> 0) {
361
- $ipobj1 = Net_IPv4::parseAddress($ip1);
362
- if (myPEAR::isError($ipobj)) {
363
- return myPEAR::raiseError("IP addresses must be an understood format or a Net_IPv4 object");
364
- }
365
- }
366
- if (! is_object($ip2) || strcasecmp(get_class($ip2), 'net_ipv4') <> 0) {
367
- $ipobj2 = Net_IPv4::parseAddress($ip2);
368
- if (myPEAR::isError($ipobj)) {
369
- return myPEAR::raiseError("IP addresses must be an understood format or a Net_IPv4 object");
370
- }
371
- }
372
- if ($ipobj1->network == $ipobj2->network &&
373
- $ipobj1->bitmask == $ipobj2->bitmask) {
374
- return true;
375
- }
376
- return false;
377
  }
378
-
379
- // }}}
380
- // {{{ atoh()
381
-
382
- /**
383
- * Converts a dot-quad formatted IP address into a hexadecimal string
384
- * @param string $addr IP-adress in dot-quad format
385
- * @return mixed false if invalid IP and hexadecimal representation as string if valid
386
- */
387
- function atoh($addr)
388
- {
389
- if (! Net_IPv4::validateIP($addr)) {
390
- return false;
391
- }
392
- $ap = explode(".", $addr);
393
- return sprintf("%02x%02x%02x%02x", $ap[0], $ap[1], $ap[2], $ap[3]);
394
- }
395
-
396
- // }}}
397
- // {{{ htoa()
398
-
399
- /**
400
- * Converts a hexadecimal string into a dot-quad formatted IP address
401
- * @param string $addr IP-adress in hexadecimal format
402
- * @return mixed false if invalid IP and dot-quad formatted IP as string if valid
403
- */
404
- function htoa($addr)
405
- {
406
- if (preg_match("/^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i",
407
- $addr, $regs)) {
408
- return hexdec($regs[1]) . "." . hexdec($regs[2]) . "." .
409
- hexdec($regs[3]) . "." . hexdec($regs[4]);
410
- }
411
- return false;
412
- }
413
-
414
- // }}}
415
- // {{{ ip2double()
416
-
417
- /**
418
- * Converts an IP address to a PHP double. Better than ip2long because
419
- * a long in PHP is a signed integer.
420
- * @param string $ip dot-quad formatted IP adress
421
- * @return float IP adress as double - positive value unlike ip2long
422
- */
423
- static function ip2double($ip)
424
- {
425
- return (double)(sprintf("%u", ip2long($ip)));
426
- }
427
-
428
- // }}}
429
- // {{{ ipInNetwork()
430
-
431
- /**
432
- * Determines whether or not the supplied IP is within the supplied network.
433
- *
434
- * This function determines whether an IP address is within a network.
435
- * The IP address ($ip) must be supplied in dot-quad format, and the
436
- * network ($network) may be either a string containing a CIDR
437
- * formatted network definition, or a Net_IPv4 object.
438
- *
439
- * @param string $ip A dot quad representation of an IP address
440
- * @param string $network A string representing the network in CIDR format or a Net_IPv4 object.
441
- * @return bool true if the IP address exists within the network
442
- */
443
- static function ipInNetwork($ip, $network)
444
- {
445
- if (! is_object($network) || strcasecmp(get_class($network), 'net_ipv4') <> 0) {
446
- $network = Net_IPv4::parseAddress($network);
447
- }
448
- if (strcasecmp(get_class($network), 'pear_error') === 0) {
449
- return false;
450
- }
451
- $net = Net_IPv4::ip2double($network->network);
452
- $bcast = Net_IPv4::ip2double($network->broadcast);
453
- $ip = Net_IPv4::ip2double($ip);
454
- unset($network);
455
- if ($ip >= $net && $ip <= $bcast) {
456
- return true;
457
- }
458
- return false;
459
- }
460
-
461
- // }}}
462
- }
463
-
464
- // }}}
465
-
466
- /*
467
- * vim: sts=4 ts=4 sw=4 cindent fdm=marker
468
- */
469
- ?>
1
  <?php
2
  /**
3
+ * Class to provide IPv4 calculations
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  *
5
+ * PHP versions 4, 5 and 7
 
6
  *
7
+ * @link http://php.net/manual/en/function.ip2long.php#82397
8
+ * @link http://stackoverflow.com/questions/594112/matching-an-ip-to-a-cidr-mask-in-php-5#answer-14841828
9
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ class Net_IPv4 {
12
+ public static function ipInNetwork( $ip, $cidr ) {
13
+ list ( $net, $mask ) = explode ( '/', $cidr );
14
+ return ( ip2long( $ip ) & ~ ( ( 1 << ( 32 - $mask ) ) - 1 ) ) == ip2long( $net );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  }
16
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Net/IPv6.php CHANGED
@@ -19,10 +19,21 @@
19
  * @author Alexander Merz <alexander.merz@web.de>
20
  * @copyright 2003-2005 The PHP Group
21
  * @license BSD License http://www.opensource.org/licenses/bsd-license.php
22
- * @version CVS: $Id: IPv6.php 336941 2015-06-14 13:19:33Z alexmerz $
23
  * @link http://pear.php.net/package/Net_IPv6
24
  */
25
 
 
 
 
 
 
 
 
 
 
 
 
26
  // {{{ constants
27
 
28
  /**
@@ -305,9 +316,9 @@ class Net_IPv6
305
 
306
  } else {
307
 
308
- include_once 'PEAR.php';
309
 
310
- return PEAR::raiseError(NET_IPV6_NO_NETMASK_MSG,
311
  NET_IPV6_NO_NETMASK);
312
  }
313
 
@@ -368,8 +379,8 @@ class Net_IPv6
368
 
369
  if (null == $bits) {
370
 
371
- include_once 'PEAR.php';
372
- return PEAR::raiseError(NET_IPV6_NO_NETMASK_MSG,
373
  NET_IPV6_NO_NETMASK);
374
 
375
  }
@@ -880,6 +891,10 @@ class Net_IPv6
880
  if (!empty($ipPart[0])) {
881
  $ipv6 = explode(':', $ipPart[0]);
882
 
 
 
 
 
883
  foreach($ipv6 as $element) { // made a validate precheck
884
  if(!preg_match('/[0-9a-fA-F]*/', $element)) {
885
  return false;
@@ -989,9 +1004,9 @@ class Net_IPv6
989
 
990
  } else {
991
 
992
- include_once 'PEAR.php';
993
 
994
- return PEAR::raiseError(NET_IPV6_NO_NETMASK_MSG,
995
  NET_IPV6_NO_NETMASK);
996
  }
997
  } else {
19
  * @author Alexander Merz <alexander.merz@web.de>
20
  * @copyright 2003-2005 The PHP Group
21
  * @license BSD License http://www.opensource.org/licenses/bsd-license.php
22
+ * @version CVS: $Id: IPv6.php 338818 2016-03-25 12:15:02Z alexmerz $
23
  * @link http://pear.php.net/package/Net_IPv6
24
  */
25
 
26
+ if ( ! class_exists( 'IP_Geo_Block_Pear' ) ):
27
+ class IP_Geo_Block_Pear {
28
+ public static function raiseError( $msg ) {
29
+ return false;
30
+ }
31
+ public static function isError( $data, $msgcode ) {
32
+ return false === $data;
33
+ }
34
+ }
35
+ endif;
36
+
37
  // {{{ constants
38
 
39
  /**
316
 
317
  } else {
318
 
319
+ //include_once 'PEAR.php';
320
 
321
+ return IP_Geo_Block_Pear::raiseError(NET_IPV6_NO_NETMASK_MSG,
322
  NET_IPV6_NO_NETMASK);
323
  }
324
 
379
 
380
  if (null == $bits) {
381
 
382
+ //include_once 'PEAR.php';
383
+ return IP_Geo_Block_Pear::raiseError(NET_IPV6_NO_NETMASK_MSG,
384
  NET_IPV6_NO_NETMASK);
385
 
386
  }
891
  if (!empty($ipPart[0])) {
892
  $ipv6 = explode(':', $ipPart[0]);
893
 
894
+ if(8 < count($ipv6)) {
895
+ return false;
896
+ }
897
+
898
  foreach($ipv6 as $element) { // made a validate precheck
899
  if(!preg_match('/[0-9a-fA-F]*/', $element)) {
900
  return false;
1004
 
1005
  } else {
1006
 
1007
+ //include_once 'PEAR.php';
1008
 
1009
+ return IP_Geo_Block_Pear::raiseError(NET_IPV6_NO_NETMASK_MSG,
1010
  NET_IPV6_NO_NETMASK);
1011
  }
1012
  } else {
includes/Net/LICENSE ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Net_DNS2 - DNS Library for handling lookups and updates.
2
+
3
+ Copyright (c) 2010-2013, Mike Pultz <mike@mikepultz.com>.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+
10
+ * Redistributions of source code must retain the above copyright
11
+ notice, this list of conditions and the following disclaimer.
12
+
13
+ * Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in
15
+ the documentation and/or other materials provided with the
16
+ distribution.
17
+
18
+ * Neither the name of Mike Pultz nor the names of his contributors
19
+ may be used to endorse or promote products derived from this
20
+ software without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
+ POSSIBILITY OF SUCH DAMAGE.
ip-geo-block.php CHANGED
@@ -8,12 +8,12 @@
8
  * @author tokkonopapa <tokkonopapa@yahoo.com>
9
  * @license GPL-2.0+
10
  * @link http://www.ipgeoblock.com/
11
- * @copyright 2013-2016 tokkonopapa
12
  *
13
  * Plugin Name: IP Geo Block
14
  * Plugin URI: http://wordpress.org/plugins/ip-geo-block/
15
  * Description: It blocks any spams, login attempts and malicious access to the admin area posted from outside your nation, and also prevents zero-day exploit.
16
- * Version: 2.2.9.1
17
  * Author: tokkonopapa
18
  * Author URI: http://www.ipgeoblock.com/
19
  * Text Domain: ip-geo-block
@@ -43,19 +43,23 @@ define( 'IP_GEO_BLOCK_BASE', plugin_basename( __FILE__ ) ); // @since 1.5
43
  * Load class
44
  *
45
  */
46
- require( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block.php' );
 
 
 
 
47
 
48
  /**
49
  * Register hooks that are fired when the plugin is activated or deactivated.
50
  * When the plugin is deleted, the uninstall.php file is loaded.
51
  */
52
  function ip_geo_block_activate( $network_wide = FALSE ) {
53
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-actv.php' );
54
  IP_Geo_Block_Activate::activate( $network_wide );
55
  }
56
 
57
  function ip_geo_block_deactivate( $network_wide = FALSE ) {
58
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-actv.php' );
59
  IP_Geo_Block_Activate::deactivate( $network_wide );
60
  }
61
 
@@ -77,7 +81,7 @@ add_action( 'plugins_loaded', array( 'IP_Geo_Block', 'get_instance' ) );
77
  *
78
  */
79
  if ( is_admin() ) {
80
- require( IP_GEO_BLOCK_PATH . 'admin/class-ip-geo-block-admin.php' );
81
  add_action( 'plugins_loaded', array( 'IP_Geo_Block_Admin', 'get_instance' ) );
82
  }
83
 
@@ -89,8 +93,10 @@ endif; // ! class_exists( 'IP_Geo_Block' )
89
 
90
  /**
91
  * Invalidate blocking behavior in case yourself is locked out.
92
- * @note: activate the following code and upload this file via FTP.
93
- */ /* -- EDIT THIS LINE AND ACTIVATE THE FOLLOWING FUNCTIONS -- *
 
 
94
  function ip_geo_block_emergency( $validate ) {
95
  $validate['result'] = 'passed';
96
  return $validate;
8
  * @author tokkonopapa <tokkonopapa@yahoo.com>
9
  * @license GPL-2.0+
10
  * @link http://www.ipgeoblock.com/
11
+ * @copyright 2013-2017 tokkonopapa
12
  *
13
  * Plugin Name: IP Geo Block
14
  * Plugin URI: http://wordpress.org/plugins/ip-geo-block/
15
  * Description: It blocks any spams, login attempts and malicious access to the admin area posted from outside your nation, and also prevents zero-day exploit.
16
+ * Version: 3.0.2.2
17
  * Author: tokkonopapa
18
  * Author URI: http://www.ipgeoblock.com/
19
  * Text Domain: ip-geo-block
43
  * Load class
44
  *
45
  */
46
+ require IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block.php';
47
+ require IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-util.php';
48
+ require IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-load.php';
49
+ require IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php';
50
+ require IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-apis.php';
51
 
52
  /**
53
  * Register hooks that are fired when the plugin is activated or deactivated.
54
  * When the plugin is deleted, the uninstall.php file is loaded.
55
  */
56
  function ip_geo_block_activate( $network_wide = FALSE ) {
57
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-actv.php';
58
  IP_Geo_Block_Activate::activate( $network_wide );
59
  }
60
 
61
  function ip_geo_block_deactivate( $network_wide = FALSE ) {
62
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-actv.php';
63
  IP_Geo_Block_Activate::deactivate( $network_wide );
64
  }
65
 
81
  *
82
  */
83
  if ( is_admin() ) {
84
+ require IP_GEO_BLOCK_PATH . 'admin/class-ip-geo-block-admin.php';
85
  add_action( 'plugins_loaded', array( 'IP_Geo_Block_Admin', 'get_instance' ) );
86
  }
87
 
93
 
94
  /**
95
  * Invalidate blocking behavior in case yourself is locked out.
96
+ *
97
+ * How to use: Activate the following code and upload this file via FTP.
98
+ */
99
+ /* -- ADD `/` TO THE TOP OR END OF THIS LINE TO ACTIVATE THE FOLLOWINGS -- *
100
  function ip_geo_block_emergency( $validate ) {
101
  $validate['result'] = 'passed';
102
  return $validate;
languages/ip-geo-block-ja.mo CHANGED
Binary file
languages/ip-geo-block-ja.po CHANGED
@@ -1,11 +1,11 @@
1
- # Copyright (C) 2013-2016 tokkonopapa
2
  # This file is distributed under the same license as the IP Geo Block package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: IP Geo Block 2.2.9.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ip-geo-block\n"
7
- "POT-Creation-Date: 2016-11-12 15:12+0900\n"
8
- "PO-Revision-Date: 2016-11-12 15:21+0900\n"
9
  "Last-Translator: tokkonopapa <tokkonopapa@yahoo.com>\n"
10
  "Language-Team: \n"
11
  "MIME-Version: 1.0\n"
@@ -27,25 +27,53 @@ msgstr ""
27
  "自国以外から投稿されるスパム、ログインフォーム、さらにゼロデイ攻撃を含む管理"
28
  "領域への悪意あるアクセスからサイトを守ります。"
29
 
30
- #: admin/class-ip-geo-block-admin.php:185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  msgid "Contribute at GitHub"
32
  msgstr "開発に参加"
33
 
34
- #: admin/class-ip-geo-block-admin.php:202
35
- #: admin/class-ip-geo-block-admin.php:356
36
  msgid "Settings"
37
  msgstr "設定"
38
 
39
- #: admin/class-ip-geo-block-admin.php:248
40
- #: admin/class-ip-geo-block-admin.php:249
41
  msgid "IP Geo Block"
42
  msgstr "IP Geo Block"
43
 
44
- #: admin/class-ip-geo-block-admin.php:270
45
  msgid "You need WordPress 3.7+."
46
  msgstr "WordPress 3.7&thinsp;以上が必要です。"
47
 
48
- #: admin/class-ip-geo-block-admin.php:278
49
  #, php-format
50
  msgid ""
51
  "Now downloading geolocation databases in background. After a little while, "
@@ -56,7 +84,7 @@ msgstr ""
56
  "いた後、あなたの国コードと「<strong>マッチング規則</strong>」を「<a href=\"%s"
57
  "\">検証ルールの設定</a>」で確認して下さい。"
58
 
59
- #: admin/class-ip-geo-block-admin.php:284
60
  #, php-format
61
  msgid ""
62
  "The &#8220;<strong>Matching rule</strong>&#8221; is not set properly. Please "
@@ -65,11 +93,28 @@ msgstr ""
65
  "「<strong>マッチング規則</strong>」が正しく設定されていません。「<a href=\"%s"
66
  "\">検証ルールの設定</a>」を確認して下さい。"
67
 
68
- #: admin/class-ip-geo-block-admin.php:293
69
  msgid "Local database and matching rule have been updated."
70
  msgstr "ローカル・データベースとマッチング規則を更新しました。"
71
 
72
- #: admin/class-ip-geo-block-admin.php:304
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  msgid ""
74
  "Once you logout, you will be unable to login again because your country code "
75
  "or IP address is in the blacklist."
@@ -77,7 +122,7 @@ msgstr ""
77
  "あなたの国コードまたはIPアドレスがブラックリストに含まれているため、ログアウ"
78
  "トすると再びログインする事が出来なくなります。"
79
 
80
- #: admin/class-ip-geo-block-admin.php:305
81
  msgid ""
82
  "Once you logout, you will be unable to login again because your country code "
83
  "or IP address is not in the whitelist."
@@ -85,36 +130,36 @@ msgstr ""
85
  "あなたの国コードまたはIPアドレスがホワイトリストに含まれていないため、ログア"
86
  "ウトすると再びログインする事が出来なくなります。"
87
 
88
- #: admin/class-ip-geo-block-admin.php:308
89
  #, php-format
90
  msgid "Please check your <a href=\"%s\">Validation rule settings</a>."
91
  msgstr "「<a href=\"%s\">検証ルールの設定</a>」を確認して下さい。"
92
 
93
- #: admin/class-ip-geo-block-admin.php:357
94
  msgid "Statistics"
95
  msgstr "統計"
96
 
97
- #: admin/class-ip-geo-block-admin.php:358
98
  msgid "Logs"
99
  msgstr "ログ"
100
 
101
- #: admin/class-ip-geo-block-admin.php:359
102
  msgid "Search"
103
  msgstr "検索"
104
 
105
- #: admin/class-ip-geo-block-admin.php:360
106
  msgid "Attribution"
107
  msgstr "リンク"
108
 
109
- #: admin/class-ip-geo-block-admin.php:372
110
  msgid "Toggle all"
111
  msgstr "全てを開閉"
112
 
113
- #: admin/class-ip-geo-block-admin.php:396
114
  msgid "Thanks for providing these great services for free."
115
  msgstr "これらのすばらしいサービスの提供元に、敬意と感謝の意を表します!"
116
 
117
- #: admin/class-ip-geo-block-admin.php:397
118
  msgid ""
119
  "(Most browsers will redirect you to each site <a href=\"http://www."
120
  "ipgeoblock.com/etc/referer.html\" title=\"Referer Checker\">without referrer "
@@ -124,117 +169,134 @@ msgstr ""
124
  "html\" title=\"Referer Checker\">参照元を残さずにリンク先にリダイレクトできま"
125
  "す</a>。)"
126
 
127
- #: admin/class-ip-geo-block-admin.php:402
128
  msgid "Back to top"
129
  msgstr "トップに戻る"
130
 
131
- #: admin/class-ip-geo-block-admin.php:494
132
  msgid "Enable"
133
  msgstr "有効"
134
 
135
- #: admin/class-ip-geo-block-admin.php:789
136
- #: admin/class-ip-geo-block-admin.php:802
137
- #: classes/class-ip-geo-block-opts.php:257
138
- #: classes/class-ip-geo-block-util.php:114
 
139
  #, php-format
140
  msgid "Unable to write %s. Please check the permission."
141
  msgstr "%s に書き込めません。パーミッションを確認して下さい。"
142
 
143
- #: admin/class-ip-geo-block-admin.php:790
144
  #, php-format
145
  msgid "Or please refer to %s to set it manually."
146
  msgid_plural "Or please refer to %s to set them manually."
147
  msgstr[0] "あるいは %s を参照し、手動で設定して下さい。"
148
  msgstr[1] "あるいは %s を参照し、手動で設定して下さい。"
149
 
150
- #: admin/includes/class-admin-ajax.php:54
151
  msgid "n/a"
152
  msgstr "n/a"
153
 
154
- #: admin/includes/class-admin-ajax.php:57 admin/includes/tab-settings.php:80
155
  msgid "UNKNOWN"
156
  msgstr "不明"
157
 
158
- #: admin/includes/tab-accesslog.php:22 admin/includes/tab-accesslog.php:65
159
  msgid "Validation logs"
160
  msgstr "検証のログ"
161
 
162
- #: admin/includes/tab-accesslog.php:30
 
 
 
 
 
 
 
 
163
  msgid "Clear logs"
164
  msgstr "ログのクリア"
165
 
166
- #: admin/includes/tab-accesslog.php:38 admin/includes/tab-statistics.php:171
167
- #: admin/includes/tab-statistics.php:277
168
  msgid "Clear now"
169
  msgstr "今すぐクリア"
170
 
171
- #: admin/includes/tab-accesslog.php:46
172
  msgid "Export logs"
173
  msgstr "ログをエクスポート"
174
 
175
- #: admin/includes/tab-accesslog.php:52 admin/includes/tab-settings.php:942
176
  msgid "Export to the local file"
177
  msgstr "ローカル・ファイルにエクスポートする"
178
 
179
- #: admin/includes/tab-accesslog.php:52
180
  msgid "Export csv"
181
  msgstr "CSVをエクスポート"
182
 
183
- #: admin/includes/tab-accesslog.php:92 admin/includes/tab-settings.php:330
184
  #, php-format
185
- msgid "<dfn title=\"Validate request to %s.\">%s</dfn>"
186
- msgstr "<dfn title=\"%sへのリクエストを検証します。\">%s</dfn>"
187
 
188
- #: admin/includes/tab-accesslog.php:94 admin/includes/tab-settings.php:332
189
  msgid "Comment post"
190
  msgstr "コメント投稿"
191
 
192
- #: admin/includes/tab-accesslog.php:95 admin/includes/tab-settings.php:333
193
  msgid "XML-RPC"
194
  msgstr "XML-RPC"
195
 
196
- #: admin/includes/tab-accesslog.php:96 admin/includes/tab-settings.php:334
197
  msgid "Login form"
198
  msgstr "ログイン・フォーム"
199
 
200
- #: admin/includes/tab-accesslog.php:97 admin/includes/tab-settings.php:335
201
  msgid "Admin area"
202
  msgstr "管理領域"
203
 
204
- #: admin/includes/tab-accesslog.php:103
 
 
 
 
 
 
 
 
205
  msgid "Date"
206
  msgstr "日時"
207
 
208
- #: admin/includes/tab-accesslog.php:104 admin/includes/tab-geolocation.php:65
209
  #: admin/includes/tab-statistics.php:217
210
  msgid "IP address"
211
  msgstr "IPアドレス"
212
 
213
- #: admin/includes/tab-accesslog.php:105
214
  msgid "Code"
215
  msgstr "国"
216
 
217
- #: admin/includes/tab-accesslog.php:106
218
  msgid "Result"
219
  msgstr "判定"
220
 
221
- #: admin/includes/tab-accesslog.php:107
222
  msgid "Request"
223
  msgstr "リクエスト"
224
 
225
- #: admin/includes/tab-accesslog.php:108
226
  msgid "User agent"
227
  msgstr "ユーザーエージェント"
228
 
229
- #: admin/includes/tab-accesslog.php:109
230
  msgid "HTTP headers"
231
  msgstr "HTTPヘッダ"
232
 
233
- #: admin/includes/tab-accesslog.php:110
234
  msgid "$_POST data"
235
  msgstr "$_POSTデータ"
236
 
237
- #: admin/includes/tab-accesslog.php:128
238
  msgid ""
239
  "Current selection of [<strong>Record validation logs</strong>] on "
240
  "[<strong>Settings</strong>] tab is [<strong>Disable</strong>]."
@@ -242,7 +304,7 @@ msgstr ""
242
  "現在[<strong>設定</strong>]タブの[<strong>検証のログを記録</strong>]は"
243
  "[<strong>無効</strong>]が選択されています。"
244
 
245
- #: admin/includes/tab-accesslog.php:129
246
  msgid ""
247
  "Please select the proper condition to record and analyze the validation logs."
248
  msgstr "検証のログを記録し分析するためには、適切な条件を選択して下さい。"
@@ -267,41 +329,41 @@ msgstr "位置情報の検索"
267
  msgid "Search now"
268
  msgstr "今すぐ検索"
269
 
270
- #: admin/includes/tab-settings.php:52
271
  msgid "Validation rule settings"
272
  msgstr "検証ルールの設定"
273
 
274
- #: admin/includes/tab-settings.php:72
275
  msgid ""
276
  "<dfn title=\"You can confirm the appropriate Geolocation APIs and country "
277
- "code by referring &#8220;Scan your country code&#8221;.\">Your IP address / "
278
  "Country</dfn>"
279
  msgstr ""
280
  "<dfn title=\"「国コードを検索する」を参照し、適切な位置情報APIと国コードを設"
281
  "定して下さい。\">あなたのIPアドレス / 国コード</dfn>"
282
 
283
- #: admin/includes/tab-settings.php:81
284
  msgid "Scan all the APIs you selected at Geolocation API settings"
285
  msgstr "選択された位置情報APIを検索します"
286
 
287
- #: admin/includes/tab-settings.php:81
288
- msgid "Scan your country code"
289
  msgstr "国コードを検索する"
290
 
291
- #: admin/includes/tab-settings.php:88
292
  msgid "Whitelist"
293
  msgstr "ホワイトリスト"
294
 
295
- #: admin/includes/tab-settings.php:89
296
  msgid "Blacklist"
297
  msgstr "ブラックリスト"
298
 
299
- #: admin/includes/tab-settings.php:93
300
  msgid ""
301
  "Please select either &#8220;Whitelist&#8221; or &#8220;Blacklist&#8221;."
302
  msgstr "「ホワイトリスト」または「ブラックリスト」のいずれかを選択して下さい。"
303
 
304
- #: admin/includes/tab-settings.php:94
305
  msgid ""
306
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
307
  "empty. All the countries will be blocked in case you put &#8220;XX&#8221; "
@@ -311,7 +373,7 @@ msgstr ""
311
  "を指定した場合には、全ての国がブロック対象になります。\">国コードのホワイトリ"
312
  "スト</dfn>"
313
 
314
- #: admin/includes/tab-settings.php:95
315
  msgid ""
316
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
317
  "empty. Please consider to include &#8220;ZZ&#8221; which means UNKNOWN "
@@ -320,19 +382,19 @@ msgstr ""
320
  "<dfn title=\"空欄の場合、「国コードで遮断」はバイパスされます。また「不明」を"
321
  "表す「ZZ」を含める事を検討して下さい。\">国コードのブラックリスト</dfn>"
322
 
323
- #: admin/includes/tab-settings.php:99
324
  msgid "(comma separated)"
325
  msgstr "(カンマ区切り)"
326
 
327
- #: admin/includes/tab-settings.php:100
328
  msgid "(comma or RET separated)"
329
  msgstr "(カンマ、または改行区切り)"
330
 
331
- #: admin/includes/tab-settings.php:107
332
  msgid "Matching rule"
333
  msgstr "マッチング規則"
334
 
335
- #: admin/includes/tab-settings.php:119
336
  msgid ""
337
  "A request from which the country code or IP address is <strong>NOT</strong> "
338
  "in the whitelist will be blocked."
@@ -340,7 +402,7 @@ msgstr ""
340
  "国コードまたはIPアドレスがホワイトリストに<strong>含まれていない</strong>リク"
341
  "エストを遮断します。"
342
 
343
- #: admin/includes/tab-settings.php:120
344
  msgid ""
345
  "A request from which the country code or IP address is in the blacklist will "
346
  "be blocked."
@@ -348,7 +410,7 @@ msgstr ""
348
  "国コードまたはIPアドレスがブラックリストに<strong>含まれている</strong>リクエ"
349
  "ストを遮断します。"
350
 
351
- #: admin/includes/tab-settings.php:165
352
  msgid ""
353
  "<dfn title=\"e.g. &#8220;192.0.64.0/18&#8221; for Jetpack server, "
354
  "&#8220;69.46.36.0/27&#8221; for WordFence server\">Whitelist of extra IP "
@@ -357,7 +419,7 @@ msgstr ""
357
  "<dfn title=\"例)192.0.64.0/18(Jetpackサーバー)、69.46.36.0/27(WordFence"
358
  "サーバー)\">国コードに優先して検証するIPアドレスのホワイトリスト</dfn>"
359
 
360
- #: admin/includes/tab-settings.php:184
361
  msgid ""
362
  "<dfn title=\"Server level access control is recommended (e.g. .htaccess)."
363
  "\">Blacklist of extra IP addresses prior to country code</dfn>"
@@ -365,7 +427,7 @@ msgstr ""
365
  "<dfn title=\"サーバー・レベルのアクセス制御の使用をお勧めします(例:."
366
  "htaccess)。\">国コードに優先して検証するIPアドレスのブラックリスト</dfn>"
367
 
368
- #: admin/includes/tab-settings.php:204
369
  msgid ""
370
  "<dfn title=\"e.g. HTTP_X_FORWARDED_FOR\">$_SERVER keys to retrieve extra IP "
371
  "addresses</dfn>"
@@ -373,7 +435,7 @@ msgstr ""
373
  "<dfn title=\"例)HTTP_X_FORWARDED_FOR\">IPアドレスを追加抽出する&thinsp;"
374
  "$_SERVER&thinsp;のキー</dfn>"
375
 
376
- #: admin/includes/tab-settings.php:222
377
  msgid ""
378
  "<dfn title=\"It validates malicious signatures independently of &#8220;Block "
379
  "by country&#8221; and &#8220;Prevent Zero-day Exploit&#8221; for the target "
@@ -390,16 +452,37 @@ msgstr ""
390
  "字化けした場合、クリックして復元して下さい。\"><span id=\"ip-geo-block-cycle"
391
  "\"></span></a>)</nobr>"
392
 
393
- #: admin/includes/tab-settings.php:239
394
  #, php-format
395
  msgid ""
396
  "<dfn title=\"You can put your original 403.php and so on into your theme "
397
  "directory.\">Response code</dfn> %s"
398
  msgstr ""
399
- "<dfn title=\"テーマ・ディレクトリに独自の403.phpなどのファイルを設置する事が"
400
- "出来ます。\">レスポンス・コード</dfn> %s"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
 
402
- #: admin/includes/tab-settings.php:269
403
  msgid ""
404
  "<dfn title=\"Applied to &#8220;XML-RPC&#8221; and &#8220;Login form&#8221;. "
405
  "Lockout period is defined as expiration time at &#8220;Cache settings&#8221;."
@@ -409,23 +492,23 @@ msgstr ""
409
  "時間は「キャッシュの設定」の「有効時間」で定義されます。\">IPアドレス当たりの"
410
  "ログイン試行可能回数</dfn>"
411
 
412
- #: admin/includes/tab-settings.php:296
413
  msgid "Select when to run the validation."
414
  msgstr "検証を実行するタイミングを選択します。"
415
 
416
- #: admin/includes/tab-settings.php:296
417
  msgid "Validation timing"
418
  msgstr "検証のタイミング"
419
 
420
- #: admin/includes/tab-settings.php:307
421
  msgid "&#8220;init&#8221; action hook"
422
  msgstr "&#8220;init&#8221; アクション・フック"
423
 
424
- #: admin/includes/tab-settings.php:308
425
  msgid "&#8220;mu-plugins&#8221; (ip-geo-block-mu.php)"
426
  msgstr "&#8220;mu-plugins&#8221; (ip-geo-block-mu.php)"
427
 
428
- #: admin/includes/tab-settings.php:311
429
  msgid ""
430
  "Validate at &#8220;init&#8221; action hook in the same manner as typical "
431
  "plugins."
@@ -433,54 +516,65 @@ msgstr ""
433
  "標準的な他のプラグインと同様、init アクション・フックのタイミングで検証を実行"
434
  "します。"
435
 
436
- #: admin/includes/tab-settings.php:312
437
  msgid ""
438
  "Validate at an earlier phase than other typical plugins. It can reduce load "
439
- "on server but has <a href='http://www.ipgeoblock.com/codex/validation-timing."
440
- "html' title='Validation timing | IP Geo Block'>some restrictions</a>."
 
441
  msgstr ""
442
  "標準的な他のプラグインより早いタイミングで検証を実行します。これによりサー"
443
- "バーの負荷は軽減されますが、<a href='http://www.ipgeoblock.com/codex/"
444
- "validation-timing.html' title='Validation timing | IP Geo Block'>幾つかの制限"
445
- "事項</a>が生じます。"
 
 
 
 
 
 
 
 
 
446
 
447
- #: admin/includes/tab-settings.php:324
448
- msgid "Validation target settings"
449
- msgstr "検証対象の設定"
450
 
451
- #: admin/includes/tab-settings.php:353 admin/includes/tab-settings.php:373
452
- #: admin/includes/tab-settings.php:406 admin/includes/tab-settings.php:412
 
453
  msgid "Block by country"
454
  msgstr "国コードで遮断"
455
 
456
- #: admin/includes/tab-settings.php:372 admin/includes/tab-settings.php:459
457
- #: admin/includes/tab-settings.php:723
458
  msgid "Disable"
459
  msgstr "無効"
460
 
461
- #: admin/includes/tab-settings.php:374
462
  msgid "Completely close"
463
  msgstr "完全に閉鎖"
464
 
465
- #: admin/includes/tab-settings.php:407
466
  msgid ""
467
  "<dfn title=\"Specify the individual action as a blocking target.\">Target "
468
  "actions</dfn>"
469
  msgstr ""
470
  "<dfn title=\"遮断対象とするアクションを指定します。\">対象アクション</dfn>"
471
 
472
- #: admin/includes/tab-settings.php:413
473
  msgid "Prevent Zero-day Exploit"
474
  msgstr "ゼロデイ攻撃を遮断"
475
 
476
- #: admin/includes/tab-settings.php:416
477
  msgid ""
478
  "It will block a request related to the services for both public facing pages "
479
  "and the dashboard."
480
  msgstr ""
481
  "一般公開ページとダッシュボード向けサービスに関連するリクエストを遮断します。"
482
 
483
- #: admin/includes/tab-settings.php:417
484
  msgid ""
485
  "Regardless of the country code, it will block a malicious request related to "
486
  "the services only for the dashboard."
@@ -488,11 +582,42 @@ msgstr ""
488
  "国コードに拘らず、ダッシュボード向けサービスだけに関連する悪意のあるリクエス"
489
  "トを遮断します。"
490
 
491
- #: admin/includes/tab-settings.php:444
 
 
 
 
 
 
 
 
492
  msgid "Admin ajax/post"
493
  msgstr "管理領域&thinsp;ajax/post"
494
 
495
- #: admin/includes/tab-settings.php:461
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
496
  #, php-format
497
  msgid ""
498
  "Regardless of the country code, it will block a malicious request to <code>"
@@ -501,16 +626,16 @@ msgstr ""
501
  "国コードに拘らず、<code>%s&hellip;/*.php</code>への悪意のあるリクエストを遮断"
502
  "します。"
503
 
504
- #: admin/includes/tab-settings.php:462
505
  #, php-format
506
  msgid ""
507
- "It configures &#8220%s&#8221 to validate a request to the PHP file which "
508
  "does not load WordPress core."
509
  msgstr ""
510
  "WordPressコアを読み込まないPHPファイルへのリクエストを検証対象とするため"
511
  "に、%s を設定します。"
512
 
513
- #: admin/includes/tab-settings.php:463
514
  msgid ""
515
  "<dfn title=\"Select the item which causes undesired blocking in order to "
516
  "exclude from the validation target. Grayed item indicates &#8220;"
@@ -520,23 +645,123 @@ msgstr ""
520
  "す。灰色で表示された項目は、「非アクティブ」であることを示しています。\">除外"
521
  "する項目</dfn>"
522
 
523
- #: admin/includes/tab-settings.php:499 admin/includes/tab-settings.php:552
524
  msgid "Force to load WP core"
525
  msgstr "WPコアの読み込みを強制"
526
 
527
- #: admin/includes/tab-settings.php:504
528
  msgid "Plugins area"
529
  msgstr "プラグイン領域"
530
 
531
- #: admin/includes/tab-settings.php:557
532
  msgid "Themes area"
533
  msgstr "テーマ領域"
534
 
535
- #: admin/includes/tab-settings.php:585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
  msgid "Geolocation API settings"
537
  msgstr "位置情報APIの設定"
538
 
539
- #: admin/includes/tab-settings.php:594
540
  msgid ""
541
  "<dfn title=\"Cache and local database are scanned at the top priority.\">API "
542
  "selection and key settings</dfn>"
@@ -544,89 +769,97 @@ msgstr ""
544
  "<dfn title=\"キャッシュとローカルのデータベースが最優先で検索されます。\">API"
545
  "の選択とキーの設定</dfn>"
546
 
547
- #: admin/includes/tab-settings.php:616
548
  #, php-format
549
  msgid ""
550
- "Please download <a href=\"https://github.com/tokkonopapa/WordPress-IP-Geo-"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
  "API/archive/master.zip\" title=\"Download the contents of tokkonopapa/"
552
- "WordPress-IP-Geo-API as a zip file\">ZIP file</a> from <a href=\"https://"
553
- "github.com/tokkonopapa/WordPress-IP-Geo-API\" title=\"tokkonopapa/WordPress-"
554
- "IP-Geo-API - GitHub\">WordPress-IP-Geo-API</a> and upload <code>ip-geo-api</"
555
- "code> to <code>%s</code> with write permission."
556
- msgstr ""
557
- "<a href=\"https://github.com/tokkonopapa/WordPress-IP-Geo-API\" title="
558
- "\"tokkonopapa/WordPress-IP-Geo-API - GitHub\">WordPress-IP-Geo-API</a>から<a "
559
- "href=\"https://github.com/tokkonopapa/WordPress-IP-Geo-API/archive/master.zip"
560
- "\" title=\"Download the contents of tokkonopapa/WordPress-IP-Geo-API as a "
561
- "zip file\">ZIPファイル</a>をダウンロードし、<code>ip-geo-api</code>を書き込み"
562
- "権限付きで<code>%s</code>にアップロードして下さい。"
563
-
564
- #: admin/includes/tab-settings.php:625
565
  msgid "Local database settings"
566
  msgstr "ローカル・データベースの設定"
567
 
568
- #: admin/includes/tab-settings.php:640
569
  msgid "database"
570
  msgstr "ファイル"
571
 
572
- #: admin/includes/tab-settings.php:641 classes/class-ip-geo-block-util.php:159
573
  #, php-format
574
  msgid "Last update: %s"
575
  msgstr "最終更新:%s"
576
 
577
- #: admin/includes/tab-settings.php:650
578
  msgid "Auto updating (once a month)"
579
  msgstr "自動更新(月1回)"
580
 
581
- #: admin/includes/tab-settings.php:667
582
  msgid "Download database"
583
  msgstr "データベースのダウンロード"
584
 
585
- #: admin/includes/tab-settings.php:675
586
  msgid "Download now"
587
  msgstr "今すぐダウンロード"
588
 
589
- #: admin/includes/tab-settings.php:687
590
  msgid "Record settings"
591
  msgstr "記録の設定"
592
 
593
- #: admin/includes/tab-settings.php:696
594
  msgid "Record validation statistics"
595
  msgstr "検証の統計を記録"
596
 
597
- #: admin/includes/tab-settings.php:712
598
  msgid "Record validation logs"
599
  msgstr "検証のログを記録"
600
 
601
- #: admin/includes/tab-settings.php:724
602
  msgid "Only when blocked"
603
  msgstr "遮断時に記録"
604
 
605
- #: admin/includes/tab-settings.php:725
606
  msgid "Only when passed"
607
  msgstr "通過時に記録"
608
 
609
- #: admin/includes/tab-settings.php:726
610
  msgid "Unauthenticated user"
611
  msgstr "未認証ユーザーを記録"
612
 
613
- #: admin/includes/tab-settings.php:727
614
  msgid "Authenticated user"
615
  msgstr "認証済ユーザーを記録"
616
 
617
- #: admin/includes/tab-settings.php:728
618
  msgid "All of validation"
619
  msgstr "すべての検証を記録"
620
 
621
- #: admin/includes/tab-settings.php:737
622
  msgid "Recording period of the logs (days)"
623
  msgstr "ログの記録期間(日)"
624
 
625
- #: admin/includes/tab-settings.php:753
626
  msgid "Maximum length of logs for each target"
627
- msgstr "各ターゲット毎のログ最大長"
628
 
629
- #: admin/includes/tab-settings.php:770
630
  msgid ""
631
  "<dfn title=\"e.g. action, comment, log, pwd\">$_POST keys to be recorded "
632
  "with their values in logs</dfn>"
@@ -634,15 +867,15 @@ msgstr ""
634
  "<dfn title=\"例)action, comment, log, pwd\">ログに記録する際に内容を展開する"
635
  "$_POSTのキー</dfn>"
636
 
637
- #: admin/includes/tab-settings.php:788
638
  msgid "<dfn title=\"e.g. 123.456.789.***\">Anonymize IP address</dfn>"
639
  msgstr "<dfn title=\"例)123.456.789.***\">IPアドレスを匿名化する</dfn>"
640
 
641
- #: admin/includes/tab-settings.php:806
642
- msgid "Cache settings"
643
- msgstr "キャッシュの設定"
644
 
645
- #: admin/includes/tab-settings.php:815
646
  #, php-format
647
  msgid ""
648
  "<dfn title=\"If user authentication fails consecutively %d times, subsequent "
@@ -652,43 +885,47 @@ msgstr ""
652
  "<dfn title=\"ユーザ認証が連続%d回失敗した場合も、以降のログインがこの期間だけ"
653
  "(ガベージコレクション周期を含む)禁止されます。\">有効時間 [sec]</dfn>"
654
 
655
- #: admin/includes/tab-settings.php:831
 
 
 
 
656
  msgid "Number of entries to be displayed in cache"
657
  msgstr "「キャッシュ中のIPアドレス」に表示する最大数"
658
 
659
- #: admin/includes/tab-settings.php:849
660
  msgid "Submission settings"
661
  msgstr "投稿時の設定"
662
 
663
- #: admin/includes/tab-settings.php:861
664
  msgid "The whole will be wrapped by &lt;p&gt; tag. Allowed tags: "
665
  msgstr "全体が&lt;p&gt;タグで囲われます。使用可能タグ:"
666
 
667
- #: admin/includes/tab-settings.php:861
668
  msgid "Message on comment form"
669
  msgstr "投稿フォーム上のメッセージ"
670
 
671
- #: admin/includes/tab-settings.php:873
672
  msgid "None"
673
  msgstr "なし"
674
 
675
- #: admin/includes/tab-settings.php:874
676
  msgid "Top"
677
  msgstr "上部"
678
 
679
- #: admin/includes/tab-settings.php:875
680
  msgid "Bottom"
681
  msgstr "下部"
682
 
683
- #: admin/includes/tab-settings.php:887
684
  msgid "Plugin settings"
685
  msgstr "プラグインの設定"
686
 
687
- #: admin/includes/tab-settings.php:896
688
  msgid "Remove all settings at uninstallation"
689
  msgstr "アンインストール時に全設定を削除"
690
 
691
- #: admin/includes/tab-settings.php:915
692
  msgid ""
693
  "<dfn title=\"Valid key for Google Maps JavaScript API\">Google Maps API key</"
694
  "dfn>"
@@ -696,7 +933,7 @@ msgstr ""
696
  "<dfn title=\"Google Maps JavaScript API に有効なキー\">Google Maps API キー</"
697
  "dfn>"
698
 
699
- #: admin/includes/tab-settings.php:929
700
  msgid ""
701
  "You need to click the &#8220;Save Changes&#8221; button for imported "
702
  "settings to take effect."
@@ -704,87 +941,109 @@ msgstr ""
704
  "インポートされた設定を有効にするには、「変更を保存」ボタンをクリックする必要"
705
  "があります。"
706
 
707
- #: admin/includes/tab-settings.php:935
708
  msgid "Export / Import settings"
709
  msgstr "設定のエクスポート、インポート"
710
 
711
- #: admin/includes/tab-settings.php:942
712
  msgid "Export settings"
713
  msgstr "エクスポート"
714
 
715
- #: admin/includes/tab-settings.php:943
716
  msgid "Import from the local file"
717
  msgstr "ローカル・ファイルからインポートします"
718
 
719
- #: admin/includes/tab-settings.php:943
720
  msgid "Import settings"
721
  msgstr "インポート"
722
 
723
- #: admin/includes/tab-settings.php:952
724
  msgid "Import pre-defined settings"
725
  msgstr "プリセットのインポート"
726
 
727
- #: admin/includes/tab-settings.php:959
 
 
 
 
 
 
 
 
 
 
728
  msgid ""
729
  "Import the default settings to revert to the &#8220;Right after "
730
  "installing&#8221; state"
731
  msgstr "インストール直後の状態に戻すための設定値をインポートします"
732
 
733
- #: admin/includes/tab-settings.php:959
734
  msgid "Default settings"
735
  msgstr "初期設定"
736
 
737
- #: admin/includes/tab-settings.php:960
738
- msgid ""
739
- "Import the preferred settings mainly for the &#8220;Validation target "
740
- "settings&#8221;"
741
- msgstr "主に「検証対象の設定」に関する推奨の設定値をインポートします"
742
-
743
- #: admin/includes/tab-settings.php:960
744
- msgid "Best practice"
745
- msgstr "ベスト・プラクティス"
746
-
747
- #: admin/includes/tab-settings.php:970
748
  msgid "Delete DB table for validation logs"
749
  msgstr "検証のログ用データベース・テーブルの削除"
750
 
751
- #: admin/includes/tab-settings.php:978
752
  msgid "Delete now"
753
  msgstr "今すぐ削除"
754
 
755
- #: admin/includes/tab-settings.php:986
756
  msgid "Create DB table for validation logs"
757
  msgstr "検証のログ用データベース・テーブルの作成"
758
 
759
- #: admin/includes/tab-settings.php:994
760
  msgid "Create now"
761
  msgstr "今すぐ作成"
762
 
763
- #: admin/includes/tab-settings.php:1009
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
764
  msgid ""
765
- "To enhance the protection ability, please refer to &#8220;<a href=\"http://"
766
- "www.ipgeoblock.com/codex/the-best-practice-of-target-settings.html\" title="
767
- "\"The best practice of target settings | IP Geo Block\">The best practice of "
768
- "target settings</a>&#8221;."
769
  msgstr ""
770
- "防御性能をより高めるための設定については、&#8220;<a href=\"http://www."
771
- "ipgeoblock.com/codex/the-best-practice-of-target-settings.html\" title=\"The "
772
- "best practice of target settings | IP Geo Block\">The best practice of "
773
- "target settings</a>&#8220;&thinsp;を参照してください。"
774
 
775
- #: admin/includes/tab-settings.php:1010
776
  msgid ""
777
- "If you have any troubles with these, please open an issue at <a class=\"ip-"
778
- "geo-block-link\" href=\"http://wordpress.org/support/plugin/ip-geo-block\" "
779
- "title=\"WordPress &#8250; Support &raquo; IP Geo Block\" "
780
- "target=_blank>support forum</a>."
 
781
  msgstr ""
782
- "何か問題が発生した場合は、<a class=\"ip-geo-block-link\" href=\"http://"
783
- "wordpress.org/support/plugin/ip-geo-block\" title=\"WordPress &#8250; "
784
- "Support &raquo; IP Geo Block\" target=_blank>サポート・フォーラム</a>へご報告"
785
- "ください。"
 
786
 
787
- #: admin/includes/tab-settings.php:1017
788
  msgid ""
789
  "While Maxmind and IP2Location will fetch the local database, others will "
790
  "pass an IP address to the APIs via HTTP."
@@ -792,11 +1051,45 @@ msgstr ""
792
  "MaxmindとIP2Locationはローカルのデータベースを検索しますが、他はHTTPを介して"
793
  "APIにIPアドレスを渡します。"
794
 
795
- #: admin/includes/tab-settings.php:1018
796
  msgid ""
797
  "Please select the appropriate APIs to fit the privacy law in your country."
798
  msgstr "自国のプライバシー関連法規に合わせ、適切なAPIを選択して下さい。"
799
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
800
  #: admin/includes/tab-statistics.php:24 admin/includes/tab-statistics.php:184
801
  msgid "Statistics of validation"
802
  msgstr "検証の統計"
@@ -849,15 +1142,15 @@ msgstr "国コード / アクセス先"
849
  msgid "Elapsed [sec] / Calls"
850
  msgstr "経過時間 [sec] / 回数"
851
 
852
- #: admin/includes/tab-statistics.php:254
853
  msgid "IP address in cache"
854
  msgstr "キャッシュ中のIPアドレス"
855
 
856
- #: admin/includes/tab-statistics.php:269
857
  msgid "Clear cache"
858
  msgstr "キャッシュのクリア"
859
 
860
- #: admin/includes/tab-statistics.php:288
861
  msgid ""
862
  "Current setting of [<strong>Record validation statistics</strong>] on "
863
  "[<strong>Settings</strong>] tab is not selected [<strong>Enable</strong>]."
@@ -865,13 +1158,13 @@ msgstr ""
865
  "現在[<strong>設定</strong>]タブの[<strong>検証の統計を記録</strong>]は"
866
  "[<strong>有効</strong>]が選択されていません。"
867
 
868
- #: admin/includes/tab-statistics.php:289
869
  msgid ""
870
  "Please set the proper condition to record and analyze the validation "
871
  "statistics."
872
  msgstr "検証の統計を記録し分析するためには、適切な条件を設定して下さい。"
873
 
874
- #: classes/class-ip-geo-block-apis.php:672
875
  msgid ""
876
  "You need to select at least one IP geolocation service. Otherwise "
877
  "<strong>you'll be blocked</strong> after the cache expires."
@@ -879,27 +1172,57 @@ msgstr ""
879
  "少なくとも1つ以上の位置情報サービスを選択して下さい。未選択の場合、キャッシュ"
880
  "の有効期限切れと共にロックアウトされます。"
881
 
882
- #: classes/class-ip-geo-block-logs.php:112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
883
  #, php-format
884
  msgid ""
885
  "Creating a DB table %s had failed. Once de-activate this plugin, and then "
886
  "activate again."
887
  msgstr ""
888
- "%s用のテーブルが作成されていません。一旦このプラグインを無効化し、再度有効化"
889
  "して下さい。"
890
 
891
- #: classes/class-ip-geo-block-util.php:77
892
- msgid "Your database file is up-to-date."
893
- msgstr "データベース・ファイルは最新です。"
894
-
895
- #: classes/class-ip-geo-block-util.php:106
896
- #, php-format
897
- msgid "Unable to read %s. Please check the permission."
898
- msgstr "%sが読めません。パーミッションを確認して下さい。"
899
-
900
- #: wp-content/ip-geo-api/ip2location/class-ip2location.php:145
901
- #: wp-content/ip-geo-api/ip2location/class-ip2location.php:174
902
- #: wp-content/ip-geo-api/maxmind/class-maxmind.php:149
903
- #: wp-content/ip-geo-api/maxmind/class-maxmind.php:178
904
  msgid "Database file does not exist."
905
  msgstr "データベース・ファイルが見つかりません。"
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2013-2017 tokkonopapa
2
  # This file is distributed under the same license as the IP Geo Block package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: IP Geo Block 3.0.2.2\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ip-geo-block\n"
7
+ "POT-Creation-Date: 2017-04-30 12:56+0900\n"
8
+ "PO-Revision-Date: 2017-04-30 13:27+0900\n"
9
  "Last-Translator: tokkonopapa <tokkonopapa@yahoo.com>\n"
10
  "Language-Team: \n"
11
  "MIME-Version: 1.0\n"
27
  "自国以外から投稿されるスパム、ログインフォーム、さらにゼロデイ攻撃を含む管理"
28
  "領域への悪意あるアクセスからサイトを守ります。"
29
 
30
+ #: admin/class-ip-geo-block-admin.php:160
31
+ msgid "Import settings ?"
32
+ msgstr "設定をインポートしますか?"
33
+
34
+ #: admin/class-ip-geo-block-admin.php:161
35
+ msgid "Create table ?"
36
+ msgstr "テーブルを作成しますか?"
37
+
38
+ #: admin/class-ip-geo-block-admin.php:162
39
+ msgid "Delete table ?"
40
+ msgstr "テーブルを削除しますか?"
41
+
42
+ #: admin/class-ip-geo-block-admin.php:163
43
+ msgid "Clear statistics ?"
44
+ msgstr "統計をクリアしますか?"
45
+
46
+ #: admin/class-ip-geo-block-admin.php:164
47
+ msgid "Clear cache ?"
48
+ msgstr "キャッシュをクリアしますか?"
49
+
50
+ #: admin/class-ip-geo-block-admin.php:165
51
+ msgid "Clear logs ?"
52
+ msgstr "ログをクリアしますか?"
53
+
54
+ #: admin/class-ip-geo-block-admin.php:166
55
+ msgid "This feature is available with HTML5 compliant browsers."
56
+ msgstr "HTML5準拠のブラウザでのみ機能します。"
57
+
58
+ #: admin/class-ip-geo-block-admin.php:193
59
  msgid "Contribute at GitHub"
60
  msgstr "開発に参加"
61
 
62
+ #: admin/class-ip-geo-block-admin.php:210
63
+ #: admin/class-ip-geo-block-admin.php:390
64
  msgid "Settings"
65
  msgstr "設定"
66
 
67
+ #: admin/class-ip-geo-block-admin.php:265
68
+ #: admin/class-ip-geo-block-admin.php:266
69
  msgid "IP Geo Block"
70
  msgstr "IP Geo Block"
71
 
72
+ #: admin/class-ip-geo-block-admin.php:284
73
  msgid "You need WordPress 3.7+."
74
  msgstr "WordPress 3.7&thinsp;以上が必要です。"
75
 
76
+ #: admin/class-ip-geo-block-admin.php:293
77
  #, php-format
78
  msgid ""
79
  "Now downloading geolocation databases in background. After a little while, "
84
  "いた後、あなたの国コードと「<strong>マッチング規則</strong>」を「<a href=\"%s"
85
  "\">検証ルールの設定</a>」で確認して下さい。"
86
 
87
+ #: admin/class-ip-geo-block-admin.php:299
88
  #, php-format
89
  msgid ""
90
  "The &#8220;<strong>Matching rule</strong>&#8221; is not set properly. Please "
93
  "「<strong>マッチング規則</strong>」が正しく設定されていません。「<a href=\"%s"
94
  "\">検証ルールの設定</a>」を確認して下さい。"
95
 
96
+ #: admin/class-ip-geo-block-admin.php:308
97
  msgid "Local database and matching rule have been updated."
98
  msgstr "ローカル・データベースとマッチング規則を更新しました。"
99
 
100
+ #: admin/class-ip-geo-block-admin.php:319
101
+ msgid ""
102
+ "Once you logout, you will be unable to login again because the number of "
103
+ "login attempts reaches the limit."
104
+ msgstr ""
105
+ "あなたのIPアドレスのログイン試行可能回数がリミットに達したため、ログアウトす"
106
+ "ると再びログインする事が出来なくなります。"
107
+
108
+ #: admin/class-ip-geo-block-admin.php:321
109
+ #, php-format
110
+ msgid ""
111
+ "Please execute \"<strong>Clear cache</strong>\" on <a href=\"%s\">Statistics "
112
+ "tab</a> to prevent locking yourself out."
113
+ msgstr ""
114
+ "<a href=\"%s\">「統計」タブ</a>の \"<strong>キャッシュのクリア</strong>\" を"
115
+ "実行し、ロックアウトを回避してください。"
116
+
117
+ #: admin/class-ip-geo-block-admin.php:331
118
  msgid ""
119
  "Once you logout, you will be unable to login again because your country code "
120
  "or IP address is in the blacklist."
122
  "あなたの国コードまたはIPアドレスがブラックリストに含まれているため、ログアウ"
123
  "トすると再びログインする事が出来なくなります。"
124
 
125
+ #: admin/class-ip-geo-block-admin.php:332
126
  msgid ""
127
  "Once you logout, you will be unable to login again because your country code "
128
  "or IP address is not in the whitelist."
130
  "あなたの国コードまたはIPアドレスがホワイトリストに含まれていないため、ログア"
131
  "ウトすると再びログインする事が出来なくなります。"
132
 
133
+ #: admin/class-ip-geo-block-admin.php:335
134
  #, php-format
135
  msgid "Please check your <a href=\"%s\">Validation rule settings</a>."
136
  msgstr "「<a href=\"%s\">検証ルールの設定</a>」を確認して下さい。"
137
 
138
+ #: admin/class-ip-geo-block-admin.php:391
139
  msgid "Statistics"
140
  msgstr "統計"
141
 
142
+ #: admin/class-ip-geo-block-admin.php:392
143
  msgid "Logs"
144
  msgstr "ログ"
145
 
146
+ #: admin/class-ip-geo-block-admin.php:393
147
  msgid "Search"
148
  msgstr "検索"
149
 
150
+ #: admin/class-ip-geo-block-admin.php:394
151
  msgid "Attribution"
152
  msgstr "リンク"
153
 
154
+ #: admin/class-ip-geo-block-admin.php:405
155
  msgid "Toggle all"
156
  msgstr "全てを開閉"
157
 
158
+ #: admin/class-ip-geo-block-admin.php:429
159
  msgid "Thanks for providing these great services for free."
160
  msgstr "これらのすばらしいサービスの提供元に、敬意と感謝の意を表します!"
161
 
162
+ #: admin/class-ip-geo-block-admin.php:430
163
  msgid ""
164
  "(Most browsers will redirect you to each site <a href=\"http://www."
165
  "ipgeoblock.com/etc/referer.html\" title=\"Referer Checker\">without referrer "
169
  "html\" title=\"Referer Checker\">参照元を残さずにリンク先にリダイレクトできま"
170
  "す</a>。)"
171
 
172
+ #: admin/class-ip-geo-block-admin.php:435
173
  msgid "Back to top"
174
  msgstr "トップに戻る"
175
 
176
+ #: admin/class-ip-geo-block-admin.php:527
177
  msgid "Enable"
178
  msgstr "有効"
179
 
180
+ #: admin/class-ip-geo-block-admin.php:840
181
+ #: admin/class-ip-geo-block-admin.php:851
182
+ #: classes/class-ip-geo-block-cron.php:260
183
+ #: classes/class-ip-geo-block-cron.php:318
184
+ #: classes/class-ip-geo-block-opts.php:311
185
  #, php-format
186
  msgid "Unable to write %s. Please check the permission."
187
  msgstr "%s に書き込めません。パーミッションを確認して下さい。"
188
 
189
+ #: admin/class-ip-geo-block-admin.php:841
190
  #, php-format
191
  msgid "Or please refer to %s to set it manually."
192
  msgid_plural "Or please refer to %s to set them manually."
193
  msgstr[0] "あるいは %s を参照し、手動で設定して下さい。"
194
  msgstr[1] "あるいは %s を参照し、手動で設定して下さい。"
195
 
196
+ #: admin/includes/class-admin-ajax.php:60
197
  msgid "n/a"
198
  msgstr "n/a"
199
 
200
+ #: admin/includes/class-admin-ajax.php:63 admin/includes/tab-settings.php:81
201
  msgid "UNKNOWN"
202
  msgstr "不明"
203
 
204
+ #: admin/includes/tab-accesslog.php:22 admin/includes/tab-accesslog.php:82
205
  msgid "Validation logs"
206
  msgstr "検証のログ"
207
 
208
+ #: admin/includes/tab-accesslog.php:31
209
+ msgid "Filter logs"
210
+ msgstr "ログをフィルタ"
211
+
212
+ #: admin/includes/tab-accesslog.php:40
213
+ msgid "Reset"
214
+ msgstr "リセット"
215
+
216
+ #: admin/includes/tab-accesslog.php:47
217
  msgid "Clear logs"
218
  msgstr "ログのクリア"
219
 
220
+ #: admin/includes/tab-accesslog.php:55 admin/includes/tab-statistics.php:171
221
+ #: admin/includes/tab-statistics.php:275
222
  msgid "Clear now"
223
  msgstr "今すぐクリア"
224
 
225
+ #: admin/includes/tab-accesslog.php:63
226
  msgid "Export logs"
227
  msgstr "ログをエクスポート"
228
 
229
+ #: admin/includes/tab-accesslog.php:69 admin/includes/tab-settings.php:1265
230
  msgid "Export to the local file"
231
  msgstr "ローカル・ファイルにエクスポートする"
232
 
233
+ #: admin/includes/tab-accesslog.php:69
234
  msgid "Export csv"
235
  msgstr "CSVをエクスポート"
236
 
237
+ #: admin/includes/tab-accesslog.php:109
238
  #, php-format
239
+ msgid "<dfn title=\"Validation log of request to %s.\">%s</dfn>"
240
+ msgstr "<dfn title=\"%s に対するリクエストの検証ログです。\">%s</dfn>"
241
 
242
+ #: admin/includes/tab-accesslog.php:111 admin/includes/tab-settings.php:368
243
  msgid "Comment post"
244
  msgstr "コメント投稿"
245
 
246
+ #: admin/includes/tab-accesslog.php:112 admin/includes/tab-settings.php:369
247
  msgid "XML-RPC"
248
  msgstr "XML-RPC"
249
 
250
+ #: admin/includes/tab-accesslog.php:113 admin/includes/tab-settings.php:370
251
  msgid "Login form"
252
  msgstr "ログイン・フォーム"
253
 
254
+ #: admin/includes/tab-accesslog.php:114 admin/includes/tab-settings.php:371
255
  msgid "Admin area"
256
  msgstr "管理領域"
257
 
258
+ #: admin/includes/tab-accesslog.php:115 admin/includes/tab-settings.php:373
259
+ msgid "public facing pages"
260
+ msgstr "一般公開ページ"
261
+
262
+ #: admin/includes/tab-accesslog.php:115 admin/includes/tab-settings.php:373
263
+ msgid "Public facing pages"
264
+ msgstr "一般公開ページ"
265
+
266
+ #: admin/includes/tab-accesslog.php:121
267
  msgid "Date"
268
  msgstr "日時"
269
 
270
+ #: admin/includes/tab-accesslog.php:122 admin/includes/tab-geolocation.php:65
271
  #: admin/includes/tab-statistics.php:217
272
  msgid "IP address"
273
  msgstr "IPアドレス"
274
 
275
+ #: admin/includes/tab-accesslog.php:123
276
  msgid "Code"
277
  msgstr "国"
278
 
279
+ #: admin/includes/tab-accesslog.php:124
280
  msgid "Result"
281
  msgstr "判定"
282
 
283
+ #: admin/includes/tab-accesslog.php:125
284
  msgid "Request"
285
  msgstr "リクエスト"
286
 
287
+ #: admin/includes/tab-accesslog.php:126
288
  msgid "User agent"
289
  msgstr "ユーザーエージェント"
290
 
291
+ #: admin/includes/tab-accesslog.php:127
292
  msgid "HTTP headers"
293
  msgstr "HTTPヘッダ"
294
 
295
+ #: admin/includes/tab-accesslog.php:128
296
  msgid "$_POST data"
297
  msgstr "$_POSTデータ"
298
 
299
+ #: admin/includes/tab-accesslog.php:146
300
  msgid ""
301
  "Current selection of [<strong>Record validation logs</strong>] on "
302
  "[<strong>Settings</strong>] tab is [<strong>Disable</strong>]."
304
  "現在[<strong>設定</strong>]タブの[<strong>検証のログを記録</strong>]は"
305
  "[<strong>無効</strong>]が選択されています。"
306
 
307
+ #: admin/includes/tab-accesslog.php:147
308
  msgid ""
309
  "Please select the proper condition to record and analyze the validation logs."
310
  msgstr "検証のログを記録し分析するためには、適切な条件を選択して下さい。"
329
  msgid "Search now"
330
  msgstr "今すぐ検索"
331
 
332
+ #: admin/includes/tab-settings.php:49
333
  msgid "Validation rule settings"
334
  msgstr "検証ルールの設定"
335
 
336
+ #: admin/includes/tab-settings.php:73
337
  msgid ""
338
  "<dfn title=\"You can confirm the appropriate Geolocation APIs and country "
339
+ "code by referring &#8220;Scan country code&#8221;.\">Your IP address / "
340
  "Country</dfn>"
341
  msgstr ""
342
  "<dfn title=\"「国コードを検索する」を参照し、適切な位置情報APIと国コードを設"
343
  "定して下さい。\">あなたのIPアドレス / 国コード</dfn>"
344
 
345
+ #: admin/includes/tab-settings.php:82
346
  msgid "Scan all the APIs you selected at Geolocation API settings"
347
  msgstr "選択された位置情報APIを検索します"
348
 
349
+ #: admin/includes/tab-settings.php:82
350
+ msgid "Scan country code"
351
  msgstr "国コードを検索する"
352
 
353
+ #: admin/includes/tab-settings.php:89
354
  msgid "Whitelist"
355
  msgstr "ホワイトリスト"
356
 
357
+ #: admin/includes/tab-settings.php:90
358
  msgid "Blacklist"
359
  msgstr "ブラックリスト"
360
 
361
+ #: admin/includes/tab-settings.php:94
362
  msgid ""
363
  "Please select either &#8220;Whitelist&#8221; or &#8220;Blacklist&#8221;."
364
  msgstr "「ホワイトリスト」または「ブラックリスト」のいずれかを選択して下さい。"
365
 
366
+ #: admin/includes/tab-settings.php:95
367
  msgid ""
368
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
369
  "empty. All the countries will be blocked in case you put &#8220;XX&#8221; "
373
  "を指定した場合には、全ての国がブロック対象になります。\">国コードのホワイトリ"
374
  "スト</dfn>"
375
 
376
+ #: admin/includes/tab-settings.php:96
377
  msgid ""
378
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
379
  "empty. Please consider to include &#8220;ZZ&#8221; which means UNKNOWN "
382
  "<dfn title=\"空欄の場合、「国コードで遮断」はバイパスされます。また「不明」を"
383
  "表す「ZZ」を含める事を検討して下さい。\">国コードのブラックリスト</dfn>"
384
 
385
+ #: admin/includes/tab-settings.php:100
386
  msgid "(comma separated)"
387
  msgstr "(カンマ区切り)"
388
 
389
+ #: admin/includes/tab-settings.php:101
390
  msgid "(comma or RET separated)"
391
  msgstr "(カンマ、または改行区切り)"
392
 
393
+ #: admin/includes/tab-settings.php:108 admin/includes/tab-settings.php:708
394
  msgid "Matching rule"
395
  msgstr "マッチング規則"
396
 
397
+ #: admin/includes/tab-settings.php:120
398
  msgid ""
399
  "A request from which the country code or IP address is <strong>NOT</strong> "
400
  "in the whitelist will be blocked."
402
  "国コードまたはIPアドレスがホワイトリストに<strong>含まれていない</strong>リク"
403
  "エストを遮断します。"
404
 
405
+ #: admin/includes/tab-settings.php:121
406
  msgid ""
407
  "A request from which the country code or IP address is in the blacklist will "
408
  "be blocked."
410
  "国コードまたはIPアドレスがブラックリストに<strong>含まれている</strong>リクエ"
411
  "ストを遮断します。"
412
 
413
+ #: admin/includes/tab-settings.php:166
414
  msgid ""
415
  "<dfn title=\"e.g. &#8220;192.0.64.0/18&#8221; for Jetpack server, "
416
  "&#8220;69.46.36.0/27&#8221; for WordFence server\">Whitelist of extra IP "
419
  "<dfn title=\"例)192.0.64.0/18(Jetpackサーバー)、69.46.36.0/27(WordFence"
420
  "サーバー)\">国コードに優先して検証するIPアドレスのホワイトリスト</dfn>"
421
 
422
+ #: admin/includes/tab-settings.php:185
423
  msgid ""
424
  "<dfn title=\"Server level access control is recommended (e.g. .htaccess)."
425
  "\">Blacklist of extra IP addresses prior to country code</dfn>"
427
  "<dfn title=\"サーバー・レベルのアクセス制御の使用をお勧めします(例:."
428
  "htaccess)。\">国コードに優先して検証するIPアドレスのブラックリスト</dfn>"
429
 
430
+ #: admin/includes/tab-settings.php:205
431
  msgid ""
432
  "<dfn title=\"e.g. HTTP_X_FORWARDED_FOR\">$_SERVER keys to retrieve extra IP "
433
  "addresses</dfn>"
435
  "<dfn title=\"例)HTTP_X_FORWARDED_FOR\">IPアドレスを追加抽出する&thinsp;"
436
  "$_SERVER&thinsp;のキー</dfn>"
437
 
438
+ #: admin/includes/tab-settings.php:223
439
  msgid ""
440
  "<dfn title=\"It validates malicious signatures independently of &#8220;Block "
441
  "by country&#8221; and &#8220;Prevent Zero-day Exploit&#8221; for the target "
452
  "字化けした場合、クリックして復元して下さい。\"><span id=\"ip-geo-block-cycle"
453
  "\"></span></a>)</nobr>"
454
 
455
+ #: admin/includes/tab-settings.php:240
456
  #, php-format
457
  msgid ""
458
  "<dfn title=\"You can put your original 403.php and so on into your theme "
459
  "directory.\">Response code</dfn> %s"
460
  msgstr ""
461
+ "<dfn title=\"テーマ・ディレクトリには&thinsp;403.php&thinsp;など、独自のファ"
462
+ "イルを設置する事が出来ます。\">レスポンス・コード</dfn> %s"
463
+
464
+ #: admin/includes/tab-settings.php:270
465
+ msgid ""
466
+ "<dfn title=\"Specify the URL for response code 2xx and 3xx. Front-end URL on "
467
+ "your site would not be blocked to prevent loop of redirection even when you "
468
+ "enable [Front-end target settings]. Empty URL is altered to your home."
469
+ "\">Redirect URL</dfn>"
470
+ msgstr ""
471
+ "<dfn title=\"レスポンス・コード&thinsp;2xx&thinsp;、3xx&thinsp;用のリダイレク"
472
+ "ト先&thinsp;URL&thinsp;を指定します。リダイレクトのループを避けるため、自サイ"
473
+ "ト内の&thinsp;URL&thinsp;は「フロントエンドの設定」に関わらず遮断の対象外とな"
474
+ "ります。空欄の場合、サイトのホームが使用されます。\">リダイレクト先&thinsp;"
475
+ "URL</dfn>"
476
+
477
+ #: admin/includes/tab-settings.php:287
478
+ msgid ""
479
+ "<dfn title=\"Specify the message for response code 4xx and 5xx.\">Response "
480
+ "message</dfn>"
481
+ msgstr ""
482
+ "<dfn title=\"レスポンス・コード&thinsp;4xx、5xx&thinsp;用のメッセージを指定し"
483
+ "ます。\">レスポンス・メッセージ</dfn>"
484
 
485
+ #: admin/includes/tab-settings.php:304
486
  msgid ""
487
  "<dfn title=\"Applied to &#8220;XML-RPC&#8221; and &#8220;Login form&#8221;. "
488
  "Lockout period is defined as expiration time at &#8220;Cache settings&#8221;."
492
  "時間は「キャッシュの設定」の「有効時間」で定義されます。\">IPアドレス当たりの"
493
  "ログイン試行可能回数</dfn>"
494
 
495
+ #: admin/includes/tab-settings.php:332
496
  msgid "Select when to run the validation."
497
  msgstr "検証を実行するタイミングを選択します。"
498
 
499
+ #: admin/includes/tab-settings.php:332
500
  msgid "Validation timing"
501
  msgstr "検証のタイミング"
502
 
503
+ #: admin/includes/tab-settings.php:343
504
  msgid "&#8220;init&#8221; action hook"
505
  msgstr "&#8220;init&#8221; アクション・フック"
506
 
507
+ #: admin/includes/tab-settings.php:344
508
  msgid "&#8220;mu-plugins&#8221; (ip-geo-block-mu.php)"
509
  msgstr "&#8220;mu-plugins&#8221; (ip-geo-block-mu.php)"
510
 
511
+ #: admin/includes/tab-settings.php:347
512
  msgid ""
513
  "Validate at &#8220;init&#8221; action hook in the same manner as typical "
514
  "plugins."
516
  "標準的な他のプラグインと同様、init アクション・フックのタイミングで検証を実行"
517
  "します。"
518
 
519
+ #: admin/includes/tab-settings.php:348
520
  msgid ""
521
  "Validate at an earlier phase than other typical plugins. It can reduce load "
522
+ "on server but has <a rel='noreferrer' href='http://www.ipgeoblock.com/codex/"
523
+ "validation-timing.html' title='Validation timing | IP Geo Block'>some "
524
+ "restrictions</a>."
525
  msgstr ""
526
  "標準的な他のプラグインより早いタイミングで検証を実行します。これによりサー"
527
+ "バーの負荷は軽減されますが、<a rel='noreferrer' href='http://www.ipgeoblock."
528
+ "com/codex/validation-timing.html' title='Validation timing | IP Geo Block'>幾"
529
+ "つかの制限事項</a>&thinsp;が生じます。"
530
+
531
+ #: admin/includes/tab-settings.php:360
532
+ msgid "Back-end target settings"
533
+ msgstr "バックエンドの設定"
534
+
535
+ #: admin/includes/tab-settings.php:366
536
+ #, php-format
537
+ msgid "<dfn title=\"Validate request to %s.\">%s</dfn>"
538
+ msgstr "<dfn title=\"%s へのリクエストを検証します。\">%s</dfn>"
539
 
540
+ #: admin/includes/tab-settings.php:372
541
+ msgid "Other areas"
542
+ msgstr "その他のディレクトリ"
543
 
544
+ #: admin/includes/tab-settings.php:391 admin/includes/tab-settings.php:411
545
+ #: admin/includes/tab-settings.php:444 admin/includes/tab-settings.php:450
546
+ #: admin/includes/tab-settings.php:696
547
  msgid "Block by country"
548
  msgstr "国コードで遮断"
549
 
550
+ #: admin/includes/tab-settings.php:410 admin/includes/tab-settings.php:551
551
+ #: admin/includes/tab-settings.php:1029
552
  msgid "Disable"
553
  msgstr "無効"
554
 
555
+ #: admin/includes/tab-settings.php:412
556
  msgid "Completely close"
557
  msgstr "完全に閉鎖"
558
 
559
+ #: admin/includes/tab-settings.php:445
560
  msgid ""
561
  "<dfn title=\"Specify the individual action as a blocking target.\">Target "
562
  "actions</dfn>"
563
  msgstr ""
564
  "<dfn title=\"遮断対象とするアクションを指定します。\">対象アクション</dfn>"
565
 
566
+ #: admin/includes/tab-settings.php:451
567
  msgid "Prevent Zero-day Exploit"
568
  msgstr "ゼロデイ攻撃を遮断"
569
 
570
+ #: admin/includes/tab-settings.php:455
571
  msgid ""
572
  "It will block a request related to the services for both public facing pages "
573
  "and the dashboard."
574
  msgstr ""
575
  "一般公開ページとダッシュボード向けサービスに関連するリクエストを遮断します。"
576
 
577
+ #: admin/includes/tab-settings.php:456
578
  msgid ""
579
  "Regardless of the country code, it will block a malicious request related to "
580
  "the services only for the dashboard."
582
  "国コードに拘らず、ダッシュボード向けサービスだけに関連する悪意のあるリクエス"
583
  "トを遮断します。"
584
 
585
+ #: admin/includes/tab-settings.php:507
586
+ msgid "for logged-in users"
587
+ msgstr "ログインユーザー用"
588
+
589
+ #: admin/includes/tab-settings.php:508
590
+ msgid "for non logged-in users"
591
+ msgstr "一般訪問者用"
592
+
593
+ #: admin/includes/tab-settings.php:527
594
  msgid "Admin ajax/post"
595
  msgstr "管理領域&thinsp;ajax/post"
596
 
597
+ #: admin/includes/tab-settings.php:540
598
+ msgid ""
599
+ "<dfn title=\"Select actions that cause undesired blocking to skip &#8220;"
600
+ "Prevent Zero-day Exploit&#8221; for logged-in users and &#8220;Block by "
601
+ "country&#8221; for non logged-in users. If you can not find the right one in "
602
+ "the candidate list, you can put a certain page name (&#8220;&hellip;&#8221; "
603
+ "in &#8220;page=&hellip;&#8221;) or action name (&#8220;&hellip;&#8221; in "
604
+ "&#8220;action=&hellip;&#8221;), which would be implemented with a non "
605
+ "WordPress standard way, into the field to specify the request.\">Exceptions</"
606
+ "dfn>"
607
+ msgstr ""
608
+ "<dfn title=\"検証対象から「ゼロデイ攻撃を遮断(ログインユーザー用)」、「国"
609
+ "コードで遮断(一般訪問者用)」を除外するアクション名を選択してください。"
610
+ "WordPress&thinsp;の標準的な方法で実装されていない場合は「候補アクション」に現"
611
+ "れないため、リクエストを特定するページ名(&#8220;page=&hellip;&#8221; の "
612
+ "&#8220;&hellip;&#8221; 部分)かアクション名(&#8220;action=&hellip;&#8221; "
613
+ "の &#8220;&hellip;&#8221; 部分)をテキストで指定してください。\">除外する項目"
614
+ "</dfn>"
615
+
616
+ #: admin/includes/tab-settings.php:545
617
+ msgid "Candidate actions"
618
+ msgstr "候補アクション"
619
+
620
+ #: admin/includes/tab-settings.php:553
621
  #, php-format
622
  msgid ""
623
  "Regardless of the country code, it will block a malicious request to <code>"
626
  "国コードに拘らず、<code>%s&hellip;/*.php</code>への悪意のあるリクエストを遮断"
627
  "します。"
628
 
629
+ #: admin/includes/tab-settings.php:554
630
  #, php-format
631
  msgid ""
632
+ "It configures &#8220;%s&#8221; to validate a request to the PHP file which "
633
  "does not load WordPress core."
634
  msgstr ""
635
  "WordPressコアを読み込まないPHPファイルへのリクエストを検証対象とするため"
636
  "に、%s を設定します。"
637
 
638
+ #: admin/includes/tab-settings.php:555
639
  msgid ""
640
  "<dfn title=\"Select the item which causes undesired blocking in order to "
641
  "exclude from the validation target. Grayed item indicates &#8220;"
645
  "す。灰色で表示された項目は、「非アクティブ」であることを示しています。\">除外"
646
  "する項目</dfn>"
647
 
648
+ #: admin/includes/tab-settings.php:591 admin/includes/tab-settings.php:644
649
  msgid "Force to load WP core"
650
  msgstr "WPコアの読み込みを強制"
651
 
652
+ #: admin/includes/tab-settings.php:596
653
  msgid "Plugins area"
654
  msgstr "プラグイン領域"
655
 
656
+ #: admin/includes/tab-settings.php:649
657
  msgid "Themes area"
658
  msgstr "テーマ領域"
659
 
660
+ #: admin/includes/tab-settings.php:677
661
+ msgid "Front-end target settings"
662
+ msgstr "フロントエンドの設定"
663
+
664
+ #: admin/includes/tab-settings.php:701
665
+ msgid "Follow &#8220;Validation rule settings&#8221;"
666
+ msgstr "「検証ルールの設定」に従う"
667
+
668
+ #: admin/includes/tab-settings.php:758
669
+ msgid ""
670
+ "<dfn title=\"Specify the individual page as a blocking target.\">Page</dfn>"
671
+ msgstr "<dfn title=\"特定のページを遮断対象に指定します。\">ページ</dfn>"
672
+
673
+ #: admin/includes/tab-settings.php:770
674
+ msgid ""
675
+ "<dfn title=\"Specify the individual post type on a single page as a blocking "
676
+ "target.\">Post type</dfn>"
677
+ msgstr ""
678
+ "<dfn title=\"特定の投稿タイプのシングルページを遮断対象に指定します。\">投稿"
679
+ "タイプ</dfn>"
680
+
681
+ #: admin/includes/tab-settings.php:782
682
+ msgid ""
683
+ "<dfn title=\"Specify the individual category on a single page or archive "
684
+ "page as a blocking target.\">Category</dfn>"
685
+ msgstr ""
686
+ "<dfn title=\"特定のカテゴリを含むシングルページかアーカイブページを遮断対象に"
687
+ "指定します。\">カテゴリ</dfn>"
688
+
689
+ #: admin/includes/tab-settings.php:794
690
+ msgid ""
691
+ "<dfn title=\"Specify the individual tag on a single page or archive page as "
692
+ "a blocking target.\">Tag</dfn>"
693
+ msgstr ""
694
+ "<dfn title=\"特定のタグを含むシングルページかアーカイブページを遮断対象に指定"
695
+ "します。\">タグ</dfn>"
696
+
697
+ #: admin/includes/tab-settings.php:809
698
+ msgid "Specify the validation target on front-end."
699
+ msgstr "フロント・エンドの検証対象を設定します。"
700
+
701
+ #: admin/includes/tab-settings.php:809
702
+ msgid "Validation target"
703
+ msgstr "検証対象"
704
+
705
+ #: admin/includes/tab-settings.php:820
706
+ msgid "All requests"
707
+ msgstr "全てのリクエスト"
708
+
709
+ #: admin/includes/tab-settings.php:821
710
+ msgid "Specify the targets"
711
+ msgstr "ターゲットを指定"
712
+
713
+ #: admin/includes/tab-settings.php:824
714
+ msgid ""
715
+ "Notice that &#8220;Validation timing&#8221; is deferred till &#8220;"
716
+ "wp&#8221; action hook. It means that this feature would not be compatible "
717
+ "with any page caching."
718
+ msgstr ""
719
+ "「検証のタイミング」が &#8220;wp&#8221; アクション・フックまで遅延されます。"
720
+ "これにより、ページ・キャッシュとの互換性がなくなることに注意してください。"
721
+
722
+ #: admin/includes/tab-settings.php:834
723
+ msgid ""
724
+ "A part of user agent string and a qualification connected with a separator "
725
+ "that indicates an applicable rule and can be &#8220;:&#8221; (pass) or "
726
+ "&#8220;#&#8221; (block). A &#8220;qualification&#8221; can be &#8220;"
727
+ "DNS&#8221;, &#8220;FEED&#8221;, country code or IP address with CIDR. A "
728
+ "negative operator &#8220;!&#8221; can be placed just before a &#8220;"
729
+ "qualification&#8221;."
730
+ msgstr ""
731
+ "適用されるルールを表す記号(「:」は通過、「#」は遮断)で区切られたユーザー"
732
+ "エージェント文字列の一部と「条件」のペアです。「条件」には「DNS」、「FEED」、"
733
+ "国コード、または&nbsp;IPアドレス(CIDR記法)が使えます。また否定を表す記号"
734
+ "「!」を「条件」の直前に配置する事が出来ます。"
735
+
736
+ #: admin/includes/tab-settings.php:834
737
+ msgid "UA string and qualification"
738
+ msgstr "ユーザーエージェント文字列と条件"
739
+
740
+ #: admin/includes/tab-settings.php:853
741
+ msgid "Specify the name of action that is invariably blocked."
742
+ msgstr "遮断されるアクション名を指定します。"
743
+
744
+ #: admin/includes/tab-settings.php:853
745
+ msgid "Excluded actions"
746
+ msgstr "除外するアクション"
747
+
748
+ #: admin/includes/tab-settings.php:872
749
+ msgid ""
750
+ "It enables to simulate validation without deployment. The results can be "
751
+ "found at &#8220;Public facing pages&#8221; in Logs."
752
+ msgstr ""
753
+ "機能を有効にする事なくリクエストの検証をシミュレートします。結果はログで確認"
754
+ "する事が出来ます。"
755
+
756
+ #: admin/includes/tab-settings.php:872
757
+ msgid "Simulation mode"
758
+ msgstr "シミュレーション・モード"
759
+
760
+ #: admin/includes/tab-settings.php:891
761
  msgid "Geolocation API settings"
762
  msgstr "位置情報APIの設定"
763
 
764
+ #: admin/includes/tab-settings.php:900
765
  msgid ""
766
  "<dfn title=\"Cache and local database are scanned at the top priority.\">API "
767
  "selection and key settings</dfn>"
769
  "<dfn title=\"キャッシュとローカルのデータベースが最優先で検索されます。\">API"
770
  "の選択とキーの設定</dfn>"
771
 
772
+ #: admin/includes/tab-settings.php:922
773
  #, php-format
774
  msgid ""
775
+ "Can not find geolocation API libraries in <code>%s</code>. It seems to have "
776
+ "failed downloading <a rel=\"noreferrer\" href=\"https://github.com/"
777
+ "tokkonopapa/WordPress-IP-Geo-API/archive/master.zip\" title=\"Download the "
778
+ "contents of tokkonopapa/WordPress-IP-Geo-API as a zip file\">ZIP file</a> "
779
+ "from <a rel=\"noreferrer\" href=\"https://github.com/tokkonopapa/WordPress-"
780
+ "IP-Geo-API\" title=\"tokkonopapa/WordPress-IP-Geo-API - GitHub\">WordPress-"
781
+ "IP-Geo-API</a>. Please refer to the <a rel=\"noreferrer\" href=\"http://www."
782
+ "ipgeoblock.com/codex/how-to-fix-permission-troubles.html\" title=\"How can I "
783
+ "fix permission troubles? | IP Geo Block\">FAQ</a> to install <code>ip-geo-"
784
+ "api</code> with write permission."
785
+ msgstr ""
786
+ "<code>%s</code> に位置情報APIライブラリが見つかりません。<a rel=\"noreferrer"
787
+ "\" href=\"https://github.com/tokkonopapa/WordPress-IP-Geo-API\" title="
788
+ "\"tokkonopapa/WordPress-IP-Geo-API - GitHub\">WordPress-IP-Geo-API</a> から "
789
+ "<a rel=\"noreferrer\" href=\"https://github.com/tokkonopapa/WordPress-IP-Geo-"
790
  "API/archive/master.zip\" title=\"Download the contents of tokkonopapa/"
791
+ "WordPress-IP-Geo-API as a zip file\">ZIP file</a> のダウンロードに失敗したよ"
792
+ "うです。<a rel=\"noreferrer\" href=\"http://www.ipgeoblock.com/codex/how-to-"
793
+ "fix-permission-troubles.html\" title=\"How can I fix permission troubles? | "
794
+ "IP Geo Block\">FAQ</a> を参照し、適切な書き込み権限と共に <code>ip-geo-api</"
795
+ "code> をインストールしてください。"
796
+
797
+ #: admin/includes/tab-settings.php:931
 
 
 
 
 
 
798
  msgid "Local database settings"
799
  msgstr "ローカル・データベースの設定"
800
 
801
+ #: admin/includes/tab-settings.php:946
802
  msgid "database"
803
  msgstr "ファイル"
804
 
805
+ #: admin/includes/tab-settings.php:947 classes/class-ip-geo-block-cron.php:370
806
  #, php-format
807
  msgid "Last update: %s"
808
  msgstr "最終更新:%s"
809
 
810
+ #: admin/includes/tab-settings.php:956
811
  msgid "Auto updating (once a month)"
812
  msgstr "自動更新(月1回)"
813
 
814
+ #: admin/includes/tab-settings.php:973
815
  msgid "Download database"
816
  msgstr "データベースのダウンロード"
817
 
818
+ #: admin/includes/tab-settings.php:981
819
  msgid "Download now"
820
  msgstr "今すぐダウンロード"
821
 
822
+ #: admin/includes/tab-settings.php:993
823
  msgid "Record settings"
824
  msgstr "記録の設定"
825
 
826
+ #: admin/includes/tab-settings.php:1002
827
  msgid "Record validation statistics"
828
  msgstr "検証の統計を記録"
829
 
830
+ #: admin/includes/tab-settings.php:1018
831
  msgid "Record validation logs"
832
  msgstr "検証のログを記録"
833
 
834
+ #: admin/includes/tab-settings.php:1030
835
  msgid "Only when blocked"
836
  msgstr "遮断時に記録"
837
 
838
+ #: admin/includes/tab-settings.php:1031
839
  msgid "Only when passed"
840
  msgstr "通過時に記録"
841
 
842
+ #: admin/includes/tab-settings.php:1032
843
  msgid "Unauthenticated user"
844
  msgstr "未認証ユーザーを記録"
845
 
846
+ #: admin/includes/tab-settings.php:1033
847
  msgid "Authenticated user"
848
  msgstr "認証済ユーザーを記録"
849
 
850
+ #: admin/includes/tab-settings.php:1034
851
  msgid "All of validation"
852
  msgstr "すべての検証を記録"
853
 
854
+ #: admin/includes/tab-settings.php:1043
855
  msgid "Recording period of the logs (days)"
856
  msgstr "ログの記録期間(日)"
857
 
858
+ #: admin/includes/tab-settings.php:1059
859
  msgid "Maximum length of logs for each target"
860
+ msgstr "ログの記録最大数"
861
 
862
+ #: admin/includes/tab-settings.php:1076
863
  msgid ""
864
  "<dfn title=\"e.g. action, comment, log, pwd\">$_POST keys to be recorded "
865
  "with their values in logs</dfn>"
867
  "<dfn title=\"例)action, comment, log, pwd\">ログに記録する際に内容を展開する"
868
  "$_POSTのキー</dfn>"
869
 
870
+ #: admin/includes/tab-settings.php:1094
871
  msgid "<dfn title=\"e.g. 123.456.789.***\">Anonymize IP address</dfn>"
872
  msgstr "<dfn title=\"例)123.456.789.***\">IPアドレスを匿名化する</dfn>"
873
 
874
+ #: admin/includes/tab-settings.php:1112
875
+ msgid "IP address cache settings"
876
+ msgstr "IPアドレスのキャッシュ設定"
877
 
878
+ #: admin/includes/tab-settings.php:1121
879
  #, php-format
880
  msgid ""
881
  "<dfn title=\"If user authentication fails consecutively %d times, subsequent "
885
  "<dfn title=\"ユーザ認証が連続%d回失敗した場合も、以降のログインがこの期間だけ"
886
  "(ガベージコレクション周期を含む)禁止されます。\">有効時間 [sec]</dfn>"
887
 
888
+ #: admin/includes/tab-settings.php:1137
889
+ msgid "Garbage collection period [sec]"
890
+ msgstr "ガベージコレクション周期 [秒]"
891
+
892
+ #: admin/includes/tab-settings.php:1154
893
  msgid "Number of entries to be displayed in cache"
894
  msgstr "「キャッシュ中のIPアドレス」に表示する最大数"
895
 
896
+ #: admin/includes/tab-settings.php:1173
897
  msgid "Submission settings"
898
  msgstr "投稿時の設定"
899
 
900
+ #: admin/includes/tab-settings.php:1185
901
  msgid "The whole will be wrapped by &lt;p&gt; tag. Allowed tags: "
902
  msgstr "全体が&lt;p&gt;タグで囲われます。使用可能タグ:"
903
 
904
+ #: admin/includes/tab-settings.php:1185
905
  msgid "Message on comment form"
906
  msgstr "投稿フォーム上のメッセージ"
907
 
908
+ #: admin/includes/tab-settings.php:1197
909
  msgid "None"
910
  msgstr "なし"
911
 
912
+ #: admin/includes/tab-settings.php:1198
913
  msgid "Top"
914
  msgstr "上部"
915
 
916
+ #: admin/includes/tab-settings.php:1199
917
  msgid "Bottom"
918
  msgstr "下部"
919
 
920
+ #: admin/includes/tab-settings.php:1211
921
  msgid "Plugin settings"
922
  msgstr "プラグインの設定"
923
 
924
+ #: admin/includes/tab-settings.php:1220
925
  msgid "Remove all settings at uninstallation"
926
  msgstr "アンインストール時に全設定を削除"
927
 
928
+ #: admin/includes/tab-settings.php:1238
929
  msgid ""
930
  "<dfn title=\"Valid key for Google Maps JavaScript API\">Google Maps API key</"
931
  "dfn>"
933
  "<dfn title=\"Google Maps JavaScript API に有効なキー\">Google Maps API キー</"
934
  "dfn>"
935
 
936
+ #: admin/includes/tab-settings.php:1252
937
  msgid ""
938
  "You need to click the &#8220;Save Changes&#8221; button for imported "
939
  "settings to take effect."
941
  "インポートされた設定を有効にするには、「変更を保存」ボタンをクリックする必要"
942
  "があります。"
943
 
944
+ #: admin/includes/tab-settings.php:1258
945
  msgid "Export / Import settings"
946
  msgstr "設定のエクスポート、インポート"
947
 
948
+ #: admin/includes/tab-settings.php:1265
949
  msgid "Export settings"
950
  msgstr "エクスポート"
951
 
952
+ #: admin/includes/tab-settings.php:1266
953
  msgid "Import from the local file"
954
  msgstr "ローカル・ファイルからインポートします"
955
 
956
+ #: admin/includes/tab-settings.php:1266
957
  msgid "Import settings"
958
  msgstr "インポート"
959
 
960
+ #: admin/includes/tab-settings.php:1275
961
  msgid "Import pre-defined settings"
962
  msgstr "プリセットのインポート"
963
 
964
+ #: admin/includes/tab-settings.php:1282
965
+ msgid ""
966
+ "Import the preferred settings mainly for the &#8220;Back-end target "
967
+ "settings&#8221;"
968
+ msgstr "主に「バックエンドの設定」に関する推奨の設定値をインポートします"
969
+
970
+ #: admin/includes/tab-settings.php:1282
971
+ msgid "Best settings"
972
+ msgstr "ベストな設定"
973
+
974
+ #: admin/includes/tab-settings.php:1283
975
  msgid ""
976
  "Import the default settings to revert to the &#8220;Right after "
977
  "installing&#8221; state"
978
  msgstr "インストール直後の状態に戻すための設定値をインポートします"
979
 
980
+ #: admin/includes/tab-settings.php:1283
981
  msgid "Default settings"
982
  msgstr "初期設定"
983
 
984
+ #: admin/includes/tab-settings.php:1293
 
 
 
 
 
 
 
 
 
 
985
  msgid "Delete DB table for validation logs"
986
  msgstr "検証のログ用データベース・テーブルの削除"
987
 
988
+ #: admin/includes/tab-settings.php:1301
989
  msgid "Delete now"
990
  msgstr "今すぐ削除"
991
 
992
+ #: admin/includes/tab-settings.php:1309
993
  msgid "Create DB table for validation logs"
994
  msgstr "検証のログ用データベース・テーブルの作成"
995
 
996
+ #: admin/includes/tab-settings.php:1317
997
  msgid "Create now"
998
  msgstr "今すぐ作成"
999
 
1000
+ #: admin/includes/tab-settings.php:1327
1001
+ msgid ""
1002
+ "<dfn title=\"Please copy &amp; paste when submitting your issue to support "
1003
+ "forum.\">Installation information</dfn><br />[ <a rel=\"noreferrer\" href="
1004
+ "\"https://wordpress.org/support/plugin/ip-geo-block\" title=\"WordPress "
1005
+ "&#8250; Support &raquo; IP Geo Block\">support forum</a> ]"
1006
+ msgstr ""
1007
+ "<dfn title=\"フォーラムに問題を投稿する際、コピーして張り付けてください。\">"
1008
+ "インストール情報</dfn><br />[ <a rel=\"noreferrer\" href=\"https://wordpress."
1009
+ "org/support/plugin/ip-geo-block\" title=\"WordPress &#8250; Support &raquo; "
1010
+ "IP Geo Block\">サポートフォーラム</a> ]"
1011
+
1012
+ #: admin/includes/tab-settings.php:1334
1013
+ msgid "Show PHP, WordPress, theme and plugins information."
1014
+ msgstr "PHP、WordPress、テーマ、プラグインの情報を表示します。"
1015
+
1016
+ #: admin/includes/tab-settings.php:1334
1017
+ msgid "Show information"
1018
+ msgstr "情報を表示"
1019
+
1020
+ #: admin/includes/tab-settings.php:1348
1021
  msgid ""
1022
+ "To enhance the protection ability, please refer to &#8220;<a rel=\"noreferrer"
1023
+ "\" href=\"http://www.ipgeoblock.com/codex/the-best-practice-for-target-"
1024
+ "settings.html\" title=\"The best practice for target settings | IP Geo Block"
1025
+ "\">The best practice for target settings</a>&#8221;."
1026
  msgstr ""
1027
+ "防御性能をより高めるための設定については、&#8220;<a rel=\"noreferrer\" href="
1028
+ "\"http://www.ipgeoblock.com/codex/the-best-practice-for-target-settings.html"
1029
+ "\" title=\"The best practice for target settings | IP Geo Block\">The best "
1030
+ "practice fortarget settings</a>&#8220;&thinsp;を参照してください。"
1031
 
1032
+ #: admin/includes/tab-settings.php:1349
1033
  msgid ""
1034
+ "If you have any troubles with these, please check FAQ at <a rel=\"noreferrer"
1035
+ "\" href=\"https://wordpress.org/plugins/ip-geo-block/faq/\" title=\"IP Geo "
1036
+ "Block &mdash; WordPress Plugins\">WordPress.org</a> and <a rel=\"noreferrer"
1037
+ "\" href=\"http://www.ipgeoblock.com/codex/#faq\" title=\"Codex | IP Geo Block"
1038
+ "\">Codex</a>."
1039
  msgstr ""
1040
+ "何か問題が発生した場合は、<a rel=\"noreferrer\" href=\"https://wordpress.org/"
1041
+ "plugins/ip-geo-block/faq/\" title=\"IP Geo Block &mdash; WordPress Plugins"
1042
+ "\">WordPress.org</a> <a rel=\"noreferrer\" href=\"http://www.ipgeoblock."
1043
+ "com/codex/#faq\" title=\"Codex | IP Geo Block\">Codex</a> の FAQ を参照してく"
1044
+ "ださい。"
1045
 
1046
+ #: admin/includes/tab-settings.php:1356
1047
  msgid ""
1048
  "While Maxmind and IP2Location will fetch the local database, others will "
1049
  "pass an IP address to the APIs via HTTP."
1051
  "MaxmindとIP2Locationはローカルのデータベースを検索しますが、他はHTTPを介して"
1052
  "APIにIPアドレスを渡します。"
1053
 
1054
+ #: admin/includes/tab-settings.php:1357
1055
  msgid ""
1056
  "Please select the appropriate APIs to fit the privacy law in your country."
1057
  msgstr "自国のプライバシー関連法規に合わせ、適切なAPIを選択して下さい。"
1058
 
1059
+ #: admin/includes/tab-settings.php:1364
1060
+ msgid ""
1061
+ "Please refer to the document &#8220;<a rel=\"noreferrer\" href=\"http://www."
1062
+ "ipgeoblock.com/codex/#blocking-on-front-end\" title=\"Codex | IP Geo Block"
1063
+ "\">Blocking on front-end</a>&#8221; for details, including restrictions on "
1064
+ "cache plugin."
1065
+ msgstr ""
1066
+ "キャッシュ・プラグインに関する制限事項を含め、詳しくはドキュメント &#8220;<a "
1067
+ "rel=\"noreferrer\" href=\"http://www.ipgeoblock.com/codex/#blocking-on-front-"
1068
+ "end\" title=\"Codex | IP Geo Block\">Blocking on front-end</a>&#8221; を参照"
1069
+ "してください。"
1070
+
1071
+ #: admin/includes/tab-settings.php:1365
1072
+ msgid ""
1073
+ "If you find any issues or have something to suggest, please feel free to "
1074
+ "open an issue at <a rel=\"noreferrer\" href=\"https://wordpress.org/support/"
1075
+ "plugin/ip-geo-block\" title=\"WordPress &#8250; Support &raquo; IP Geo Block"
1076
+ "\">support forum</a>."
1077
+ msgstr ""
1078
+ "問題を発見したり改善の提案がある場合は、お気軽に <a rel=\"noreferrer\" href="
1079
+ "\"https://wordpress.org/support/plugin/ip-geo-block\" title=\"WordPress "
1080
+ "&#8250; Support &raquo; IP Geo Block\">サポートフォーラム</a> に投稿をお願い"
1081
+ "します。"
1082
+
1083
+ #: admin/includes/tab-settings.php:1372
1084
+ msgid ""
1085
+ "Please refer to the document &#8220;<a rel=\"noreferrer\" href=\"http://www."
1086
+ "ipgeoblock.com/codex/record-settings-and-logs.html\" title=\"Codex | IP Geo "
1087
+ "Block\">Record settings and logs</a>&#8221; for details."
1088
+ msgstr ""
1089
+ "詳しくは &#8220;<a rel=\"noreferrer\" href=\"http://www.ipgeoblock.com/codex/"
1090
+ "record-settings-and-logs.html\" title=\"Codex | IP Geo Block\">Record "
1091
+ "settings and logs</a>&#8221; を参照ください。"
1092
+
1093
  #: admin/includes/tab-statistics.php:24 admin/includes/tab-statistics.php:184
1094
  msgid "Statistics of validation"
1095
  msgstr "検証の統計"
1142
  msgid "Elapsed [sec] / Calls"
1143
  msgstr "経過時間 [sec] / 回数"
1144
 
1145
+ #: admin/includes/tab-statistics.php:252
1146
  msgid "IP address in cache"
1147
  msgstr "キャッシュ中のIPアドレス"
1148
 
1149
+ #: admin/includes/tab-statistics.php:267
1150
  msgid "Clear cache"
1151
  msgstr "キャッシュのクリア"
1152
 
1153
+ #: admin/includes/tab-statistics.php:286
1154
  msgid ""
1155
  "Current setting of [<strong>Record validation statistics</strong>] on "
1156
  "[<strong>Settings</strong>] tab is not selected [<strong>Enable</strong>]."
1158
  "現在[<strong>設定</strong>]タブの[<strong>検証の統計を記録</strong>]は"
1159
  "[<strong>有効</strong>]が選択されていません。"
1160
 
1161
+ #: admin/includes/tab-statistics.php:287
1162
  msgid ""
1163
  "Please set the proper condition to record and analyze the validation "
1164
  "statistics."
1165
  msgstr "検証の統計を記録し分析するためには、適切な条件を設定して下さい。"
1166
 
1167
+ #: classes/class-ip-geo-block-apis.php:651
1168
  msgid ""
1169
  "You need to select at least one IP geolocation service. Otherwise "
1170
  "<strong>you'll be blocked</strong> after the cache expires."
1172
  "少なくとも1つ以上の位置情報サービスを選択して下さい。未選択の場合、キャッシュ"
1173
  "の有効期限切れと共にロックアウトされます。"
1174
 
1175
+ #: classes/class-ip-geo-block-cron.php:227
1176
+ msgid "Your database file is up-to-date."
1177
+ msgstr "データベース・ファイルは最新です。"
1178
+
1179
+ #: classes/class-ip-geo-block-cron.php:255
1180
+ #: classes/class-ip-geo-block-cron.php:313
1181
+ #, php-format
1182
+ msgid "Unable to read %s. Please check the permission."
1183
+ msgstr "%s が読めません。パーミッションを確認して下さい。"
1184
+
1185
+ #: classes/class-ip-geo-block-cron.php:265
1186
+ #: classes/class-ip-geo-block-cron.php:323
1187
+ #, php-format
1188
+ msgid "Can't lock %s. Please try again after a while."
1189
+ msgstr "%s をロックできません。パーミッションを確認して下さい。"
1190
+
1191
+ #: classes/class-ip-geo-block-cron.php:293
1192
+ #, php-format
1193
+ msgid "Unable to read %s. Please check permission."
1194
+ msgstr "%sを読み込むことが出来ません。パーミションをチェックしてください。"
1195
+
1196
+ #: classes/class-ip-geo-block-cron.php:302
1197
+ #, php-format
1198
+ msgid "Unable to write %s. Please check permission."
1199
+ msgstr "%sに書き込むことが出来ません。パーミションをチェックしてください。"
1200
+
1201
+ #: classes/class-ip-geo-block-cron.php:335
1202
+ msgid "gz or zip is not supported on your system."
1203
+ msgstr "gz または zip がサポートされていません。"
1204
+
1205
+ #: classes/class-ip-geo-block-logs.php:149
1206
  #, php-format
1207
  msgid ""
1208
  "Creating a DB table %s had failed. Once de-activate this plugin, and then "
1209
  "activate again."
1210
  msgstr ""
1211
+ "%s 用のテーブルが作成されていません。一旦このプラグインを無効化し、再度有効化"
1212
  "して下さい。"
1213
 
1214
+ #: wp-content/ip-geo-api/ip2location/class-ip2location.php:157
1215
+ #: wp-content/ip-geo-api/ip2location/class-ip2location.php:186
1216
+ #: wp-content/ip-geo-api/maxmind/class-maxmind.php:171
1217
+ #: wp-content/ip-geo-api/maxmind/class-maxmind.php:200
 
 
 
 
 
 
 
 
 
1218
  msgid "Database file does not exist."
1219
  msgstr "データベース・ファイルが見つかりません。"
1220
+
1221
+ #: wp-content/mu-plugins/ip-geo-block-mu.php:72
1222
+ #, php-format
1223
+ msgid ""
1224
+ "Can't find IP Geo Block in your plugins directory. Please remove <code>%s</"
1225
+ "code> or re-install %s."
1226
+ msgstr ""
1227
+ "プラグイン・ディレクトリにIP Geo Blockが見つかりません。<code>%s</code>を削除"
1228
+ "するか、%sを再インストールしてください。"
languages/ip-geo-block.mo CHANGED
Binary file
languages/ip-geo-block.po CHANGED
@@ -1,11 +1,11 @@
1
- # Copyright (C) 2013-2016 tokkonopapa
2
  # This file is distributed under the same license as the IP Geo Block package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: IP Geo Block 2.2.9.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ip-geo-block\n"
7
- "POT-Creation-Date: 2016-11-12 15:12+0900\n"
8
- "PO-Revision-Date: 2016-11-12 15:14+0900\n"
9
  "Last-Translator: tokkonopapa <tokkonopapa@yahoo.com>\n"
10
  "Language-Team: \n"
11
  "MIME-Version: 1.0\n"
@@ -25,25 +25,53 @@ msgid ""
25
  "posted from outside your nation, and also prevents zero-day exploit."
26
  msgstr ""
27
 
28
- #: admin/class-ip-geo-block-admin.php:185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  msgid "Contribute at GitHub"
30
  msgstr ""
31
 
32
- #: admin/class-ip-geo-block-admin.php:202
33
- #: admin/class-ip-geo-block-admin.php:356
34
  msgid "Settings"
35
  msgstr ""
36
 
37
- #: admin/class-ip-geo-block-admin.php:248
38
- #: admin/class-ip-geo-block-admin.php:249
39
  msgid "IP Geo Block"
40
  msgstr ""
41
 
42
- #: admin/class-ip-geo-block-admin.php:270
43
  msgid "You need WordPress 3.7+."
44
  msgstr ""
45
 
46
- #: admin/class-ip-geo-block-admin.php:278
47
  #, php-format
48
  msgid ""
49
  "Now downloading geolocation databases in background. After a little while, "
@@ -51,182 +79,212 @@ msgid ""
51
  "strong>&#8221; at <a href=\"%s\">Validation rule settings</a>."
52
  msgstr ""
53
 
54
- #: admin/class-ip-geo-block-admin.php:284
55
  #, php-format
56
  msgid ""
57
  "The &#8220;<strong>Matching rule</strong>&#8221; is not set properly. Please "
58
  "confirm it at <a href=\"%s\">Validation rule settings</a>."
59
  msgstr ""
60
 
61
- #: admin/class-ip-geo-block-admin.php:293
62
  msgid "Local database and matching rule have been updated."
63
  msgstr ""
64
 
65
- #: admin/class-ip-geo-block-admin.php:304
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  msgid ""
67
  "Once you logout, you will be unable to login again because your country code "
68
  "or IP address is in the blacklist."
69
  msgstr ""
70
 
71
- #: admin/class-ip-geo-block-admin.php:305
72
  msgid ""
73
  "Once you logout, you will be unable to login again because your country code "
74
  "or IP address is not in the whitelist."
75
  msgstr ""
76
 
77
- #: admin/class-ip-geo-block-admin.php:308
78
  #, php-format
79
  msgid "Please check your <a href=\"%s\">Validation rule settings</a>."
80
  msgstr ""
81
 
82
- #: admin/class-ip-geo-block-admin.php:357
83
  msgid "Statistics"
84
  msgstr ""
85
 
86
- #: admin/class-ip-geo-block-admin.php:358
87
  msgid "Logs"
88
  msgstr ""
89
 
90
- #: admin/class-ip-geo-block-admin.php:359
91
  msgid "Search"
92
  msgstr ""
93
 
94
- #: admin/class-ip-geo-block-admin.php:360
95
  msgid "Attribution"
96
  msgstr ""
97
 
98
- #: admin/class-ip-geo-block-admin.php:372
99
  msgid "Toggle all"
100
  msgstr ""
101
 
102
- #: admin/class-ip-geo-block-admin.php:396
103
  msgid "Thanks for providing these great services for free."
104
  msgstr ""
105
 
106
- #: admin/class-ip-geo-block-admin.php:397
107
  msgid ""
108
  "(Most browsers will redirect you to each site <a href=\"http://www."
109
  "ipgeoblock.com/etc/referer.html\" title=\"Referer Checker\">without referrer "
110
  "when you click the link</a>.)"
111
  msgstr ""
112
 
113
- #: admin/class-ip-geo-block-admin.php:402
114
  msgid "Back to top"
115
  msgstr ""
116
 
117
- #: admin/class-ip-geo-block-admin.php:494
118
  msgid "Enable"
119
  msgstr ""
120
 
121
- #: admin/class-ip-geo-block-admin.php:789
122
- #: admin/class-ip-geo-block-admin.php:802
123
- #: classes/class-ip-geo-block-opts.php:257
124
- #: classes/class-ip-geo-block-util.php:114
 
125
  #, php-format
126
  msgid "Unable to write %s. Please check the permission."
127
  msgstr ""
128
 
129
- #: admin/class-ip-geo-block-admin.php:790
130
  #, php-format
131
  msgid "Or please refer to %s to set it manually."
132
  msgid_plural "Or please refer to %s to set them manually."
133
  msgstr[0] ""
134
  msgstr[1] ""
135
 
136
- #: admin/includes/class-admin-ajax.php:54
137
  msgid "n/a"
138
  msgstr ""
139
 
140
- #: admin/includes/class-admin-ajax.php:57 admin/includes/tab-settings.php:80
141
  msgid "UNKNOWN"
142
  msgstr ""
143
 
144
- #: admin/includes/tab-accesslog.php:22 admin/includes/tab-accesslog.php:65
145
  msgid "Validation logs"
146
  msgstr ""
147
 
148
- #: admin/includes/tab-accesslog.php:30
 
 
 
 
 
 
 
 
149
  msgid "Clear logs"
150
  msgstr ""
151
 
152
- #: admin/includes/tab-accesslog.php:38 admin/includes/tab-statistics.php:171
153
- #: admin/includes/tab-statistics.php:277
154
  msgid "Clear now"
155
  msgstr ""
156
 
157
- #: admin/includes/tab-accesslog.php:46
158
  msgid "Export logs"
159
  msgstr ""
160
 
161
- #: admin/includes/tab-accesslog.php:52 admin/includes/tab-settings.php:942
162
  msgid "Export to the local file"
163
  msgstr ""
164
 
165
- #: admin/includes/tab-accesslog.php:52
166
  msgid "Export csv"
167
  msgstr ""
168
 
169
- #: admin/includes/tab-accesslog.php:92 admin/includes/tab-settings.php:330
170
  #, php-format
171
- msgid "<dfn title=\"Validate request to %s.\">%s</dfn>"
172
  msgstr ""
173
 
174
- #: admin/includes/tab-accesslog.php:94 admin/includes/tab-settings.php:332
175
  msgid "Comment post"
176
  msgstr ""
177
 
178
- #: admin/includes/tab-accesslog.php:95 admin/includes/tab-settings.php:333
179
  msgid "XML-RPC"
180
  msgstr ""
181
 
182
- #: admin/includes/tab-accesslog.php:96 admin/includes/tab-settings.php:334
183
  msgid "Login form"
184
  msgstr ""
185
 
186
- #: admin/includes/tab-accesslog.php:97 admin/includes/tab-settings.php:335
187
  msgid "Admin area"
188
  msgstr ""
189
 
190
- #: admin/includes/tab-accesslog.php:103
 
 
 
 
 
 
 
 
191
  msgid "Date"
192
  msgstr ""
193
 
194
- #: admin/includes/tab-accesslog.php:104 admin/includes/tab-geolocation.php:65
195
  #: admin/includes/tab-statistics.php:217
196
  msgid "IP address"
197
  msgstr ""
198
 
199
- #: admin/includes/tab-accesslog.php:105
200
  msgid "Code"
201
  msgstr ""
202
 
203
- #: admin/includes/tab-accesslog.php:106
204
  msgid "Result"
205
  msgstr ""
206
 
207
- #: admin/includes/tab-accesslog.php:107
208
  msgid "Request"
209
  msgstr ""
210
 
211
- #: admin/includes/tab-accesslog.php:108
212
  msgid "User agent"
213
  msgstr ""
214
 
215
- #: admin/includes/tab-accesslog.php:109
216
  msgid "HTTP headers"
217
  msgstr ""
218
 
219
- #: admin/includes/tab-accesslog.php:110
220
  msgid "$_POST data"
221
  msgstr ""
222
 
223
- #: admin/includes/tab-accesslog.php:128
224
  msgid ""
225
  "Current selection of [<strong>Record validation logs</strong>] on "
226
  "[<strong>Settings</strong>] tab is [<strong>Disable</strong>]."
227
  msgstr ""
228
 
229
- #: admin/includes/tab-accesslog.php:129
230
  msgid ""
231
  "Please select the proper condition to record and analyze the validation logs."
232
  msgstr ""
@@ -251,96 +309,96 @@ msgstr ""
251
  msgid "Search now"
252
  msgstr ""
253
 
254
- #: admin/includes/tab-settings.php:52
255
  msgid "Validation rule settings"
256
  msgstr ""
257
 
258
- #: admin/includes/tab-settings.php:72
259
  msgid ""
260
  "<dfn title=\"You can confirm the appropriate Geolocation APIs and country "
261
- "code by referring &#8220;Scan your country code&#8221;.\">Your IP address / "
262
  "Country</dfn>"
263
  msgstr ""
264
 
265
- #: admin/includes/tab-settings.php:81
266
  msgid "Scan all the APIs you selected at Geolocation API settings"
267
  msgstr ""
268
 
269
- #: admin/includes/tab-settings.php:81
270
- msgid "Scan your country code"
271
  msgstr ""
272
 
273
- #: admin/includes/tab-settings.php:88
274
  msgid "Whitelist"
275
  msgstr ""
276
 
277
- #: admin/includes/tab-settings.php:89
278
  msgid "Blacklist"
279
  msgstr ""
280
 
281
- #: admin/includes/tab-settings.php:93
282
  msgid ""
283
  "Please select either &#8220;Whitelist&#8221; or &#8220;Blacklist&#8221;."
284
  msgstr ""
285
 
286
- #: admin/includes/tab-settings.php:94
287
  msgid ""
288
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
289
  "empty. All the countries will be blocked in case you put &#8220;XX&#8221; "
290
  "only.\">Whitelist of country code</dfn>"
291
  msgstr ""
292
 
293
- #: admin/includes/tab-settings.php:95
294
  msgid ""
295
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
296
  "empty. Please consider to include &#8220;ZZ&#8221; which means UNKNOWN "
297
  "country.\">Blacklist of country code</dfn>"
298
  msgstr ""
299
 
300
- #: admin/includes/tab-settings.php:99
301
  msgid "(comma separated)"
302
  msgstr ""
303
 
304
- #: admin/includes/tab-settings.php:100
305
  msgid "(comma or RET separated)"
306
  msgstr ""
307
 
308
- #: admin/includes/tab-settings.php:107
309
  msgid "Matching rule"
310
  msgstr ""
311
 
312
- #: admin/includes/tab-settings.php:119
313
  msgid ""
314
  "A request from which the country code or IP address is <strong>NOT</strong> "
315
  "in the whitelist will be blocked."
316
  msgstr ""
317
 
318
- #: admin/includes/tab-settings.php:120
319
  msgid ""
320
  "A request from which the country code or IP address is in the blacklist will "
321
  "be blocked."
322
  msgstr ""
323
 
324
- #: admin/includes/tab-settings.php:165
325
  msgid ""
326
  "<dfn title=\"e.g. &#8220;192.0.64.0/18&#8221; for Jetpack server, "
327
  "&#8220;69.46.36.0/27&#8221; for WordFence server\">Whitelist of extra IP "
328
  "addresses prior to country code</dfn>"
329
  msgstr ""
330
 
331
- #: admin/includes/tab-settings.php:184
332
  msgid ""
333
  "<dfn title=\"Server level access control is recommended (e.g. .htaccess)."
334
  "\">Blacklist of extra IP addresses prior to country code</dfn>"
335
  msgstr ""
336
 
337
- #: admin/includes/tab-settings.php:204
338
  msgid ""
339
  "<dfn title=\"e.g. HTTP_X_FORWARDED_FOR\">$_SERVER keys to retrieve extra IP "
340
  "addresses</dfn>"
341
  msgstr ""
342
 
343
- #: admin/includes/tab-settings.php:222
344
  msgid ""
345
  "<dfn title=\"It validates malicious signatures independently of &#8220;Block "
346
  "by country&#8221; and &#8220;Prevent Zero-day Exploit&#8221; for the target "
@@ -351,227 +409,366 @@ msgid ""
351
  "restore.\"><span id=\"ip-geo-block-cycle\"></span></a>)</nobr>"
352
  msgstr ""
353
 
354
- #: admin/includes/tab-settings.php:239
355
  #, php-format
356
  msgid ""
357
  "<dfn title=\"You can put your original 403.php and so on into your theme "
358
  "directory.\">Response code</dfn> %s"
359
  msgstr ""
360
 
361
- #: admin/includes/tab-settings.php:269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  msgid ""
363
  "<dfn title=\"Applied to &#8220;XML-RPC&#8221; and &#8220;Login form&#8221;. "
364
  "Lockout period is defined as expiration time at &#8220;Cache settings&#8221;."
365
  "\">Max number of failed login attempts per IP address</dfn>"
366
  msgstr ""
367
 
368
- #: admin/includes/tab-settings.php:296
369
  msgid "Select when to run the validation."
370
  msgstr ""
371
 
372
- #: admin/includes/tab-settings.php:296
373
  msgid "Validation timing"
374
  msgstr ""
375
 
376
- #: admin/includes/tab-settings.php:307
377
  msgid "&#8220;init&#8221; action hook"
378
  msgstr ""
379
 
380
- #: admin/includes/tab-settings.php:308
381
  msgid "&#8220;mu-plugins&#8221; (ip-geo-block-mu.php)"
382
  msgstr ""
383
 
384
- #: admin/includes/tab-settings.php:311
385
  msgid ""
386
  "Validate at &#8220;init&#8221; action hook in the same manner as typical "
387
  "plugins."
388
  msgstr ""
389
 
390
- #: admin/includes/tab-settings.php:312
391
  msgid ""
392
  "Validate at an earlier phase than other typical plugins. It can reduce load "
393
- "on server but has <a href='http://www.ipgeoblock.com/codex/validation-timing."
394
- "html' title='Validation timing | IP Geo Block'>some restrictions</a>."
 
 
 
 
 
395
  msgstr ""
396
 
397
- #: admin/includes/tab-settings.php:324
398
- msgid "Validation target settings"
 
399
  msgstr ""
400
 
401
- #: admin/includes/tab-settings.php:353 admin/includes/tab-settings.php:373
402
- #: admin/includes/tab-settings.php:406 admin/includes/tab-settings.php:412
 
 
 
 
 
403
  msgid "Block by country"
404
  msgstr ""
405
 
406
- #: admin/includes/tab-settings.php:372 admin/includes/tab-settings.php:459
407
- #: admin/includes/tab-settings.php:723
408
  msgid "Disable"
409
  msgstr ""
410
 
411
- #: admin/includes/tab-settings.php:374
412
  msgid "Completely close"
413
  msgstr ""
414
 
415
- #: admin/includes/tab-settings.php:407
416
  msgid ""
417
  "<dfn title=\"Specify the individual action as a blocking target.\">Target "
418
  "actions</dfn>"
419
  msgstr ""
420
 
421
- #: admin/includes/tab-settings.php:413
422
  msgid "Prevent Zero-day Exploit"
423
  msgstr ""
424
 
425
- #: admin/includes/tab-settings.php:416
426
  msgid ""
427
  "It will block a request related to the services for both public facing pages "
428
  "and the dashboard."
429
  msgstr ""
430
 
431
- #: admin/includes/tab-settings.php:417
432
  msgid ""
433
  "Regardless of the country code, it will block a malicious request related to "
434
  "the services only for the dashboard."
435
  msgstr ""
436
 
437
- #: admin/includes/tab-settings.php:444
 
 
 
 
 
 
 
 
438
  msgid "Admin ajax/post"
439
  msgstr ""
440
 
441
- #: admin/includes/tab-settings.php:461
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
442
  #, php-format
443
  msgid ""
444
  "Regardless of the country code, it will block a malicious request to <code>"
445
  "%s&hellip;/*.php</code>."
446
  msgstr ""
447
 
448
- #: admin/includes/tab-settings.php:462
449
  #, php-format
450
  msgid ""
451
- "It configures &#8220%s&#8221 to validate a request to the PHP file which "
452
  "does not load WordPress core."
453
  msgstr ""
454
 
455
- #: admin/includes/tab-settings.php:463
456
  msgid ""
457
  "<dfn title=\"Select the item which causes undesired blocking in order to "
458
  "exclude from the validation target. Grayed item indicates &#8220;"
459
  "INACTIVE&#8221;.\">Exceptions</dfn>"
460
  msgstr ""
461
 
462
- #: admin/includes/tab-settings.php:499 admin/includes/tab-settings.php:552
463
  msgid "Force to load WP core"
464
  msgstr ""
465
 
466
- #: admin/includes/tab-settings.php:504
467
  msgid "Plugins area"
468
  msgstr ""
469
 
470
- #: admin/includes/tab-settings.php:557
471
  msgid "Themes area"
472
  msgstr ""
473
 
474
- #: admin/includes/tab-settings.php:585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
  msgid "Geolocation API settings"
476
  msgstr ""
477
 
478
- #: admin/includes/tab-settings.php:594
479
  msgid ""
480
  "<dfn title=\"Cache and local database are scanned at the top priority.\">API "
481
  "selection and key settings</dfn>"
482
  msgstr ""
483
 
484
- #: admin/includes/tab-settings.php:616
485
  #, php-format
486
  msgid ""
487
- "Please download <a href=\"https://github.com/tokkonopapa/WordPress-IP-Geo-"
488
- "API/archive/master.zip\" title=\"Download the contents of tokkonopapa/"
489
- "WordPress-IP-Geo-API as a zip file\">ZIP file</a> from <a href=\"https://"
490
- "github.com/tokkonopapa/WordPress-IP-Geo-API\" title=\"tokkonopapa/WordPress-"
491
- "IP-Geo-API - GitHub\">WordPress-IP-Geo-API</a> and upload <code>ip-geo-api</"
492
- "code> to <code>%s</code> with write permission."
493
- msgstr ""
494
-
495
- #: admin/includes/tab-settings.php:625
 
 
 
 
496
  msgid "Local database settings"
497
  msgstr ""
498
 
499
- #: admin/includes/tab-settings.php:640
500
  msgid "database"
501
  msgstr ""
502
 
503
- #: admin/includes/tab-settings.php:641 classes/class-ip-geo-block-util.php:159
504
  #, php-format
505
  msgid "Last update: %s"
506
  msgstr ""
507
 
508
- #: admin/includes/tab-settings.php:650
509
  msgid "Auto updating (once a month)"
510
  msgstr ""
511
 
512
- #: admin/includes/tab-settings.php:667
513
  msgid "Download database"
514
  msgstr ""
515
 
516
- #: admin/includes/tab-settings.php:675
517
  msgid "Download now"
518
  msgstr ""
519
 
520
- #: admin/includes/tab-settings.php:687
521
  msgid "Record settings"
522
  msgstr ""
523
 
524
- #: admin/includes/tab-settings.php:696
525
  msgid "Record validation statistics"
526
  msgstr ""
527
 
528
- #: admin/includes/tab-settings.php:712
529
  msgid "Record validation logs"
530
  msgstr ""
531
 
532
- #: admin/includes/tab-settings.php:724
533
  msgid "Only when blocked"
534
  msgstr ""
535
 
536
- #: admin/includes/tab-settings.php:725
537
  msgid "Only when passed"
538
  msgstr ""
539
 
540
- #: admin/includes/tab-settings.php:726
541
  msgid "Unauthenticated user"
542
  msgstr ""
543
 
544
- #: admin/includes/tab-settings.php:727
545
  msgid "Authenticated user"
546
  msgstr ""
547
 
548
- #: admin/includes/tab-settings.php:728
549
  msgid "All of validation"
550
  msgstr ""
551
 
552
- #: admin/includes/tab-settings.php:737
553
  msgid "Recording period of the logs (days)"
554
  msgstr ""
555
 
556
- #: admin/includes/tab-settings.php:753
557
  msgid "Maximum length of logs for each target"
558
  msgstr ""
559
 
560
- #: admin/includes/tab-settings.php:770
561
  msgid ""
562
  "<dfn title=\"e.g. action, comment, log, pwd\">$_POST keys to be recorded "
563
  "with their values in logs</dfn>"
564
  msgstr ""
565
 
566
- #: admin/includes/tab-settings.php:788
567
  msgid "<dfn title=\"e.g. 123.456.789.***\">Anonymize IP address</dfn>"
568
  msgstr ""
569
 
570
- #: admin/includes/tab-settings.php:806
571
- msgid "Cache settings"
572
  msgstr ""
573
 
574
- #: admin/includes/tab-settings.php:815
575
  #, php-format
576
  msgid ""
577
  "<dfn title=\"If user authentication fails consecutively %d times, subsequent "
@@ -579,137 +776,181 @@ msgid ""
579
  "\">Expiration time [sec]</dfn>"
580
  msgstr ""
581
 
582
- #: admin/includes/tab-settings.php:831
 
 
 
 
583
  msgid "Number of entries to be displayed in cache"
584
  msgstr ""
585
 
586
- #: admin/includes/tab-settings.php:849
587
  msgid "Submission settings"
588
  msgstr ""
589
 
590
- #: admin/includes/tab-settings.php:861
591
  msgid "The whole will be wrapped by &lt;p&gt; tag. Allowed tags: "
592
  msgstr ""
593
 
594
- #: admin/includes/tab-settings.php:861
595
  msgid "Message on comment form"
596
  msgstr ""
597
 
598
- #: admin/includes/tab-settings.php:873
599
  msgid "None"
600
  msgstr ""
601
 
602
- #: admin/includes/tab-settings.php:874
603
  msgid "Top"
604
  msgstr ""
605
 
606
- #: admin/includes/tab-settings.php:875
607
  msgid "Bottom"
608
  msgstr ""
609
 
610
- #: admin/includes/tab-settings.php:887
611
  msgid "Plugin settings"
612
  msgstr ""
613
 
614
- #: admin/includes/tab-settings.php:896
615
  msgid "Remove all settings at uninstallation"
616
  msgstr ""
617
 
618
- #: admin/includes/tab-settings.php:915
619
  msgid ""
620
  "<dfn title=\"Valid key for Google Maps JavaScript API\">Google Maps API key</"
621
  "dfn>"
622
  msgstr ""
623
 
624
- #: admin/includes/tab-settings.php:929
625
  msgid ""
626
  "You need to click the &#8220;Save Changes&#8221; button for imported "
627
  "settings to take effect."
628
  msgstr ""
629
 
630
- #: admin/includes/tab-settings.php:935
631
  msgid "Export / Import settings"
632
  msgstr ""
633
 
634
- #: admin/includes/tab-settings.php:942
635
  msgid "Export settings"
636
  msgstr ""
637
 
638
- #: admin/includes/tab-settings.php:943
639
  msgid "Import from the local file"
640
  msgstr ""
641
 
642
- #: admin/includes/tab-settings.php:943
643
  msgid "Import settings"
644
  msgstr ""
645
 
646
- #: admin/includes/tab-settings.php:952
647
  msgid "Import pre-defined settings"
648
  msgstr ""
649
 
650
- #: admin/includes/tab-settings.php:959
651
  msgid ""
652
- "Import the default settings to revert to the &#8220;Right after "
653
- "installing&#8221; state"
654
  msgstr ""
655
 
656
- #: admin/includes/tab-settings.php:959
657
- msgid "Default settings"
658
  msgstr ""
659
 
660
- #: admin/includes/tab-settings.php:960
661
  msgid ""
662
- "Import the preferred settings mainly for the &#8220;Validation target "
663
- "settings&#8221;"
664
  msgstr ""
665
 
666
- #: admin/includes/tab-settings.php:960
667
- msgid "Best practice"
668
  msgstr ""
669
 
670
- #: admin/includes/tab-settings.php:970
671
  msgid "Delete DB table for validation logs"
672
  msgstr ""
673
 
674
- #: admin/includes/tab-settings.php:978
675
  msgid "Delete now"
676
  msgstr ""
677
 
678
- #: admin/includes/tab-settings.php:986
679
  msgid "Create DB table for validation logs"
680
  msgstr ""
681
 
682
- #: admin/includes/tab-settings.php:994
683
  msgid "Create now"
684
  msgstr ""
685
 
686
- #: admin/includes/tab-settings.php:1009
687
  msgid ""
688
- "To enhance the protection ability, please refer to &#8220;<a href=\"http://"
689
- "www.ipgeoblock.com/codex/the-best-practice-of-target-settings.html\" title="
690
- "\"The best practice of target settings | IP Geo Block\">The best practice of "
691
- "target settings</a>&#8221;."
 
 
 
 
692
  msgstr ""
693
 
694
- #: admin/includes/tab-settings.php:1010
 
 
 
 
695
  msgid ""
696
- "If you have any troubles with these, please open an issue at <a class=\"ip-"
697
- "geo-block-link\" href=\"http://wordpress.org/support/plugin/ip-geo-block\" "
698
- "title=\"WordPress &#8250; Support &raquo; IP Geo Block\" "
699
- "target=_blank>support forum</a>."
700
  msgstr ""
701
 
702
- #: admin/includes/tab-settings.php:1017
 
 
 
 
 
 
 
 
 
703
  msgid ""
704
  "While Maxmind and IP2Location will fetch the local database, others will "
705
  "pass an IP address to the APIs via HTTP."
706
  msgstr ""
707
 
708
- #: admin/includes/tab-settings.php:1018
709
  msgid ""
710
  "Please select the appropriate APIs to fit the privacy law in your country."
711
  msgstr ""
712
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713
  #: admin/includes/tab-statistics.php:24 admin/includes/tab-statistics.php:184
714
  msgid "Statistics of validation"
715
  msgstr ""
@@ -762,51 +1003,79 @@ msgstr ""
762
  msgid "Elapsed [sec] / Calls"
763
  msgstr ""
764
 
765
- #: admin/includes/tab-statistics.php:254
766
  msgid "IP address in cache"
767
  msgstr ""
768
 
769
- #: admin/includes/tab-statistics.php:269
770
  msgid "Clear cache"
771
  msgstr ""
772
 
773
- #: admin/includes/tab-statistics.php:288
774
  msgid ""
775
  "Current setting of [<strong>Record validation statistics</strong>] on "
776
  "[<strong>Settings</strong>] tab is not selected [<strong>Enable</strong>]."
777
  msgstr ""
778
 
779
- #: admin/includes/tab-statistics.php:289
780
  msgid ""
781
  "Please set the proper condition to record and analyze the validation "
782
  "statistics."
783
  msgstr ""
784
 
785
- #: classes/class-ip-geo-block-apis.php:672
786
  msgid ""
787
  "You need to select at least one IP geolocation service. Otherwise "
788
  "<strong>you'll be blocked</strong> after the cache expires."
789
  msgstr ""
790
 
791
- #: classes/class-ip-geo-block-logs.php:112
 
 
 
 
 
792
  #, php-format
793
- msgid ""
794
- "Creating a DB table %s had failed. Once de-activate this plugin, and then "
795
- "activate again."
796
  msgstr ""
797
 
798
- #: classes/class-ip-geo-block-util.php:77
799
- msgid "Your database file is up-to-date."
 
 
800
  msgstr ""
801
 
802
- #: classes/class-ip-geo-block-util.php:106
803
  #, php-format
804
- msgid "Unable to read %s. Please check the permission."
 
 
 
 
 
 
 
 
 
805
  msgstr ""
806
 
807
- #: wp-content/ip-geo-api/ip2location/class-ip2location.php:145
808
- #: wp-content/ip-geo-api/ip2location/class-ip2location.php:174
809
- #: wp-content/ip-geo-api/maxmind/class-maxmind.php:149
810
- #: wp-content/ip-geo-api/maxmind/class-maxmind.php:178
 
 
 
 
 
 
 
811
  msgid "Database file does not exist."
812
  msgstr ""
 
 
 
 
 
 
 
1
+ # Copyright (C) 2013-2017 tokkonopapa
2
  # This file is distributed under the same license as the IP Geo Block package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: IP Geo Block 3.0.2.2\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ip-geo-block\n"
7
+ "POT-Creation-Date: 2017-04-30 12:56+0900\n"
8
+ "PO-Revision-Date: 2017-04-30 13:10+0900\n"
9
  "Last-Translator: tokkonopapa <tokkonopapa@yahoo.com>\n"
10
  "Language-Team: \n"
11
  "MIME-Version: 1.0\n"
25
  "posted from outside your nation, and also prevents zero-day exploit."
26
  msgstr ""
27
 
28
+ #: admin/class-ip-geo-block-admin.php:160
29
+ msgid "Import settings ?"
30
+ msgstr ""
31
+
32
+ #: admin/class-ip-geo-block-admin.php:161
33
+ msgid "Create table ?"
34
+ msgstr ""
35
+
36
+ #: admin/class-ip-geo-block-admin.php:162
37
+ msgid "Delete table ?"
38
+ msgstr ""
39
+
40
+ #: admin/class-ip-geo-block-admin.php:163
41
+ msgid "Clear statistics ?"
42
+ msgstr ""
43
+
44
+ #: admin/class-ip-geo-block-admin.php:164
45
+ msgid "Clear cache ?"
46
+ msgstr ""
47
+
48
+ #: admin/class-ip-geo-block-admin.php:165
49
+ msgid "Clear logs ?"
50
+ msgstr ""
51
+
52
+ #: admin/class-ip-geo-block-admin.php:166
53
+ msgid "This feature is available with HTML5 compliant browsers."
54
+ msgstr ""
55
+
56
+ #: admin/class-ip-geo-block-admin.php:193
57
  msgid "Contribute at GitHub"
58
  msgstr ""
59
 
60
+ #: admin/class-ip-geo-block-admin.php:210
61
+ #: admin/class-ip-geo-block-admin.php:390
62
  msgid "Settings"
63
  msgstr ""
64
 
65
+ #: admin/class-ip-geo-block-admin.php:265
66
+ #: admin/class-ip-geo-block-admin.php:266
67
  msgid "IP Geo Block"
68
  msgstr ""
69
 
70
+ #: admin/class-ip-geo-block-admin.php:284
71
  msgid "You need WordPress 3.7+."
72
  msgstr ""
73
 
74
+ #: admin/class-ip-geo-block-admin.php:293
75
  #, php-format
76
  msgid ""
77
  "Now downloading geolocation databases in background. After a little while, "
79
  "strong>&#8221; at <a href=\"%s\">Validation rule settings</a>."
80
  msgstr ""
81
 
82
+ #: admin/class-ip-geo-block-admin.php:299
83
  #, php-format
84
  msgid ""
85
  "The &#8220;<strong>Matching rule</strong>&#8221; is not set properly. Please "
86
  "confirm it at <a href=\"%s\">Validation rule settings</a>."
87
  msgstr ""
88
 
89
+ #: admin/class-ip-geo-block-admin.php:308
90
  msgid "Local database and matching rule have been updated."
91
  msgstr ""
92
 
93
+ #: admin/class-ip-geo-block-admin.php:319
94
+ msgid ""
95
+ "Once you logout, you will be unable to login again because the number of "
96
+ "login attempts reaches the limit."
97
+ msgstr ""
98
+
99
+ #: admin/class-ip-geo-block-admin.php:321
100
+ #, php-format
101
+ msgid ""
102
+ "Please execute \"<strong>Clear cache</strong>\" on <a href=\"%s\">Statistics "
103
+ "tab</a> to prevent locking yourself out."
104
+ msgstr ""
105
+
106
+ #: admin/class-ip-geo-block-admin.php:331
107
  msgid ""
108
  "Once you logout, you will be unable to login again because your country code "
109
  "or IP address is in the blacklist."
110
  msgstr ""
111
 
112
+ #: admin/class-ip-geo-block-admin.php:332
113
  msgid ""
114
  "Once you logout, you will be unable to login again because your country code "
115
  "or IP address is not in the whitelist."
116
  msgstr ""
117
 
118
+ #: admin/class-ip-geo-block-admin.php:335
119
  #, php-format
120
  msgid "Please check your <a href=\"%s\">Validation rule settings</a>."
121
  msgstr ""
122
 
123
+ #: admin/class-ip-geo-block-admin.php:391
124
  msgid "Statistics"
125
  msgstr ""
126
 
127
+ #: admin/class-ip-geo-block-admin.php:392
128
  msgid "Logs"
129
  msgstr ""
130
 
131
+ #: admin/class-ip-geo-block-admin.php:393
132
  msgid "Search"
133
  msgstr ""
134
 
135
+ #: admin/class-ip-geo-block-admin.php:394
136
  msgid "Attribution"
137
  msgstr ""
138
 
139
+ #: admin/class-ip-geo-block-admin.php:405
140
  msgid "Toggle all"
141
  msgstr ""
142
 
143
+ #: admin/class-ip-geo-block-admin.php:429
144
  msgid "Thanks for providing these great services for free."
145
  msgstr ""
146
 
147
+ #: admin/class-ip-geo-block-admin.php:430
148
  msgid ""
149
  "(Most browsers will redirect you to each site <a href=\"http://www."
150
  "ipgeoblock.com/etc/referer.html\" title=\"Referer Checker\">without referrer "
151
  "when you click the link</a>.)"
152
  msgstr ""
153
 
154
+ #: admin/class-ip-geo-block-admin.php:435
155
  msgid "Back to top"
156
  msgstr ""
157
 
158
+ #: admin/class-ip-geo-block-admin.php:527
159
  msgid "Enable"
160
  msgstr ""
161
 
162
+ #: admin/class-ip-geo-block-admin.php:840
163
+ #: admin/class-ip-geo-block-admin.php:851
164
+ #: classes/class-ip-geo-block-cron.php:260
165
+ #: classes/class-ip-geo-block-cron.php:318
166
+ #: classes/class-ip-geo-block-opts.php:311
167
  #, php-format
168
  msgid "Unable to write %s. Please check the permission."
169
  msgstr ""
170
 
171
+ #: admin/class-ip-geo-block-admin.php:841
172
  #, php-format
173
  msgid "Or please refer to %s to set it manually."
174
  msgid_plural "Or please refer to %s to set them manually."
175
  msgstr[0] ""
176
  msgstr[1] ""
177
 
178
+ #: admin/includes/class-admin-ajax.php:60
179
  msgid "n/a"
180
  msgstr ""
181
 
182
+ #: admin/includes/class-admin-ajax.php:63 admin/includes/tab-settings.php:81
183
  msgid "UNKNOWN"
184
  msgstr ""
185
 
186
+ #: admin/includes/tab-accesslog.php:22 admin/includes/tab-accesslog.php:82
187
  msgid "Validation logs"
188
  msgstr ""
189
 
190
+ #: admin/includes/tab-accesslog.php:31
191
+ msgid "Filter logs"
192
+ msgstr ""
193
+
194
+ #: admin/includes/tab-accesslog.php:40
195
+ msgid "Reset"
196
+ msgstr ""
197
+
198
+ #: admin/includes/tab-accesslog.php:47
199
  msgid "Clear logs"
200
  msgstr ""
201
 
202
+ #: admin/includes/tab-accesslog.php:55 admin/includes/tab-statistics.php:171
203
+ #: admin/includes/tab-statistics.php:275
204
  msgid "Clear now"
205
  msgstr ""
206
 
207
+ #: admin/includes/tab-accesslog.php:63
208
  msgid "Export logs"
209
  msgstr ""
210
 
211
+ #: admin/includes/tab-accesslog.php:69 admin/includes/tab-settings.php:1265
212
  msgid "Export to the local file"
213
  msgstr ""
214
 
215
+ #: admin/includes/tab-accesslog.php:69
216
  msgid "Export csv"
217
  msgstr ""
218
 
219
+ #: admin/includes/tab-accesslog.php:109
220
  #, php-format
221
+ msgid "<dfn title=\"Validation log of request to %s.\">%s</dfn>"
222
  msgstr ""
223
 
224
+ #: admin/includes/tab-accesslog.php:111 admin/includes/tab-settings.php:368
225
  msgid "Comment post"
226
  msgstr ""
227
 
228
+ #: admin/includes/tab-accesslog.php:112 admin/includes/tab-settings.php:369
229
  msgid "XML-RPC"
230
  msgstr ""
231
 
232
+ #: admin/includes/tab-accesslog.php:113 admin/includes/tab-settings.php:370
233
  msgid "Login form"
234
  msgstr ""
235
 
236
+ #: admin/includes/tab-accesslog.php:114 admin/includes/tab-settings.php:371
237
  msgid "Admin area"
238
  msgstr ""
239
 
240
+ #: admin/includes/tab-accesslog.php:115 admin/includes/tab-settings.php:373
241
+ msgid "public facing pages"
242
+ msgstr ""
243
+
244
+ #: admin/includes/tab-accesslog.php:115 admin/includes/tab-settings.php:373
245
+ msgid "Public facing pages"
246
+ msgstr ""
247
+
248
+ #: admin/includes/tab-accesslog.php:121
249
  msgid "Date"
250
  msgstr ""
251
 
252
+ #: admin/includes/tab-accesslog.php:122 admin/includes/tab-geolocation.php:65
253
  #: admin/includes/tab-statistics.php:217
254
  msgid "IP address"
255
  msgstr ""
256
 
257
+ #: admin/includes/tab-accesslog.php:123
258
  msgid "Code"
259
  msgstr ""
260
 
261
+ #: admin/includes/tab-accesslog.php:124
262
  msgid "Result"
263
  msgstr ""
264
 
265
+ #: admin/includes/tab-accesslog.php:125
266
  msgid "Request"
267
  msgstr ""
268
 
269
+ #: admin/includes/tab-accesslog.php:126
270
  msgid "User agent"
271
  msgstr ""
272
 
273
+ #: admin/includes/tab-accesslog.php:127
274
  msgid "HTTP headers"
275
  msgstr ""
276
 
277
+ #: admin/includes/tab-accesslog.php:128
278
  msgid "$_POST data"
279
  msgstr ""
280
 
281
+ #: admin/includes/tab-accesslog.php:146
282
  msgid ""
283
  "Current selection of [<strong>Record validation logs</strong>] on "
284
  "[<strong>Settings</strong>] tab is [<strong>Disable</strong>]."
285
  msgstr ""
286
 
287
+ #: admin/includes/tab-accesslog.php:147
288
  msgid ""
289
  "Please select the proper condition to record and analyze the validation logs."
290
  msgstr ""
309
  msgid "Search now"
310
  msgstr ""
311
 
312
+ #: admin/includes/tab-settings.php:49
313
  msgid "Validation rule settings"
314
  msgstr ""
315
 
316
+ #: admin/includes/tab-settings.php:73
317
  msgid ""
318
  "<dfn title=\"You can confirm the appropriate Geolocation APIs and country "
319
+ "code by referring &#8220;Scan country code&#8221;.\">Your IP address / "
320
  "Country</dfn>"
321
  msgstr ""
322
 
323
+ #: admin/includes/tab-settings.php:82
324
  msgid "Scan all the APIs you selected at Geolocation API settings"
325
  msgstr ""
326
 
327
+ #: admin/includes/tab-settings.php:82
328
+ msgid "Scan country code"
329
  msgstr ""
330
 
331
+ #: admin/includes/tab-settings.php:89
332
  msgid "Whitelist"
333
  msgstr ""
334
 
335
+ #: admin/includes/tab-settings.php:90
336
  msgid "Blacklist"
337
  msgstr ""
338
 
339
+ #: admin/includes/tab-settings.php:94
340
  msgid ""
341
  "Please select either &#8220;Whitelist&#8221; or &#8220;Blacklist&#8221;."
342
  msgstr ""
343
 
344
+ #: admin/includes/tab-settings.php:95
345
  msgid ""
346
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
347
  "empty. All the countries will be blocked in case you put &#8220;XX&#8221; "
348
  "only.\">Whitelist of country code</dfn>"
349
  msgstr ""
350
 
351
+ #: admin/includes/tab-settings.php:96
352
  msgid ""
353
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
354
  "empty. Please consider to include &#8220;ZZ&#8221; which means UNKNOWN "
355
  "country.\">Blacklist of country code</dfn>"
356
  msgstr ""
357
 
358
+ #: admin/includes/tab-settings.php:100
359
  msgid "(comma separated)"
360
  msgstr ""
361
 
362
+ #: admin/includes/tab-settings.php:101
363
  msgid "(comma or RET separated)"
364
  msgstr ""
365
 
366
+ #: admin/includes/tab-settings.php:108 admin/includes/tab-settings.php:708
367
  msgid "Matching rule"
368
  msgstr ""
369
 
370
+ #: admin/includes/tab-settings.php:120
371
  msgid ""
372
  "A request from which the country code or IP address is <strong>NOT</strong> "
373
  "in the whitelist will be blocked."
374
  msgstr ""
375
 
376
+ #: admin/includes/tab-settings.php:121
377
  msgid ""
378
  "A request from which the country code or IP address is in the blacklist will "
379
  "be blocked."
380
  msgstr ""
381
 
382
+ #: admin/includes/tab-settings.php:166
383
  msgid ""
384
  "<dfn title=\"e.g. &#8220;192.0.64.0/18&#8221; for Jetpack server, "
385
  "&#8220;69.46.36.0/27&#8221; for WordFence server\">Whitelist of extra IP "
386
  "addresses prior to country code</dfn>"
387
  msgstr ""
388
 
389
+ #: admin/includes/tab-settings.php:185
390
  msgid ""
391
  "<dfn title=\"Server level access control is recommended (e.g. .htaccess)."
392
  "\">Blacklist of extra IP addresses prior to country code</dfn>"
393
  msgstr ""
394
 
395
+ #: admin/includes/tab-settings.php:205
396
  msgid ""
397
  "<dfn title=\"e.g. HTTP_X_FORWARDED_FOR\">$_SERVER keys to retrieve extra IP "
398
  "addresses</dfn>"
399
  msgstr ""
400
 
401
+ #: admin/includes/tab-settings.php:223
402
  msgid ""
403
  "<dfn title=\"It validates malicious signatures independently of &#8220;Block "
404
  "by country&#8221; and &#8220;Prevent Zero-day Exploit&#8221; for the target "
409
  "restore.\"><span id=\"ip-geo-block-cycle\"></span></a>)</nobr>"
410
  msgstr ""
411
 
412
+ #: admin/includes/tab-settings.php:240
413
  #, php-format
414
  msgid ""
415
  "<dfn title=\"You can put your original 403.php and so on into your theme "
416
  "directory.\">Response code</dfn> %s"
417
  msgstr ""
418
 
419
+ #: admin/includes/tab-settings.php:270
420
+ msgid ""
421
+ "<dfn title=\"Specify the URL for response code 2xx and 3xx. Front-end URL on "
422
+ "your site would not be blocked to prevent loop of redirection even when you "
423
+ "enable [Front-end target settings]. Empty URL is altered to your home."
424
+ "\">Redirect URL</dfn>"
425
+ msgstr ""
426
+
427
+ #: admin/includes/tab-settings.php:287
428
+ msgid ""
429
+ "<dfn title=\"Specify the message for response code 4xx and 5xx.\">Response "
430
+ "message</dfn>"
431
+ msgstr ""
432
+
433
+ #: admin/includes/tab-settings.php:304
434
  msgid ""
435
  "<dfn title=\"Applied to &#8220;XML-RPC&#8221; and &#8220;Login form&#8221;. "
436
  "Lockout period is defined as expiration time at &#8220;Cache settings&#8221;."
437
  "\">Max number of failed login attempts per IP address</dfn>"
438
  msgstr ""
439
 
440
+ #: admin/includes/tab-settings.php:332
441
  msgid "Select when to run the validation."
442
  msgstr ""
443
 
444
+ #: admin/includes/tab-settings.php:332
445
  msgid "Validation timing"
446
  msgstr ""
447
 
448
+ #: admin/includes/tab-settings.php:343
449
  msgid "&#8220;init&#8221; action hook"
450
  msgstr ""
451
 
452
+ #: admin/includes/tab-settings.php:344
453
  msgid "&#8220;mu-plugins&#8221; (ip-geo-block-mu.php)"
454
  msgstr ""
455
 
456
+ #: admin/includes/tab-settings.php:347
457
  msgid ""
458
  "Validate at &#8220;init&#8221; action hook in the same manner as typical "
459
  "plugins."
460
  msgstr ""
461
 
462
+ #: admin/includes/tab-settings.php:348
463
  msgid ""
464
  "Validate at an earlier phase than other typical plugins. It can reduce load "
465
+ "on server but has <a rel='noreferrer' href='http://www.ipgeoblock.com/codex/"
466
+ "validation-timing.html' title='Validation timing | IP Geo Block'>some "
467
+ "restrictions</a>."
468
+ msgstr ""
469
+
470
+ #: admin/includes/tab-settings.php:360
471
+ msgid "Back-end target settings"
472
  msgstr ""
473
 
474
+ #: admin/includes/tab-settings.php:366
475
+ #, php-format
476
+ msgid "<dfn title=\"Validate request to %s.\">%s</dfn>"
477
  msgstr ""
478
 
479
+ #: admin/includes/tab-settings.php:372
480
+ msgid "Other areas"
481
+ msgstr ""
482
+
483
+ #: admin/includes/tab-settings.php:391 admin/includes/tab-settings.php:411
484
+ #: admin/includes/tab-settings.php:444 admin/includes/tab-settings.php:450
485
+ #: admin/includes/tab-settings.php:696
486
  msgid "Block by country"
487
  msgstr ""
488
 
489
+ #: admin/includes/tab-settings.php:410 admin/includes/tab-settings.php:551
490
+ #: admin/includes/tab-settings.php:1029
491
  msgid "Disable"
492
  msgstr ""
493
 
494
+ #: admin/includes/tab-settings.php:412
495
  msgid "Completely close"
496
  msgstr ""
497
 
498
+ #: admin/includes/tab-settings.php:445
499
  msgid ""
500
  "<dfn title=\"Specify the individual action as a blocking target.\">Target "
501
  "actions</dfn>"
502
  msgstr ""
503
 
504
+ #: admin/includes/tab-settings.php:451
505
  msgid "Prevent Zero-day Exploit"
506
  msgstr ""
507
 
508
+ #: admin/includes/tab-settings.php:455
509
  msgid ""
510
  "It will block a request related to the services for both public facing pages "
511
  "and the dashboard."
512
  msgstr ""
513
 
514
+ #: admin/includes/tab-settings.php:456
515
  msgid ""
516
  "Regardless of the country code, it will block a malicious request related to "
517
  "the services only for the dashboard."
518
  msgstr ""
519
 
520
+ #: admin/includes/tab-settings.php:507
521
+ msgid "for logged-in users"
522
+ msgstr ""
523
+
524
+ #: admin/includes/tab-settings.php:508
525
+ msgid "for non logged-in users"
526
+ msgstr ""
527
+
528
+ #: admin/includes/tab-settings.php:527
529
  msgid "Admin ajax/post"
530
  msgstr ""
531
 
532
+ #: admin/includes/tab-settings.php:540
533
+ msgid ""
534
+ "<dfn title=\"Select actions that cause undesired blocking to skip &#8220;"
535
+ "Prevent Zero-day Exploit&#8221; for logged-in users and &#8220;Block by "
536
+ "country&#8221; for non logged-in users. If you can not find the right one in "
537
+ "the candidate list, you can put a certain page name (&#8220;&hellip;&#8221; "
538
+ "in &#8220;page=&hellip;&#8221;) or action name (&#8220;&hellip;&#8221; in "
539
+ "&#8220;action=&hellip;&#8221;), which would be implemented with a non "
540
+ "WordPress standard way, into the field to specify the request.\">Exceptions</"
541
+ "dfn>"
542
+ msgstr ""
543
+
544
+ #: admin/includes/tab-settings.php:545
545
+ msgid "Candidate actions"
546
+ msgstr ""
547
+
548
+ #: admin/includes/tab-settings.php:553
549
  #, php-format
550
  msgid ""
551
  "Regardless of the country code, it will block a malicious request to <code>"
552
  "%s&hellip;/*.php</code>."
553
  msgstr ""
554
 
555
+ #: admin/includes/tab-settings.php:554
556
  #, php-format
557
  msgid ""
558
+ "It configures &#8220;%s&#8221; to validate a request to the PHP file which "
559
  "does not load WordPress core."
560
  msgstr ""
561
 
562
+ #: admin/includes/tab-settings.php:555
563
  msgid ""
564
  "<dfn title=\"Select the item which causes undesired blocking in order to "
565
  "exclude from the validation target. Grayed item indicates &#8220;"
566
  "INACTIVE&#8221;.\">Exceptions</dfn>"
567
  msgstr ""
568
 
569
+ #: admin/includes/tab-settings.php:591 admin/includes/tab-settings.php:644
570
  msgid "Force to load WP core"
571
  msgstr ""
572
 
573
+ #: admin/includes/tab-settings.php:596
574
  msgid "Plugins area"
575
  msgstr ""
576
 
577
+ #: admin/includes/tab-settings.php:649
578
  msgid "Themes area"
579
  msgstr ""
580
 
581
+ #: admin/includes/tab-settings.php:677
582
+ msgid "Front-end target settings"
583
+ msgstr ""
584
+
585
+ #: admin/includes/tab-settings.php:701
586
+ msgid "Follow &#8220;Validation rule settings&#8221;"
587
+ msgstr ""
588
+
589
+ #: admin/includes/tab-settings.php:758
590
+ msgid ""
591
+ "<dfn title=\"Specify the individual page as a blocking target.\">Page</dfn>"
592
+ msgstr ""
593
+
594
+ #: admin/includes/tab-settings.php:770
595
+ msgid ""
596
+ "<dfn title=\"Specify the individual post type on a single page as a blocking "
597
+ "target.\">Post type</dfn>"
598
+ msgstr ""
599
+
600
+ #: admin/includes/tab-settings.php:782
601
+ msgid ""
602
+ "<dfn title=\"Specify the individual category on a single page or archive "
603
+ "page as a blocking target.\">Category</dfn>"
604
+ msgstr ""
605
+
606
+ #: admin/includes/tab-settings.php:794
607
+ msgid ""
608
+ "<dfn title=\"Specify the individual tag on a single page or archive page as "
609
+ "a blocking target.\">Tag</dfn>"
610
+ msgstr ""
611
+
612
+ #: admin/includes/tab-settings.php:809
613
+ msgid "Specify the validation target on front-end."
614
+ msgstr ""
615
+
616
+ #: admin/includes/tab-settings.php:809
617
+ msgid "Validation target"
618
+ msgstr ""
619
+
620
+ #: admin/includes/tab-settings.php:820
621
+ msgid "All requests"
622
+ msgstr ""
623
+
624
+ #: admin/includes/tab-settings.php:821
625
+ msgid "Specify the targets"
626
+ msgstr ""
627
+
628
+ #: admin/includes/tab-settings.php:824
629
+ msgid ""
630
+ "Notice that &#8220;Validation timing&#8221; is deferred till &#8220;"
631
+ "wp&#8221; action hook. It means that this feature would not be compatible "
632
+ "with any page caching."
633
+ msgstr ""
634
+
635
+ #: admin/includes/tab-settings.php:834
636
+ msgid ""
637
+ "A part of user agent string and a qualification connected with a separator "
638
+ "that indicates an applicable rule and can be &#8220;:&#8221; (pass) or "
639
+ "&#8220;#&#8221; (block). A &#8220;qualification&#8221; can be &#8220;"
640
+ "DNS&#8221;, &#8220;FEED&#8221;, country code or IP address with CIDR. A "
641
+ "negative operator &#8220;!&#8221; can be placed just before a &#8220;"
642
+ "qualification&#8221;."
643
+ msgstr ""
644
+
645
+ #: admin/includes/tab-settings.php:834
646
+ msgid "UA string and qualification"
647
+ msgstr ""
648
+
649
+ #: admin/includes/tab-settings.php:853
650
+ msgid "Specify the name of action that is invariably blocked."
651
+ msgstr ""
652
+
653
+ #: admin/includes/tab-settings.php:853
654
+ msgid "Excluded actions"
655
+ msgstr ""
656
+
657
+ #: admin/includes/tab-settings.php:872
658
+ msgid ""
659
+ "It enables to simulate validation without deployment. The results can be "
660
+ "found at &#8220;Public facing pages&#8221; in Logs."
661
+ msgstr ""
662
+
663
+ #: admin/includes/tab-settings.php:872
664
+ msgid "Simulation mode"
665
+ msgstr ""
666
+
667
+ #: admin/includes/tab-settings.php:891
668
  msgid "Geolocation API settings"
669
  msgstr ""
670
 
671
+ #: admin/includes/tab-settings.php:900
672
  msgid ""
673
  "<dfn title=\"Cache and local database are scanned at the top priority.\">API "
674
  "selection and key settings</dfn>"
675
  msgstr ""
676
 
677
+ #: admin/includes/tab-settings.php:922
678
  #, php-format
679
  msgid ""
680
+ "Can not find geolocation API libraries in <code>%s</code>. It seems to have "
681
+ "failed downloading <a rel=\"noreferrer\" href=\"https://github.com/"
682
+ "tokkonopapa/WordPress-IP-Geo-API/archive/master.zip\" title=\"Download the "
683
+ "contents of tokkonopapa/WordPress-IP-Geo-API as a zip file\">ZIP file</a> "
684
+ "from <a rel=\"noreferrer\" href=\"https://github.com/tokkonopapa/WordPress-"
685
+ "IP-Geo-API\" title=\"tokkonopapa/WordPress-IP-Geo-API - GitHub\">WordPress-"
686
+ "IP-Geo-API</a>. Please refer to the <a rel=\"noreferrer\" href=\"http://www."
687
+ "ipgeoblock.com/codex/how-to-fix-permission-troubles.html\" title=\"How can I "
688
+ "fix permission troubles? | IP Geo Block\">FAQ</a> to install <code>ip-geo-"
689
+ "api</code> with write permission."
690
+ msgstr ""
691
+
692
+ #: admin/includes/tab-settings.php:931
693
  msgid "Local database settings"
694
  msgstr ""
695
 
696
+ #: admin/includes/tab-settings.php:946
697
  msgid "database"
698
  msgstr ""
699
 
700
+ #: admin/includes/tab-settings.php:947 classes/class-ip-geo-block-cron.php:370
701
  #, php-format
702
  msgid "Last update: %s"
703
  msgstr ""
704
 
705
+ #: admin/includes/tab-settings.php:956
706
  msgid "Auto updating (once a month)"
707
  msgstr ""
708
 
709
+ #: admin/includes/tab-settings.php:973
710
  msgid "Download database"
711
  msgstr ""
712
 
713
+ #: admin/includes/tab-settings.php:981
714
  msgid "Download now"
715
  msgstr ""
716
 
717
+ #: admin/includes/tab-settings.php:993
718
  msgid "Record settings"
719
  msgstr ""
720
 
721
+ #: admin/includes/tab-settings.php:1002
722
  msgid "Record validation statistics"
723
  msgstr ""
724
 
725
+ #: admin/includes/tab-settings.php:1018
726
  msgid "Record validation logs"
727
  msgstr ""
728
 
729
+ #: admin/includes/tab-settings.php:1030
730
  msgid "Only when blocked"
731
  msgstr ""
732
 
733
+ #: admin/includes/tab-settings.php:1031
734
  msgid "Only when passed"
735
  msgstr ""
736
 
737
+ #: admin/includes/tab-settings.php:1032
738
  msgid "Unauthenticated user"
739
  msgstr ""
740
 
741
+ #: admin/includes/tab-settings.php:1033
742
  msgid "Authenticated user"
743
  msgstr ""
744
 
745
+ #: admin/includes/tab-settings.php:1034
746
  msgid "All of validation"
747
  msgstr ""
748
 
749
+ #: admin/includes/tab-settings.php:1043
750
  msgid "Recording period of the logs (days)"
751
  msgstr ""
752
 
753
+ #: admin/includes/tab-settings.php:1059
754
  msgid "Maximum length of logs for each target"
755
  msgstr ""
756
 
757
+ #: admin/includes/tab-settings.php:1076
758
  msgid ""
759
  "<dfn title=\"e.g. action, comment, log, pwd\">$_POST keys to be recorded "
760
  "with their values in logs</dfn>"
761
  msgstr ""
762
 
763
+ #: admin/includes/tab-settings.php:1094
764
  msgid "<dfn title=\"e.g. 123.456.789.***\">Anonymize IP address</dfn>"
765
  msgstr ""
766
 
767
+ #: admin/includes/tab-settings.php:1112
768
+ msgid "IP address cache settings"
769
  msgstr ""
770
 
771
+ #: admin/includes/tab-settings.php:1121
772
  #, php-format
773
  msgid ""
774
  "<dfn title=\"If user authentication fails consecutively %d times, subsequent "
776
  "\">Expiration time [sec]</dfn>"
777
  msgstr ""
778
 
779
+ #: admin/includes/tab-settings.php:1137
780
+ msgid "Garbage collection period [sec]"
781
+ msgstr ""
782
+
783
+ #: admin/includes/tab-settings.php:1154
784
  msgid "Number of entries to be displayed in cache"
785
  msgstr ""
786
 
787
+ #: admin/includes/tab-settings.php:1173
788
  msgid "Submission settings"
789
  msgstr ""
790
 
791
+ #: admin/includes/tab-settings.php:1185
792
  msgid "The whole will be wrapped by &lt;p&gt; tag. Allowed tags: "
793
  msgstr ""
794
 
795
+ #: admin/includes/tab-settings.php:1185
796
  msgid "Message on comment form"
797
  msgstr ""
798
 
799
+ #: admin/includes/tab-settings.php:1197
800
  msgid "None"
801
  msgstr ""
802
 
803
+ #: admin/includes/tab-settings.php:1198
804
  msgid "Top"
805
  msgstr ""
806
 
807
+ #: admin/includes/tab-settings.php:1199
808
  msgid "Bottom"
809
  msgstr ""
810
 
811
+ #: admin/includes/tab-settings.php:1211
812
  msgid "Plugin settings"
813
  msgstr ""
814
 
815
+ #: admin/includes/tab-settings.php:1220
816
  msgid "Remove all settings at uninstallation"
817
  msgstr ""
818
 
819
+ #: admin/includes/tab-settings.php:1238
820
  msgid ""
821
  "<dfn title=\"Valid key for Google Maps JavaScript API\">Google Maps API key</"
822
  "dfn>"
823
  msgstr ""
824
 
825
+ #: admin/includes/tab-settings.php:1252
826
  msgid ""
827
  "You need to click the &#8220;Save Changes&#8221; button for imported "
828
  "settings to take effect."
829
  msgstr ""
830
 
831
+ #: admin/includes/tab-settings.php:1258
832
  msgid "Export / Import settings"
833
  msgstr ""
834
 
835
+ #: admin/includes/tab-settings.php:1265
836
  msgid "Export settings"
837
  msgstr ""
838
 
839
+ #: admin/includes/tab-settings.php:1266
840
  msgid "Import from the local file"
841
  msgstr ""
842
 
843
+ #: admin/includes/tab-settings.php:1266
844
  msgid "Import settings"
845
  msgstr ""
846
 
847
+ #: admin/includes/tab-settings.php:1275
848
  msgid "Import pre-defined settings"
849
  msgstr ""
850
 
851
+ #: admin/includes/tab-settings.php:1282
852
  msgid ""
853
+ "Import the preferred settings mainly for the &#8220;Back-end target "
854
+ "settings&#8221;"
855
  msgstr ""
856
 
857
+ #: admin/includes/tab-settings.php:1282
858
+ msgid "Best settings"
859
  msgstr ""
860
 
861
+ #: admin/includes/tab-settings.php:1283
862
  msgid ""
863
+ "Import the default settings to revert to the &#8220;Right after "
864
+ "installing&#8221; state"
865
  msgstr ""
866
 
867
+ #: admin/includes/tab-settings.php:1283
868
+ msgid "Default settings"
869
  msgstr ""
870
 
871
+ #: admin/includes/tab-settings.php:1293
872
  msgid "Delete DB table for validation logs"
873
  msgstr ""
874
 
875
+ #: admin/includes/tab-settings.php:1301
876
  msgid "Delete now"
877
  msgstr ""
878
 
879
+ #: admin/includes/tab-settings.php:1309
880
  msgid "Create DB table for validation logs"
881
  msgstr ""
882
 
883
+ #: admin/includes/tab-settings.php:1317
884
  msgid "Create now"
885
  msgstr ""
886
 
887
+ #: admin/includes/tab-settings.php:1327
888
  msgid ""
889
+ "<dfn title=\"Please copy &amp; paste when submitting your issue to support "
890
+ "forum.\">Installation information</dfn><br />[ <a rel=\"noreferrer\" href="
891
+ "\"https://wordpress.org/support/plugin/ip-geo-block\" title=\"WordPress "
892
+ "&#8250; Support &raquo; IP Geo Block\">support forum</a> ]"
893
+ msgstr ""
894
+
895
+ #: admin/includes/tab-settings.php:1334
896
+ msgid "Show PHP, WordPress, theme and plugins information."
897
  msgstr ""
898
 
899
+ #: admin/includes/tab-settings.php:1334
900
+ msgid "Show information"
901
+ msgstr ""
902
+
903
+ #: admin/includes/tab-settings.php:1348
904
  msgid ""
905
+ "To enhance the protection ability, please refer to &#8220;<a rel=\"noreferrer"
906
+ "\" href=\"http://www.ipgeoblock.com/codex/the-best-practice-for-target-"
907
+ "settings.html\" title=\"The best practice for target settings | IP Geo Block"
908
+ "\">The best practice for target settings</a>&#8221;."
909
  msgstr ""
910
 
911
+ #: admin/includes/tab-settings.php:1349
912
+ msgid ""
913
+ "If you have any troubles with these, please check FAQ at <a rel=\"noreferrer"
914
+ "\" href=\"https://wordpress.org/plugins/ip-geo-block/faq/\" title=\"IP Geo "
915
+ "Block &mdash; WordPress Plugins\">WordPress.org</a> and <a rel=\"noreferrer"
916
+ "\" href=\"http://www.ipgeoblock.com/codex/#faq\" title=\"Codex | IP Geo Block"
917
+ "\">Codex</a>."
918
+ msgstr ""
919
+
920
+ #: admin/includes/tab-settings.php:1356
921
  msgid ""
922
  "While Maxmind and IP2Location will fetch the local database, others will "
923
  "pass an IP address to the APIs via HTTP."
924
  msgstr ""
925
 
926
+ #: admin/includes/tab-settings.php:1357
927
  msgid ""
928
  "Please select the appropriate APIs to fit the privacy law in your country."
929
  msgstr ""
930
 
931
+ #: admin/includes/tab-settings.php:1364
932
+ msgid ""
933
+ "Please refer to the document &#8220;<a rel=\"noreferrer\" href=\"http://www."
934
+ "ipgeoblock.com/codex/#blocking-on-front-end\" title=\"Codex | IP Geo Block"
935
+ "\">Blocking on front-end</a>&#8221; for details, including restrictions on "
936
+ "cache plugin."
937
+ msgstr ""
938
+
939
+ #: admin/includes/tab-settings.php:1365
940
+ msgid ""
941
+ "If you find any issues or have something to suggest, please feel free to "
942
+ "open an issue at <a rel=\"noreferrer\" href=\"https://wordpress.org/support/"
943
+ "plugin/ip-geo-block\" title=\"WordPress &#8250; Support &raquo; IP Geo Block"
944
+ "\">support forum</a>."
945
+ msgstr ""
946
+
947
+ #: admin/includes/tab-settings.php:1372
948
+ msgid ""
949
+ "Please refer to the document &#8220;<a rel=\"noreferrer\" href=\"http://www."
950
+ "ipgeoblock.com/codex/record-settings-and-logs.html\" title=\"Codex | IP Geo "
951
+ "Block\">Record settings and logs</a>&#8221; for details."
952
+ msgstr ""
953
+
954
  #: admin/includes/tab-statistics.php:24 admin/includes/tab-statistics.php:184
955
  msgid "Statistics of validation"
956
  msgstr ""
1003
  msgid "Elapsed [sec] / Calls"
1004
  msgstr ""
1005
 
1006
+ #: admin/includes/tab-statistics.php:252
1007
  msgid "IP address in cache"
1008
  msgstr ""
1009
 
1010
+ #: admin/includes/tab-statistics.php:267
1011
  msgid "Clear cache"
1012
  msgstr ""
1013
 
1014
+ #: admin/includes/tab-statistics.php:286
1015
  msgid ""
1016
  "Current setting of [<strong>Record validation statistics</strong>] on "
1017
  "[<strong>Settings</strong>] tab is not selected [<strong>Enable</strong>]."
1018
  msgstr ""
1019
 
1020
+ #: admin/includes/tab-statistics.php:287
1021
  msgid ""
1022
  "Please set the proper condition to record and analyze the validation "
1023
  "statistics."
1024
  msgstr ""
1025
 
1026
+ #: classes/class-ip-geo-block-apis.php:651
1027
  msgid ""
1028
  "You need to select at least one IP geolocation service. Otherwise "
1029
  "<strong>you'll be blocked</strong> after the cache expires."
1030
  msgstr ""
1031
 
1032
+ #: classes/class-ip-geo-block-cron.php:227
1033
+ msgid "Your database file is up-to-date."
1034
+ msgstr ""
1035
+
1036
+ #: classes/class-ip-geo-block-cron.php:255
1037
+ #: classes/class-ip-geo-block-cron.php:313
1038
  #, php-format
1039
+ msgid "Unable to read %s. Please check the permission."
 
 
1040
  msgstr ""
1041
 
1042
+ #: classes/class-ip-geo-block-cron.php:265
1043
+ #: classes/class-ip-geo-block-cron.php:323
1044
+ #, php-format
1045
+ msgid "Can't lock %s. Please try again after a while."
1046
  msgstr ""
1047
 
1048
+ #: classes/class-ip-geo-block-cron.php:293
1049
  #, php-format
1050
+ msgid "Unable to read %s. Please check permission."
1051
+ msgstr ""
1052
+
1053
+ #: classes/class-ip-geo-block-cron.php:302
1054
+ #, php-format
1055
+ msgid "Unable to write %s. Please check permission."
1056
+ msgstr ""
1057
+
1058
+ #: classes/class-ip-geo-block-cron.php:335
1059
+ msgid "gz or zip is not supported on your system."
1060
  msgstr ""
1061
 
1062
+ #: classes/class-ip-geo-block-logs.php:149
1063
+ #, php-format
1064
+ msgid ""
1065
+ "Creating a DB table %s had failed. Once de-activate this plugin, and then "
1066
+ "activate again."
1067
+ msgstr ""
1068
+
1069
+ #: wp-content/ip-geo-api/ip2location/class-ip2location.php:157
1070
+ #: wp-content/ip-geo-api/ip2location/class-ip2location.php:186
1071
+ #: wp-content/ip-geo-api/maxmind/class-maxmind.php:171
1072
+ #: wp-content/ip-geo-api/maxmind/class-maxmind.php:200
1073
  msgid "Database file does not exist."
1074
  msgstr ""
1075
+
1076
+ #: wp-content/mu-plugins/ip-geo-block-mu.php:72
1077
+ #, php-format
1078
+ msgid ""
1079
+ "Can't find IP Geo Block in your plugins directory. Please remove <code>%s</"
1080
+ "code> or re-install %s."
1081
+ msgstr ""
languages/ip-geo-block.pot CHANGED
@@ -1,11 +1,11 @@
1
- # Copyright (C) 2013-2016 tokkonopapa
2
  # This file is distributed under the same license as the IP Geo Block package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: IP Geo Block 2.2.9.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ip-geo-block\n"
7
- "POT-Creation-Date: 2016-11-12 15:12+0900\n"
8
- "PO-Revision-Date: 2016-11-12 15:12+0900\n"
9
  "Last-Translator: tokkonopapa <tokkonopapa@yahoo.com>\n"
10
  "Language-Team: \n"
11
  "MIME-Version: 1.0\n"
@@ -25,25 +25,53 @@ msgid ""
25
  "posted from outside your nation, and also prevents zero-day exploit."
26
  msgstr ""
27
 
28
- #: admin/class-ip-geo-block-admin.php:185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  msgid "Contribute at GitHub"
30
  msgstr ""
31
 
32
- #: admin/class-ip-geo-block-admin.php:202
33
- #: admin/class-ip-geo-block-admin.php:356
34
  msgid "Settings"
35
  msgstr ""
36
 
37
- #: admin/class-ip-geo-block-admin.php:248
38
- #: admin/class-ip-geo-block-admin.php:249
39
  msgid "IP Geo Block"
40
  msgstr ""
41
 
42
- #: admin/class-ip-geo-block-admin.php:270
43
  msgid "You need WordPress 3.7+."
44
  msgstr ""
45
 
46
- #: admin/class-ip-geo-block-admin.php:278
47
  #, php-format
48
  msgid ""
49
  "Now downloading geolocation databases in background. After a little while, "
@@ -51,182 +79,212 @@ msgid ""
51
  "strong>&#8221; at <a href=\"%s\">Validation rule settings</a>."
52
  msgstr ""
53
 
54
- #: admin/class-ip-geo-block-admin.php:284
55
  #, php-format
56
  msgid ""
57
  "The &#8220;<strong>Matching rule</strong>&#8221; is not set properly. Please "
58
  "confirm it at <a href=\"%s\">Validation rule settings</a>."
59
  msgstr ""
60
 
61
- #: admin/class-ip-geo-block-admin.php:293
62
  msgid "Local database and matching rule have been updated."
63
  msgstr ""
64
 
65
- #: admin/class-ip-geo-block-admin.php:304
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  msgid ""
67
  "Once you logout, you will be unable to login again because your country code "
68
  "or IP address is in the blacklist."
69
  msgstr ""
70
 
71
- #: admin/class-ip-geo-block-admin.php:305
72
  msgid ""
73
  "Once you logout, you will be unable to login again because your country code "
74
  "or IP address is not in the whitelist."
75
  msgstr ""
76
 
77
- #: admin/class-ip-geo-block-admin.php:308
78
  #, php-format
79
  msgid "Please check your <a href=\"%s\">Validation rule settings</a>."
80
  msgstr ""
81
 
82
- #: admin/class-ip-geo-block-admin.php:357
83
  msgid "Statistics"
84
  msgstr ""
85
 
86
- #: admin/class-ip-geo-block-admin.php:358
87
  msgid "Logs"
88
  msgstr ""
89
 
90
- #: admin/class-ip-geo-block-admin.php:359
91
  msgid "Search"
92
  msgstr ""
93
 
94
- #: admin/class-ip-geo-block-admin.php:360
95
  msgid "Attribution"
96
  msgstr ""
97
 
98
- #: admin/class-ip-geo-block-admin.php:372
99
  msgid "Toggle all"
100
  msgstr ""
101
 
102
- #: admin/class-ip-geo-block-admin.php:396
103
  msgid "Thanks for providing these great services for free."
104
  msgstr ""
105
 
106
- #: admin/class-ip-geo-block-admin.php:397
107
  msgid ""
108
  "(Most browsers will redirect you to each site <a href=\"http://www."
109
  "ipgeoblock.com/etc/referer.html\" title=\"Referer Checker\">without referrer "
110
  "when you click the link</a>.)"
111
  msgstr ""
112
 
113
- #: admin/class-ip-geo-block-admin.php:402
114
  msgid "Back to top"
115
  msgstr ""
116
 
117
- #: admin/class-ip-geo-block-admin.php:494
118
  msgid "Enable"
119
  msgstr ""
120
 
121
- #: admin/class-ip-geo-block-admin.php:789
122
- #: admin/class-ip-geo-block-admin.php:802
123
- #: classes/class-ip-geo-block-opts.php:257
124
- #: classes/class-ip-geo-block-util.php:114
 
125
  #, php-format
126
  msgid "Unable to write %s. Please check the permission."
127
  msgstr ""
128
 
129
- #: admin/class-ip-geo-block-admin.php:790
130
  #, php-format
131
  msgid "Or please refer to %s to set it manually."
132
  msgid_plural "Or please refer to %s to set them manually."
133
  msgstr[0] ""
134
  msgstr[1] ""
135
 
136
- #: admin/includes/class-admin-ajax.php:54
137
  msgid "n/a"
138
  msgstr ""
139
 
140
- #: admin/includes/class-admin-ajax.php:57 admin/includes/tab-settings.php:80
141
  msgid "UNKNOWN"
142
  msgstr ""
143
 
144
- #: admin/includes/tab-accesslog.php:22 admin/includes/tab-accesslog.php:65
145
  msgid "Validation logs"
146
  msgstr ""
147
 
148
- #: admin/includes/tab-accesslog.php:30
 
 
 
 
 
 
 
 
149
  msgid "Clear logs"
150
  msgstr ""
151
 
152
- #: admin/includes/tab-accesslog.php:38 admin/includes/tab-statistics.php:171
153
- #: admin/includes/tab-statistics.php:277
154
  msgid "Clear now"
155
  msgstr ""
156
 
157
- #: admin/includes/tab-accesslog.php:46
158
  msgid "Export logs"
159
  msgstr ""
160
 
161
- #: admin/includes/tab-accesslog.php:52 admin/includes/tab-settings.php:942
162
  msgid "Export to the local file"
163
  msgstr ""
164
 
165
- #: admin/includes/tab-accesslog.php:52
166
  msgid "Export csv"
167
  msgstr ""
168
 
169
- #: admin/includes/tab-accesslog.php:92 admin/includes/tab-settings.php:330
170
  #, php-format
171
- msgid "<dfn title=\"Validate request to %s.\">%s</dfn>"
172
  msgstr ""
173
 
174
- #: admin/includes/tab-accesslog.php:94 admin/includes/tab-settings.php:332
175
  msgid "Comment post"
176
  msgstr ""
177
 
178
- #: admin/includes/tab-accesslog.php:95 admin/includes/tab-settings.php:333
179
  msgid "XML-RPC"
180
  msgstr ""
181
 
182
- #: admin/includes/tab-accesslog.php:96 admin/includes/tab-settings.php:334
183
  msgid "Login form"
184
  msgstr ""
185
 
186
- #: admin/includes/tab-accesslog.php:97 admin/includes/tab-settings.php:335
187
  msgid "Admin area"
188
  msgstr ""
189
 
190
- #: admin/includes/tab-accesslog.php:103
 
 
 
 
 
 
 
 
191
  msgid "Date"
192
  msgstr ""
193
 
194
- #: admin/includes/tab-accesslog.php:104 admin/includes/tab-geolocation.php:65
195
  #: admin/includes/tab-statistics.php:217
196
  msgid "IP address"
197
  msgstr ""
198
 
199
- #: admin/includes/tab-accesslog.php:105
200
  msgid "Code"
201
  msgstr ""
202
 
203
- #: admin/includes/tab-accesslog.php:106
204
  msgid "Result"
205
  msgstr ""
206
 
207
- #: admin/includes/tab-accesslog.php:107
208
  msgid "Request"
209
  msgstr ""
210
 
211
- #: admin/includes/tab-accesslog.php:108
212
  msgid "User agent"
213
  msgstr ""
214
 
215
- #: admin/includes/tab-accesslog.php:109
216
  msgid "HTTP headers"
217
  msgstr ""
218
 
219
- #: admin/includes/tab-accesslog.php:110
220
  msgid "$_POST data"
221
  msgstr ""
222
 
223
- #: admin/includes/tab-accesslog.php:128
224
  msgid ""
225
  "Current selection of [<strong>Record validation logs</strong>] on "
226
  "[<strong>Settings</strong>] tab is [<strong>Disable</strong>]."
227
  msgstr ""
228
 
229
- #: admin/includes/tab-accesslog.php:129
230
  msgid ""
231
  "Please select the proper condition to record and analyze the validation logs."
232
  msgstr ""
@@ -251,96 +309,96 @@ msgstr ""
251
  msgid "Search now"
252
  msgstr ""
253
 
254
- #: admin/includes/tab-settings.php:52
255
  msgid "Validation rule settings"
256
  msgstr ""
257
 
258
- #: admin/includes/tab-settings.php:72
259
  msgid ""
260
  "<dfn title=\"You can confirm the appropriate Geolocation APIs and country "
261
- "code by referring &#8220;Scan your country code&#8221;.\">Your IP address / "
262
  "Country</dfn>"
263
  msgstr ""
264
 
265
- #: admin/includes/tab-settings.php:81
266
  msgid "Scan all the APIs you selected at Geolocation API settings"
267
  msgstr ""
268
 
269
- #: admin/includes/tab-settings.php:81
270
- msgid "Scan your country code"
271
  msgstr ""
272
 
273
- #: admin/includes/tab-settings.php:88
274
  msgid "Whitelist"
275
  msgstr ""
276
 
277
- #: admin/includes/tab-settings.php:89
278
  msgid "Blacklist"
279
  msgstr ""
280
 
281
- #: admin/includes/tab-settings.php:93
282
  msgid ""
283
  "Please select either &#8220;Whitelist&#8221; or &#8220;Blacklist&#8221;."
284
  msgstr ""
285
 
286
- #: admin/includes/tab-settings.php:94
287
  msgid ""
288
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
289
  "empty. All the countries will be blocked in case you put &#8220;XX&#8221; "
290
  "only.\">Whitelist of country code</dfn>"
291
  msgstr ""
292
 
293
- #: admin/includes/tab-settings.php:95
294
  msgid ""
295
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
296
  "empty. Please consider to include &#8220;ZZ&#8221; which means UNKNOWN "
297
  "country.\">Blacklist of country code</dfn>"
298
  msgstr ""
299
 
300
- #: admin/includes/tab-settings.php:99
301
  msgid "(comma separated)"
302
  msgstr ""
303
 
304
- #: admin/includes/tab-settings.php:100
305
  msgid "(comma or RET separated)"
306
  msgstr ""
307
 
308
- #: admin/includes/tab-settings.php:107
309
  msgid "Matching rule"
310
  msgstr ""
311
 
312
- #: admin/includes/tab-settings.php:119
313
  msgid ""
314
  "A request from which the country code or IP address is <strong>NOT</strong> "
315
  "in the whitelist will be blocked."
316
  msgstr ""
317
 
318
- #: admin/includes/tab-settings.php:120
319
  msgid ""
320
  "A request from which the country code or IP address is in the blacklist will "
321
  "be blocked."
322
  msgstr ""
323
 
324
- #: admin/includes/tab-settings.php:165
325
  msgid ""
326
  "<dfn title=\"e.g. &#8220;192.0.64.0/18&#8221; for Jetpack server, "
327
  "&#8220;69.46.36.0/27&#8221; for WordFence server\">Whitelist of extra IP "
328
  "addresses prior to country code</dfn>"
329
  msgstr ""
330
 
331
- #: admin/includes/tab-settings.php:184
332
  msgid ""
333
  "<dfn title=\"Server level access control is recommended (e.g. .htaccess)."
334
  "\">Blacklist of extra IP addresses prior to country code</dfn>"
335
  msgstr ""
336
 
337
- #: admin/includes/tab-settings.php:204
338
  msgid ""
339
  "<dfn title=\"e.g. HTTP_X_FORWARDED_FOR\">$_SERVER keys to retrieve extra IP "
340
  "addresses</dfn>"
341
  msgstr ""
342
 
343
- #: admin/includes/tab-settings.php:222
344
  msgid ""
345
  "<dfn title=\"It validates malicious signatures independently of &#8220;Block "
346
  "by country&#8221; and &#8220;Prevent Zero-day Exploit&#8221; for the target "
@@ -351,227 +409,366 @@ msgid ""
351
  "restore.\"><span id=\"ip-geo-block-cycle\"></span></a>)</nobr>"
352
  msgstr ""
353
 
354
- #: admin/includes/tab-settings.php:239
355
  #, php-format
356
  msgid ""
357
  "<dfn title=\"You can put your original 403.php and so on into your theme "
358
  "directory.\">Response code</dfn> %s"
359
  msgstr ""
360
 
361
- #: admin/includes/tab-settings.php:269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  msgid ""
363
  "<dfn title=\"Applied to &#8220;XML-RPC&#8221; and &#8220;Login form&#8221;. "
364
  "Lockout period is defined as expiration time at &#8220;Cache settings&#8221;."
365
  "\">Max number of failed login attempts per IP address</dfn>"
366
  msgstr ""
367
 
368
- #: admin/includes/tab-settings.php:296
369
  msgid "Select when to run the validation."
370
  msgstr ""
371
 
372
- #: admin/includes/tab-settings.php:296
373
  msgid "Validation timing"
374
  msgstr ""
375
 
376
- #: admin/includes/tab-settings.php:307
377
  msgid "&#8220;init&#8221; action hook"
378
  msgstr ""
379
 
380
- #: admin/includes/tab-settings.php:308
381
  msgid "&#8220;mu-plugins&#8221; (ip-geo-block-mu.php)"
382
  msgstr ""
383
 
384
- #: admin/includes/tab-settings.php:311
385
  msgid ""
386
  "Validate at &#8220;init&#8221; action hook in the same manner as typical "
387
  "plugins."
388
  msgstr ""
389
 
390
- #: admin/includes/tab-settings.php:312
391
  msgid ""
392
  "Validate at an earlier phase than other typical plugins. It can reduce load "
393
- "on server but has <a href='http://www.ipgeoblock.com/codex/validation-timing."
394
- "html' title='Validation timing | IP Geo Block'>some restrictions</a>."
 
 
 
 
 
395
  msgstr ""
396
 
397
- #: admin/includes/tab-settings.php:324
398
- msgid "Validation target settings"
 
399
  msgstr ""
400
 
401
- #: admin/includes/tab-settings.php:353 admin/includes/tab-settings.php:373
402
- #: admin/includes/tab-settings.php:406 admin/includes/tab-settings.php:412
 
 
 
 
 
403
  msgid "Block by country"
404
  msgstr ""
405
 
406
- #: admin/includes/tab-settings.php:372 admin/includes/tab-settings.php:459
407
- #: admin/includes/tab-settings.php:723
408
  msgid "Disable"
409
  msgstr ""
410
 
411
- #: admin/includes/tab-settings.php:374
412
  msgid "Completely close"
413
  msgstr ""
414
 
415
- #: admin/includes/tab-settings.php:407
416
  msgid ""
417
  "<dfn title=\"Specify the individual action as a blocking target.\">Target "
418
  "actions</dfn>"
419
  msgstr ""
420
 
421
- #: admin/includes/tab-settings.php:413
422
  msgid "Prevent Zero-day Exploit"
423
  msgstr ""
424
 
425
- #: admin/includes/tab-settings.php:416
426
  msgid ""
427
  "It will block a request related to the services for both public facing pages "
428
  "and the dashboard."
429
  msgstr ""
430
 
431
- #: admin/includes/tab-settings.php:417
432
  msgid ""
433
  "Regardless of the country code, it will block a malicious request related to "
434
  "the services only for the dashboard."
435
  msgstr ""
436
 
437
- #: admin/includes/tab-settings.php:444
 
 
 
 
 
 
 
 
438
  msgid "Admin ajax/post"
439
  msgstr ""
440
 
441
- #: admin/includes/tab-settings.php:461
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
442
  #, php-format
443
  msgid ""
444
  "Regardless of the country code, it will block a malicious request to <code>"
445
  "%s&hellip;/*.php</code>."
446
  msgstr ""
447
 
448
- #: admin/includes/tab-settings.php:462
449
  #, php-format
450
  msgid ""
451
- "It configures &#8220%s&#8221 to validate a request to the PHP file which "
452
  "does not load WordPress core."
453
  msgstr ""
454
 
455
- #: admin/includes/tab-settings.php:463
456
  msgid ""
457
  "<dfn title=\"Select the item which causes undesired blocking in order to "
458
  "exclude from the validation target. Grayed item indicates &#8220;"
459
  "INACTIVE&#8221;.\">Exceptions</dfn>"
460
  msgstr ""
461
 
462
- #: admin/includes/tab-settings.php:499 admin/includes/tab-settings.php:552
463
  msgid "Force to load WP core"
464
  msgstr ""
465
 
466
- #: admin/includes/tab-settings.php:504
467
  msgid "Plugins area"
468
  msgstr ""
469
 
470
- #: admin/includes/tab-settings.php:557
471
  msgid "Themes area"
472
  msgstr ""
473
 
474
- #: admin/includes/tab-settings.php:585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
  msgid "Geolocation API settings"
476
  msgstr ""
477
 
478
- #: admin/includes/tab-settings.php:594
479
  msgid ""
480
  "<dfn title=\"Cache and local database are scanned at the top priority.\">API "
481
  "selection and key settings</dfn>"
482
  msgstr ""
483
 
484
- #: admin/includes/tab-settings.php:616
485
  #, php-format
486
  msgid ""
487
- "Please download <a href=\"https://github.com/tokkonopapa/WordPress-IP-Geo-"
488
- "API/archive/master.zip\" title=\"Download the contents of tokkonopapa/"
489
- "WordPress-IP-Geo-API as a zip file\">ZIP file</a> from <a href=\"https://"
490
- "github.com/tokkonopapa/WordPress-IP-Geo-API\" title=\"tokkonopapa/WordPress-"
491
- "IP-Geo-API - GitHub\">WordPress-IP-Geo-API</a> and upload <code>ip-geo-api</"
492
- "code> to <code>%s</code> with write permission."
493
- msgstr ""
494
-
495
- #: admin/includes/tab-settings.php:625
 
 
 
 
496
  msgid "Local database settings"
497
  msgstr ""
498
 
499
- #: admin/includes/tab-settings.php:640
500
  msgid "database"
501
  msgstr ""
502
 
503
- #: admin/includes/tab-settings.php:641 classes/class-ip-geo-block-util.php:159
504
  #, php-format
505
  msgid "Last update: %s"
506
  msgstr ""
507
 
508
- #: admin/includes/tab-settings.php:650
509
  msgid "Auto updating (once a month)"
510
  msgstr ""
511
 
512
- #: admin/includes/tab-settings.php:667
513
  msgid "Download database"
514
  msgstr ""
515
 
516
- #: admin/includes/tab-settings.php:675
517
  msgid "Download now"
518
  msgstr ""
519
 
520
- #: admin/includes/tab-settings.php:687
521
  msgid "Record settings"
522
  msgstr ""
523
 
524
- #: admin/includes/tab-settings.php:696
525
  msgid "Record validation statistics"
526
  msgstr ""
527
 
528
- #: admin/includes/tab-settings.php:712
529
  msgid "Record validation logs"
530
  msgstr ""
531
 
532
- #: admin/includes/tab-settings.php:724
533
  msgid "Only when blocked"
534
  msgstr ""
535
 
536
- #: admin/includes/tab-settings.php:725
537
  msgid "Only when passed"
538
  msgstr ""
539
 
540
- #: admin/includes/tab-settings.php:726
541
  msgid "Unauthenticated user"
542
  msgstr ""
543
 
544
- #: admin/includes/tab-settings.php:727
545
  msgid "Authenticated user"
546
  msgstr ""
547
 
548
- #: admin/includes/tab-settings.php:728
549
  msgid "All of validation"
550
  msgstr ""
551
 
552
- #: admin/includes/tab-settings.php:737
553
  msgid "Recording period of the logs (days)"
554
  msgstr ""
555
 
556
- #: admin/includes/tab-settings.php:753
557
  msgid "Maximum length of logs for each target"
558
  msgstr ""
559
 
560
- #: admin/includes/tab-settings.php:770
561
  msgid ""
562
  "<dfn title=\"e.g. action, comment, log, pwd\">$_POST keys to be recorded "
563
  "with their values in logs</dfn>"
564
  msgstr ""
565
 
566
- #: admin/includes/tab-settings.php:788
567
  msgid "<dfn title=\"e.g. 123.456.789.***\">Anonymize IP address</dfn>"
568
  msgstr ""
569
 
570
- #: admin/includes/tab-settings.php:806
571
- msgid "Cache settings"
572
  msgstr ""
573
 
574
- #: admin/includes/tab-settings.php:815
575
  #, php-format
576
  msgid ""
577
  "<dfn title=\"If user authentication fails consecutively %d times, subsequent "
@@ -579,137 +776,181 @@ msgid ""
579
  "\">Expiration time [sec]</dfn>"
580
  msgstr ""
581
 
582
- #: admin/includes/tab-settings.php:831
 
 
 
 
583
  msgid "Number of entries to be displayed in cache"
584
  msgstr ""
585
 
586
- #: admin/includes/tab-settings.php:849
587
  msgid "Submission settings"
588
  msgstr ""
589
 
590
- #: admin/includes/tab-settings.php:861
591
  msgid "The whole will be wrapped by &lt;p&gt; tag. Allowed tags: "
592
  msgstr ""
593
 
594
- #: admin/includes/tab-settings.php:861
595
  msgid "Message on comment form"
596
  msgstr ""
597
 
598
- #: admin/includes/tab-settings.php:873
599
  msgid "None"
600
  msgstr ""
601
 
602
- #: admin/includes/tab-settings.php:874
603
  msgid "Top"
604
  msgstr ""
605
 
606
- #: admin/includes/tab-settings.php:875
607
  msgid "Bottom"
608
  msgstr ""
609
 
610
- #: admin/includes/tab-settings.php:887
611
  msgid "Plugin settings"
612
  msgstr ""
613
 
614
- #: admin/includes/tab-settings.php:896
615
  msgid "Remove all settings at uninstallation"
616
  msgstr ""
617
 
618
- #: admin/includes/tab-settings.php:915
619
  msgid ""
620
  "<dfn title=\"Valid key for Google Maps JavaScript API\">Google Maps API key</"
621
  "dfn>"
622
  msgstr ""
623
 
624
- #: admin/includes/tab-settings.php:929
625
  msgid ""
626
  "You need to click the &#8220;Save Changes&#8221; button for imported "
627
  "settings to take effect."
628
  msgstr ""
629
 
630
- #: admin/includes/tab-settings.php:935
631
  msgid "Export / Import settings"
632
  msgstr ""
633
 
634
- #: admin/includes/tab-settings.php:942
635
  msgid "Export settings"
636
  msgstr ""
637
 
638
- #: admin/includes/tab-settings.php:943
639
  msgid "Import from the local file"
640
  msgstr ""
641
 
642
- #: admin/includes/tab-settings.php:943
643
  msgid "Import settings"
644
  msgstr ""
645
 
646
- #: admin/includes/tab-settings.php:952
647
  msgid "Import pre-defined settings"
648
  msgstr ""
649
 
650
- #: admin/includes/tab-settings.php:959
651
  msgid ""
652
- "Import the default settings to revert to the &#8220;Right after "
653
- "installing&#8221; state"
654
  msgstr ""
655
 
656
- #: admin/includes/tab-settings.php:959
657
- msgid "Default settings"
658
  msgstr ""
659
 
660
- #: admin/includes/tab-settings.php:960
661
  msgid ""
662
- "Import the preferred settings mainly for the &#8220;Validation target "
663
- "settings&#8221;"
664
  msgstr ""
665
 
666
- #: admin/includes/tab-settings.php:960
667
- msgid "Best practice"
668
  msgstr ""
669
 
670
- #: admin/includes/tab-settings.php:970
671
  msgid "Delete DB table for validation logs"
672
  msgstr ""
673
 
674
- #: admin/includes/tab-settings.php:978
675
  msgid "Delete now"
676
  msgstr ""
677
 
678
- #: admin/includes/tab-settings.php:986
679
  msgid "Create DB table for validation logs"
680
  msgstr ""
681
 
682
- #: admin/includes/tab-settings.php:994
683
  msgid "Create now"
684
  msgstr ""
685
 
686
- #: admin/includes/tab-settings.php:1009
687
  msgid ""
688
- "To enhance the protection ability, please refer to &#8220;<a href=\"http://"
689
- "www.ipgeoblock.com/codex/the-best-practice-of-target-settings.html\" title="
690
- "\"The best practice of target settings | IP Geo Block\">The best practice of "
691
- "target settings</a>&#8221;."
 
 
 
 
692
  msgstr ""
693
 
694
- #: admin/includes/tab-settings.php:1010
 
 
 
 
695
  msgid ""
696
- "If you have any troubles with these, please open an issue at <a class=\"ip-"
697
- "geo-block-link\" href=\"http://wordpress.org/support/plugin/ip-geo-block\" "
698
- "title=\"WordPress &#8250; Support &raquo; IP Geo Block\" "
699
- "target=_blank>support forum</a>."
700
  msgstr ""
701
 
702
- #: admin/includes/tab-settings.php:1017
 
 
 
 
 
 
 
 
 
703
  msgid ""
704
  "While Maxmind and IP2Location will fetch the local database, others will "
705
  "pass an IP address to the APIs via HTTP."
706
  msgstr ""
707
 
708
- #: admin/includes/tab-settings.php:1018
709
  msgid ""
710
  "Please select the appropriate APIs to fit the privacy law in your country."
711
  msgstr ""
712
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713
  #: admin/includes/tab-statistics.php:24 admin/includes/tab-statistics.php:184
714
  msgid "Statistics of validation"
715
  msgstr ""
@@ -762,51 +1003,79 @@ msgstr ""
762
  msgid "Elapsed [sec] / Calls"
763
  msgstr ""
764
 
765
- #: admin/includes/tab-statistics.php:254
766
  msgid "IP address in cache"
767
  msgstr ""
768
 
769
- #: admin/includes/tab-statistics.php:269
770
  msgid "Clear cache"
771
  msgstr ""
772
 
773
- #: admin/includes/tab-statistics.php:288
774
  msgid ""
775
  "Current setting of [<strong>Record validation statistics</strong>] on "
776
  "[<strong>Settings</strong>] tab is not selected [<strong>Enable</strong>]."
777
  msgstr ""
778
 
779
- #: admin/includes/tab-statistics.php:289
780
  msgid ""
781
  "Please set the proper condition to record and analyze the validation "
782
  "statistics."
783
  msgstr ""
784
 
785
- #: classes/class-ip-geo-block-apis.php:672
786
  msgid ""
787
  "You need to select at least one IP geolocation service. Otherwise "
788
  "<strong>you'll be blocked</strong> after the cache expires."
789
  msgstr ""
790
 
791
- #: classes/class-ip-geo-block-logs.php:112
 
 
 
 
 
792
  #, php-format
793
- msgid ""
794
- "Creating a DB table %s had failed. Once de-activate this plugin, and then "
795
- "activate again."
796
  msgstr ""
797
 
798
- #: classes/class-ip-geo-block-util.php:77
799
- msgid "Your database file is up-to-date."
 
 
800
  msgstr ""
801
 
802
- #: classes/class-ip-geo-block-util.php:106
803
  #, php-format
804
- msgid "Unable to read %s. Please check the permission."
 
 
 
 
 
 
 
 
 
805
  msgstr ""
806
 
807
- #: wp-content/ip-geo-api/ip2location/class-ip2location.php:145
808
- #: wp-content/ip-geo-api/ip2location/class-ip2location.php:174
809
- #: wp-content/ip-geo-api/maxmind/class-maxmind.php:149
810
- #: wp-content/ip-geo-api/maxmind/class-maxmind.php:178
 
 
 
 
 
 
 
811
  msgid "Database file does not exist."
812
  msgstr ""
 
 
 
 
 
 
 
1
+ # Copyright (C) 2013-2017 tokkonopapa
2
  # This file is distributed under the same license as the IP Geo Block package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: IP Geo Block 3.0.2.2\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ip-geo-block\n"
7
+ "POT-Creation-Date: 2017-04-30 12:56+0900\n"
8
+ "PO-Revision-Date: 2017-04-30 13:09+0900\n"
9
  "Last-Translator: tokkonopapa <tokkonopapa@yahoo.com>\n"
10
  "Language-Team: \n"
11
  "MIME-Version: 1.0\n"
25
  "posted from outside your nation, and also prevents zero-day exploit."
26
  msgstr ""
27
 
28
+ #: admin/class-ip-geo-block-admin.php:160
29
+ msgid "Import settings ?"
30
+ msgstr ""
31
+
32
+ #: admin/class-ip-geo-block-admin.php:161
33
+ msgid "Create table ?"
34
+ msgstr ""
35
+
36
+ #: admin/class-ip-geo-block-admin.php:162
37
+ msgid "Delete table ?"
38
+ msgstr ""
39
+
40
+ #: admin/class-ip-geo-block-admin.php:163
41
+ msgid "Clear statistics ?"
42
+ msgstr ""
43
+
44
+ #: admin/class-ip-geo-block-admin.php:164
45
+ msgid "Clear cache ?"
46
+ msgstr ""
47
+
48
+ #: admin/class-ip-geo-block-admin.php:165
49
+ msgid "Clear logs ?"
50
+ msgstr ""
51
+
52
+ #: admin/class-ip-geo-block-admin.php:166
53
+ msgid "This feature is available with HTML5 compliant browsers."
54
+ msgstr ""
55
+
56
+ #: admin/class-ip-geo-block-admin.php:193
57
  msgid "Contribute at GitHub"
58
  msgstr ""
59
 
60
+ #: admin/class-ip-geo-block-admin.php:210
61
+ #: admin/class-ip-geo-block-admin.php:390
62
  msgid "Settings"
63
  msgstr ""
64
 
65
+ #: admin/class-ip-geo-block-admin.php:265
66
+ #: admin/class-ip-geo-block-admin.php:266
67
  msgid "IP Geo Block"
68
  msgstr ""
69
 
70
+ #: admin/class-ip-geo-block-admin.php:284
71
  msgid "You need WordPress 3.7+."
72
  msgstr ""
73
 
74
+ #: admin/class-ip-geo-block-admin.php:293
75
  #, php-format
76
  msgid ""
77
  "Now downloading geolocation databases in background. After a little while, "
79
  "strong>&#8221; at <a href=\"%s\">Validation rule settings</a>."
80
  msgstr ""
81
 
82
+ #: admin/class-ip-geo-block-admin.php:299
83
  #, php-format
84
  msgid ""
85
  "The &#8220;<strong>Matching rule</strong>&#8221; is not set properly. Please "
86
  "confirm it at <a href=\"%s\">Validation rule settings</a>."
87
  msgstr ""
88
 
89
+ #: admin/class-ip-geo-block-admin.php:308
90
  msgid "Local database and matching rule have been updated."
91
  msgstr ""
92
 
93
+ #: admin/class-ip-geo-block-admin.php:319
94
+ msgid ""
95
+ "Once you logout, you will be unable to login again because the number of "
96
+ "login attempts reaches the limit."
97
+ msgstr ""
98
+
99
+ #: admin/class-ip-geo-block-admin.php:321
100
+ #, php-format
101
+ msgid ""
102
+ "Please execute \"<strong>Clear cache</strong>\" on <a href=\"%s\">Statistics "
103
+ "tab</a> to prevent locking yourself out."
104
+ msgstr ""
105
+
106
+ #: admin/class-ip-geo-block-admin.php:331
107
  msgid ""
108
  "Once you logout, you will be unable to login again because your country code "
109
  "or IP address is in the blacklist."
110
  msgstr ""
111
 
112
+ #: admin/class-ip-geo-block-admin.php:332
113
  msgid ""
114
  "Once you logout, you will be unable to login again because your country code "
115
  "or IP address is not in the whitelist."
116
  msgstr ""
117
 
118
+ #: admin/class-ip-geo-block-admin.php:335
119
  #, php-format
120
  msgid "Please check your <a href=\"%s\">Validation rule settings</a>."
121
  msgstr ""
122
 
123
+ #: admin/class-ip-geo-block-admin.php:391
124
  msgid "Statistics"
125
  msgstr ""
126
 
127
+ #: admin/class-ip-geo-block-admin.php:392
128
  msgid "Logs"
129
  msgstr ""
130
 
131
+ #: admin/class-ip-geo-block-admin.php:393
132
  msgid "Search"
133
  msgstr ""
134
 
135
+ #: admin/class-ip-geo-block-admin.php:394
136
  msgid "Attribution"
137
  msgstr ""
138
 
139
+ #: admin/class-ip-geo-block-admin.php:405
140
  msgid "Toggle all"
141
  msgstr ""
142
 
143
+ #: admin/class-ip-geo-block-admin.php:429
144
  msgid "Thanks for providing these great services for free."
145
  msgstr ""
146
 
147
+ #: admin/class-ip-geo-block-admin.php:430
148
  msgid ""
149
  "(Most browsers will redirect you to each site <a href=\"http://www."
150
  "ipgeoblock.com/etc/referer.html\" title=\"Referer Checker\">without referrer "
151
  "when you click the link</a>.)"
152
  msgstr ""
153
 
154
+ #: admin/class-ip-geo-block-admin.php:435
155
  msgid "Back to top"
156
  msgstr ""
157
 
158
+ #: admin/class-ip-geo-block-admin.php:527
159
  msgid "Enable"
160
  msgstr ""
161
 
162
+ #: admin/class-ip-geo-block-admin.php:840
163
+ #: admin/class-ip-geo-block-admin.php:851
164
+ #: classes/class-ip-geo-block-cron.php:260
165
+ #: classes/class-ip-geo-block-cron.php:318
166
+ #: classes/class-ip-geo-block-opts.php:311
167
  #, php-format
168
  msgid "Unable to write %s. Please check the permission."
169
  msgstr ""
170
 
171
+ #: admin/class-ip-geo-block-admin.php:841
172
  #, php-format
173
  msgid "Or please refer to %s to set it manually."
174
  msgid_plural "Or please refer to %s to set them manually."
175
  msgstr[0] ""
176
  msgstr[1] ""
177
 
178
+ #: admin/includes/class-admin-ajax.php:60
179
  msgid "n/a"
180
  msgstr ""
181
 
182
+ #: admin/includes/class-admin-ajax.php:63 admin/includes/tab-settings.php:81
183
  msgid "UNKNOWN"
184
  msgstr ""
185
 
186
+ #: admin/includes/tab-accesslog.php:22 admin/includes/tab-accesslog.php:82
187
  msgid "Validation logs"
188
  msgstr ""
189
 
190
+ #: admin/includes/tab-accesslog.php:31
191
+ msgid "Filter logs"
192
+ msgstr ""
193
+
194
+ #: admin/includes/tab-accesslog.php:40
195
+ msgid "Reset"
196
+ msgstr ""
197
+
198
+ #: admin/includes/tab-accesslog.php:47
199
  msgid "Clear logs"
200
  msgstr ""
201
 
202
+ #: admin/includes/tab-accesslog.php:55 admin/includes/tab-statistics.php:171
203
+ #: admin/includes/tab-statistics.php:275
204
  msgid "Clear now"
205
  msgstr ""
206
 
207
+ #: admin/includes/tab-accesslog.php:63
208
  msgid "Export logs"
209
  msgstr ""
210
 
211
+ #: admin/includes/tab-accesslog.php:69 admin/includes/tab-settings.php:1265
212
  msgid "Export to the local file"
213
  msgstr ""
214
 
215
+ #: admin/includes/tab-accesslog.php:69
216
  msgid "Export csv"
217
  msgstr ""
218
 
219
+ #: admin/includes/tab-accesslog.php:109
220
  #, php-format
221
+ msgid "<dfn title=\"Validation log of request to %s.\">%s</dfn>"
222
  msgstr ""
223
 
224
+ #: admin/includes/tab-accesslog.php:111 admin/includes/tab-settings.php:368
225
  msgid "Comment post"
226
  msgstr ""
227
 
228
+ #: admin/includes/tab-accesslog.php:112 admin/includes/tab-settings.php:369
229
  msgid "XML-RPC"
230
  msgstr ""
231
 
232
+ #: admin/includes/tab-accesslog.php:113 admin/includes/tab-settings.php:370
233
  msgid "Login form"
234
  msgstr ""
235
 
236
+ #: admin/includes/tab-accesslog.php:114 admin/includes/tab-settings.php:371
237
  msgid "Admin area"
238
  msgstr ""
239
 
240
+ #: admin/includes/tab-accesslog.php:115 admin/includes/tab-settings.php:373
241
+ msgid "public facing pages"
242
+ msgstr ""
243
+
244
+ #: admin/includes/tab-accesslog.php:115 admin/includes/tab-settings.php:373
245
+ msgid "Public facing pages"
246
+ msgstr ""
247
+
248
+ #: admin/includes/tab-accesslog.php:121
249
  msgid "Date"
250
  msgstr ""
251
 
252
+ #: admin/includes/tab-accesslog.php:122 admin/includes/tab-geolocation.php:65
253
  #: admin/includes/tab-statistics.php:217
254
  msgid "IP address"
255
  msgstr ""
256
 
257
+ #: admin/includes/tab-accesslog.php:123
258
  msgid "Code"
259
  msgstr ""
260
 
261
+ #: admin/includes/tab-accesslog.php:124
262
  msgid "Result"
263
  msgstr ""
264
 
265
+ #: admin/includes/tab-accesslog.php:125
266
  msgid "Request"
267
  msgstr ""
268
 
269
+ #: admin/includes/tab-accesslog.php:126
270
  msgid "User agent"
271
  msgstr ""
272
 
273
+ #: admin/includes/tab-accesslog.php:127
274
  msgid "HTTP headers"
275
  msgstr ""
276
 
277
+ #: admin/includes/tab-accesslog.php:128
278
  msgid "$_POST data"
279
  msgstr ""
280
 
281
+ #: admin/includes/tab-accesslog.php:146
282
  msgid ""
283
  "Current selection of [<strong>Record validation logs</strong>] on "
284
  "[<strong>Settings</strong>] tab is [<strong>Disable</strong>]."
285
  msgstr ""
286
 
287
+ #: admin/includes/tab-accesslog.php:147
288
  msgid ""
289
  "Please select the proper condition to record and analyze the validation logs."
290
  msgstr ""
309
  msgid "Search now"
310
  msgstr ""
311
 
312
+ #: admin/includes/tab-settings.php:49
313
  msgid "Validation rule settings"
314
  msgstr ""
315
 
316
+ #: admin/includes/tab-settings.php:73
317
  msgid ""
318
  "<dfn title=\"You can confirm the appropriate Geolocation APIs and country "
319
+ "code by referring &#8220;Scan country code&#8221;.\">Your IP address / "
320
  "Country</dfn>"
321
  msgstr ""
322
 
323
+ #: admin/includes/tab-settings.php:82
324
  msgid "Scan all the APIs you selected at Geolocation API settings"
325
  msgstr ""
326
 
327
+ #: admin/includes/tab-settings.php:82
328
+ msgid "Scan country code"
329
  msgstr ""
330
 
331
+ #: admin/includes/tab-settings.php:89
332
  msgid "Whitelist"
333
  msgstr ""
334
 
335
+ #: admin/includes/tab-settings.php:90
336
  msgid "Blacklist"
337
  msgstr ""
338
 
339
+ #: admin/includes/tab-settings.php:94
340
  msgid ""
341
  "Please select either &#8220;Whitelist&#8221; or &#8220;Blacklist&#8221;."
342
  msgstr ""
343
 
344
+ #: admin/includes/tab-settings.php:95
345
  msgid ""
346
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
347
  "empty. All the countries will be blocked in case you put &#8220;XX&#8221; "
348
  "only.\">Whitelist of country code</dfn>"
349
  msgstr ""
350
 
351
+ #: admin/includes/tab-settings.php:96
352
  msgid ""
353
  "<dfn title=\"&#8220;Block by country&#8221; will be bypassed in case of "
354
  "empty. Please consider to include &#8220;ZZ&#8221; which means UNKNOWN "
355
  "country.\">Blacklist of country code</dfn>"
356
  msgstr ""
357
 
358
+ #: admin/includes/tab-settings.php:100
359
  msgid "(comma separated)"
360
  msgstr ""
361
 
362
+ #: admin/includes/tab-settings.php:101
363
  msgid "(comma or RET separated)"
364
  msgstr ""
365
 
366
+ #: admin/includes/tab-settings.php:108 admin/includes/tab-settings.php:708
367
  msgid "Matching rule"
368
  msgstr ""
369
 
370
+ #: admin/includes/tab-settings.php:120
371
  msgid ""
372
  "A request from which the country code or IP address is <strong>NOT</strong> "
373
  "in the whitelist will be blocked."
374
  msgstr ""
375
 
376
+ #: admin/includes/tab-settings.php:121
377
  msgid ""
378
  "A request from which the country code or IP address is in the blacklist will "
379
  "be blocked."
380
  msgstr ""
381
 
382
+ #: admin/includes/tab-settings.php:166
383
  msgid ""
384
  "<dfn title=\"e.g. &#8220;192.0.64.0/18&#8221; for Jetpack server, "
385
  "&#8220;69.46.36.0/27&#8221; for WordFence server\">Whitelist of extra IP "
386
  "addresses prior to country code</dfn>"
387
  msgstr ""
388
 
389
+ #: admin/includes/tab-settings.php:185
390
  msgid ""
391
  "<dfn title=\"Server level access control is recommended (e.g. .htaccess)."
392
  "\">Blacklist of extra IP addresses prior to country code</dfn>"
393
  msgstr ""
394
 
395
+ #: admin/includes/tab-settings.php:205
396
  msgid ""
397
  "<dfn title=\"e.g. HTTP_X_FORWARDED_FOR\">$_SERVER keys to retrieve extra IP "
398
  "addresses</dfn>"
399
  msgstr ""
400
 
401
+ #: admin/includes/tab-settings.php:223
402
  msgid ""
403
  "<dfn title=\"It validates malicious signatures independently of &#8220;Block "
404
  "by country&#8221; and &#8220;Prevent Zero-day Exploit&#8221; for the target "
409
  "restore.\"><span id=\"ip-geo-block-cycle\"></span></a>)</nobr>"
410
  msgstr ""
411
 
412
+ #: admin/includes/tab-settings.php:240
413
  #, php-format
414
  msgid ""
415
  "<dfn title=\"You can put your original 403.php and so on into your theme "
416
  "directory.\">Response code</dfn> %s"
417
  msgstr ""
418
 
419
+ #: admin/includes/tab-settings.php:270
420
+ msgid ""
421
+ "<dfn title=\"Specify the URL for response code 2xx and 3xx. Front-end URL on "
422
+ "your site would not be blocked to prevent loop of redirection even when you "
423
+ "enable [Front-end target settings]. Empty URL is altered to your home."
424
+ "\">Redirect URL</dfn>"
425
+ msgstr ""
426
+
427
+ #: admin/includes/tab-settings.php:287
428
+ msgid ""
429
+ "<dfn title=\"Specify the message for response code 4xx and 5xx.\">Response "
430
+ "message</dfn>"
431
+ msgstr ""
432
+
433
+ #: admin/includes/tab-settings.php:304
434
  msgid ""
435
  "<dfn title=\"Applied to &#8220;XML-RPC&#8221; and &#8220;Login form&#8221;. "
436
  "Lockout period is defined as expiration time at &#8220;Cache settings&#8221;."
437
  "\">Max number of failed login attempts per IP address</dfn>"
438
  msgstr ""
439
 
440
+ #: admin/includes/tab-settings.php:332
441
  msgid "Select when to run the validation."
442
  msgstr ""
443
 
444
+ #: admin/includes/tab-settings.php:332
445
  msgid "Validation timing"
446
  msgstr ""
447
 
448
+ #: admin/includes/tab-settings.php:343
449
  msgid "&#8220;init&#8221; action hook"
450
  msgstr ""
451
 
452
+ #: admin/includes/tab-settings.php:344
453
  msgid "&#8220;mu-plugins&#8221; (ip-geo-block-mu.php)"
454
  msgstr ""
455
 
456
+ #: admin/includes/tab-settings.php:347
457
  msgid ""
458
  "Validate at &#8220;init&#8221; action hook in the same manner as typical "
459
  "plugins."
460
  msgstr ""
461
 
462
+ #: admin/includes/tab-settings.php:348
463
  msgid ""
464
  "Validate at an earlier phase than other typical plugins. It can reduce load "
465
+ "on server but has <a rel='noreferrer' href='http://www.ipgeoblock.com/codex/"
466
+ "validation-timing.html' title='Validation timing | IP Geo Block'>some "
467
+ "restrictions</a>."
468
+ msgstr ""
469
+
470
+ #: admin/includes/tab-settings.php:360
471
+ msgid "Back-end target settings"
472
  msgstr ""
473
 
474
+ #: admin/includes/tab-settings.php:366
475
+ #, php-format
476
+ msgid "<dfn title=\"Validate request to %s.\">%s</dfn>"
477
  msgstr ""
478
 
479
+ #: admin/includes/tab-settings.php:372
480
+ msgid "Other areas"
481
+ msgstr ""
482
+
483
+ #: admin/includes/tab-settings.php:391 admin/includes/tab-settings.php:411
484
+ #: admin/includes/tab-settings.php:444 admin/includes/tab-settings.php:450
485
+ #: admin/includes/tab-settings.php:696
486
  msgid "Block by country"
487
  msgstr ""
488
 
489
+ #: admin/includes/tab-settings.php:410 admin/includes/tab-settings.php:551
490
+ #: admin/includes/tab-settings.php:1029
491
  msgid "Disable"
492
  msgstr ""
493
 
494
+ #: admin/includes/tab-settings.php:412
495
  msgid "Completely close"
496
  msgstr ""
497
 
498
+ #: admin/includes/tab-settings.php:445
499
  msgid ""
500
  "<dfn title=\"Specify the individual action as a blocking target.\">Target "
501
  "actions</dfn>"
502
  msgstr ""
503
 
504
+ #: admin/includes/tab-settings.php:451
505
  msgid "Prevent Zero-day Exploit"
506
  msgstr ""
507
 
508
+ #: admin/includes/tab-settings.php:455
509
  msgid ""
510
  "It will block a request related to the services for both public facing pages "
511
  "and the dashboard."
512
  msgstr ""
513
 
514
+ #: admin/includes/tab-settings.php:456
515
  msgid ""
516
  "Regardless of the country code, it will block a malicious request related to "
517
  "the services only for the dashboard."
518
  msgstr ""
519
 
520
+ #: admin/includes/tab-settings.php:507
521
+ msgid "for logged-in users"
522
+ msgstr ""
523
+
524
+ #: admin/includes/tab-settings.php:508
525
+ msgid "for non logged-in users"
526
+ msgstr ""
527
+
528
+ #: admin/includes/tab-settings.php:527
529
  msgid "Admin ajax/post"
530
  msgstr ""
531
 
532
+ #: admin/includes/tab-settings.php:540
533
+ msgid ""
534
+ "<dfn title=\"Select actions that cause undesired blocking to skip &#8220;"
535
+ "Prevent Zero-day Exploit&#8221; for logged-in users and &#8220;Block by "
536
+ "country&#8221; for non logged-in users. If you can not find the right one in "
537
+ "the candidate list, you can put a certain page name (&#8220;&hellip;&#8221; "
538
+ "in &#8220;page=&hellip;&#8221;) or action name (&#8220;&hellip;&#8221; in "
539
+ "&#8220;action=&hellip;&#8221;), which would be implemented with a non "
540
+ "WordPress standard way, into the field to specify the request.\">Exceptions</"
541
+ "dfn>"
542
+ msgstr ""
543
+
544
+ #: admin/includes/tab-settings.php:545
545
+ msgid "Candidate actions"
546
+ msgstr ""
547
+
548
+ #: admin/includes/tab-settings.php:553
549
  #, php-format
550
  msgid ""
551
  "Regardless of the country code, it will block a malicious request to <code>"
552
  "%s&hellip;/*.php</code>."
553
  msgstr ""
554
 
555
+ #: admin/includes/tab-settings.php:554
556
  #, php-format
557
  msgid ""
558
+ "It configures &#8220;%s&#8221; to validate a request to the PHP file which "
559
  "does not load WordPress core."
560
  msgstr ""
561
 
562
+ #: admin/includes/tab-settings.php:555
563
  msgid ""
564
  "<dfn title=\"Select the item which causes undesired blocking in order to "
565
  "exclude from the validation target. Grayed item indicates &#8220;"
566
  "INACTIVE&#8221;.\">Exceptions</dfn>"
567
  msgstr ""
568
 
569
+ #: admin/includes/tab-settings.php:591 admin/includes/tab-settings.php:644
570
  msgid "Force to load WP core"
571
  msgstr ""
572
 
573
+ #: admin/includes/tab-settings.php:596
574
  msgid "Plugins area"
575
  msgstr ""
576
 
577
+ #: admin/includes/tab-settings.php:649
578
  msgid "Themes area"
579
  msgstr ""
580
 
581
+ #: admin/includes/tab-settings.php:677
582
+ msgid "Front-end target settings"
583
+ msgstr ""
584
+
585
+ #: admin/includes/tab-settings.php:701
586
+ msgid "Follow &#8220;Validation rule settings&#8221;"
587
+ msgstr ""
588
+
589
+ #: admin/includes/tab-settings.php:758
590
+ msgid ""
591
+ "<dfn title=\"Specify the individual page as a blocking target.\">Page</dfn>"
592
+ msgstr ""
593
+
594
+ #: admin/includes/tab-settings.php:770
595
+ msgid ""
596
+ "<dfn title=\"Specify the individual post type on a single page as a blocking "
597
+ "target.\">Post type</dfn>"
598
+ msgstr ""
599
+
600
+ #: admin/includes/tab-settings.php:782
601
+ msgid ""
602
+ "<dfn title=\"Specify the individual category on a single page or archive "
603
+ "page as a blocking target.\">Category</dfn>"
604
+ msgstr ""
605
+
606
+ #: admin/includes/tab-settings.php:794
607
+ msgid ""
608
+ "<dfn title=\"Specify the individual tag on a single page or archive page as "
609
+ "a blocking target.\">Tag</dfn>"
610
+ msgstr ""
611
+
612
+ #: admin/includes/tab-settings.php:809
613
+ msgid "Specify the validation target on front-end."
614
+ msgstr ""
615
+
616
+ #: admin/includes/tab-settings.php:809
617
+ msgid "Validation target"
618
+ msgstr ""
619
+
620
+ #: admin/includes/tab-settings.php:820
621
+ msgid "All requests"
622
+ msgstr ""
623
+
624
+ #: admin/includes/tab-settings.php:821
625
+ msgid "Specify the targets"
626
+ msgstr ""
627
+
628
+ #: admin/includes/tab-settings.php:824
629
+ msgid ""
630
+ "Notice that &#8220;Validation timing&#8221; is deferred till &#8220;"
631
+ "wp&#8221; action hook. It means that this feature would not be compatible "
632
+ "with any page caching."
633
+ msgstr ""
634
+
635
+ #: admin/includes/tab-settings.php:834
636
+ msgid ""
637
+ "A part of user agent string and a qualification connected with a separator "
638
+ "that indicates an applicable rule and can be &#8220;:&#8221; (pass) or "
639
+ "&#8220;#&#8221; (block). A &#8220;qualification&#8221; can be &#8220;"
640
+ "DNS&#8221;, &#8220;FEED&#8221;, country code or IP address with CIDR. A "
641
+ "negative operator &#8220;!&#8221; can be placed just before a &#8220;"
642
+ "qualification&#8221;."
643
+ msgstr ""
644
+
645
+ #: admin/includes/tab-settings.php:834
646
+ msgid "UA string and qualification"
647
+ msgstr ""
648
+
649
+ #: admin/includes/tab-settings.php:853
650
+ msgid "Specify the name of action that is invariably blocked."
651
+ msgstr ""
652
+
653
+ #: admin/includes/tab-settings.php:853
654
+ msgid "Excluded actions"
655
+ msgstr ""
656
+
657
+ #: admin/includes/tab-settings.php:872
658
+ msgid ""
659
+ "It enables to simulate validation without deployment. The results can be "
660
+ "found at &#8220;Public facing pages&#8221; in Logs."
661
+ msgstr ""
662
+
663
+ #: admin/includes/tab-settings.php:872
664
+ msgid "Simulation mode"
665
+ msgstr ""
666
+
667
+ #: admin/includes/tab-settings.php:891
668
  msgid "Geolocation API settings"
669
  msgstr ""
670
 
671
+ #: admin/includes/tab-settings.php:900
672
  msgid ""
673
  "<dfn title=\"Cache and local database are scanned at the top priority.\">API "
674
  "selection and key settings</dfn>"
675
  msgstr ""
676
 
677
+ #: admin/includes/tab-settings.php:922
678
  #, php-format
679
  msgid ""
680
+ "Can not find geolocation API libraries in <code>%s</code>. It seems to have "
681
+ "failed downloading <a rel=\"noreferrer\" href=\"https://github.com/"
682
+ "tokkonopapa/WordPress-IP-Geo-API/archive/master.zip\" title=\"Download the "
683
+ "contents of tokkonopapa/WordPress-IP-Geo-API as a zip file\">ZIP file</a> "
684
+ "from <a rel=\"noreferrer\" href=\"https://github.com/tokkonopapa/WordPress-"
685
+ "IP-Geo-API\" title=\"tokkonopapa/WordPress-IP-Geo-API - GitHub\">WordPress-"
686
+ "IP-Geo-API</a>. Please refer to the <a rel=\"noreferrer\" href=\"http://www."
687
+ "ipgeoblock.com/codex/how-to-fix-permission-troubles.html\" title=\"How can I "
688
+ "fix permission troubles? | IP Geo Block\">FAQ</a> to install <code>ip-geo-"
689
+ "api</code> with write permission."
690
+ msgstr ""
691
+
692
+ #: admin/includes/tab-settings.php:931
693
  msgid "Local database settings"
694
  msgstr ""
695
 
696
+ #: admin/includes/tab-settings.php:946
697
  msgid "database"
698
  msgstr ""
699
 
700
+ #: admin/includes/tab-settings.php:947 classes/class-ip-geo-block-cron.php:370
701
  #, php-format
702
  msgid "Last update: %s"
703
  msgstr ""
704
 
705
+ #: admin/includes/tab-settings.php:956
706
  msgid "Auto updating (once a month)"
707
  msgstr ""
708
 
709
+ #: admin/includes/tab-settings.php:973
710
  msgid "Download database"
711
  msgstr ""
712
 
713
+ #: admin/includes/tab-settings.php:981
714
  msgid "Download now"
715
  msgstr ""
716
 
717
+ #: admin/includes/tab-settings.php:993
718
  msgid "Record settings"
719
  msgstr ""
720
 
721
+ #: admin/includes/tab-settings.php:1002
722
  msgid "Record validation statistics"
723
  msgstr ""
724
 
725
+ #: admin/includes/tab-settings.php:1018
726
  msgid "Record validation logs"
727
  msgstr ""
728
 
729
+ #: admin/includes/tab-settings.php:1030
730
  msgid "Only when blocked"
731
  msgstr ""
732
 
733
+ #: admin/includes/tab-settings.php:1031
734
  msgid "Only when passed"
735
  msgstr ""
736
 
737
+ #: admin/includes/tab-settings.php:1032
738
  msgid "Unauthenticated user"
739
  msgstr ""
740
 
741
+ #: admin/includes/tab-settings.php:1033
742
  msgid "Authenticated user"
743
  msgstr ""
744
 
745
+ #: admin/includes/tab-settings.php:1034
746
  msgid "All of validation"
747
  msgstr ""
748
 
749
+ #: admin/includes/tab-settings.php:1043
750
  msgid "Recording period of the logs (days)"
751
  msgstr ""
752
 
753
+ #: admin/includes/tab-settings.php:1059
754
  msgid "Maximum length of logs for each target"
755
  msgstr ""
756
 
757
+ #: admin/includes/tab-settings.php:1076
758
  msgid ""
759
  "<dfn title=\"e.g. action, comment, log, pwd\">$_POST keys to be recorded "
760
  "with their values in logs</dfn>"
761
  msgstr ""
762
 
763
+ #: admin/includes/tab-settings.php:1094
764
  msgid "<dfn title=\"e.g. 123.456.789.***\">Anonymize IP address</dfn>"
765
  msgstr ""
766
 
767
+ #: admin/includes/tab-settings.php:1112
768
+ msgid "IP address cache settings"
769
  msgstr ""
770
 
771
+ #: admin/includes/tab-settings.php:1121
772
  #, php-format
773
  msgid ""
774
  "<dfn title=\"If user authentication fails consecutively %d times, subsequent "
776
  "\">Expiration time [sec]</dfn>"
777
  msgstr ""
778
 
779
+ #: admin/includes/tab-settings.php:1137
780
+ msgid "Garbage collection period [sec]"
781
+ msgstr ""
782
+
783
+ #: admin/includes/tab-settings.php:1154
784
  msgid "Number of entries to be displayed in cache"
785
  msgstr ""
786
 
787
+ #: admin/includes/tab-settings.php:1173
788
  msgid "Submission settings"
789
  msgstr ""
790
 
791
+ #: admin/includes/tab-settings.php:1185
792
  msgid "The whole will be wrapped by &lt;p&gt; tag. Allowed tags: "
793
  msgstr ""
794
 
795
+ #: admin/includes/tab-settings.php:1185
796
  msgid "Message on comment form"
797
  msgstr ""
798
 
799
+ #: admin/includes/tab-settings.php:1197
800
  msgid "None"
801
  msgstr ""
802
 
803
+ #: admin/includes/tab-settings.php:1198
804
  msgid "Top"
805
  msgstr ""
806
 
807
+ #: admin/includes/tab-settings.php:1199
808
  msgid "Bottom"
809
  msgstr ""
810
 
811
+ #: admin/includes/tab-settings.php:1211
812
  msgid "Plugin settings"
813
  msgstr ""
814
 
815
+ #: admin/includes/tab-settings.php:1220
816
  msgid "Remove all settings at uninstallation"
817
  msgstr ""
818
 
819
+ #: admin/includes/tab-settings.php:1238
820
  msgid ""
821
  "<dfn title=\"Valid key for Google Maps JavaScript API\">Google Maps API key</"
822
  "dfn>"
823
  msgstr ""
824
 
825
+ #: admin/includes/tab-settings.php:1252
826
  msgid ""
827
  "You need to click the &#8220;Save Changes&#8221; button for imported "
828
  "settings to take effect."
829
  msgstr ""
830
 
831
+ #: admin/includes/tab-settings.php:1258
832
  msgid "Export / Import settings"
833
  msgstr ""
834
 
835
+ #: admin/includes/tab-settings.php:1265
836
  msgid "Export settings"
837
  msgstr ""
838
 
839
+ #: admin/includes/tab-settings.php:1266
840
  msgid "Import from the local file"
841
  msgstr ""
842
 
843
+ #: admin/includes/tab-settings.php:1266
844
  msgid "Import settings"
845
  msgstr ""
846
 
847
+ #: admin/includes/tab-settings.php:1275
848
  msgid "Import pre-defined settings"
849
  msgstr ""
850
 
851
+ #: admin/includes/tab-settings.php:1282
852
  msgid ""
853
+ "Import the preferred settings mainly for the &#8220;Back-end target "
854
+ "settings&#8221;"
855
  msgstr ""
856
 
857
+ #: admin/includes/tab-settings.php:1282
858
+ msgid "Best settings"
859
  msgstr ""
860
 
861
+ #: admin/includes/tab-settings.php:1283
862
  msgid ""
863
+ "Import the default settings to revert to the &#8220;Right after "
864
+ "installing&#8221; state"
865
  msgstr ""
866
 
867
+ #: admin/includes/tab-settings.php:1283
868
+ msgid "Default settings"
869
  msgstr ""
870
 
871
+ #: admin/includes/tab-settings.php:1293
872
  msgid "Delete DB table for validation logs"
873
  msgstr ""
874
 
875
+ #: admin/includes/tab-settings.php:1301
876
  msgid "Delete now"
877
  msgstr ""
878
 
879
+ #: admin/includes/tab-settings.php:1309
880
  msgid "Create DB table for validation logs"
881
  msgstr ""
882
 
883
+ #: admin/includes/tab-settings.php:1317
884
  msgid "Create now"
885
  msgstr ""
886
 
887
+ #: admin/includes/tab-settings.php:1327
888
  msgid ""
889
+ "<dfn title=\"Please copy &amp; paste when submitting your issue to support "
890
+ "forum.\">Installation information</dfn><br />[ <a rel=\"noreferrer\" href="
891
+ "\"https://wordpress.org/support/plugin/ip-geo-block\" title=\"WordPress "
892
+ "&#8250; Support &raquo; IP Geo Block\">support forum</a> ]"
893
+ msgstr ""
894
+
895
+ #: admin/includes/tab-settings.php:1334
896
+ msgid "Show PHP, WordPress, theme and plugins information."
897
  msgstr ""
898
 
899
+ #: admin/includes/tab-settings.php:1334
900
+ msgid "Show information"
901
+ msgstr ""
902
+
903
+ #: admin/includes/tab-settings.php:1348
904
  msgid ""
905
+ "To enhance the protection ability, please refer to &#8220;<a rel=\"noreferrer"
906
+ "\" href=\"http://www.ipgeoblock.com/codex/the-best-practice-for-target-"
907
+ "settings.html\" title=\"The best practice for target settings | IP Geo Block"
908
+ "\">The best practice for target settings</a>&#8221;."
909
  msgstr ""
910
 
911
+ #: admin/includes/tab-settings.php:1349
912
+ msgid ""
913
+ "If you have any troubles with these, please check FAQ at <a rel=\"noreferrer"
914
+ "\" href=\"https://wordpress.org/plugins/ip-geo-block/faq/\" title=\"IP Geo "
915
+ "Block &mdash; WordPress Plugins\">WordPress.org</a> and <a rel=\"noreferrer"
916
+ "\" href=\"http://www.ipgeoblock.com/codex/#faq\" title=\"Codex | IP Geo Block"
917
+ "\">Codex</a>."
918
+ msgstr ""
919
+
920
+ #: admin/includes/tab-settings.php:1356
921
  msgid ""
922
  "While Maxmind and IP2Location will fetch the local database, others will "
923
  "pass an IP address to the APIs via HTTP."
924
  msgstr ""
925
 
926
+ #: admin/includes/tab-settings.php:1357
927
  msgid ""
928
  "Please select the appropriate APIs to fit the privacy law in your country."
929
  msgstr ""
930
 
931
+ #: admin/includes/tab-settings.php:1364
932
+ msgid ""
933
+ "Please refer to the document &#8220;<a rel=\"noreferrer\" href=\"http://www."
934
+ "ipgeoblock.com/codex/#blocking-on-front-end\" title=\"Codex | IP Geo Block"
935
+ "\">Blocking on front-end</a>&#8221; for details, including restrictions on "
936
+ "cache plugin."
937
+ msgstr ""
938
+
939
+ #: admin/includes/tab-settings.php:1365
940
+ msgid ""
941
+ "If you find any issues or have something to suggest, please feel free to "
942
+ "open an issue at <a rel=\"noreferrer\" href=\"https://wordpress.org/support/"
943
+ "plugin/ip-geo-block\" title=\"WordPress &#8250; Support &raquo; IP Geo Block"
944
+ "\">support forum</a>."
945
+ msgstr ""
946
+
947
+ #: admin/includes/tab-settings.php:1372
948
+ msgid ""
949
+ "Please refer to the document &#8220;<a rel=\"noreferrer\" href=\"http://www."
950
+ "ipgeoblock.com/codex/record-settings-and-logs.html\" title=\"Codex | IP Geo "
951
+ "Block\">Record settings and logs</a>&#8221; for details."
952
+ msgstr ""
953
+
954
  #: admin/includes/tab-statistics.php:24 admin/includes/tab-statistics.php:184
955
  msgid "Statistics of validation"
956
  msgstr ""
1003
  msgid "Elapsed [sec] / Calls"
1004
  msgstr ""
1005
 
1006
+ #: admin/includes/tab-statistics.php:252
1007
  msgid "IP address in cache"
1008
  msgstr ""
1009
 
1010
+ #: admin/includes/tab-statistics.php:267
1011
  msgid "Clear cache"
1012
  msgstr ""
1013
 
1014
+ #: admin/includes/tab-statistics.php:286
1015
  msgid ""
1016
  "Current setting of [<strong>Record validation statistics</strong>] on "
1017
  "[<strong>Settings</strong>] tab is not selected [<strong>Enable</strong>]."
1018
  msgstr ""
1019
 
1020
+ #: admin/includes/tab-statistics.php:287
1021
  msgid ""
1022
  "Please set the proper condition to record and analyze the validation "
1023
  "statistics."
1024
  msgstr ""
1025
 
1026
+ #: classes/class-ip-geo-block-apis.php:651
1027
  msgid ""
1028
  "You need to select at least one IP geolocation service. Otherwise "
1029
  "<strong>you'll be blocked</strong> after the cache expires."
1030
  msgstr ""
1031
 
1032
+ #: classes/class-ip-geo-block-cron.php:227
1033
+ msgid "Your database file is up-to-date."
1034
+ msgstr ""
1035
+
1036
+ #: classes/class-ip-geo-block-cron.php:255
1037
+ #: classes/class-ip-geo-block-cron.php:313
1038
  #, php-format
1039
+ msgid "Unable to read %s. Please check the permission."
 
 
1040
  msgstr ""
1041
 
1042
+ #: classes/class-ip-geo-block-cron.php:265
1043
+ #: classes/class-ip-geo-block-cron.php:323
1044
+ #, php-format
1045
+ msgid "Can't lock %s. Please try again after a while."
1046
  msgstr ""
1047
 
1048
+ #: classes/class-ip-geo-block-cron.php:293
1049
  #, php-format
1050
+ msgid "Unable to read %s. Please check permission."
1051
+ msgstr ""
1052
+
1053
+ #: classes/class-ip-geo-block-cron.php:302
1054
+ #, php-format
1055
+ msgid "Unable to write %s. Please check permission."
1056
+ msgstr ""
1057
+
1058
+ #: classes/class-ip-geo-block-cron.php:335
1059
+ msgid "gz or zip is not supported on your system."
1060
  msgstr ""
1061
 
1062
+ #: classes/class-ip-geo-block-logs.php:149
1063
+ #, php-format
1064
+ msgid ""
1065
+ "Creating a DB table %s had failed. Once de-activate this plugin, and then "
1066
+ "activate again."
1067
+ msgstr ""
1068
+
1069
+ #: wp-content/ip-geo-api/ip2location/class-ip2location.php:157
1070
+ #: wp-content/ip-geo-api/ip2location/class-ip2location.php:186
1071
+ #: wp-content/ip-geo-api/maxmind/class-maxmind.php:171
1072
+ #: wp-content/ip-geo-api/maxmind/class-maxmind.php:200
1073
  msgid "Database file does not exist."
1074
  msgstr ""
1075
+
1076
+ #: wp-content/mu-plugins/ip-geo-block-mu.php:72
1077
+ #, php-format
1078
+ msgid ""
1079
+ "Can't find IP Geo Block in your plugins directory. Please remove <code>%s</"
1080
+ "code> or re-install %s."
1081
+ msgstr ""
rewrite.php CHANGED
@@ -6,15 +6,15 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2013-2016 tokkonopapa
10
  *
11
  * THIS IS FOR THE ADVANCED USERS:
12
- * This file is for WP-ZEP. If a php file in the plugin/theme directory accepts
13
- * some malicious requests directly without loading WP core, then validation by
14
- * WP-ZEP will be bypassed. To avoid such a bypassing, those requests should be
15
- * redirected to this file in order to load WP core. The `.htaccess` in the
16
- * plugin/theme directory will help this redirection if it will be configured
17
- * as follows (for apache):
18
  *
19
  * # BEGIN IP Geo Block
20
  * <IfModule mod_rewrite.c>
@@ -27,7 +27,7 @@
27
  *
28
  * The redirected requests will be verified against the certain attack patterns
29
  * such as null byte attack or directory traversal, and then load the WordPress
30
- * core module through wp-load.php to triger WP-ZEP. If it ends up successfully,
31
  * this includes the originally requested php file to excute it.
32
  */
33
 
@@ -85,19 +85,25 @@ class IP_Geo_Block_Rewrite {
85
  if ( $settings['save_statistics'] )
86
  IP_Geo_Block_Logs::update_stat( 'admin', $validate, $settings );
87
 
 
 
 
 
 
 
88
  // send response code to refuse
89
- $context->send_response( 'admin', $exist ? $settings['response_code'] : 404 );
90
  }
91
 
92
  /**
93
  * Validation of direct excution
94
  *
95
- * @note: This function doesn't care about malicious query string.
96
  */
97
  public static function exec( $context, $validate, $settings ) {
98
 
99
  // get document root
100
- // @note: super global can not be infected even when `register_globals` is on.
101
  // @see wp-admin/network.php, get_home_path() in wp-admin/includes/file.php
102
  // @link http://php.net/manual/en/security.globals.php
103
  // @link http://php.net/manual/en/reserved.variables.php#63831
@@ -115,9 +121,9 @@ class IP_Geo_Block_Rewrite {
115
 
116
  // while malicios URI may be intercepted by the server,
117
  // null byte attack should be invalidated just in case.
118
- // @note: is_file(), is_readable(), file_exists() need a valid path.
119
- // @link: http://php.net/releases/5_3_4.php, https://bugs.php.net/bug.php?id=39863
120
- // ex) $path = "/etc/passwd\0.php"; is_file( $path ) === true (5.2.14), false (5.4.4)
121
  $path = self::realpath( str_replace( "\0", '', $path ) );
122
 
123
  // check path if under the document root
@@ -131,7 +137,7 @@ class IP_Geo_Block_Rewrite {
131
  $path .= 'index.php';
132
 
133
  // check file extention
134
- // @note: if it fails, rewrite rule may be misconfigured
135
  if ( FALSE === strripos( strtolower( $path ), '.php', -4 ) )
136
  self::abort( $context, $validate, $settings, file_exists( $path ) );
137
 
@@ -209,7 +215,7 @@ endif; /* ! class_exists( 'IP_Geo_Block_Rewrite' ) */
209
  * RewriteRule ^.*\.php$ rewrite.php [L]
210
  * </IfModule>
211
  * # END IP Geo Block
212
- *
213
  * 2. `/wordpress/wp-content/themes/.htaccess`
214
  *
215
  * # BEGIN IP Geo Block
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
  *
11
  * THIS IS FOR THE ADVANCED USERS:
12
+ * This file is for WP-ZEP. If some php files in the plugins/themes directory
13
+ * accept malicious requests directly without loading WP core, then validation
14
+ * by WP-ZEP will be bypassed. To avoid such bypassing, those requests should
15
+ * be redirected to this file in order to load WP core. The `.htaccess` in the
16
+ * plugins/themes directory will help this redirection if it is configured as
17
+ * follows (for apache):
18
  *
19
  * # BEGIN IP Geo Block
20
  * <IfModule mod_rewrite.c>
27
  *
28
  * The redirected requests will be verified against the certain attack patterns
29
  * such as null byte attack or directory traversal, and then load the WordPress
30
+ * core module through wp-load.php to triger WP-ZEP. If it ends up successfully
31
  * this includes the originally requested php file to excute it.
32
  */
33
 
85
  if ( $settings['save_statistics'] )
86
  IP_Geo_Block_Logs::update_stat( 'admin', $validate, $settings );
87
 
88
+ // compose status code and message
89
+ if ( ! $exist && 404 != $settings['response_code'] ) {
90
+ $settings['response_code'] = 404;
91
+ $settings['response_msg' ] = 'Not Found';
92
+ }
93
+
94
  // send response code to refuse
95
+ $context->send_response( 'admin', $validate, $settings );
96
  }
97
 
98
  /**
99
  * Validation of direct excution
100
  *
101
+ * Note: This function doesn't care about malicious query string.
102
  */
103
  public static function exec( $context, $validate, $settings ) {
104
 
105
  // get document root
106
+ // Note: super global can not be infected even when `register_globals` is on.
107
  // @see wp-admin/network.php, get_home_path() in wp-admin/includes/file.php
108
  // @link http://php.net/manual/en/security.globals.php
109
  // @link http://php.net/manual/en/reserved.variables.php#63831
121
 
122
  // while malicios URI may be intercepted by the server,
123
  // null byte attack should be invalidated just in case.
124
+ // Note: is_file(), is_readable(), file_exists() need a valid path.
125
+ // @link http://php.net/releases/5_3_4.php, https://bugs.php.net/bug.php?id=39863
126
+ // @example $path = "/etc/passwd\0.php"; is_file( $path ) === true (5.2.14), false (5.4.4)
127
  $path = self::realpath( str_replace( "\0", '', $path ) );
128
 
129
  // check path if under the document root
137
  $path .= 'index.php';
138
 
139
  // check file extention
140
+ // if it fails, rewrite rule may be misconfigured
141
  if ( FALSE === strripos( strtolower( $path ), '.php', -4 ) )
142
  self::abort( $context, $validate, $settings, file_exists( $path ) );
143
 
215
  * RewriteRule ^.*\.php$ rewrite.php [L]
216
  * </IfModule>
217
  * # END IP Geo Block
218
+ *
219
  * 2. `/wordpress/wp-content/themes/.htaccess`
220
  *
221
  * # BEGIN IP Geo Block
samples.php CHANGED
@@ -1,14 +1,4 @@
1
  <?php
2
- /**
3
- * This block is for test purpose.
4
- *
5
- */
6
- if ( ! empty( $_GET['wp-load'] ) )
7
- include_once substr( __FILE__, 0, strpos( __FILE__, '/wp-content/' ) ) . '/wp-load.php';
8
-
9
- // Status same as admin-ajax.php
10
- die( '0' );
11
-
12
  /**
13
  * Samples/Snippets to extend functionality of IP Geo Block
14
  *
@@ -16,11 +6,16 @@ die( '0' );
16
  * @author tokkonopapa <tokkonopapa@yahoo.com>
17
  * @license GPL-2.0+
18
  * @link http://www.ipgeoblock.com/
19
- * @copyright 2014-2016 tokkonopapa
20
  */
21
- if ( class_exists( 'IP_Geo_Block' ) ):
 
 
 
 
 
22
 
23
- define( 'IP_GEO_BLOCK_DEBUG', false );
24
 
25
  /**
26
  * Example 1: Usage of 'ip-geo-block-ip-addr'
1
  <?php
 
 
 
 
 
 
 
 
 
 
2
  /**
3
  * Samples/Snippets to extend functionality of IP Geo Block
4
  *
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2014-2017 tokkonopapa
10
  */
11
+ /* Start loading wp-load.php */
12
+ if ( ! empty( $_GET['wp-load'] ) ) {
13
+ include_once substr( __FILE__, 0, strpos( __FILE__, '/wp-content/' ) ) . '/wp-load.php';
14
+ }
15
+ die( '0' );
16
+ /* End of loading wp-load.php */
17
 
18
+ if ( class_exists( 'IP_Geo_Block' ) ):
19
 
20
  /**
21
  * Example 1: Usage of 'ip-geo-block-ip-addr'
uninstall.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
- * @copyright 2013-2016 tokkonopapa
10
  */
11
 
12
  // If uninstall not called from WordPress, then exit
@@ -15,10 +15,11 @@ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
15
  }
16
 
17
  define( 'IP_GEO_BLOCK_PATH', plugin_dir_path( __FILE__ ) ); // @since 2.8
18
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block.php' );
19
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-util.php' );
20
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php' );
21
- require_once( IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php' );
 
22
 
23
  class IP_Geo_Block_Uninstall {
24
 
@@ -28,7 +29,6 @@ class IP_Geo_Block_Uninstall {
28
  */
29
  private static function delete_blog_options() {
30
  delete_option( IP_Geo_Block::OPTION_NAME ); // @since 1.2.0
31
- delete_transient( IP_Geo_Block::CACHE_NAME ); // @since 2.8
32
  IP_Geo_Block_Logs::delete_tables();
33
  }
34
 
6
  * @author tokkonopapa <tokkonopapa@yahoo.com>
7
  * @license GPL-2.0+
8
  * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
  */
11
 
12
  // If uninstall not called from WordPress, then exit
15
  }
16
 
17
  define( 'IP_GEO_BLOCK_PATH', plugin_dir_path( __FILE__ ) ); // @since 2.8
18
+
19
+ require IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block.php';
20
+ require IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-util.php';
21
+ require IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php';
22
+ require IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php';
23
 
24
  class IP_Geo_Block_Uninstall {
25
 
29
  */
30
  private static function delete_blog_options() {
31
  delete_option( IP_Geo_Block::OPTION_NAME ); // @since 1.2.0
 
32
  IP_Geo_Block_Logs::delete_tables();
33
  }
34
 
wp-content/ip-geo-api/drop-in-sample.php CHANGED
@@ -8,6 +8,8 @@
8
  * @author tokkonopapa <tokkonopapa@yahoo.com>
9
  * @license GPL-2.0+
10
  * @link http://www.ipgeoblock.com/
 
 
11
  */
12
  if ( ! class_exists( 'IP_Geo_Block' ) ) {
13
  die;
@@ -21,12 +23,41 @@ if ( ! class_exists( 'IP_Geo_Block' ) ) {
21
 
22
  /**
23
  * Example: Returns "404 Not found" to hide login page.
24
- * Note: Use IP_Geo_Block::add_filter() instead of add_filter()
 
 
25
  */
26
- /*
27
  function my_login_status( $code ) {
28
  return 404;
29
  }
30
 
31
  IP_Geo_Block::add_filter( 'ip-geo-block-login-status', 'my_login_status', 10, 1 );
32
- //*/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  * @author tokkonopapa <tokkonopapa@yahoo.com>
9
  * @license GPL-2.0+
10
  * @link http://www.ipgeoblock.com/
11
+ * @see http://www.ipgeoblock.com/codex/#filter-hooks
12
+ * @example Use `IP_Geo_Block::add_filter()` instead of `add_filter()`
13
  */
14
  if ( ! class_exists( 'IP_Geo_Block' ) ) {
15
  die;
23
 
24
  /**
25
  * Example: Returns "404 Not found" to hide login page.
26
+ *
27
+ * @param int $code HTTP status code.
28
+ * @return int modified HTTP status code.
29
  */
30
+ /* -- ADD `/` TO THE TOP OR END OF THIS LINE TO ACTIVATE THE FOLLOWINGS -- *
31
  function my_login_status( $code ) {
32
  return 404;
33
  }
34
 
35
  IP_Geo_Block::add_filter( 'ip-geo-block-login-status', 'my_login_status', 10, 1 );
36
+ //*/
37
+
38
+ /**
39
+ * Example: Change mode of recording log according to the target.
40
+ *
41
+ * @param int $mode 1:blocked 2:passed 3:unauth 4:auth 5:all
42
+ * @param string $hook 'comment', 'xmlrpc', 'login', 'admin', 'public'
43
+ * @param array 'ip', 'auth', 'code', 'result'
44
+ * @return int $mode modefied recording mode.
45
+ */
46
+ /* -- ADD `/` TO THE TOP OR END OF THIS LINE TO ACTIVATE THE FOLLOWINGS -- *
47
+ function my_record_logs( $mode, $hook, $validate ) {
48
+ // Countries where you want to supress recording logs.
49
+ $whitelist = array(
50
+ 'JP',
51
+ );
52
+
53
+ // Suppress recording logs in case of whitelisted countries on public facing pages.
54
+ if ( 'public' !== $hook || in_array( $validate['code'], $whitelist, TRUE ) ) {
55
+ return 1; // Only when blocked
56
+ }
57
+ else {
58
+ return 3; // Unauthenticated user
59
+ }
60
+ }
61
+
62
+ IP_Geo_Block::add_filter( 'ip-geo-block-record-logs', 'my_record_logs', 10, 3 );
63
+ //*/
wp-content/ip-geo-api/ip2location/IP2Location.php CHANGED
@@ -204,6 +204,7 @@ class IP2Location {
204
  throw new Exception('IP2Location.class.php: Unable to open file "' . $file . '".');
205
  }
206
 
 
207
  $stats = fstat($fp);
208
 
209
  if ($shm_id = @shmop_open(self::SHM_KEY, 'w', 0, 0)) {
@@ -220,6 +221,7 @@ class IP2Location {
220
  }
221
  shmop_close($shm_id);
222
  }
 
223
  fclose($fp);
224
 
225
  $this->shmId = @shmop_open(self::SHM_KEY, 'a', 0, 0);
@@ -233,11 +235,13 @@ class IP2Location {
233
  default:
234
  $this->mode = self::FILE_IO;
235
  $this->resource = fopen($file, 'rb');
 
236
 
237
  if ($mode == self::MEMORY_CACHE) {
238
  $this->mode = self::MEMORY_CACHE;
239
  $stats = fstat($this->resource);
240
  $this->buffer = fread($this->resource, $stats['size']);
 
241
  }
242
  }
243
 
@@ -254,6 +258,19 @@ class IP2Location {
254
  $this->result = new IP2LocationRecord();
255
  }
256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  /**
258
  * Read bytes.
259
  */
204
  throw new Exception('IP2Location.class.php: Unable to open file "' . $file . '".');
205
  }
206
 
207
+ flock($fp, LOCK_SH); // @since 1.1.6
208
  $stats = fstat($fp);
209
 
210
  if ($shm_id = @shmop_open(self::SHM_KEY, 'w', 0, 0)) {
221
  }
222
  shmop_close($shm_id);
223
  }
224
+ flock($fp, LOCK_UN); // @since 1.1.6
225
  fclose($fp);
226
 
227
  $this->shmId = @shmop_open(self::SHM_KEY, 'a', 0, 0);
235
  default:
236
  $this->mode = self::FILE_IO;
237
  $this->resource = fopen($file, 'rb');
238
+ flock($this->resource, LOCK_SH); // @since 1.1.6
239
 
240
  if ($mode == self::MEMORY_CACHE) {
241
  $this->mode = self::MEMORY_CACHE;
242
  $stats = fstat($this->resource);
243
  $this->buffer = fread($this->resource, $stats['size']);
244
+ $this->close(); // @since 1.1.6
245
  }
246
  }
247
 
258
  $this->result = new IP2LocationRecord();
259
  }
260
 
261
+ /**
262
+ * Close resource.
263
+ *
264
+ * @since 1.1.6
265
+ */
266
+ public function close() {
267
+ if ($this->resource) {
268
+ flock($this->resource, LOCK_UN);
269
+ fclose($this->resource);
270
+ $this->resource = NULL;
271
+ }
272
+ }
273
+
274
  /**
275
  * Read bytes.
276
  */
wp-content/ip-geo-api/ip2location/class-ip2location.php CHANGED
@@ -1,4 +1,13 @@
1
  <?php
 
 
 
 
 
 
 
 
 
2
  if ( class_exists( 'IP_Geo_Block_API' ) ) :
3
 
4
  /**
@@ -9,9 +18,10 @@ define( 'IP_GEO_BLOCK_IP2LOC_IPV4_DAT', 'IP2LOCATION-LITE-DB1.BIN' );
9
  define( 'IP_GEO_BLOCK_IP2LOC_IPV6_DAT', 'IP2LOCATION-LITE-DB1.IPV6.BIN' );
10
  define( 'IP_GEO_BLOCK_IP2LOC_IPV4_ZIP', 'http://download.ip2location.com/lite/IP2LOCATION-LITE-DB1.BIN.ZIP' );
11
  define( 'IP_GEO_BLOCK_IP2LOC_IPV6_ZIP', 'http://download.ip2location.com/lite/IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP' );
 
12
 
13
  /**
14
- * Class for IP2Location (ver. 1.1.5)
15
  *
16
  * URL : http://www.ip2location.com/
17
  * Term of use : http://www.ip2location.com/terms
@@ -63,8 +73,10 @@ class IP_Geo_Block_API_IP2Location extends IP_Geo_Block_API {
63
  try {
64
  $geo = new IP2Location( $file );
65
  if ( $geo && ( $geo->get_database_type() & $type ) ) {
66
- $res = array();
67
  $data = $geo->lookup( $ip );
 
 
 
68
 
69
  foreach ( $this->transform_table as $key => $val ) {
70
  if ( isset( $data->$val ) && IP2Location::FIELD_NOT_SUPPORTED !== $data->$val )
@@ -127,7 +139,7 @@ class IP_Geo_Block_API_IP2Location extends IP_Geo_Block_API {
127
  }
128
 
129
  public function get_attribution() {
130
- return 'This site or product includes IP2Location LITE data available from <a class="ip-geo-block-link" href="http://www.ip2location.com" rel=noreferrer target=_blank>http://www.ip2location.com</a>. (CC BY-SA 4.0)';
131
  }
132
 
133
  public function add_settings_field( $field, $section, $option_slug, $option_name, $options, $callback, $str_path, $str_last ) {
@@ -150,7 +162,7 @@ class IP_Geo_Block_API_IP2Location extends IP_Geo_Block_API {
150
 
151
  add_settings_field(
152
  $option_name . $field . '_ipv4',
153
- "$field $str_path (IPv4)",
154
  $callback,
155
  $option_slug,
156
  $section,
@@ -179,7 +191,7 @@ class IP_Geo_Block_API_IP2Location extends IP_Geo_Block_API {
179
 
180
  add_settings_field(
181
  $option_name . $field . '_ipv6',
182
- "$field $str_path (IPv6)",
183
  $callback,
184
  $option_slug,
185
  $section,
1
  <?php
2
+ /**
3
+ * IP Geo Block API class library for IP2Location
4
+ *
5
+ * @version 1.1.8
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
+ */
11
  if ( class_exists( 'IP_Geo_Block_API' ) ) :
12
 
13
  /**
18
  define( 'IP_GEO_BLOCK_IP2LOC_IPV6_DAT', 'IP2LOCATION-LITE-DB1.IPV6.BIN' );
19
  define( 'IP_GEO_BLOCK_IP2LOC_IPV4_ZIP', 'http://download.ip2location.com/lite/IP2LOCATION-LITE-DB1.BIN.ZIP' );
20
  define( 'IP_GEO_BLOCK_IP2LOC_IPV6_ZIP', 'http://download.ip2location.com/lite/IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP' );
21
+ define( 'IP_GEO_BLOCK_IP2LOC_DOWNLOAD', 'http://lite.ip2location.com/database/ip-country' );
22
 
23
  /**
24
+ * Class for IP2Location
25
  *
26
  * URL : http://www.ip2location.com/
27
  * Term of use : http://www.ip2location.com/terms
73
  try {
74
  $geo = new IP2Location( $file );
75
  if ( $geo && ( $geo->get_database_type() & $type ) ) {
 
76
  $data = $geo->lookup( $ip );
77
+ $geo->close(); // @since 1.1.6
78
+
79
+ $res = array();
80
 
81
  foreach ( $this->transform_table as $key => $val ) {
82
  if ( isset( $data->$val ) && IP2Location::FIELD_NOT_SUPPORTED !== $data->$val )
139
  }
140
 
141
  public function get_attribution() {
142
+ return 'This site or product includes IP2Location LITE data available from <a class="ip-geo-block-link" href="http://www.ip2location.com" rel=noreferrer target=_blank>http://www.ip2location.com</a>. (<a href="https://creativecommons.org/licenses/by-sa/4.0/" title="Creative Commons &mdash; Attribution-ShareAlike 4.0 International &mdash; CC BY-SA 4.0" rel=noreferrer target=_blank>CC BY-SA 4.0</a>)';
143
  }
144
 
145
  public function add_settings_field( $field, $section, $option_slug, $option_name, $options, $callback, $str_path, $str_last ) {
162
 
163
  add_settings_field(
164
  $option_name . $field . '_ipv4',
165
+ "$field $str_path (<a rel='noreferrer' href='" . IP_GEO_BLOCK_IP2LOC_DOWNLOAD . "' title='" . IP_GEO_BLOCK_IP2LOC_IPV4_ZIP . "'>IPv4</a>)",
166
  $callback,
167
  $option_slug,
168
  $section,
191
 
192
  add_settings_field(
193
  $option_name . $field . '_ipv6',
194
+ "$field $str_path (<a rel='noreferrer' href='" . IP_GEO_BLOCK_IP2LOC_DOWNLOAD . "' title='" . IP_GEO_BLOCK_IP2LOC_IPV6_ZIP . "'>IPv6</a>)",
195
  $callback,
196
  $option_slug,
197
  $section,
wp-content/ip-geo-api/maxmind/class-maxmind.php CHANGED
@@ -1,4 +1,13 @@
1
  <?php
 
 
 
 
 
 
 
 
 
2
  if ( class_exists( 'IP_Geo_Block_API' ) ) :
3
 
4
  /**
@@ -9,9 +18,10 @@ define( 'IP_GEO_BLOCK_MAXMIND_IPV4_DAT', 'GeoIP.dat' );
9
  define( 'IP_GEO_BLOCK_MAXMIND_IPV6_DAT', 'GeoIPv6.dat' );
10
  define( 'IP_GEO_BLOCK_MAXMIND_IPV4_ZIP', 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz' );
11
  define( 'IP_GEO_BLOCK_MAXMIND_IPV6_ZIP', 'http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz' );
 
12
 
13
  /**
14
- * Class for Maxmind (ver. 1.1.5)
15
  *
16
  * URL : http://dev.maxmind.com/geoip/legacy/geolite/
17
  * Term of use : http://dev.maxmind.com/geoip/legacy/geolite/#License
@@ -34,6 +44,10 @@ class IP_Geo_Block_API_Maxmind extends IP_Geo_Block_API {
34
  );
35
  }
36
 
 
 
 
 
37
  public function get_location( $ip, $args = array() ) {
38
  $settings = IP_Geo_Block::get_option();
39
 
@@ -82,6 +96,14 @@ class IP_Geo_Block_API_Maxmind extends IP_Geo_Block_API {
82
  $res = $this->location_city( geoip_record_by_addr_v6( $geo, $ip ) );
83
  break;
84
 
 
 
 
 
 
 
 
 
85
  default:
86
  $res = array( 'errorMessage' => 'unknown database type' );
87
  }
@@ -134,7 +156,7 @@ class IP_Geo_Block_API_Maxmind extends IP_Geo_Block_API {
134
  }
135
 
136
  public function get_attribution() {
137
- return 'This product includes GeoLite data created by MaxMind, available from <a class="ip-geo-block-link" href="http://www.maxmind.com" rel=noreferrer target=_blank>http://www.maxmind.com</a>. (CC BY-SA 3.0)';
138
  }
139
 
140
  public function add_settings_field( $field, $section, $option_slug, $option_name, $options, $callback, $str_path, $str_last ) {
@@ -154,7 +176,7 @@ class IP_Geo_Block_API_Maxmind extends IP_Geo_Block_API {
154
 
155
  add_settings_field(
156
  $option_name . $field . '_ipv4',
157
- "$field $str_path (IPv4)",
158
  $callback,
159
  $option_slug,
160
  $section,
@@ -183,7 +205,7 @@ class IP_Geo_Block_API_Maxmind extends IP_Geo_Block_API {
183
 
184
  add_settings_field(
185
  $option_name . $field . '_ipv6',
186
- "$field $str_path (IPv6)",
187
  $callback,
188
  $option_slug,
189
  $section,
1
  <?php
2
+ /**
3
+ * IP Geo Block API class library for Maxmind
4
+ *
5
+ * @version 1.1.8
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2017 tokkonopapa
10
+ */
11
  if ( class_exists( 'IP_Geo_Block_API' ) ) :
12
 
13
  /**
18
  define( 'IP_GEO_BLOCK_MAXMIND_IPV6_DAT', 'GeoIPv6.dat' );
19
  define( 'IP_GEO_BLOCK_MAXMIND_IPV4_ZIP', 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz' );
20
  define( 'IP_GEO_BLOCK_MAXMIND_IPV6_ZIP', 'http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz' );
21
+ define( 'IP_GEO_BLOCK_MAXMIND_DOWNLOAD', 'http://dev.maxmind.com/geoip/legacy/geolite/' );
22
 
23
  /**
24
+ * Class for Maxmind
25
  *
26
  * URL : http://dev.maxmind.com/geoip/legacy/geolite/
27
  * Term of use : http://dev.maxmind.com/geoip/legacy/geolite/#License
44
  );
45
  }
46
 
47
+ private function location_asnumber( $record ) {
48
+ return array( 'ASN' => $record );
49
+ }
50
+
51
  public function get_location( $ip, $args = array() ) {
52
  $settings = IP_Geo_Block::get_option();
53
 
96
  $res = $this->location_city( geoip_record_by_addr_v6( $geo, $ip ) );
97
  break;
98
 
99
+ case GEOIP_ASNUM_EDITION:
100
+ $res = $this->location_asnumber( geoip_name_by_addr( $geo, $ip ) );
101
+ break;
102
+
103
+ case GEOIP_ASNUM_EDITION_V6:
104
+ $res = $this->location_asnumber( geoip_name_by_addr_v6( $geo, $ip ) );
105
+ break;
106
+
107
  default:
108
  $res = array( 'errorMessage' => 'unknown database type' );
109
  }
156
  }
157
 
158
  public function get_attribution() {
159
+ return 'This product includes GeoLite data created by MaxMind, available from <a class="ip-geo-block-link" href="http://www.maxmind.com" rel=noreferrer target=_blank>http://www.maxmind.com</a>. (<a href="https://creativecommons.org/licenses/by-sa/4.0/" title="Creative Commons &mdash; Attribution-ShareAlike 4.0 International &mdash; CC BY-SA 4.0" rel=noreferrer target=_blank>CC BY-SA 4.0</a>)';
160
  }
161
 
162
  public function add_settings_field( $field, $section, $option_slug, $option_name, $options, $callback, $str_path, $str_last ) {
176
 
177
  add_settings_field(
178
  $option_name . $field . '_ipv4',
179
+ "$field $str_path (<a rel='noreferrer' href='" . IP_GEO_BLOCK_MAXMIND_DOWNLOAD . "' title='" . IP_GEO_BLOCK_MAXMIND_IPV4_ZIP . "'>IPv4</a>)",
180
  $callback,
181
  $option_slug,
182
  $section,
205
 
206
  add_settings_field(
207
  $option_name . $field . '_ipv6',
208
+ "$field $str_path (<a rel='noreferrer' href='" . IP_GEO_BLOCK_MAXMIND_DOWNLOAD . "' title='" . IP_GEO_BLOCK_MAXMIND_IPV6_ZIP . "'>IPv6</a>)",
209
  $callback,
210
  $option_slug,
211
  $section,
wp-content/ip-geo-api/maxmind/geoip.inc CHANGED
@@ -255,7 +255,8 @@ function geoip_open($filename, $flags)
255
  if ($gi->flags & GEOIP_SHARED_MEMORY) {
256
  $gi->shmid = @shmop_open(GEOIP_SHM_KEY, "a", 0, 0);
257
  } else {
258
- $gi->filehandle = fopen($filename, "rb") or die("Can not open $filename\n");
 
259
  if ($gi->flags & GEOIP_MEMORY_CACHE) {
260
  $s_array = fstat($gi->filehandle);
261
  $gi->memory_buffer = fread($gi->filehandle, $s_array['size']);
@@ -272,7 +273,7 @@ function geoip_close($gi)
272
  return true;
273
  }
274
 
275
- return fclose($gi->filehandle);
276
  }
277
 
278
  function geoip_country_id_by_addr_v6($gi, $addr)
@@ -406,6 +407,55 @@ function _geoip_seek_country($gi, $ipnum)
406
  trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
407
  return false;
408
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
 
410
  function _safe_substr($string, $start, $length)
411
  {
255
  if ($gi->flags & GEOIP_SHARED_MEMORY) {
256
  $gi->shmid = @shmop_open(GEOIP_SHM_KEY, "a", 0, 0);
257
  } else {
258
+ $gi->filehandle = fopen($filename, "rb"); if (!$gi->filehandle) return FALSE; // or die("Can not open $filename\n");
259
+ flock($gi->filehandle, LOCK_SH); // @since 1.1.6
260
  if ($gi->flags & GEOIP_MEMORY_CACHE) {
261
  $s_array = fstat($gi->filehandle);
262
  $gi->memory_buffer = fread($gi->filehandle, $s_array['size']);
273
  return true;
274
  }
275
 
276
+ return flock($gi->filehandle, LOCK_UN) and fclose($gi->filehandle); // @since 1.1.6
277
  }
278
 
279
  function geoip_country_id_by_addr_v6($gi, $addr)
407
  trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
408
  return false;
409
  }
410
+ function _common_get_org($gi, $seek_org)
411
+ {
412
+ $record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments;
413
+ if ($gi->flags & GEOIP_SHARED_MEMORY) {
414
+ $org_buf = _sharedMemRead($gi, $record_pointer, MAX_ORG_RECORD_LENGTH);
415
+ } else {
416
+ fseek($gi->filehandle, $record_pointer, SEEK_SET);
417
+ $org_buf = fread($gi->filehandle, MAX_ORG_RECORD_LENGTH);
418
+ }
419
+ $org_buf = _safe_substr($org_buf, 0, strpos($org_buf, "\0"));
420
+ return $org_buf;
421
+ }
422
+
423
+ function _get_org_v6($gi, $ipnum)
424
+ {
425
+ $seek_org = _geoip_seek_country_v6($gi, $ipnum);
426
+ if ($seek_org == $gi->databaseSegments) {
427
+ return null;
428
+ }
429
+ return _common_get_org($gi, $seek_org);
430
+ }
431
+
432
+ function _get_org($gi, $ipnum)
433
+ {
434
+ $seek_org = _geoip_seek_country($gi, $ipnum);
435
+ if ($seek_org == $gi->databaseSegments) {
436
+ return null;
437
+ }
438
+ return _common_get_org($gi, $seek_org);
439
+ }
440
+
441
+
442
+ function geoip_name_by_addr_v6($gi, $addr)
443
+ {
444
+ if ($addr == null) {
445
+ return 0;
446
+ }
447
+ $ipnum = inet_pton($addr);
448
+ return _get_org_v6($gi, $ipnum);
449
+ }
450
+
451
+ function geoip_name_by_addr($gi, $addr)
452
+ {
453
+ if ($addr == null) {
454
+ return 0;
455
+ }
456
+ $ipnum = ip2long($addr);
457
+ return _get_org($gi, $ipnum);
458
+ }
459
 
460
  function _safe_substr($string, $start, $length)
461
  {
wp-content/mu-plugins/ip-geo-block-mu.php CHANGED
@@ -8,9 +8,9 @@
8
  * @author tokkonopapa <tokkonopapa@yahoo.com>
9
  * @license GPL-2.0+
10
  * @link http://www.ipgeoblock.com/
11
- * @copyright 2013-2016 tokkonopapa
12
  *
13
- * Plugin Name: IP Geo Block
14
  * Plugin URI: http://wordpress.org/plugins/ip-geo-block/
15
  * Description: It blocks any spams, login attempts and malicious access to the admin area posted from outside your nation, and also prevents zero-day exploit.
16
  * Version: 3.0.0
@@ -31,29 +31,49 @@ if ( ! class_exists( 'IP_Geo_Block' ) ):
31
  /*----------------------------------------------------------------------------*
32
  * Detect plugin. For use on Front End only.
33
  *----------------------------------------------------------------------------*/
34
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
35
 
36
  $plugin = 'ip-geo-block/ip-geo-block.php';
37
 
38
  if ( is_plugin_active( $plugin ) || is_plugin_active_for_network( $plugin ) ) {
39
 
40
  // Load plugin class
41
- require( WP_PLUGIN_DIR . '/' . $plugin );
 
42
 
43
- $plugin = IP_Geo_Block::get_option();
44
 
45
- // check setup had already done
46
- if ( version_compare( $plugin['version'], IP_Geo_Block::VERSION ) >= 0 && $plugin['matching_rule'] >= 0 ) {
47
 
48
- // Remove instanciation
49
- remove_action( 'plugins_loaded', array( 'IP_Geo_Block', 'get_instance' ) );
50
 
51
- // Instanciate immediately
52
- IP_Geo_Block::get_instance();
53
- // add_action( 'muplugins_loaded', array( 'IP_Geo_Block', 'get_instance' ) );
54
  }
 
 
 
 
 
55
  }
56
 
57
  unset( $plugin );
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  endif; // ! class_exists( 'IP_Geo_Block' )
8
  * @author tokkonopapa <tokkonopapa@yahoo.com>
9
  * @license GPL-2.0+
10
  * @link http://www.ipgeoblock.com/
11
+ * @copyright 2013-2017 tokkonopapa
12
  *
13
+ * Plugin Name: IP Geo Block (mu)
14
  * Plugin URI: http://wordpress.org/plugins/ip-geo-block/
15
  * Description: It blocks any spams, login attempts and malicious access to the admin area posted from outside your nation, and also prevents zero-day exploit.
16
  * Version: 3.0.0
31
  /*----------------------------------------------------------------------------*
32
  * Detect plugin. For use on Front End only.
33
  *----------------------------------------------------------------------------*/
34
+ include_once ABSPATH . 'wp-admin/includes/plugin.php';
35
 
36
  $plugin = 'ip-geo-block/ip-geo-block.php';
37
 
38
  if ( is_plugin_active( $plugin ) || is_plugin_active_for_network( $plugin ) ) {
39
 
40
  // Load plugin class
41
+ if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin ) ) {
42
+ require WP_PLUGIN_DIR . '/' . $plugin;
43
 
44
+ $plugin = IP_Geo_Block::get_option();
45
 
46
+ // check setup had already done
47
+ if ( version_compare( $plugin['version'], IP_Geo_Block::VERSION ) >= 0 && $plugin['matching_rule'] >= 0 ) {
48
 
49
+ // Remove instanciation
50
+ remove_action( 'plugins_loaded', array( 'IP_Geo_Block', 'get_instance' ) );
51
 
52
+ // Instanciate immediately
53
+ IP_Geo_Block::get_instance();
54
+ }
55
  }
56
+
57
+ else {
58
+ add_action( 'admin_notices', 'ip_geo_block_mu_notice' );
59
+ }
60
+
61
  }
62
 
63
  unset( $plugin );
64
 
65
+ /**
66
+ * Show global notice.
67
+ *
68
+ */
69
+ function ip_geo_block_mu_notice() {
70
+ echo '<div class="notice notice-error is-dismissible"><p>';
71
+ echo sprintf(
72
+ __( 'Can\'t find IP Geo Block in your plugins directory. Please remove <code>%s</code> or re-install %s.', 'ip-geo-block' ),
73
+ __FILE__,
74
+ '<a href="https://wordpress.org/plugins/ip-geo-block/" title="IP Geo Block &mdash; WordPress Plugins">IP Geo Block</a>'
75
+ );
76
+ echo '</></div>' . "\n";
77
+ }
78
+
79
  endif; // ! class_exists( 'IP_Geo_Block' )