Version Description
Sep 23 2020 = * Fix: URL exclusions setting. * Fix: Login scripts output fixed. * Fix: Updater function name fixed. * New: Debug mode for Anti-Crawler. * Fix: Pass AC check if 301 HTTP response code received. * Fix: Antibot cookie value fixed.
Download this release
Release Info
Developer | shagimuratov |
Plugin | Spam protection, AntiSpam, FireWall by CleanTalk |
Version | 5.146.1 |
Comparing to | |
See all releases |
Code changes from version 5.146 to 5.146.1
- cleantalk.php +1 -1
- inc/cleantalk-admin.php +1 -1
- inc/cleantalk-common.php +3 -3
- inc/cleantalk-public.php +11 -3
- inc/cleantalk-settings.php +1 -1
- inc/cleantalk-updater.php +1 -1
- lib/Cleantalk/Antispam/Cleantalk.php +542 -542
- lib/Cleantalk/ApbctWP/Firewall/AntiCrawler.php +42 -19
- lib/Cleantalk/ApbctWP/Firewall/SFW.php +3 -1
- lib/Cleantalk/ApbctWP/Firewall/die_page_anticrawler.html +3 -0
- lib/Cleantalk/Templates/Singleton.php +35 -35
- lib/cleantalk-php-patch.php +90 -79
- readme.txt +10 -8
cleantalk.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Anti-Spam by CleanTalk
|
4 |
Plugin URI: https://cleantalk.org
|
5 |
Description: Max power, all-in-one, no Captcha, premium anti-spam plugin. No comment spam, no registration spam, no contact spam, protects any WordPress forms.
|
6 |
-
Version: 5.146
|
7 |
Author: СleanTalk <welcome@cleantalk.org>
|
8 |
Author URI: https://cleantalk.org
|
9 |
Text Domain: cleantalk-spam-protect
|
3 |
Plugin Name: Anti-Spam by CleanTalk
|
4 |
Plugin URI: https://cleantalk.org
|
5 |
Description: Max power, all-in-one, no Captcha, premium anti-spam plugin. No comment spam, no registration spam, no contact spam, protects any WordPress forms.
|
6 |
+
Version: 5.146.1
|
7 |
Author: СleanTalk <welcome@cleantalk.org>
|
8 |
Author URI: https://cleantalk.org
|
9 |
Text Domain: cleantalk-spam-protect
|
inc/cleantalk-admin.php
CHANGED
@@ -14,7 +14,7 @@ add_action( 'admin_head','apbct_admin_set_cookie_for_anti_bot' );
|
|
14 |
|
15 |
function apbct_admin_set_cookie_for_anti_bot(){
|
16 |
global $apbct;
|
17 |
-
echo '<script>document.cookie = "apbct_antibot=' .
|
18 |
}
|
19 |
|
20 |
function apbct_add_buttons_to_comments_and_users( $unused_argument ) {
|
14 |
|
15 |
function apbct_admin_set_cookie_for_anti_bot(){
|
16 |
global $apbct;
|
17 |
+
echo '<script>document.cookie = "apbct_antibot=' . hash( 'sha256', $apbct->api_key . $apbct->data['salt'] ) . '; path=/; expires=0; samesite=lax";</script>';
|
18 |
}
|
19 |
|
20 |
function apbct_add_buttons_to_comments_and_users( $unused_argument ) {
|
inc/cleantalk-common.php
CHANGED
@@ -273,11 +273,11 @@ function apbct_exclusions_check__url() {
|
|
273 |
// Fix for AJAX forms
|
274 |
$haystack = apbct_get_server_variable( 'REQUEST_URI' ) == '/wp-admin/admin-ajax.php' && ! apbct_get_server_variable( 'HTTP_REFERER' )
|
275 |
? apbct_get_server_variable( 'HTTP_REFERER' )
|
276 |
-
: apbct_get_server_variable( 'REQUEST_URI' );
|
277 |
-
|
278 |
foreach ( $exclusions as $exclusion ) {
|
279 |
if (
|
280 |
-
($apbct->settings['exclusions__urls__use_regexp'] && preg_match( '
|
281 |
stripos( $haystack, $exclusion ) !== false
|
282 |
){
|
283 |
return true;
|
273 |
// Fix for AJAX forms
|
274 |
$haystack = apbct_get_server_variable( 'REQUEST_URI' ) == '/wp-admin/admin-ajax.php' && ! apbct_get_server_variable( 'HTTP_REFERER' )
|
275 |
? apbct_get_server_variable( 'HTTP_REFERER' )
|
276 |
+
: \Cleantalk\Variables\Server::get('HTTP_HOST') . apbct_get_server_variable( 'REQUEST_URI' );
|
277 |
+
|
278 |
foreach ( $exclusions as $exclusion ) {
|
279 |
if (
|
280 |
+
($apbct->settings['exclusions__urls__use_regexp'] && preg_match( '@' . $exclusion . '@', $haystack ) === 1) ||
|
281 |
stripos( $haystack, $exclusion ) !== false
|
282 |
){
|
283 |
return true;
|
inc/cleantalk-public.php
CHANGED
@@ -1736,9 +1736,17 @@ function ct_register_form() {
|
|
1736 |
}
|
1737 |
|
1738 |
function apbct_login__scripts(){
|
1739 |
-
|
1740 |
-
|
1741 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1742 |
}
|
1743 |
|
1744 |
/**
|
1736 |
}
|
1737 |
|
1738 |
function apbct_login__scripts(){
|
1739 |
+
global $apbct;
|
1740 |
+
|
1741 |
+
// Differnt JS params
|
1742 |
+
wp_enqueue_script( 'ct_public', APBCT_URL_PATH . '/js/apbct-public.min.js', array( 'jquery' ), APBCT_VERSION, false /*in header*/ );
|
1743 |
+
|
1744 |
+
wp_localize_script('ct_public', 'ctPublic', array(
|
1745 |
+
'_ajax_nonce' => wp_create_nonce('ct_secret_stuff'),
|
1746 |
+
'_ajax_url' => admin_url('admin-ajax.php'),
|
1747 |
+
));
|
1748 |
+
|
1749 |
+
$apbct->public_script_loaded = true;
|
1750 |
}
|
1751 |
|
1752 |
/**
|
inc/cleantalk-settings.php
CHANGED
@@ -1645,7 +1645,7 @@ function apbct_settings__sanitize__exclusions($exclusions, $regexp = false){
|
|
1645 |
if( ! empty( $exclusions ) ){
|
1646 |
$exclusions = explode( ',', $exclusions );
|
1647 |
foreach ( $exclusions as $exclusion ){
|
1648 |
-
$sanitized_exclusion = trim( $exclusion );
|
1649 |
if ( ! empty( $sanitized_exclusion ) ) {
|
1650 |
if( $regexp && ! apbct_is_regexp( $exclusion ) )
|
1651 |
return false;
|
1645 |
if( ! empty( $exclusions ) ){
|
1646 |
$exclusions = explode( ',', $exclusions );
|
1647 |
foreach ( $exclusions as $exclusion ){
|
1648 |
+
$sanitized_exclusion = trim( $exclusion, " \t\n\r\0\x0B/\/" );
|
1649 |
if ( ! empty( $sanitized_exclusion ) ) {
|
1650 |
if( $regexp && ! apbct_is_regexp( $exclusion ) )
|
1651 |
return false;
|
inc/cleantalk-updater.php
CHANGED
@@ -596,7 +596,7 @@ function apbct_update_to_5_143_2() {
|
|
596 |
|
597 |
}
|
598 |
|
599 |
-
function
|
600 |
|
601 |
global $apbct;
|
602 |
|
596 |
|
597 |
}
|
598 |
|
599 |
+
function apbct_update_to_5_146_1() {
|
600 |
|
601 |
global $apbct;
|
602 |
|
lib/Cleantalk/Antispam/Cleantalk.php
CHANGED
@@ -1,542 +1,542 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Cleantalk\Antispam;
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Cleantalk base class
|
7 |
-
*
|
8 |
-
* @version 2.2
|
9 |
-
* @package Cleantalk
|
10 |
-
* @subpackage Base
|
11 |
-
* @author Cleantalk team (welcome@cleantalk.org)
|
12 |
-
* @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
|
13 |
-
* @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
|
14 |
-
* @see https://github.com/CleanTalk/php-antispam
|
15 |
-
*
|
16 |
-
*/
|
17 |
-
class Cleantalk {
|
18 |
-
|
19 |
-
/*
|
20 |
-
* Use Wordpress built-in API
|
21 |
-
*/
|
22 |
-
public $use_bultin_api = false;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Maximum data size in bytes
|
26 |
-
* @var int
|
27 |
-
*/
|
28 |
-
private $dataMaxSise = 32768;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Data compression rate
|
32 |
-
* @var int
|
33 |
-
*/
|
34 |
-
private $compressRate = 6;
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Server connection timeout in seconds
|
38 |
-
* @var int
|
39 |
-
*/
|
40 |
-
private $server_timeout = 15;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* Cleantalk server url
|
44 |
-
* @var string
|
45 |
-
*/
|
46 |
-
public $server_url = null;
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Last work url
|
50 |
-
* @var string
|
51 |
-
*/
|
52 |
-
public $work_url = null;
|
53 |
-
|
54 |
-
/**
|
55 |
-
* WOrk url ttl
|
56 |
-
* @var int
|
57 |
-
*/
|
58 |
-
public $server_ttl = null;
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Time wotk_url changer
|
62 |
-
* @var int
|
63 |
-
*/
|
64 |
-
public $server_changed = null;
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Flag is change server url
|
68 |
-
* @var bool
|
69 |
-
*/
|
70 |
-
public $server_change = false;
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Codepage of the data
|
74 |
-
* @var bool
|
75 |
-
*/
|
76 |
-
public $data_codepage = null;
|
77 |
-
|
78 |
-
/**
|
79 |
-
* API version to use
|
80 |
-
* @var string
|
81 |
-
*/
|
82 |
-
public $api_version = '/api2.0';
|
83 |
-
|
84 |
-
/**
|
85 |
-
* Use https connection to servers
|
86 |
-
* @var bool
|
87 |
-
*/
|
88 |
-
public $ssl_on = false;
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Path to SSL certificate
|
92 |
-
* @var string
|
93 |
-
*/
|
94 |
-
public $ssl_path = '';
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Minimal server response in miliseconds to catch the server
|
98 |
-
*
|
99 |
-
*/
|
100 |
-
public $min_server_timeout = 50;
|
101 |
-
|
102 |
-
/**
|
103 |
-
* Maximal server response in miliseconds to catch the server
|
104 |
-
*
|
105 |
-
*/
|
106 |
-
public $max_server_timeout = 1500;
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Function checks whether it is possible to publish the message
|
110 |
-
*
|
111 |
-
* @param CleantalkRequest $request
|
112 |
-
*
|
113 |
-
* @return bool|CleantalkResponse
|
114 |
-
*/
|
115 |
-
public function isAllowMessage(CleantalkRequest $request) {
|
116 |
-
$msg = $this->createMsg('check_message', $request);
|
117 |
-
return $this->httpRequest($msg);
|
118 |
-
}
|
119 |
-
|
120 |
-
/**
|
121 |
-
* Function checks whether it is possible to publish the message
|
122 |
-
*
|
123 |
-
* @param CleantalkRequest $request
|
124 |
-
*
|
125 |
-
* @return bool|CleantalkResponse
|
126 |
-
*/
|
127 |
-
public function isAllowUser(CleantalkRequest $request) {
|
128 |
-
$msg = $this->createMsg('check_newuser', $request);
|
129 |
-
return $this->httpRequest($msg);
|
130 |
-
}
|
131 |
-
|
132 |
-
/**
|
133 |
-
* Function sends the results of manual moderation
|
134 |
-
*
|
135 |
-
* @param CleantalkRequest $request
|
136 |
-
*
|
137 |
-
* @return bool|CleantalkResponse
|
138 |
-
*/
|
139 |
-
public function sendFeedback(CleantalkRequest $request) {
|
140 |
-
$msg = $this->createMsg('send_feedback', $request);
|
141 |
-
return $this->httpRequest($msg);
|
142 |
-
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* Create msg for cleantalk server
|
146 |
-
* @param string $method
|
147 |
-
* @param CleantalkRequest $request
|
148 |
-
* @return CleantalkRequest
|
149 |
-
*/
|
150 |
-
private function createMsg($method, CleantalkRequest $request) {
|
151 |
-
|
152 |
-
switch ($method) {
|
153 |
-
case 'check_message':
|
154 |
-
// Convert strings to UTF8
|
155 |
-
$request->message = \Cleantalk\ApbctWP\Helper::toUTF8($request->message, $this->data_codepage);
|
156 |
-
$request->example = \Cleantalk\ApbctWP\Helper::toUTF8($request->example, $this->data_codepage);
|
157 |
-
$request->sender_email = \Cleantalk\ApbctWP\Helper::toUTF8($request->sender_email, $this->data_codepage);
|
158 |
-
$request->sender_nickname = \Cleantalk\ApbctWP\Helper::toUTF8($request->sender_nickname, $this->data_codepage);
|
159 |
-
$request->message = $this->compressData($request->message);
|
160 |
-
$request->example = $this->compressData($request->example);
|
161 |
-
break;
|
162 |
-
|
163 |
-
case 'check_newuser':
|
164 |
-
// Convert strings to UTF8
|
165 |
-
$request->sender_email = \Cleantalk\ApbctWP\Helper::toUTF8($request->sender_email, $this->data_codepage);
|
166 |
-
$request->sender_nickname = \Cleantalk\ApbctWP\Helper::toUTF8($request->sender_nickname, $this->data_codepage);
|
167 |
-
break;
|
168 |
-
|
169 |
-
case 'send_feedback':
|
170 |
-
if (is_array($request->feedback)) {
|
171 |
-
$request->feedback = implode(';', $request->feedback);
|
172 |
-
}
|
173 |
-
break;
|
174 |
-
}
|
175 |
-
|
176 |
-
// Removing non UTF8 characters from request, because non UTF8 or malformed characters break json_encode().
|
177 |
-
foreach ($request as $param => $value) {
|
178 |
-
if(is_array($request->$param) || is_string($request->$param))
|
179 |
-
$request->$param = \Cleantalk\ApbctWP\Helper::removeNonUTF8($value);
|
180 |
-
}
|
181 |
-
|
182 |
-
$request->method_name = $method;
|
183 |
-
$request->message = is_array($request->message) ? json_encode($request->message) : $request->message;
|
184 |
-
|
185 |
-
// Wiping cleantalk's headers but, not for send_feedback
|
186 |
-
if($request->method_name != 'send_feedback'){
|
187 |
-
|
188 |
-
$ct_tmp = apache_request_headers();
|
189 |
-
|
190 |
-
if(isset($ct_tmp['Cookie']))
|
191 |
-
$cookie_name = 'Cookie';
|
192 |
-
elseif(isset($ct_tmp['cookie']))
|
193 |
-
$cookie_name = 'cookie';
|
194 |
-
else
|
195 |
-
$cookie_name = 'COOKIE';
|
196 |
-
|
197 |
-
$ct_tmp[$cookie_name] = preg_replace(array(
|
198 |
-
'/\s?ct_checkjs=[a-z0-9]*[^;]*;?/',
|
199 |
-
'/\s?ct_timezone=.{0,1}\d{1,2}[^;]*;?/',
|
200 |
-
'/\s?ct_pointer_data=.*5D[^;]*;?/',
|
201 |
-
'/\s?apbct_timestamp=\d*[^;]*;?/',
|
202 |
-
'/\s?apbct_site_landing_ts=\d*[^;]*;?/',
|
203 |
-
'/\s?apbct_cookies_test=%7B.*%7D[^;]*;?/',
|
204 |
-
'/\s?apbct_prev_referer=http.*?[^;]*;?/',
|
205 |
-
'/\s?ct_cookies_test=.*?[^;]*;?/',
|
206 |
-
'/\s?ct_ps_timestamp=.*?[^;]*;?/',
|
207 |
-
'/\s?ct_fkp_timestamp=\d*?[^;]*;?/',
|
208 |
-
'/\s?ct_sfw_pass_key=\d*?[^;]*;?/',
|
209 |
-
'/\s?apbct_page_hits=\d*?[^;]*;?/',
|
210 |
-
'/\s?apbct_visible_fields_count=\d*?[^;]*;?/',
|
211 |
-
'/\s?apbct_visible_fields=%7B.*%7D[^;]*;?/',
|
212 |
-
), '', $ct_tmp[$cookie_name]);
|
213 |
-
$request->all_headers = json_encode($ct_tmp);
|
214 |
-
}
|
215 |
-
|
216 |
-
return $request;
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* Compress data and encode to base64
|
221 |
-
* @param type string
|
222 |
-
* @return string
|
223 |
-
*/
|
224 |
-
private function compressData($data = null){
|
225 |
-
|
226 |
-
if (strlen($data) > $this->dataMaxSise && function_exists('\gzencode') && function_exists('base64_encode')){
|
227 |
-
|
228 |
-
$localData = \gzencode($data, $this->compressRate, FORCE_GZIP);
|
229 |
-
|
230 |
-
if ($localData === false)
|
231 |
-
return $data;
|
232 |
-
|
233 |
-
$localData = base64_encode($localData);
|
234 |
-
|
235 |
-
if ($localData === false)
|
236 |
-
return $data;
|
237 |
-
|
238 |
-
return $localData;
|
239 |
-
}
|
240 |
-
|
241 |
-
return $data;
|
242 |
-
}
|
243 |
-
|
244 |
-
/**
|
245 |
-
* httpRequest
|
246 |
-
* @param $msg
|
247 |
-
* @return boolean|\CleantalkResponse
|
248 |
-
*/
|
249 |
-
private function httpRequest($msg) {
|
250 |
-
|
251 |
-
// Using current server without changing it
|
252 |
-
$result = !empty($this->work_url) && ($this->server_changed + $this->server_ttl > time())
|
253 |
-
? $this->sendRequest($msg, $this->work_url, $this->server_timeout)
|
254 |
-
: false;
|
255 |
-
|
256 |
-
// Changing server
|
257 |
-
if ($result === false || (is_object($result) && $result->errno != 0)) {
|
258 |
-
|
259 |
-
// Split server url to parts
|
260 |
-
preg_match("/^(https?:\/\/)([^\/:]+)(.*)/i", $this->server_url, $matches);
|
261 |
-
|
262 |
-
$url_protocol = isset($matches[1]) ? $matches[1] : '';
|
263 |
-
$url_host = isset($matches[2]) ? $matches[2] : '';
|
264 |
-
$url_suffix = isset($matches[3]) ? $matches[3] : '';
|
265 |
-
|
266 |
-
$servers = $this->get_servers_ip($url_host);
|
267 |
-
|
268 |
-
// Loop until find work server
|
269 |
-
foreach ($servers as $server) {
|
270 |
-
|
271 |
-
$dns = \Cleantalk\ApbctWP\Helper::ip__resolve__cleantalks($server['ip']);
|
272 |
-
if(!$dns)
|
273 |
-
continue;
|
274 |
-
|
275 |
-
$this->work_url = $url_protocol.$dns.$url_suffix;
|
276 |
-
$this->server_ttl = $server['ttl'];
|
277 |
-
|
278 |
-
$result = $this->sendRequest($msg, $this->work_url, $this->server_timeout);
|
279 |
-
|
280 |
-
if ($result !== false && $result->errno === 0) {
|
281 |
-
$this->server_change = true;
|
282 |
-
break;
|
283 |
-
}
|
284 |
-
}
|
285 |
-
}
|
286 |
-
|
287 |
-
$response = new CleantalkResponse(null, $result);
|
288 |
-
|
289 |
-
if (!empty($this->data_codepage) && $this->data_codepage !== 'UTF-8') {
|
290 |
-
if (!empty($response->comment))
|
291 |
-
$response->comment = $this->stringFromUTF8($response->comment, $this->data_codepage);
|
292 |
-
if (!empty($response->errstr))
|
293 |
-
$response->errstr = $this->stringFromUTF8($response->errstr, $this->data_codepage);
|
294 |
-
if (!empty($response->sms_error_text))
|
295 |
-
$response->sms_error_text = $this->stringFromUTF8($response->sms_error_text, $this->data_codepage);
|
296 |
-
}
|
297 |
-
|
298 |
-
return $response;
|
299 |
-
}
|
300 |
-
|
301 |
-
/**
|
302 |
-
* Function DNS request
|
303 |
-
* @param $host
|
304 |
-
* @return array
|
305 |
-
*/
|
306 |
-
public function get_servers_ip($host)
|
307 |
-
{
|
308 |
-
if (!isset($host))
|
309 |
-
return null;
|
310 |
-
|
311 |
-
$servers = array();
|
312 |
-
|
313 |
-
// Get DNS records about URL
|
314 |
-
if (function_exists('dns_get_record')) {
|
315 |
-
$records = dns_get_record($host, DNS_A);
|
316 |
-
if ($records !== FALSE) {
|
317 |
-
foreach ($records as $server) {
|
318 |
-
$servers[] = $server;
|
319 |
-
}
|
320 |
-
}
|
321 |
-
}
|
322 |
-
|
323 |
-
// Another try if first failed
|
324 |
-
if (count($servers) == 0 && function_exists('gethostbynamel')) {
|
325 |
-
$records = gethostbynamel($host);
|
326 |
-
if ($records !== FALSE) {
|
327 |
-
foreach ($records as $server) {
|
328 |
-
$servers[] = array(
|
329 |
-
"ip" => $server,
|
330 |
-
"host" => $host,
|
331 |
-
"ttl" => $this->server_ttl
|
332 |
-
);
|
333 |
-
}
|
334 |
-
}
|
335 |
-
}
|
336 |
-
|
337 |
-
// If couldn't get records
|
338 |
-
if (count($servers) == 0){
|
339 |
-
|
340 |
-
$servers[] = array(
|
341 |
-
"ip" => null,
|
342 |
-
"host" => $host,
|
343 |
-
"ttl" => $this->server_ttl
|
344 |
-
);
|
345 |
-
|
346 |
-
// If records recieved
|
347 |
-
} else {
|
348 |
-
|
349 |
-
$tmp = null;
|
350 |
-
$fast_server_found = false;
|
351 |
-
|
352 |
-
foreach ($servers as $server) {
|
353 |
-
|
354 |
-
if ($fast_server_found) {
|
355 |
-
$ping = $this->max_server_timeout;
|
356 |
-
} else {
|
357 |
-
$ping = $this->httpPing($server['ip']);
|
358 |
-
$ping = $ping * 1000;
|
359 |
-
}
|
360 |
-
|
361 |
-
$tmp[$ping] = $server;
|
362 |
-
|
363 |
-
$fast_server_found = $ping < $this->min_server_timeout ? true : false;
|
364 |
-
|
365 |
-
}
|
366 |
-
|
367 |
-
if (count($tmp)){
|
368 |
-
ksort($tmp);
|
369 |
-
$response = $tmp;
|
370 |
-
}
|
371 |
-
|
372 |
-
}
|
373 |
-
|
374 |
-
return empty($response) ? null : $response;
|
375 |
-
}
|
376 |
-
|
377 |
-
/**
|
378 |
-
* Function to check response time
|
379 |
-
* param string
|
380 |
-
* @return int
|
381 |
-
*/
|
382 |
-
function httpPing($host){
|
383 |
-
|
384 |
-
// Skip localhost ping cause it raise error at fsockopen.
|
385 |
-
// And return minimun value
|
386 |
-
if ($host == 'localhost')
|
387 |
-
return 0.001;
|
388 |
-
|
389 |
-
$starttime = microtime(true);
|
390 |
-
$file = @fsockopen ($host, 80, $errno, $errstr, $this->max_server_timeout/1000);
|
391 |
-
$stoptime = microtime(true);
|
392 |
-
|
393 |
-
if (!$file) {
|
394 |
-
$status = $this->max_server_timeout/1000; // Site is down
|
395 |
-
} else {
|
396 |
-
fclose($file);
|
397 |
-
$status = ($stoptime - $starttime);
|
398 |
-
$status = round($status, 4);
|
399 |
-
}
|
400 |
-
|
401 |
-
return $status;
|
402 |
-
}
|
403 |
-
|
404 |
-
/**
|
405 |
-
* Send JSON request to servers
|
406 |
-
* @param $msg
|
407 |
-
* @return boolean|\CleantalkResponse
|
408 |
-
*/
|
409 |
-
private function sendRequest($data = null, $url, $server_timeout = 3)
|
410 |
-
{
|
411 |
-
$original_args = func_get_args();
|
412 |
-
// Convert to array
|
413 |
-
$data = (array)json_decode(json_encode($data), true);
|
414 |
-
|
415 |
-
//Cleaning from 'null' values
|
416 |
-
$tmp_data = array();
|
417 |
-
foreach($data as $key => $value){
|
418 |
-
if($value !== null)
|
419 |
-
$tmp_data[$key] = $value;
|
420 |
-
}
|
421 |
-
$data = $tmp_data;
|
422 |
-
unset($key, $value, $tmp_data);
|
423 |
-
|
424 |
-
// Convert to JSON
|
425 |
-
$data = json_encode($data);
|
426 |
-
|
427 |
-
if (isset($this->api_version)) {
|
428 |
-
$url = $url . $this->api_version;
|
429 |
-
}
|
430 |
-
|
431 |
-
$result = false;
|
432 |
-
$curl_error = null;
|
433 |
-
|
434 |
-
// Switching to secure connection
|
435 |
-
if ($this->ssl_on && !preg_match("/^https:/", $url)){
|
436 |
-
$url = preg_replace("/^(http)/i", "$1s", $url);
|
437 |
-
}
|
438 |
-
|
439 |
-
if($this->use_bultin_api){
|
440 |
-
|
441 |
-
$args = array(
|
442 |
-
'body' => $data,
|
443 |
-
'timeout' => $server_timeout,
|
444 |
-
'user-agent' => APBCT_AGENT.' '.get_bloginfo( 'url' ),
|
445 |
-
);
|
446 |
-
|
447 |
-
$result = wp_remote_post($url, $args);
|
448 |
-
|
449 |
-
if( is_wp_error( $result ) ) {
|
450 |
-
$errors = $result->get_error_message();
|
451 |
-
$result = false;
|
452 |
-
}else{
|
453 |
-
$result = wp_remote_retrieve_body($result);
|
454 |
-
}
|
455 |
-
|
456 |
-
}else{
|
457 |
-
|
458 |
-
if(function_exists('curl_init')) {
|
459 |
-
|
460 |
-
$ch = curl_init();
|
461 |
-
|
462 |
-
curl_setopt($ch, CURLOPT_URL, $url);
|
463 |
-
curl_setopt($ch, CURLOPT_TIMEOUT, $server_timeout);
|
464 |
-
curl_setopt($ch, CURLOPT_POST, 1);
|
465 |
-
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
466 |
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // receive server response ...
|
467 |
-
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); // resolve 'Expect: 100-continue' issue
|
468 |
-
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); // see http://stackoverflow.com/a/23322368
|
469 |
-
|
470 |
-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disabling CA cert verivication and
|
471 |
-
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // Disabling common name verification
|
472 |
-
|
473 |
-
if ($this->ssl_on && $this->ssl_path != '') {
|
474 |
-
curl_setopt($ch, CURLOPT_CAINFO, $this->ssl_path);
|
475 |
-
}
|
476 |
-
|
477 |
-
$result = curl_exec($ch);
|
478 |
-
if (!$result) {
|
479 |
-
$curl_error = curl_error($ch);
|
480 |
-
// Use SSL next time, if error occurs.
|
481 |
-
if(!$this->ssl_on){
|
482 |
-
$this->ssl_on = true;
|
483 |
-
return $this->sendRequest($original_args[0], $original_args[1], $server_timeout);
|
484 |
-
}
|
485 |
-
}
|
486 |
-
|
487 |
-
curl_close($ch);
|
488 |
-
}
|
489 |
-
}
|
490 |
-
|
491 |
-
if (!$result) {
|
492 |
-
$allow_url_fopen = ini_get('allow_url_fopen');
|
493 |
-
if (function_exists('file_get_contents') && isset($allow_url_fopen) && $allow_url_fopen == '1') {
|
494 |
-
$opts = array('http' =>
|
495 |
-
array(
|
496 |
-
'method' => 'POST',
|
497 |
-
'header' => "Content-Type: text/html\r\n",
|
498 |
-
'content' => $data,
|
499 |
-
'timeout' => $server_timeout
|
500 |
-
)
|
501 |
-
);
|
502 |
-
|
503 |
-
$context = stream_context_create($opts);
|
504 |
-
$result = @file_get_contents($url, false, $context);
|
505 |
-
}
|
506 |
-
}
|
507 |
-
|
508 |
-
if (!$result) {
|
509 |
-
$response = null;
|
510 |
-
$response['errno'] = 2;
|
511 |
-
if (!\Cleantalk\ApbctWP\Helper::is_json($result)) {
|
512 |
-
$response['errstr'] = 'Wrong server response format: ' . substr( $result, 100 );
|
513 |
-
}
|
514 |
-
else {
|
515 |
-
$response['errstr'] = $curl_error
|
516 |
-
? sprintf( "CURL error: '%s'", $curl_error )
|
517 |
-
: 'No CURL support compiled in';
|
518 |
-
$response['errstr'] .= ' or disabled allow_url_fopen in php.ini.';
|
519 |
-
}
|
520 |
-
$response = json_decode( json_encode( $response ) );
|
521 |
-
|
522 |
-
return $response;
|
523 |
-
}
|
524 |
-
|
525 |
-
$errstr = null;
|
526 |
-
$response = json_decode($result);
|
527 |
-
if ($result !== false && is_object($response)) {
|
528 |
-
$response->errno = 0;
|
529 |
-
$response->errstr = $errstr;
|
530 |
-
} else {
|
531 |
-
$errstr = 'Unknown response from ' . $url . '.' . ' ' . $result;
|
532 |
-
|
533 |
-
$response = null;
|
534 |
-
$response['errno'] = 1;
|
535 |
-
$response['errstr'] = $errstr;
|
536 |
-
$response = json_decode(json_encode($response));
|
537 |
-
}
|
538 |
-
|
539 |
-
|
540 |
-
return $response;
|
541 |
-
}
|
542 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Cleantalk\Antispam;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Cleantalk base class
|
7 |
+
*
|
8 |
+
* @version 2.2
|
9 |
+
* @package Cleantalk
|
10 |
+
* @subpackage Base
|
11 |
+
* @author Cleantalk team (welcome@cleantalk.org)
|
12 |
+
* @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
|
13 |
+
* @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
|
14 |
+
* @see https://github.com/CleanTalk/php-antispam
|
15 |
+
*
|
16 |
+
*/
|
17 |
+
class Cleantalk {
|
18 |
+
|
19 |
+
/*
|
20 |
+
* Use Wordpress built-in API
|
21 |
+
*/
|
22 |
+
public $use_bultin_api = false;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Maximum data size in bytes
|
26 |
+
* @var int
|
27 |
+
*/
|
28 |
+
private $dataMaxSise = 32768;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Data compression rate
|
32 |
+
* @var int
|
33 |
+
*/
|
34 |
+
private $compressRate = 6;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Server connection timeout in seconds
|
38 |
+
* @var int
|
39 |
+
*/
|
40 |
+
private $server_timeout = 15;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Cleantalk server url
|
44 |
+
* @var string
|
45 |
+
*/
|
46 |
+
public $server_url = null;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Last work url
|
50 |
+
* @var string
|
51 |
+
*/
|
52 |
+
public $work_url = null;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* WOrk url ttl
|
56 |
+
* @var int
|
57 |
+
*/
|
58 |
+
public $server_ttl = null;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Time wotk_url changer
|
62 |
+
* @var int
|
63 |
+
*/
|
64 |
+
public $server_changed = null;
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Flag is change server url
|
68 |
+
* @var bool
|
69 |
+
*/
|
70 |
+
public $server_change = false;
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Codepage of the data
|
74 |
+
* @var bool
|
75 |
+
*/
|
76 |
+
public $data_codepage = null;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* API version to use
|
80 |
+
* @var string
|
81 |
+
*/
|
82 |
+
public $api_version = '/api2.0';
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Use https connection to servers
|
86 |
+
* @var bool
|
87 |
+
*/
|
88 |
+
public $ssl_on = false;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Path to SSL certificate
|
92 |
+
* @var string
|
93 |
+
*/
|
94 |
+
public $ssl_path = '';
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Minimal server response in miliseconds to catch the server
|
98 |
+
*
|
99 |
+
*/
|
100 |
+
public $min_server_timeout = 50;
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Maximal server response in miliseconds to catch the server
|
104 |
+
*
|
105 |
+
*/
|
106 |
+
public $max_server_timeout = 1500;
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Function checks whether it is possible to publish the message
|
110 |
+
*
|
111 |
+
* @param CleantalkRequest $request
|
112 |
+
*
|
113 |
+
* @return bool|CleantalkResponse
|
114 |
+
*/
|
115 |
+
public function isAllowMessage(CleantalkRequest $request) {
|
116 |
+
$msg = $this->createMsg('check_message', $request);
|
117 |
+
return $this->httpRequest($msg);
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Function checks whether it is possible to publish the message
|
122 |
+
*
|
123 |
+
* @param CleantalkRequest $request
|
124 |
+
*
|
125 |
+
* @return bool|CleantalkResponse
|
126 |
+
*/
|
127 |
+
public function isAllowUser(CleantalkRequest $request) {
|
128 |
+
$msg = $this->createMsg('check_newuser', $request);
|
129 |
+
return $this->httpRequest($msg);
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Function sends the results of manual moderation
|
134 |
+
*
|
135 |
+
* @param CleantalkRequest $request
|
136 |
+
*
|
137 |
+
* @return bool|CleantalkResponse
|
138 |
+
*/
|
139 |
+
public function sendFeedback(CleantalkRequest $request) {
|
140 |
+
$msg = $this->createMsg('send_feedback', $request);
|
141 |
+
return $this->httpRequest($msg);
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Create msg for cleantalk server
|
146 |
+
* @param string $method
|
147 |
+
* @param CleantalkRequest $request
|
148 |
+
* @return CleantalkRequest
|
149 |
+
*/
|
150 |
+
private function createMsg($method, CleantalkRequest $request) {
|
151 |
+
|
152 |
+
switch ($method) {
|
153 |
+
case 'check_message':
|
154 |
+
// Convert strings to UTF8
|
155 |
+
$request->message = \Cleantalk\ApbctWP\Helper::toUTF8($request->message, $this->data_codepage);
|
156 |
+
$request->example = \Cleantalk\ApbctWP\Helper::toUTF8($request->example, $this->data_codepage);
|
157 |
+
$request->sender_email = \Cleantalk\ApbctWP\Helper::toUTF8($request->sender_email, $this->data_codepage);
|
158 |
+
$request->sender_nickname = \Cleantalk\ApbctWP\Helper::toUTF8($request->sender_nickname, $this->data_codepage);
|
159 |
+
$request->message = $this->compressData($request->message);
|
160 |
+
$request->example = $this->compressData($request->example);
|
161 |
+
break;
|
162 |
+
|
163 |
+
case 'check_newuser':
|
164 |
+
// Convert strings to UTF8
|
165 |
+
$request->sender_email = \Cleantalk\ApbctWP\Helper::toUTF8($request->sender_email, $this->data_codepage);
|
166 |
+
$request->sender_nickname = \Cleantalk\ApbctWP\Helper::toUTF8($request->sender_nickname, $this->data_codepage);
|
167 |
+
break;
|
168 |
+
|
169 |
+
case 'send_feedback':
|
170 |
+
if (is_array($request->feedback)) {
|
171 |
+
$request->feedback = implode(';', $request->feedback);
|
172 |
+
}
|
173 |
+
break;
|
174 |
+
}
|
175 |
+
|
176 |
+
// Removing non UTF8 characters from request, because non UTF8 or malformed characters break json_encode().
|
177 |
+
foreach ($request as $param => $value) {
|
178 |
+
if(is_array($request->$param) || is_string($request->$param))
|
179 |
+
$request->$param = \Cleantalk\ApbctWP\Helper::removeNonUTF8($value);
|
180 |
+
}
|
181 |
+
|
182 |
+
$request->method_name = $method;
|
183 |
+
$request->message = is_array($request->message) ? json_encode($request->message) : $request->message;
|
184 |
+
|
185 |
+
// Wiping cleantalk's headers but, not for send_feedback
|
186 |
+
if($request->method_name != 'send_feedback'){
|
187 |
+
|
188 |
+
$ct_tmp = apache_request_headers();
|
189 |
+
|
190 |
+
if(isset($ct_tmp['Cookie']))
|
191 |
+
$cookie_name = 'Cookie';
|
192 |
+
elseif(isset($ct_tmp['cookie']))
|
193 |
+
$cookie_name = 'cookie';
|
194 |
+
else
|
195 |
+
$cookie_name = 'COOKIE';
|
196 |
+
|
197 |
+
$ct_tmp[$cookie_name] = preg_replace(array(
|
198 |
+
'/\s?ct_checkjs=[a-z0-9]*[^;]*;?/',
|
199 |
+
'/\s?ct_timezone=.{0,1}\d{1,2}[^;]*;?/',
|
200 |
+
'/\s?ct_pointer_data=.*5D[^;]*;?/',
|
201 |
+
'/\s?apbct_timestamp=\d*[^;]*;?/',
|
202 |
+
'/\s?apbct_site_landing_ts=\d*[^;]*;?/',
|
203 |
+
'/\s?apbct_cookies_test=%7B.*%7D[^;]*;?/',
|
204 |
+
'/\s?apbct_prev_referer=http.*?[^;]*;?/',
|
205 |
+
'/\s?ct_cookies_test=.*?[^;]*;?/',
|
206 |
+
'/\s?ct_ps_timestamp=.*?[^;]*;?/',
|
207 |
+
'/\s?ct_fkp_timestamp=\d*?[^;]*;?/',
|
208 |
+
'/\s?ct_sfw_pass_key=\d*?[^;]*;?/',
|
209 |
+
'/\s?apbct_page_hits=\d*?[^;]*;?/',
|
210 |
+
'/\s?apbct_visible_fields_count=\d*?[^;]*;?/',
|
211 |
+
'/\s?apbct_visible_fields=%7B.*%7D[^;]*;?/',
|
212 |
+
), '', $ct_tmp[$cookie_name]);
|
213 |
+
$request->all_headers = json_encode($ct_tmp);
|
214 |
+
}
|
215 |
+
|
216 |
+
return $request;
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Compress data and encode to base64
|
221 |
+
* @param type string
|
222 |
+
* @return string
|
223 |
+
*/
|
224 |
+
private function compressData($data = null){
|
225 |
+
|
226 |
+
if (strlen($data) > $this->dataMaxSise && function_exists('\gzencode') && function_exists('base64_encode')){
|
227 |
+
|
228 |
+
$localData = \gzencode($data, $this->compressRate, FORCE_GZIP);
|
229 |
+
|
230 |
+
if ($localData === false)
|
231 |
+
return $data;
|
232 |
+
|
233 |
+
$localData = base64_encode($localData);
|
234 |
+
|
235 |
+
if ($localData === false)
|
236 |
+
return $data;
|
237 |
+
|
238 |
+
return $localData;
|
239 |
+
}
|
240 |
+
|
241 |
+
return $data;
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* httpRequest
|
246 |
+
* @param $msg
|
247 |
+
* @return boolean|\CleantalkResponse
|
248 |
+
*/
|
249 |
+
private function httpRequest($msg) {
|
250 |
+
|
251 |
+
// Using current server without changing it
|
252 |
+
$result = !empty($this->work_url) && ($this->server_changed + $this->server_ttl > time())
|
253 |
+
? $this->sendRequest($msg, $this->work_url, $this->server_timeout)
|
254 |
+
: false;
|
255 |
+
|
256 |
+
// Changing server
|
257 |
+
if ($result === false || (is_object($result) && $result->errno != 0)) {
|
258 |
+
|
259 |
+
// Split server url to parts
|
260 |
+
preg_match("/^(https?:\/\/)([^\/:]+)(.*)/i", $this->server_url, $matches);
|
261 |
+
|
262 |
+
$url_protocol = isset($matches[1]) ? $matches[1] : '';
|
263 |
+
$url_host = isset($matches[2]) ? $matches[2] : '';
|
264 |
+
$url_suffix = isset($matches[3]) ? $matches[3] : '';
|
265 |
+
|
266 |
+
$servers = $this->get_servers_ip($url_host);
|
267 |
+
|
268 |
+
// Loop until find work server
|
269 |
+
foreach ($servers as $server) {
|
270 |
+
|
271 |
+
$dns = \Cleantalk\ApbctWP\Helper::ip__resolve__cleantalks($server['ip']);
|
272 |
+
if(!$dns)
|
273 |
+
continue;
|
274 |
+
|
275 |
+
$this->work_url = $url_protocol.$dns.$url_suffix;
|
276 |
+
$this->server_ttl = $server['ttl'];
|
277 |
+
|
278 |
+
$result = $this->sendRequest($msg, $this->work_url, $this->server_timeout);
|
279 |
+
|
280 |
+
if ($result !== false && $result->errno === 0) {
|
281 |
+
$this->server_change = true;
|
282 |
+
break;
|
283 |
+
}
|
284 |
+
}
|
285 |
+
}
|
286 |
+
|
287 |
+
$response = new CleantalkResponse(null, $result);
|
288 |
+
|
289 |
+
if (!empty($this->data_codepage) && $this->data_codepage !== 'UTF-8') {
|
290 |
+
if (!empty($response->comment))
|
291 |
+
$response->comment = $this->stringFromUTF8($response->comment, $this->data_codepage);
|
292 |
+
if (!empty($response->errstr))
|
293 |
+
$response->errstr = $this->stringFromUTF8($response->errstr, $this->data_codepage);
|
294 |
+
if (!empty($response->sms_error_text))
|
295 |
+
$response->sms_error_text = $this->stringFromUTF8($response->sms_error_text, $this->data_codepage);
|
296 |
+
}
|
297 |
+
|
298 |
+
return $response;
|
299 |
+
}
|
300 |
+
|
301 |
+
/**
|
302 |
+
* Function DNS request
|
303 |
+
* @param $host
|
304 |
+
* @return array
|
305 |
+
*/
|
306 |
+
public function get_servers_ip($host)
|
307 |
+
{
|
308 |
+
if (!isset($host))
|
309 |
+
return null;
|
310 |
+
|
311 |
+
$servers = array();
|
312 |
+
|
313 |
+
// Get DNS records about URL
|
314 |
+
if (function_exists('dns_get_record')) {
|
315 |
+
$records = dns_get_record($host, DNS_A);
|
316 |
+
if ($records !== FALSE) {
|
317 |
+
foreach ($records as $server) {
|
318 |
+
$servers[] = $server;
|
319 |
+
}
|
320 |
+
}
|
321 |
+
}
|
322 |
+
|
323 |
+
// Another try if first failed
|
324 |
+
if (count($servers) == 0 && function_exists('gethostbynamel')) {
|
325 |
+
$records = gethostbynamel($host);
|
326 |
+
if ($records !== FALSE) {
|
327 |
+
foreach ($records as $server) {
|
328 |
+
$servers[] = array(
|
329 |
+
"ip" => $server,
|
330 |
+
"host" => $host,
|
331 |
+
"ttl" => $this->server_ttl
|
332 |
+
);
|
333 |
+
}
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
// If couldn't get records
|
338 |
+
if (count($servers) == 0){
|
339 |
+
|
340 |
+
$servers[] = array(
|
341 |
+
"ip" => null,
|
342 |
+
"host" => $host,
|
343 |
+
"ttl" => $this->server_ttl
|
344 |
+
);
|
345 |
+
|
346 |
+
// If records recieved
|
347 |
+
} else {
|
348 |
+
|
349 |
+
$tmp = null;
|
350 |
+
$fast_server_found = false;
|
351 |
+
|
352 |
+
foreach ($servers as $server) {
|
353 |
+
|
354 |
+
if ($fast_server_found) {
|
355 |
+
$ping = $this->max_server_timeout;
|
356 |
+
} else {
|
357 |
+
$ping = $this->httpPing($server['ip']);
|
358 |
+
$ping = $ping * 1000;
|
359 |
+
}
|
360 |
+
|
361 |
+
$tmp[$ping] = $server;
|
362 |
+
|
363 |
+
$fast_server_found = $ping < $this->min_server_timeout ? true : false;
|
364 |
+
|
365 |
+
}
|
366 |
+
|
367 |
+
if (count($tmp)){
|
368 |
+
ksort($tmp);
|
369 |
+
$response = $tmp;
|
370 |
+
}
|
371 |
+
|
372 |
+
}
|
373 |
+
|
374 |
+
return empty($response) ? null : $response;
|
375 |
+
}
|
376 |
+
|
377 |
+
/**
|
378 |
+
* Function to check response time
|
379 |
+
* param string
|
380 |
+
* @return int
|
381 |
+
*/
|
382 |
+
function httpPing($host){
|
383 |
+
|
384 |
+
// Skip localhost ping cause it raise error at fsockopen.
|
385 |
+
// And return minimun value
|
386 |
+
if ($host == 'localhost')
|
387 |
+
return 0.001;
|
388 |
+
|
389 |
+
$starttime = microtime(true);
|
390 |
+
$file = @fsockopen ($host, 80, $errno, $errstr, $this->max_server_timeout/1000);
|
391 |
+
$stoptime = microtime(true);
|
392 |
+
|
393 |
+
if (!$file) {
|
394 |
+
$status = $this->max_server_timeout/1000; // Site is down
|
395 |
+
} else {
|
396 |
+
fclose($file);
|
397 |
+
$status = ($stoptime - $starttime);
|
398 |
+
$status = round($status, 4);
|
399 |
+
}
|
400 |
+
|
401 |
+
return $status;
|
402 |
+
}
|
403 |
+
|
404 |
+
/**
|
405 |
+
* Send JSON request to servers
|
406 |
+
* @param $msg
|
407 |
+
* @return boolean|\CleantalkResponse
|
408 |
+
*/
|
409 |
+
private function sendRequest($data = null, $url, $server_timeout = 3)
|
410 |
+
{
|
411 |
+
$original_args = func_get_args();
|
412 |
+
// Convert to array
|
413 |
+
$data = (array)json_decode(json_encode($data), true);
|
414 |
+
|
415 |
+
//Cleaning from 'null' values
|
416 |
+
$tmp_data = array();
|
417 |
+
foreach($data as $key => $value){
|
418 |
+
if($value !== null)
|
419 |
+
$tmp_data[$key] = $value;
|
420 |
+
}
|
421 |
+
$data = $tmp_data;
|
422 |
+
unset($key, $value, $tmp_data);
|
423 |
+
|
424 |
+
// Convert to JSON
|
425 |
+
$data = json_encode($data);
|
426 |
+
|
427 |
+
if (isset($this->api_version)) {
|
428 |
+
$url = $url . $this->api_version;
|
429 |
+
}
|
430 |
+
|
431 |
+
$result = false;
|
432 |
+
$curl_error = null;
|
433 |
+
|
434 |
+
// Switching to secure connection
|
435 |
+
if ($this->ssl_on && !preg_match("/^https:/", $url)){
|
436 |
+
$url = preg_replace("/^(http)/i", "$1s", $url);
|
437 |
+
}
|
438 |
+
|
439 |
+
if($this->use_bultin_api){
|
440 |
+
|
441 |
+
$args = array(
|
442 |
+
'body' => $data,
|
443 |
+
'timeout' => $server_timeout,
|
444 |
+
'user-agent' => APBCT_AGENT.' '.get_bloginfo( 'url' ),
|
445 |
+
);
|
446 |
+
|
447 |
+
$result = wp_remote_post($url, $args);
|
448 |
+
|
449 |
+
if( is_wp_error( $result ) ) {
|
450 |
+
$errors = $result->get_error_message();
|
451 |
+
$result = false;
|
452 |
+
}else{
|
453 |
+
$result = wp_remote_retrieve_body($result);
|
454 |
+
}
|
455 |
+
|
456 |
+
}else{
|
457 |
+
|
458 |
+
if(function_exists('curl_init')) {
|
459 |
+
|
460 |
+
$ch = curl_init();
|
461 |
+
|
462 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
463 |
+
curl_setopt($ch, CURLOPT_TIMEOUT, $server_timeout);
|
464 |
+
curl_setopt($ch, CURLOPT_POST, 1);
|
465 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
466 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // receive server response ...
|
467 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); // resolve 'Expect: 100-continue' issue
|
468 |
+
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); // see http://stackoverflow.com/a/23322368
|
469 |
+
|
470 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disabling CA cert verivication and
|
471 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // Disabling common name verification
|
472 |
+
|
473 |
+
if ($this->ssl_on && $this->ssl_path != '') {
|
474 |
+
curl_setopt($ch, CURLOPT_CAINFO, $this->ssl_path);
|
475 |
+
}
|
476 |
+
|
477 |
+
$result = curl_exec($ch);
|
478 |
+
if (!$result) {
|
479 |
+
$curl_error = curl_error($ch);
|
480 |
+
// Use SSL next time, if error occurs.
|
481 |
+
if(!$this->ssl_on){
|
482 |
+
$this->ssl_on = true;
|
483 |
+
return $this->sendRequest($original_args[0], $original_args[1], $server_timeout);
|
484 |
+
}
|
485 |
+
}
|
486 |
+
|
487 |
+
curl_close($ch);
|
488 |
+
}
|
489 |
+
}
|
490 |
+
|
491 |
+
if (!$result) {
|
492 |
+
$allow_url_fopen = ini_get('allow_url_fopen');
|
493 |
+
if (function_exists('file_get_contents') && isset($allow_url_fopen) && $allow_url_fopen == '1') {
|
494 |
+
$opts = array('http' =>
|
495 |
+
array(
|
496 |
+
'method' => 'POST',
|
497 |
+
'header' => "Content-Type: text/html\r\n",
|
498 |
+
'content' => $data,
|
499 |
+
'timeout' => $server_timeout
|
500 |
+
)
|
501 |
+
);
|
502 |
+
|
503 |
+
$context = stream_context_create($opts);
|
504 |
+
$result = @file_get_contents($url, false, $context);
|
505 |
+
}
|
506 |
+
}
|
507 |
+
|
508 |
+
if (!$result) {
|
509 |
+
$response = null;
|
510 |
+
$response['errno'] = 2;
|
511 |
+
if (!\Cleantalk\ApbctWP\Helper::is_json($result)) {
|
512 |
+
$response['errstr'] = 'Wrong server response format: ' . substr( $result, 100 );
|
513 |
+
}
|
514 |
+
else {
|
515 |
+
$response['errstr'] = $curl_error
|
516 |
+
? sprintf( "CURL error: '%s'", $curl_error )
|
517 |
+
: 'No CURL support compiled in';
|
518 |
+
$response['errstr'] .= ' or disabled allow_url_fopen in php.ini.';
|
519 |
+
}
|
520 |
+
$response = json_decode( json_encode( $response ) );
|
521 |
+
|
522 |
+
return $response;
|
523 |
+
}
|
524 |
+
|
525 |
+
$errstr = null;
|
526 |
+
$response = json_decode($result);
|
527 |
+
if ($result !== false && is_object($response)) {
|
528 |
+
$response->errno = 0;
|
529 |
+
$response->errstr = $errstr;
|
530 |
+
} else {
|
531 |
+
$errstr = 'Unknown response from ' . $url . '.' . ' ' . $result;
|
532 |
+
|
533 |
+
$response = null;
|
534 |
+
$response['errno'] = 1;
|
535 |
+
$response['errstr'] = $errstr;
|
536 |
+
$response = json_decode(json_encode($response));
|
537 |
+
}
|
538 |
+
|
539 |
+
|
540 |
+
return $response;
|
541 |
+
}
|
542 |
+
}
|
lib/Cleantalk/ApbctWP/Firewall/AntiCrawler.php
CHANGED
@@ -10,12 +10,14 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
10 |
|
11 |
public $module_name = 'ANTICRAWLER';
|
12 |
|
13 |
-
private $db__table__ac_logs;
|
14 |
private $api_key = '';
|
15 |
private $apbct = false;
|
16 |
private $store_interval = 60;
|
17 |
private $ua; //User-Agent
|
18 |
-
|
|
|
|
|
19 |
public $isExcluded = false;
|
20 |
|
21 |
/**
|
@@ -27,9 +29,12 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
27 |
*/
|
28 |
public function __construct( $log_table, $ac_logs_table, $params = array() ) {
|
29 |
|
|
|
|
|
30 |
$this->db__table__logs = $log_table ?: null;
|
31 |
$this->db__table__ac_logs = $ac_logs_table ?: null;
|
32 |
$this->ua = md5( Server::get('HTTP_USER_AGENT') );
|
|
|
33 |
|
34 |
foreach( $params as $param_name => $param ){
|
35 |
$this->$param_name = isset( $this->$param_name ) ? $param : false;
|
@@ -47,13 +52,18 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
47 |
public function check() {
|
48 |
|
49 |
$results = array();
|
50 |
-
|
51 |
-
// Skip by cookie
|
52 |
foreach( $this->ip_array as $ip_origin => $current_ip ) {
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
if( ! headers_sent() )
|
58 |
\Cleantalk\Common\Helper::apbct_cookie__set( 'apbct_anticrawler_passed', '0', time() - 86400, '/', null, false, true, 'Lax' );
|
59 |
}
|
@@ -64,21 +74,20 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
64 |
|
65 |
}
|
66 |
}
|
67 |
-
|
68 |
// Common check
|
69 |
foreach( $this->ip_array as $ip_origin => $current_ip ){
|
70 |
-
|
71 |
$result = $this->db->fetch(
|
72 |
"SELECT ip"
|
73 |
. ' FROM `' . $this->db__table__ac_logs . '`'
|
74 |
. " WHERE ip = '$current_ip'"
|
75 |
-
|
76 |
-
. " LIMIT 1;"
|
77 |
);
|
78 |
|
79 |
-
if(
|
80 |
|
81 |
-
if( Cookie::get('apbct_antibot') !==
|
82 |
|
83 |
$results[] = array( 'ip' => $current_ip, 'is_personal' => false, 'status' => 'DENY_ANTICRAWLER', );
|
84 |
|
@@ -102,8 +111,6 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
102 |
}
|
103 |
|
104 |
add_action( 'wp_head', array( '\Cleantalk\ApbctWP\Firewall\AntiCrawler', 'set_cookie' ) );
|
105 |
-
global $apbct_anticrawler_ip;
|
106 |
-
$apbct_anticrawler_ip = $current_ip;
|
107 |
|
108 |
}
|
109 |
}
|
@@ -139,8 +146,8 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
139 |
|
140 |
|
141 |
public static function set_cookie(){
|
142 |
-
global $apbct
|
143 |
-
echo '<script>document.cookie = "apbct_antibot=' .
|
144 |
}
|
145 |
|
146 |
/**
|
@@ -175,6 +182,8 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
175 |
|
176 |
public function _die( $result ){
|
177 |
|
|
|
|
|
178 |
// File exists?
|
179 |
if(file_exists(CLEANTALK_PLUGIN_DIR . "lib/Cleantalk/ApbctWP/Firewall/die_page_anticrawler.html")){
|
180 |
|
@@ -189,7 +198,7 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
189 |
'{REMOTE_ADDRESS}' => $result['ip'],
|
190 |
'{SERVICE_ID}' => $this->apbct->data['service_id'],
|
191 |
'{HOST}' => Server::get( 'HTTP_HOST' ),
|
192 |
-
'{COOKIE_ANTICRAWLER}' =>
|
193 |
'{COOKIE_ANTICRAWLER_PASSED}' => '1',
|
194 |
'{GENERATED}' => '<p>The page was generated at ' . date( 'D, d M Y H:i:s' ) . "</p>",
|
195 |
);
|
@@ -198,6 +207,20 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
198 |
$sfw_die_page = str_replace( $place_holder, $replace, $sfw_die_page );
|
199 |
}
|
200 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
wp_die($sfw_die_page, "Blacklisted", Array('response'=>403));
|
202 |
|
203 |
}else{
|
10 |
|
11 |
public $module_name = 'ANTICRAWLER';
|
12 |
|
13 |
+
private $db__table__ac_logs = null;
|
14 |
private $api_key = '';
|
15 |
private $apbct = false;
|
16 |
private $store_interval = 60;
|
17 |
private $ua; //User-Agent
|
18 |
+
|
19 |
+
private $ac_log_result = '';
|
20 |
+
|
21 |
public $isExcluded = false;
|
22 |
|
23 |
/**
|
29 |
*/
|
30 |
public function __construct( $log_table, $ac_logs_table, $params = array() ) {
|
31 |
|
32 |
+
global $apbct;
|
33 |
+
$this->apbct = $apbct;
|
34 |
$this->db__table__logs = $log_table ?: null;
|
35 |
$this->db__table__ac_logs = $ac_logs_table ?: null;
|
36 |
$this->ua = md5( Server::get('HTTP_USER_AGENT') );
|
37 |
+
|
38 |
|
39 |
foreach( $params as $param_name => $param ){
|
40 |
$this->$param_name = isset( $this->$param_name ) ? $param : false;
|
52 |
public function check() {
|
53 |
|
54 |
$results = array();
|
55 |
+
|
|
|
56 |
foreach( $this->ip_array as $ip_origin => $current_ip ) {
|
57 |
+
|
58 |
+
// Skip by 301 response code
|
59 |
+
if( http_response_code() == 301 ){
|
60 |
+
$results[] = array( 'ip' => $current_ip, 'is_personal' => false, 'status' => 'PASS_ANTICRAWLER', );
|
61 |
+
return $results;
|
62 |
+
}
|
63 |
+
|
64 |
+
// Skip by cookie
|
65 |
+
if( Cookie::get('apbct_antibot') == hash( 'sha256', $this->api_key . $this->apbct->data['salt'] ) ) {
|
66 |
+
if( Cookie::get( 'apbct_anticrawler_passed' ) == 1 ){
|
67 |
if( ! headers_sent() )
|
68 |
\Cleantalk\Common\Helper::apbct_cookie__set( 'apbct_anticrawler_passed', '0', time() - 86400, '/', null, false, true, 'Lax' );
|
69 |
}
|
74 |
|
75 |
}
|
76 |
}
|
77 |
+
|
78 |
// Common check
|
79 |
foreach( $this->ip_array as $ip_origin => $current_ip ){
|
80 |
+
|
81 |
$result = $this->db->fetch(
|
82 |
"SELECT ip"
|
83 |
. ' FROM `' . $this->db__table__ac_logs . '`'
|
84 |
. " WHERE ip = '$current_ip'"
|
85 |
+
. " AND ua = '$this->ua';"
|
|
|
86 |
);
|
87 |
|
88 |
+
if( isset( $result['ip'] ) ){
|
89 |
|
90 |
+
if( Cookie::get('apbct_antibot') !== hash( 'sha256', $this->api_key . $this->apbct->data['salt'] ) ){
|
91 |
|
92 |
$results[] = array( 'ip' => $current_ip, 'is_personal' => false, 'status' => 'DENY_ANTICRAWLER', );
|
93 |
|
111 |
}
|
112 |
|
113 |
add_action( 'wp_head', array( '\Cleantalk\ApbctWP\Firewall\AntiCrawler', 'set_cookie' ) );
|
|
|
|
|
114 |
|
115 |
}
|
116 |
}
|
146 |
|
147 |
|
148 |
public static function set_cookie(){
|
149 |
+
global $apbct;
|
150 |
+
echo '<script>document.cookie = "apbct_antibot=' . hash( 'sha256', $apbct->api_key . $apbct->data['salt'] ) . '; path=/; expires=0; samesite=lax";</script>';
|
151 |
}
|
152 |
|
153 |
/**
|
182 |
|
183 |
public function _die( $result ){
|
184 |
|
185 |
+
global $apbct;
|
186 |
+
|
187 |
// File exists?
|
188 |
if(file_exists(CLEANTALK_PLUGIN_DIR . "lib/Cleantalk/ApbctWP/Firewall/die_page_anticrawler.html")){
|
189 |
|
198 |
'{REMOTE_ADDRESS}' => $result['ip'],
|
199 |
'{SERVICE_ID}' => $this->apbct->data['service_id'],
|
200 |
'{HOST}' => Server::get( 'HTTP_HOST' ),
|
201 |
+
'{COOKIE_ANTICRAWLER}' => hash( 'sha256', $apbct->api_key . $apbct->data['salt'] ),
|
202 |
'{COOKIE_ANTICRAWLER_PASSED}' => '1',
|
203 |
'{GENERATED}' => '<p>The page was generated at ' . date( 'D, d M Y H:i:s' ) . "</p>",
|
204 |
);
|
207 |
$sfw_die_page = str_replace( $place_holder, $replace, $sfw_die_page );
|
208 |
}
|
209 |
|
210 |
+
if( isset( $_GET['debug'] ) ){
|
211 |
+
$debug = '<h1>Headers</h1>'
|
212 |
+
. str_replace( "\n", "<br>", print_r( \apache_request_headers(), true ) )
|
213 |
+
. '<h1>$_SERVER</h1>'
|
214 |
+
. str_replace( "\n", "<br>", print_r( $_SERVER, true ) )
|
215 |
+
. '<h1>AC_LOG_RESULT</h1>'
|
216 |
+
. str_replace( "\n", "<br>", print_r( $this->ac_log_result, true ) )
|
217 |
+
. '<h1>IPS</h1>'
|
218 |
+
. str_replace( "\n", "<br>", print_r( $this->ip_array, true ) );
|
219 |
+
}else{
|
220 |
+
$debug = '';
|
221 |
+
}
|
222 |
+
$sfw_die_page = str_replace( "{DEBUG}", $debug, $sfw_die_page );
|
223 |
+
|
224 |
wp_die($sfw_die_page, "Blacklisted", Array('response'=>403));
|
225 |
|
226 |
}else{
|
lib/Cleantalk/ApbctWP/Firewall/SFW.php
CHANGED
@@ -206,6 +206,8 @@ class SFW extends \Cleantalk\Common\Firewall\FirewallModule {
|
|
206 |
*/
|
207 |
public function _die( $result ){
|
208 |
|
|
|
|
|
209 |
parent::_die( $result );
|
210 |
|
211 |
// Statistics
|
@@ -241,7 +243,7 @@ class SFW extends \Cleantalk\Common\Firewall\FirewallModule {
|
|
241 |
'{COOKIE_PREFIX}' => '',
|
242 |
'{COOKIE_DOMAIN}' => $this->cookie_domain,
|
243 |
'{COOKIE_SFW}' => $this->test ? $this->test_ip : $cookie_val,
|
244 |
-
'{COOKIE_ANTICRAWLER}' =>
|
245 |
|
246 |
// Test
|
247 |
'{TEST_TITLE}' => '',
|
206 |
*/
|
207 |
public function _die( $result ){
|
208 |
|
209 |
+
global $apbct;
|
210 |
+
|
211 |
parent::_die( $result );
|
212 |
|
213 |
// Statistics
|
243 |
'{COOKIE_PREFIX}' => '',
|
244 |
'{COOKIE_DOMAIN}' => $this->cookie_domain,
|
245 |
'{COOKIE_SFW}' => $this->test ? $this->test_ip : $cookie_val,
|
246 |
+
'{COOKIE_ANTICRAWLER}' => hash( 'sha256', $apbct->api_key . $apbct->data['salt'] ),
|
247 |
|
248 |
// Test
|
249 |
'{TEST_TITLE}' => '',
|
lib/Cleantalk/ApbctWP/Firewall/die_page_anticrawler.html
CHANGED
@@ -153,5 +153,8 @@
|
|
153 |
countdown();
|
154 |
|
155 |
</script>
|
|
|
|
|
|
|
156 |
</body>
|
157 |
</html>
|
153 |
countdown();
|
154 |
|
155 |
</script>
|
156 |
+
<div class="debug">
|
157 |
+
{DEBUG}
|
158 |
+
</div>
|
159 |
</body>
|
160 |
</html>
|
lib/Cleantalk/Templates/Singleton.php
CHANGED
@@ -1,35 +1,35 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Cleantalk\Templates;
|
4 |
-
|
5 |
-
if(!trait_exists('Cleantalk\Templates\Singleton')) {
|
6 |
-
|
7 |
-
trait Singleton{
|
8 |
-
|
9 |
-
static $instance;
|
10 |
-
|
11 |
-
public function __construct(){}
|
12 |
-
public function __wakeup(){}
|
13 |
-
public function __clone(){}
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Constructor
|
17 |
-
* @return $this
|
18 |
-
*/
|
19 |
-
public static function getInstance(){
|
20 |
-
if (!isset(static::$instance)) {
|
21 |
-
static::$instance = new static;
|
22 |
-
static::$instance->init();
|
23 |
-
}
|
24 |
-
return static::$instance;
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Alternative constructor
|
29 |
-
*/
|
30 |
-
private function init(){
|
31 |
-
|
32 |
-
}
|
33 |
-
|
34 |
-
}
|
35 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Cleantalk\Templates;
|
4 |
+
|
5 |
+
if(!trait_exists('Cleantalk\Templates\Singleton')) {
|
6 |
+
|
7 |
+
trait Singleton{
|
8 |
+
|
9 |
+
static $instance;
|
10 |
+
|
11 |
+
public function __construct(){}
|
12 |
+
public function __wakeup(){}
|
13 |
+
public function __clone(){}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Constructor
|
17 |
+
* @return $this
|
18 |
+
*/
|
19 |
+
public static function getInstance(){
|
20 |
+
if (!isset(static::$instance)) {
|
21 |
+
static::$instance = new static;
|
22 |
+
static::$instance->init();
|
23 |
+
}
|
24 |
+
return static::$instance;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Alternative constructor
|
29 |
+
*/
|
30 |
+
private function init(){
|
31 |
+
|
32 |
+
}
|
33 |
+
|
34 |
+
}
|
35 |
+
}
|
lib/cleantalk-php-patch.php
CHANGED
@@ -1,80 +1,91 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/*
|
4 |
-
* Patch for apache_request_headers()
|
5 |
-
* If Apache web server is missing then making
|
6 |
-
*/
|
7 |
-
if( !function_exists('apache_request_headers') ){
|
8 |
-
function apache_request_headers(){
|
9 |
-
|
10 |
-
$headers = array();
|
11 |
-
foreach($_SERVER as $key => $val){
|
12 |
-
if(preg_match('/\AHTTP_/', $key)){
|
13 |
-
$server_key = preg_replace('/\AHTTP_/', '', $key);
|
14 |
-
$key_parts = explode('_', $server_key);
|
15 |
-
if(count($key_parts) > 0 and strlen($server_key) > 2){
|
16 |
-
foreach($key_parts as $part_index => $part){
|
17 |
-
$key_parts[$part_index] = function_exists('mb_strtolower') ? mb_strtolower($part) : strtolower($part);
|
18 |
-
$key_parts[$part_index][0] = strtoupper($key_parts[$part_index][0]);
|
19 |
-
}
|
20 |
-
$server_key = implode('-', $key_parts);
|
21 |
-
}
|
22 |
-
$headers[$server_key] = $val;
|
23 |
-
}
|
24 |
-
}
|
25 |
-
return $headers;
|
26 |
-
}
|
27 |
-
}
|
28 |
-
|
29 |
-
/*
|
30 |
-
* Patch for locale_get_display_region()
|
31 |
-
* For old PHP versions
|
32 |
-
*/
|
33 |
-
if( !function_exists('locale_get_display_region') ){
|
34 |
-
function locale_get_display_region($locale, $in_locale = 'EN'){
|
35 |
-
|
36 |
-
return 'Unkonwn' . ($locale ? ': ' . $locale : '');
|
37 |
-
}
|
38 |
-
}
|
39 |
-
|
40 |
-
/*
|
41 |
-
* Patch for utf8_decode()
|
42 |
-
* If PHP complied without XML support
|
43 |
-
* From getID3() by James Heinrich <info@getid3.org> under GNU GPL
|
44 |
-
*/
|
45 |
-
if(!function_exists('utf8_decode')){
|
46 |
-
function utf8_decode($string){
|
47 |
-
|
48 |
-
$newcharstring = '';
|
49 |
-
$offset = 0;
|
50 |
-
$stringlength = strlen($string);
|
51 |
-
while ($offset < $stringlength) {
|
52 |
-
if ((ord($string[$offset]) | 0x07) == 0xF7) {
|
53 |
-
$charval = ((ord($string[($offset + 0)]) & 0x07) << 18) &
|
54 |
-
((ord($string[($offset + 1)]) & 0x3F) << 12) &
|
55 |
-
((ord($string[($offset + 2)]) & 0x3F) << 6) &
|
56 |
-
(ord($string[($offset + 3)]) & 0x3F);
|
57 |
-
$offset += 4;
|
58 |
-
} elseif ((ord($string[$offset]) | 0x0F) == 0xEF) {
|
59 |
-
$charval = ((ord($string[($offset + 0)]) & 0x0F) << 12) &
|
60 |
-
((ord($string[($offset + 1)]) & 0x3F) << 6) &
|
61 |
-
(ord($string[($offset + 2)]) & 0x3F);
|
62 |
-
$offset += 3;
|
63 |
-
} elseif ((ord($string[$offset]) | 0x1F) == 0xDF) {
|
64 |
-
$charval = ((ord($string[($offset + 0)]) & 0x1F) << 6) &
|
65 |
-
(ord($string[($offset + 1)]) & 0x3F);
|
66 |
-
$offset += 2;
|
67 |
-
} elseif ((ord($string[$offset]) | 0x7F) == 0x7F) {
|
68 |
-
$charval = ord($string[$offset]);
|
69 |
-
$offset += 1;
|
70 |
-
} else {
|
71 |
-
$charval = false;
|
72 |
-
$offset += 1;
|
73 |
-
}
|
74 |
-
if ($charval !== false) {
|
75 |
-
$newcharstring .= (($charval < 256) ? chr($charval) : '?');
|
76 |
-
}
|
77 |
-
}
|
78 |
-
return $newcharstring;
|
79 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* Patch for apache_request_headers()
|
5 |
+
* If Apache web server is missing then making
|
6 |
+
*/
|
7 |
+
if( !function_exists('apache_request_headers') ){
|
8 |
+
function apache_request_headers(){
|
9 |
+
|
10 |
+
$headers = array();
|
11 |
+
foreach($_SERVER as $key => $val){
|
12 |
+
if(preg_match('/\AHTTP_/', $key)){
|
13 |
+
$server_key = preg_replace('/\AHTTP_/', '', $key);
|
14 |
+
$key_parts = explode('_', $server_key);
|
15 |
+
if(count($key_parts) > 0 and strlen($server_key) > 2){
|
16 |
+
foreach($key_parts as $part_index => $part){
|
17 |
+
$key_parts[$part_index] = function_exists('mb_strtolower') ? mb_strtolower($part) : strtolower($part);
|
18 |
+
$key_parts[$part_index][0] = strtoupper($key_parts[$part_index][0]);
|
19 |
+
}
|
20 |
+
$server_key = implode('-', $key_parts);
|
21 |
+
}
|
22 |
+
$headers[$server_key] = $val;
|
23 |
+
}
|
24 |
+
}
|
25 |
+
return $headers;
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
/*
|
30 |
+
* Patch for locale_get_display_region()
|
31 |
+
* For old PHP versions
|
32 |
+
*/
|
33 |
+
if( !function_exists('locale_get_display_region') ){
|
34 |
+
function locale_get_display_region($locale, $in_locale = 'EN'){
|
35 |
+
|
36 |
+
return 'Unkonwn' . ($locale ? ': ' . $locale : '');
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
/*
|
41 |
+
* Patch for utf8_decode()
|
42 |
+
* If PHP complied without XML support
|
43 |
+
* From getID3() by James Heinrich <info@getid3.org> under GNU GPL
|
44 |
+
*/
|
45 |
+
if(!function_exists('utf8_decode')){
|
46 |
+
function utf8_decode($string){
|
47 |
+
|
48 |
+
$newcharstring = '';
|
49 |
+
$offset = 0;
|
50 |
+
$stringlength = strlen($string);
|
51 |
+
while ($offset < $stringlength) {
|
52 |
+
if ((ord($string[$offset]) | 0x07) == 0xF7) {
|
53 |
+
$charval = ((ord($string[($offset + 0)]) & 0x07) << 18) &
|
54 |
+
((ord($string[($offset + 1)]) & 0x3F) << 12) &
|
55 |
+
((ord($string[($offset + 2)]) & 0x3F) << 6) &
|
56 |
+
(ord($string[($offset + 3)]) & 0x3F);
|
57 |
+
$offset += 4;
|
58 |
+
} elseif ((ord($string[$offset]) | 0x0F) == 0xEF) {
|
59 |
+
$charval = ((ord($string[($offset + 0)]) & 0x0F) << 12) &
|
60 |
+
((ord($string[($offset + 1)]) & 0x3F) << 6) &
|
61 |
+
(ord($string[($offset + 2)]) & 0x3F);
|
62 |
+
$offset += 3;
|
63 |
+
} elseif ((ord($string[$offset]) | 0x1F) == 0xDF) {
|
64 |
+
$charval = ((ord($string[($offset + 0)]) & 0x1F) << 6) &
|
65 |
+
(ord($string[($offset + 1)]) & 0x3F);
|
66 |
+
$offset += 2;
|
67 |
+
} elseif ((ord($string[$offset]) | 0x7F) == 0x7F) {
|
68 |
+
$charval = ord($string[$offset]);
|
69 |
+
$offset += 1;
|
70 |
+
} else {
|
71 |
+
$charval = false;
|
72 |
+
$offset += 1;
|
73 |
+
}
|
74 |
+
if ($charval !== false) {
|
75 |
+
$newcharstring .= (($charval < 256) ? chr($charval) : '?');
|
76 |
+
}
|
77 |
+
}
|
78 |
+
return $newcharstring;
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
if( ! function_exists( "array_column" ) ){
|
83 |
+
|
84 |
+
function array_column($array,$column_name){
|
85 |
+
|
86 |
+
return array_map( function ( $element ) use ( $column_name ){
|
87 |
+
return $element[ $column_name ];
|
88 |
+
}, $array );
|
89 |
+
|
90 |
+
}
|
91 |
}
|
readme.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
=== Spam protection, AntiSpam, FireWall by CleanTalk ===
|
2 |
Contributors: safronik
|
3 |
-
Tags: spam, antispam,
|
4 |
Requires at least: 3.0
|
5 |
Tested up to: 5.5
|
6 |
Requires PHP: 5.4
|
7 |
-
Stable tag: 5.146
|
8 |
License: GPLv2
|
9 |
|
10 |
Spam protection, anti-spam, firewall, premium plugin. No spam comments & users, no spam contact form & WooCommerce anti-spam.
|
@@ -194,7 +194,6 @@ our own CleanTalk Cloud Service. Anti Spam by CleanTalk offers a free trial, you
|
|
194 |
|
195 |
= Additional features =
|
196 |
* Daily and weekly detailed anti-spam reports: traffic VS spam.
|
197 |
-
* Apps for iPhone, Android to control anti-spam service, comments, signups, contacts, traffic and spam stats for the last 7 days.
|
198 |
* AntiSpam apps for most popular CMS on cleantalk.org.
|
199 |
|
200 |
= How to protect sites from spam bots without CAPTCHA? =
|
@@ -317,11 +316,6 @@ In WordPress multisite version you can switch the plugin to use Global Access ke
|
|
317 |
**Make it before you activated the plugin. If the plugin already activated, deactivate it and add the code and active it again.**
|
318 |
Now, all subsites will have this access key.
|
319 |
|
320 |
-
= Manage and control spam protection =
|
321 |
-
|
322 |
-
Go to <a href="https://cleantalk.org/my" target="_blank">Dashboard</a> at the cleantalk.org or use <a href="https://play.google.com/store/apps/details?id=org.cleantalk.app">Android</a>, <a href="https://itunes.apple.com/us/app/cleantalk/id825479913?mt=8">iPhone</a> anti-spam app to manage and control spam protection.
|
323 |
-
|
324 |
-
|
325 |
== Frequently Asked Questions ==
|
326 |
|
327 |
= Why are they spamming me? =
|
@@ -580,6 +574,14 @@ If your website has forms that send data to external sources, you can enable opt
|
|
580 |
|
581 |
== Changelog ==
|
582 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
583 |
= 5.146 Sep 17 2020 =
|
584 |
* Fix: Deprecated function wp_blacklist_check() fixed.
|
585 |
* Fix: Roles exclusion fixed.
|
1 |
=== Spam protection, AntiSpam, FireWall by CleanTalk ===
|
2 |
Contributors: safronik
|
3 |
+
Tags: spam, antispam, anti-spam, comments, firewall
|
4 |
Requires at least: 3.0
|
5 |
Tested up to: 5.5
|
6 |
Requires PHP: 5.4
|
7 |
+
Stable tag: 5.146.1
|
8 |
License: GPLv2
|
9 |
|
10 |
Spam protection, anti-spam, firewall, premium plugin. No spam comments & users, no spam contact form & WooCommerce anti-spam.
|
194 |
|
195 |
= Additional features =
|
196 |
* Daily and weekly detailed anti-spam reports: traffic VS spam.
|
|
|
197 |
* AntiSpam apps for most popular CMS on cleantalk.org.
|
198 |
|
199 |
= How to protect sites from spam bots without CAPTCHA? =
|
316 |
**Make it before you activated the plugin. If the plugin already activated, deactivate it and add the code and active it again.**
|
317 |
Now, all subsites will have this access key.
|
318 |
|
|
|
|
|
|
|
|
|
|
|
319 |
== Frequently Asked Questions ==
|
320 |
|
321 |
= Why are they spamming me? =
|
574 |
|
575 |
== Changelog ==
|
576 |
|
577 |
+
= 5.146.1 Sep 23 2020 =
|
578 |
+
* Fix: URL exclusions setting.
|
579 |
+
* Fix: Login scripts output fixed.
|
580 |
+
* Fix: Updater function name fixed.
|
581 |
+
* New: Debug mode for Anti-Crawler.
|
582 |
+
* Fix: Pass AC check if 301 HTTP response code received.
|
583 |
+
* Fix: Antibot cookie value fixed.
|
584 |
+
|
585 |
= 5.146 Sep 17 2020 =
|
586 |
* Fix: Deprecated function wp_blacklist_check() fixed.
|
587 |
* Fix: Roles exclusion fixed.
|