Spam protection, AntiSpam, FireWall by CleanTalk - Version 5.119

Version Description

May 30 2019 = * Fix: No more second request after registration. * Fix: Activation hook. * Fix: Alternative sessions. Clear table. * Fix: Stop capchuring AJAX requests in admin area. * Fix: Spelling. * Fix: Registration cookies set. * Mod: SFW exdtended die page when testing. * Mod: User-agent modified. * New: Test search queries for spam. * New: Gathering and output statistics.

Download this release

Release Info

Developer Safronik
Plugin Icon 128x128 Spam protection, AntiSpam, FireWall by CleanTalk
Version 5.119
Comparing to
See all releases

Code changes from version 5.118.4 to 5.119

cleantalk.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Anti-Spam by CleanTalk
4
  Plugin URI: http://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.118.4
7
  Author: СleanTalk <welcome@cleantalk.org>
8
  Author URI: http://cleantalk.org
9
  */
@@ -60,7 +60,7 @@ if(!defined('CLEANTALK_PLUGIN_DIR')){
60
 
61
  // Global ArrayObject with settings and other global varables
62
  global $apbct;
63
- $apbct = new CleantalkState('cleantalk', array('settings', 'data', 'debug', 'errors', 'remote_calls'), is_multisite());
64
 
65
  $apbct->white_label = defined('APBCT_WHITELABEL') && APBCT_WHITELABEL == true ? true : false;
66
 
@@ -130,6 +130,7 @@ if(!defined('CLEANTALK_PLUGIN_DIR')){
130
  // Set cookie only for public pages and for non-AJAX requests
131
  if (!is_admin() && !apbct_is_ajax() && !defined('DOING_CRON') && !headers_sent()
132
  && empty($_POST['ct_checkjs_register_form']) // Buddy press registration fix
 
133
  ){
134
  add_action('template_redirect','apbct_cookie', 2);
135
  add_action('template_redirect','apbct_store__urls', 2);
@@ -152,7 +153,11 @@ if(!defined('CLEANTALK_PLUGIN_DIR')){
152
  }
153
 
154
  }
155
-
 
 
 
 
156
  // Ninja Forms. Making GET action to POST action
157
  if(isset($_SERVER['REQUEST_URI']) && stripos($_SERVER['REQUEST_URI'],'admin-ajax.php') !== false && sizeof($_POST) > 0 && isset($_GET['action']) && $_GET['action']=='ninja_forms_ajax_submit')
158
  $_POST['action']='ninja_forms_ajax_submit';
@@ -318,10 +323,11 @@ if(!defined('CLEANTALK_PLUGIN_DIR')){
318
  add_filter('wp_die_handler', 'apbct_comment__sanitize_data__before_wp_die', 1); // Check comments after validation
319
 
320
  // Registrations
321
- if(!isset($_POST['wp-submit']))
322
- add_action('login_form_register', 'apbct_cookie');
323
- add_action('login_form_register', 'apbct_store__urls');
324
- add_action('login_enqueue_scripts', 'apbct_login__scripts');
 
325
  add_action('register_form', 'ct_register_form');
326
  add_filter('registration_errors', 'ct_registration_errors', 1, 3);
327
  add_filter('registration_errors', 'ct_check_registration_erros', 999999, 3);
@@ -399,7 +405,7 @@ function apbct_remote_call__perform()
399
 
400
  // SFW send logs
401
  case 'sfw_send_logs':
402
- $rc_result = ct_sfw_send_logs();
403
  die(empty($result['error']) ? 'OK' : 'FAIL '.json_encode(array('error' => $result['error_string'])));
404
  break;
405
 
@@ -458,6 +464,7 @@ function apbct_sfw__check()
458
  $sfw = new CleantalkSFW();
459
  $sfw->ip_array = (array)$sfw->ip__get(array('real'), true);
460
 
 
461
  foreach($sfw->ip_array as $ct_cur_ip){
462
  if(isset($_COOKIE['ct_sfw_pass_key']) && $_COOKIE['ct_sfw_pass_key'] == md5($ct_cur_ip.$apbct->api_key)){
463
  $is_sfw_check=false;
@@ -470,7 +477,7 @@ function apbct_sfw__check()
470
  }
471
  break;
472
  }else{
473
- $is_sfw_check=true;
474
  }
475
  }
476
 
@@ -487,25 +494,35 @@ function apbct_sfw__check()
487
  }
488
 
489
  if($is_sfw_check){
 
490
  $sfw->ip_check();
491
- if($sfw->result){
 
 
492
  if(isset($_GET['spbc_remote_call_token'], $_GET['spbc_remote_call_action'], $_GET['plugin_name'])){
493
- $resolved = gethostbyaddr($sfw->blocked_ip);
494
- if($resolved && preg_match('/cleantalk\.org/', $resolved) === 1 || $resolved === 'back'){
495
- $sfw->result = false;
496
- $sfw->passed_ip = $sfw->blocked_ip;
497
- }
 
498
  }
499
  }
500
 
501
- if($sfw->result){
502
- $sfw->logs__update($sfw->blocked_ip, 'blocked');
 
 
 
 
 
 
503
  $apbct->data['sfw_counter']['blocked']++;
504
  $apbct->saveData();
505
  $sfw->sfw_die($apbct->api_key, '', parse_url(get_option('siteurl'),PHP_URL_HOST));
506
  }else{
507
  if(!empty($apbct->settings['set_cookies']) && !headers_sent())
508
- setcookie ('ct_sfw_pass_key', md5($sfw->passed_ip.$apbct->api_key), time()+86400*30, '/', parse_url(get_option('siteurl'),PHP_URL_HOST) ,false, true);
509
  }
510
  }
511
  unset($is_sfw_check, $sfw, $sfw_ip, $ct_cur_ip);
@@ -537,10 +554,10 @@ function apbct_activation( $network = false ) {
537
  // Sessions
538
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_sessions` (
539
  `id` VARCHAR(64) NOT NULL,
540
- `name` TEXT NOT NULL,
541
  `value` TEXT NULL DEFAULT NULL,
542
  `last_update` DATETIME NULL DEFAULT NULL,
543
- PRIMARY KEY (`id`, `name`(10)))
544
  ENGINE = MYISAM;';
545
 
546
  if($network && !defined('CLEANTALK_ACCESS_KEY')){
@@ -596,7 +613,7 @@ function apbct_activation__create_tables($sqls) {
596
  }
597
 
598
  function apbct_activation__new_blog($blog_id, $user_id, $domain, $path, $site_id, $meta) {
599
- if (apbct_is_plugin_active_for_network('security-malware-firewall/security-malware-firewall.php')){
600
 
601
  switch_to_blog($blog_id);
602
 
@@ -624,7 +641,7 @@ function apbct_activation__new_blog($blog_id, $user_id, $domain, $path, $site_id
624
  `name` TEXT NOT NULL,
625
  `value` TEXT NULL DEFAULT NULL,
626
  `last_update` DATETIME NULL DEFAULT NULL,
627
- PRIMARY KEY (`id`, `name`(10)))
628
  ENGINE = MYISAM;';
629
 
630
  // Cron tasks
@@ -744,7 +761,13 @@ function ct_sfw_update($immediate = false){
744
 
745
  $file_url = isset($_GET['file_url']) ? $_GET['file_url'] : null;
746
  $result = $sfw->sfw_update($apbct->api_key, $file_url, $immediate);
747
- unset($sfw);
 
 
 
 
 
 
748
  return $result;
749
  }
750
 
@@ -763,7 +786,13 @@ function ct_sfw_send_logs()
763
 
764
  $sfw = new CleantalkSFW();
765
  $result = $sfw->logs__send($apbct->api_key);
766
- unset($sfw);
 
 
 
 
 
 
767
  return $result;
768
 
769
  }
@@ -998,6 +1027,9 @@ function apbct_cookie(){
998
  )
999
  return false;
1000
 
 
 
 
1001
  // Cookie names to validate
1002
  $cookie_test_value = array(
1003
  'cookies_names' => array(),
@@ -1126,10 +1158,6 @@ function apbct_get_submit_time()
1126
  return apbct_cookies_test() == 1 ? time() - (int)$apbct_timestamp : null;
1127
  }
1128
 
1129
- function apbct_is_user_logged_in(){
1130
- return count($_COOKIE) && defined('LOGGED_IN_COOKIE') && isset($_COOKIE[LOGGED_IN_COOKIE]);
1131
- }
1132
-
1133
  /*
1134
  * Inner function - Account status check
1135
  * Scheduled in 1800 seconds for default!
@@ -1173,6 +1201,8 @@ function ct_account_status_check($api_key = null, $process_errors = true){
1173
  if($apbct->data['notice_show'] == 0)
1174
  CleantalkCron::updateTask('check_account_status', 'ct_account_status_check', 86400);
1175
 
 
 
1176
  $apbct->saveData();
1177
  $apbct->error_delete('account_check', 'save');
1178
 
@@ -1232,6 +1262,8 @@ function ct_mail_send_connection_report() {
1232
  //* Write $message to the plugin's debug option
1233
  function apbct_log($message = 'empty', $func = null, $params = array())
1234
  {
 
 
1235
  $debug = get_option( APBCT_DEBUG );
1236
 
1237
  $function = $func ? $func : '';
@@ -1263,6 +1295,15 @@ function apbct_sfw__delete_tables( $blog_id, $drop ) {
1263
  switch_to_blog($initial_blog);
1264
  }
1265
 
 
 
 
 
 
 
 
 
 
1266
  /**
1267
  * Checks if the current user has role
1268
  *
@@ -1286,6 +1327,169 @@ function apbct_is_user_role_in( $roles, $user = false ){
1286
  return false;
1287
  }
1288
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1289
  /**
1290
  * Checks if the request is AJAX
1291
  *
@@ -1300,7 +1504,7 @@ function apbct_is_ajax() {
1300
 
1301
  }
1302
 
1303
- function apbct_is_plugin_active_for_network(){
1304
  if ( ! APBCT_WPMS )
1305
  return false;
1306
  $plugins = get_site_option( 'active_sitewide_plugins' );
3
  Plugin Name: Anti-Spam by CleanTalk
4
  Plugin URI: http://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.119
7
  Author: СleanTalk <welcome@cleantalk.org>
8
  Author URI: http://cleantalk.org
9
  */
60
 
61
  // Global ArrayObject with settings and other global varables
62
  global $apbct;
63
+ $apbct = new CleantalkState('cleantalk', array('settings', 'data', 'debug', 'errors', 'remote_calls', 'stats'), is_multisite());
64
 
65
  $apbct->white_label = defined('APBCT_WHITELABEL') && APBCT_WHITELABEL == true ? true : false;
66
 
130
  // Set cookie only for public pages and for non-AJAX requests
131
  if (!is_admin() && !apbct_is_ajax() && !defined('DOING_CRON') && !headers_sent()
132
  && empty($_POST['ct_checkjs_register_form']) // Buddy press registration fix
133
+ && empty($_GET['ct_checkjs_search_default']) // Search form fix
134
  ){
135
  add_action('template_redirect','apbct_cookie', 2);
136
  add_action('template_redirect','apbct_store__urls', 2);
153
  }
154
 
155
  }
156
+
157
+ // Default search
158
+ //add_filter( 'get_search_form', 'apbct_forms__search__addField' );
159
+ add_filter( 'get_search_query', 'apbct_forms__search__testSpam' );
160
+
161
  // Ninja Forms. Making GET action to POST action
162
  if(isset($_SERVER['REQUEST_URI']) && stripos($_SERVER['REQUEST_URI'],'admin-ajax.php') !== false && sizeof($_POST) > 0 && isset($_GET['action']) && $_GET['action']=='ninja_forms_ajax_submit')
163
  $_POST['action']='ninja_forms_ajax_submit';
323
  add_filter('wp_die_handler', 'apbct_comment__sanitize_data__before_wp_die', 1); // Check comments after validation
324
 
325
  // Registrations
326
+ if(!isset($_POST['wp-submit'])){
327
+ add_action('login_form_register', 'apbct_cookie');
328
+ add_action('login_form_register', 'apbct_store__urls');
329
+ }
330
+ add_action('login_enqueue_scripts', 'apbct_login__scripts');
331
  add_action('register_form', 'ct_register_form');
332
  add_filter('registration_errors', 'ct_registration_errors', 1, 3);
333
  add_filter('registration_errors', 'ct_check_registration_erros', 999999, 3);
405
 
406
  // SFW send logs
407
  case 'sfw_send_logs':
408
+ $result = ct_sfw_send_logs();
409
  die(empty($result['error']) ? 'OK' : 'FAIL '.json_encode(array('error' => $result['error_string'])));
410
  break;
411
 
464
  $sfw = new CleantalkSFW();
465
  $sfw->ip_array = (array)$sfw->ip__get(array('real'), true);
466
 
467
+ // Skip by cookie
468
  foreach($sfw->ip_array as $ct_cur_ip){
469
  if(isset($_COOKIE['ct_sfw_pass_key']) && $_COOKIE['ct_sfw_pass_key'] == md5($ct_cur_ip.$apbct->api_key)){
470
  $is_sfw_check=false;
477
  }
478
  break;
479
  }else{
480
+ $is_sfw_check = true;
481
  }
482
  }
483
 
494
  }
495
 
496
  if($is_sfw_check){
497
+
498
  $sfw->ip_check();
499
+
500
+ // Pass remote calls
501
+ if($sfw->pass === false){
502
  if(isset($_GET['spbc_remote_call_token'], $_GET['spbc_remote_call_action'], $_GET['plugin_name'])){
503
+ foreach($sfw->blocked_ips as $ip){
504
+ $resolved = CleantalkHelper::ip__resolve($ip['ip']);
505
+ if($resolved && preg_match('/cleantalk\.org/', $resolved) === 1 || $resolved === 'back'){
506
+ $sfw->pass = true;
507
+ }
508
+ } unset($ip);
509
  }
510
  }
511
 
512
+ if($sfw->test){
513
+ $sfw->sfw_die($apbct->api_key, '', parse_url(get_option('siteurl'),PHP_URL_HOST), 'test');
514
+ }
515
+
516
+ if($sfw->pass === false){
517
+ foreach($sfw->blocked_ips as $ip){
518
+ $sfw->logs__update($ip['ip'], 'blocked');
519
+ }
520
  $apbct->data['sfw_counter']['blocked']++;
521
  $apbct->saveData();
522
  $sfw->sfw_die($apbct->api_key, '', parse_url(get_option('siteurl'),PHP_URL_HOST));
523
  }else{
524
  if(!empty($apbct->settings['set_cookies']) && !headers_sent())
525
+ setcookie ('ct_sfw_pass_key', md5($sfw->passed_ips[key($sfw->passed_ips)]['ip'].$apbct->api_key), time()+86400*30, '/', parse_url(get_option('siteurl'),PHP_URL_HOST) ,false, true);
526
  }
527
  }
528
  unset($is_sfw_check, $sfw, $sfw_ip, $ct_cur_ip);
554
  // Sessions
555
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_sessions` (
556
  `id` VARCHAR(64) NOT NULL,
557
+ `name` VARCHAR(40) NOT NULL,
558
  `value` TEXT NULL DEFAULT NULL,
559
  `last_update` DATETIME NULL DEFAULT NULL,
560
+ PRIMARY KEY (`name`(40), `id`(64)))
561
  ENGINE = MYISAM;';
562
 
563
  if($network && !defined('CLEANTALK_ACCESS_KEY')){
613
  }
614
 
615
  function apbct_activation__new_blog($blog_id, $user_id, $domain, $path, $site_id, $meta) {
616
+ if (apbct_is_plugin_active_for_network('cleantalk-spam-protect/cleantalk.php')){
617
 
618
  switch_to_blog($blog_id);
619
 
641
  `name` TEXT NOT NULL,
642
  `value` TEXT NULL DEFAULT NULL,
643
  `last_update` DATETIME NULL DEFAULT NULL,
644
+ PRIMARY KEY (`id`(64), `name`(64)))
645
  ENGINE = MYISAM;';
646
 
647
  // Cron tasks
761
 
762
  $file_url = isset($_GET['file_url']) ? $_GET['file_url'] : null;
763
  $result = $sfw->sfw_update($apbct->api_key, $file_url, $immediate);
764
+
765
+ if(empty($result['error'])){
766
+ $apbct->stats['sfw']['last_update_time'] = time();
767
+ $apbct->stats['sfw']['entries'] = $result;
768
+ $apbct->save('stats');
769
+ }
770
+
771
  return $result;
772
  }
773
 
786
 
787
  $sfw = new CleantalkSFW();
788
  $result = $sfw->logs__send($apbct->api_key);
789
+
790
+ if(empty($result['error'])){
791
+ $apbct->stats['sfw']['last_send_time'] = time();
792
+ $apbct->stats['sfw']['last_send_amount'] = $result['rows'];
793
+ $apbct->save('stats');
794
+ }
795
+
796
  return $result;
797
 
798
  }
1027
  )
1028
  return false;
1029
 
1030
+ if($apbct->settings['store_urls__sessions'])
1031
+ apbct_alt_sessions__remove_old();
1032
+
1033
  // Cookie names to validate
1034
  $cookie_test_value = array(
1035
  'cookies_names' => array(),
1158
  return apbct_cookies_test() == 1 ? time() - (int)$apbct_timestamp : null;
1159
  }
1160
 
 
 
 
 
1161
  /*
1162
  * Inner function - Account status check
1163
  * Scheduled in 1800 seconds for default!
1201
  if($apbct->data['notice_show'] == 0)
1202
  CleantalkCron::updateTask('check_account_status', 'ct_account_status_check', 86400);
1203
 
1204
+ $apbct->data['key_is_ok'] = true;
1205
+
1206
  $apbct->saveData();
1207
  $apbct->error_delete('account_check', 'save');
1208
 
1262
  //* Write $message to the plugin's debug option
1263
  function apbct_log($message = 'empty', $func = null, $params = array())
1264
  {
1265
+ global $apbct;
1266
+
1267
  $debug = get_option( APBCT_DEBUG );
1268
 
1269
  $function = $func ? $func : '';
1295
  switch_to_blog($initial_blog);
1296
  }
1297
 
1298
+ /**
1299
+ * Checks if the user is logged in
1300
+ *
1301
+ * @return bool
1302
+ */
1303
+ function apbct_is_user_logged_in(){
1304
+ return count($_COOKIE) && defined('LOGGED_IN_COOKIE') && isset($_COOKIE[LOGGED_IN_COOKIE]);
1305
+ }
1306
+
1307
  /**
1308
  * Checks if the current user has role
1309
  *
1327
  return false;
1328
  }
1329
 
1330
+ function apbct_wp_get_current_user(){
1331
+
1332
+ global $current_user;
1333
+
1334
+ if(!(defined('XMLRPC_REQUEST') && XMLRPC_REQUEST)){
1335
+
1336
+ if(!empty($current_user)){
1337
+ $user_id = is_object($current_user) && isset($current_user->ID) && !($current_user instanceof WP_User)
1338
+ ? $current_user->ID
1339
+ : null;
1340
+ }else{
1341
+ $user_id = empty($user_id) && !empty($_COOKIE[LOGGED_IN_COOKIE])
1342
+ ? apbct_wp_validate_auth_cookie($_COOKIE[LOGGED_IN_COOKIE], 'logged_in')
1343
+ : null;
1344
+ }
1345
+
1346
+ if($user_id){
1347
+ $current_user = new WP_User($user_id);
1348
+ }
1349
+
1350
+ }
1351
+
1352
+ return $current_user;
1353
+ }
1354
+
1355
+ function apbct_wp_set_current_user($user = null){
1356
+ global $current_user;
1357
+ if($user instanceof WP_User)
1358
+ $current_user = $user;
1359
+ else
1360
+ return false;
1361
+ return true;
1362
+ }
1363
+
1364
+ /**
1365
+ * Validates authentication cookie.
1366
+ *
1367
+ * The checks include making sure that the authentication cookie is set and
1368
+ * pulling in the contents (if $cookie is not used).
1369
+ *
1370
+ * Makes sure the cookie is not expired. Verifies the hash in cookie is what is
1371
+ * should be and compares the two.
1372
+ *
1373
+ * @param string $cookie Optional. If used, will validate contents instead of cookie's
1374
+ * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
1375
+ *
1376
+ * @return false|int False if invalid cookie, User ID if valid.
1377
+ * @global int $login_grace_period
1378
+ *
1379
+ */
1380
+ function apbct_wp_validate_auth_cookie( $cookie = '', $scheme = '' ) {
1381
+
1382
+ $cookie_elements = apbct_wp_parse_auth_cookie($cookie, $scheme);
1383
+
1384
+ $scheme = $cookie_elements['scheme'];
1385
+ $username = $cookie_elements['username'];
1386
+ $hmac = $cookie_elements['hmac'];
1387
+ $token = $cookie_elements['token'];
1388
+ $expiration = $cookie_elements['expiration'];
1389
+
1390
+ // Allow a grace period for POST and Ajax requests
1391
+ $expired = apbct_is_ajax() || 'POST' == $_SERVER['REQUEST_METHOD']
1392
+ ? $expiration + HOUR_IN_SECONDS
1393
+ : $cookie_elements['expiration'];
1394
+
1395
+ // Quick check to see if an honest cookie has expired
1396
+ if($expired >= time()){
1397
+ $user = apbct_wp_get_user_by('login', $username);
1398
+ if($user){
1399
+ $pass_frag = substr($user->user_pass, 8, 4);
1400
+ $key = apbct_wp_hash($username . '|' . $pass_frag . '|' . $expiration . '|' . $token, $scheme);
1401
+ // If ext/hash is not present, compat.php's hash_hmac() does not support sha256.
1402
+ $algo = function_exists('hash') ? 'sha256' : 'sha1';
1403
+ $hash = hash_hmac($algo, $username . '|' . $expiration . '|' . $token, $key);
1404
+ if(hash_equals($hash, $hmac)){
1405
+ $sessions = get_user_meta($user->ID, 'session_tokens', true);
1406
+ $sessions = current($sessions);
1407
+ if(is_array($sessions)){
1408
+ if(is_int($sessions['expiration']) && $sessions['expiration'] > time()){
1409
+ return $user->ID;
1410
+ }else
1411
+ return false;
1412
+ }else
1413
+ return false;
1414
+ }else
1415
+ return false;
1416
+ }else
1417
+ return false;
1418
+ }else
1419
+ return false;
1420
+ }
1421
+
1422
+ function apbct_wp_get_user_by($field, $value){
1423
+
1424
+ $userdata = WP_User::get_data_by($field, $value);
1425
+
1426
+ if(!$userdata)
1427
+ return false;
1428
+
1429
+ $user = new WP_User;
1430
+ $user->init($userdata);
1431
+
1432
+ return $user;
1433
+ }
1434
+
1435
+ /**
1436
+ * Get hash of given string.
1437
+ *
1438
+ * @param string $data Plain text to hash
1439
+ * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce)
1440
+ * @return string Hash of $data
1441
+ */
1442
+ function apbct_wp_hash( $data, $scheme = 'auth' ) {
1443
+ $salt = constant(strtoupper("{$scheme}_KEY")).constant(strtoupper("{$scheme}_SALT"));
1444
+ return hash_hmac('md5', $data, $salt);
1445
+ }
1446
+
1447
+ /**
1448
+ * Parse a cookie into its components
1449
+ *
1450
+ * @param string $cookie
1451
+ * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
1452
+ *
1453
+ * @return array|false Authentication cookie components
1454
+ *
1455
+ */
1456
+ function apbct_wp_parse_auth_cookie($cookie = '', $scheme = '')
1457
+ {
1458
+ $cookie_elements = explode('|', $cookie);
1459
+ if(count($cookie_elements) !== 4){
1460
+ return false;
1461
+ }
1462
+
1463
+ list($username, $expiration, $token, $hmac) = $cookie_elements;
1464
+
1465
+ return compact('username', 'expiration', 'token', 'hmac', 'scheme');
1466
+ }
1467
+
1468
+ /**
1469
+ * Update and rotate statistics with requests exection time
1470
+ *
1471
+ * @param $exec_time
1472
+ */
1473
+ function apbct_statistics__rotate($exec_time){
1474
+
1475
+ global $apbct;
1476
+
1477
+ // Delete old stats
1478
+ if(min(array_keys($apbct->stats['requests'])) < time() - (86400 * 7))
1479
+ unset($apbct->stats['requests'][min(array_keys($apbct->stats['requests']))]);
1480
+
1481
+ // Create new if newest older than 1 day
1482
+ if(empty($apbct->stats['requests']) || max(array_keys($apbct->stats['requests'])) < time() - (86400 * 1))
1483
+ $apbct->stats['requests'][time()] = array('amount' => 0, 'average_time' => 0);
1484
+
1485
+ // Update all existing stats
1486
+ foreach($apbct->stats['requests'] as &$weak_stat){
1487
+ $weak_stat['average_time'] = ($weak_stat['average_time'] * $weak_stat['amount'] + $exec_time) / ++$weak_stat['amount'];
1488
+ }
1489
+
1490
+ $apbct->save('stats');
1491
+ }
1492
+
1493
  /**
1494
  * Checks if the request is AJAX
1495
  *
1504
 
1505
  }
1506
 
1507
+ function apbct_is_plugin_active_for_network( $plugin ){
1508
  if ( ! APBCT_WPMS )
1509
  return false;
1510
  $plugins = get_site_option( 'active_sitewide_plugins' );
inc/cleantalk-ajax.php CHANGED
@@ -246,14 +246,21 @@ function ct_mc4wp_ajax_hook( array $errors )
246
  function ct_ajax_hook($message_obj = false, $additional = false)
247
  {
248
  require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-public.php');
249
- global $apbct;
 
250
 
251
  $message_obj = (array)$message_obj;
252
 
253
- //
 
 
 
 
254
  // Skip test if Custom contact forms is disabled.
255
- //
256
- if (!$apbct->settings['general_contact_forms_test']) {
 
 
257
  return false;
258
  }
259
 
@@ -287,6 +294,8 @@ function ct_ajax_hook($message_obj = false, $additional = false)
287
  'vp_ajax_vpt_option_save', // https://themeforest.net/item/motor-vehicles-parts-equipments-accessories-wordpress-woocommerce-theme/16829946
288
  'mailster_send_test', //Mailster send test admin
289
  'acf/validate_save_post', //ACF validate post admin
 
 
290
  );
291
 
292
  //General post_info for all ajax calls
246
  function ct_ajax_hook($message_obj = false, $additional = false)
247
  {
248
  require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-public.php');
249
+
250
+ global $apbct, $current_user;
251
 
252
  $message_obj = (array)$message_obj;
253
 
254
+ // Get current_user and set it globaly
255
+ if(!($current_user instanceof WP_User)){
256
+ apbct_wp_set_current_user(apbct_wp_get_current_user());
257
+ }
258
+
259
  // Skip test if Custom contact forms is disabled.
260
+ if( !$apbct->settings['general_contact_forms_test']
261
+ || (!ct_is_user_enable())
262
+ )
263
+ {
264
  return false;
265
  }
266
 
294
  'vp_ajax_vpt_option_save', // https://themeforest.net/item/motor-vehicles-parts-equipments-accessories-wordpress-woocommerce-theme/16829946
295
  'mailster_send_test', //Mailster send test admin
296
  'acf/validate_save_post', //ACF validate post admin
297
+ 'admin:saveThemeOptions', //Ait-theme admin checking
298
+ 'save_tourmaster_option', //Tourmaster admin save
299
  );
300
 
301
  //General post_info for all ajax calls
inc/cleantalk-common.php CHANGED
@@ -118,11 +118,22 @@ function apbct_base_call($params = array(), $reg_flag = false){
118
  $ct->work_url = preg_match('/http:\/\/.+/', $config['ct_work_url']) ? $config['ct_work_url'] : null;
119
  $ct->server_ttl = $config['ct_server_ttl'];
120
  $ct->server_changed = $config['ct_server_changed'];
121
-
 
122
  $ct_result = $reg_flag
123
  ? @$ct->isAllowUser($ct_request)
124
  : @$ct->isAllowMessage($ct_request);
125
-
 
 
 
 
 
 
 
 
 
 
126
  if ($ct_result->errno === 0 && empty($ct_result->errstr))
127
  $apbct->data['connection_reports']['success']++;
128
  else
@@ -134,15 +145,15 @@ function apbct_base_call($params = array(), $reg_flag = false){
134
  'lib_report' => $ct_result->errstr,
135
  'work_url' => $ct->work_url,
136
  );
137
-
138
  if(count($apbct->data['connection_reports']['negative_report']) > 20)
139
  $apbct->data['connection_reports']['negative_report'] = array_slice($apbct->data['connection_reports']['negative_report'], -20, 20);
140
-
141
  }
142
-
143
  if ($ct->server_change) {
144
  update_option(
145
- 'cleantalk_server',
146
  array(
147
  'ct_work_url' => $ct->work_url,
148
  'ct_server_ttl' => $ct->server_ttl,
@@ -150,9 +161,9 @@ function apbct_base_call($params = array(), $reg_flag = false){
150
  )
151
  );
152
  }
153
-
154
  $ct_result = ct_change_plugin_resonse($ct_result, $ct_request->js_on);
155
-
156
  // Restart submit form counter for failed requests
157
  if ($ct_result->allow == 0){
158
  apbct_cookie(); // Setting page timer and cookies
@@ -300,8 +311,11 @@ function apbct_js_keys__get__ajax($direct_call = false){
300
  }
301
 
302
  /**
303
- * Get ct_get_checkjs_value
304
- * @return string
 
 
 
305
  */
306
  function ct_get_checkjs_value($random_key = false) {
307
 
@@ -861,6 +875,8 @@ function cleantalk_debug($key,$value)
861
  */
862
  function ct_change_plugin_resonse($ct_result = null, $checkjs = null) {
863
 
 
 
864
  if (!$ct_result) {
865
  return $ct_result;
866
  }
118
  $ct->work_url = preg_match('/http:\/\/.+/', $config['ct_work_url']) ? $config['ct_work_url'] : null;
119
  $ct->server_ttl = $config['ct_server_ttl'];
120
  $ct->server_changed = $config['ct_server_changed'];
121
+
122
+ $start = microtime(true);
123
  $ct_result = $reg_flag
124
  ? @$ct->isAllowUser($ct_request)
125
  : @$ct->isAllowMessage($ct_request);
126
+ $exec_time = microtime(true) - $start;
127
+
128
+ // Statistics
129
+ // Average request time
130
+ apbct_statistics__rotate($exec_time);
131
+ // Last request
132
+ $apbct->stats['last_request']['time'] = time();
133
+ $apbct->stats['last_request']['server'] = $ct->work_url;
134
+ $apbct->save('stats');
135
+
136
+ // Connection reports
137
  if ($ct_result->errno === 0 && empty($ct_result->errstr))
138
  $apbct->data['connection_reports']['success']++;
139
  else
145
  'lib_report' => $ct_result->errstr,
146
  'work_url' => $ct->work_url,
147
  );
148
+
149
  if(count($apbct->data['connection_reports']['negative_report']) > 20)
150
  $apbct->data['connection_reports']['negative_report'] = array_slice($apbct->data['connection_reports']['negative_report'], -20, 20);
151
+
152
  }
153
+
154
  if ($ct->server_change) {
155
  update_option(
156
+ 'cleantalk_server',
157
  array(
158
  'ct_work_url' => $ct->work_url,
159
  'ct_server_ttl' => $ct->server_ttl,
161
  )
162
  );
163
  }
164
+
165
  $ct_result = ct_change_plugin_resonse($ct_result, $ct_request->js_on);
166
+
167
  // Restart submit form counter for failed requests
168
  if ($ct_result->allow == 0){
169
  apbct_cookie(); // Setting page timer and cookies
311
  }
312
 
313
  /**
314
+ * Get ct_get_checkjs_value
315
+ *
316
+ * @param bool $random_key
317
+ *
318
+ * @return int|string|null
319
  */
320
  function ct_get_checkjs_value($random_key = false) {
321
 
875
  */
876
  function ct_change_plugin_resonse($ct_result = null, $checkjs = null) {
877
 
878
+ global $apbct;
879
+
880
  if (!$ct_result) {
881
  return $ct_result;
882
  }
inc/cleantalk-public.php CHANGED
@@ -546,6 +546,63 @@ function apbct_integration__buddyPres__private_msg_check( $bp_message_obj){
546
  wp_die("<h1>".__('Spam protection by CleanTalk', 'cleantalk')."</h1><h2>".$ct_result->comment."</h2>", '', array('response' => 403, "back_link" => true, "text_direction" => 'ltr'));
547
  }
548
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  /**
550
  * Public function - Tests for Pirate contact froms
551
  * return NULL
@@ -1246,6 +1303,11 @@ function ct_die_extended($comment_body) {
1246
  /**
1247
  * Validates JavaScript anti-spam test
1248
  *
 
 
 
 
 
1249
  */
1250
  function apbct_js_test($field_name = 'ct_checkjs', $data = null, $random_key = false) {
1251
 
@@ -1261,7 +1323,6 @@ function apbct_js_test($field_name = 'ct_checkjs', $data = null, $random_key = f
1261
 
1262
  // Random key check
1263
  if ($random_key) {
1264
- $k = $apbct->js_keys;
1265
  $out = array_key_exists($js_key, $apbct->js_keys) ? 1 : 0;
1266
  } else {
1267
  $ct_challenge = ct_get_checkjs_value();
@@ -1557,7 +1618,7 @@ function ct_test_registration($nickname, $email, $ip){
1557
  */
1558
  function ct_registration_errors($errors, $sanitized_user_login = null, $user_email = null) {
1559
 
1560
- global $ct_checkjs_register_form, $apbct_cookie_request_id_label, $apbct_cookie_register_ok_label, $bp, $ct_signup_done, $ct_negative_comment, $apbct, $ct_registration_error_comment;
1561
 
1562
  // Go out if a registrered user action
1563
  if (ct_is_user_enable() === false) {
@@ -1639,6 +1700,8 @@ function ct_registration_errors($errors, $sanitized_user_login = null, $user_ema
1639
 
1640
  $ct_result = ct_change_plugin_resonse($ct_result, $checkjs);
1641
 
 
 
1642
  if ($ct_result->inactive != 0) {
1643
  ct_send_error_notice($ct_result->comment);
1644
  return $errors;
@@ -1886,13 +1949,17 @@ function apbct_form__contactForm7__addField($html) {
1886
  * @param type $tags
1887
  * @return type
1888
  */
1889
- function apbct_form__contactForm7__tesSpam__before_validate($result, $tags) {
1890
  global $apbct;
1891
- $invalid_fields = $result->get_invalid_fields();
1892
- if(!empty($invalid_fields) && is_array($invalid_fields)){
1893
- $apbct->validation_error = $invalid_fields[key($invalid_fields)]['reason'];
1894
- apbct_form__contactForm7__testSpam(false);
 
 
 
1895
  }
 
1896
  return $result;
1897
  }
1898
 
546
  wp_die("<h1>".__('Spam protection by CleanTalk', 'cleantalk')."</h1><h2>".$ct_result->comment."</h2>", '', array('response' => 403, "back_link" => true, "text_direction" => 'ltr'));
547
  }
548
 
549
+ /**
550
+ * Adds hiden filed to deafualt serach form
551
+ *
552
+ * @param $form string
553
+ * @return string
554
+ */
555
+ function apbct_forms__search__addField( $form ){
556
+ global $apbct;
557
+ if($apbct->settings['search_test'] == 1){
558
+ $js_filed = ct_add_hidden_fields(true, 'ct_checkjs_search_default', true, false, false, false);
559
+ $form = str_replace('</form>', $js_filed, $form);
560
+ }
561
+ return $form;
562
+ }
563
+
564
+ /**
565
+ * Test default search string for spam
566
+ *
567
+ * @param $search string
568
+ * @return string
569
+ */
570
+ function apbct_forms__search__testSpam( $search ){
571
+
572
+ global $apbct, $cleantalk_executed;
573
+
574
+ if(
575
+ empty($search) ||
576
+ $cleantalk_executed ||
577
+ $apbct->settings['search_test'] == 0 ||
578
+ $apbct->settings['protect_logged_in'] != 1 && is_user_logged_in() // Skip processing for logged in users.
579
+ ){
580
+ return $search;
581
+ }
582
+
583
+ if(apbct_is_user_logged_in())
584
+ $user = wp_get_current_user();
585
+
586
+ $base_call_result = apbct_base_call(
587
+ array(
588
+ 'message' => $search,
589
+ 'sender_email' => !empty($user) ? $user->user_email : null,
590
+ 'sender_nickname' => !empty($user) ? $user->user_login : null,
591
+ 'post_info' => array('comment_type' => 'site_search_wordpress'),
592
+ //'js_on' => apbct_js_test('ct_checkjs_search_default', $_GET, true),
593
+ )
594
+ );
595
+ $ct_result = $base_call_result['ct_result'];
596
+
597
+ $cleantalk_executed = true;
598
+
599
+ if ($ct_result->allow == 0){
600
+ die($ct_result->comment);
601
+ }
602
+
603
+ return $search;
604
+ }
605
+
606
  /**
607
  * Public function - Tests for Pirate contact froms
608
  * return NULL
1303
  /**
1304
  * Validates JavaScript anti-spam test
1305
  *
1306
+ * @param string $field_name
1307
+ * @param null $data
1308
+ * @param bool $random_key
1309
+ *
1310
+ * @return int|null
1311
  */
1312
  function apbct_js_test($field_name = 'ct_checkjs', $data = null, $random_key = false) {
1313
 
1323
 
1324
  // Random key check
1325
  if ($random_key) {
 
1326
  $out = array_key_exists($js_key, $apbct->js_keys) ? 1 : 0;
1327
  } else {
1328
  $ct_challenge = ct_get_checkjs_value();
1618
  */
1619
  function ct_registration_errors($errors, $sanitized_user_login = null, $user_email = null) {
1620
 
1621
+ global $ct_checkjs_register_form, $apbct_cookie_request_id_label, $apbct_cookie_register_ok_label, $bp, $ct_signup_done, $ct_negative_comment, $apbct, $ct_registration_error_comment, $cleantalk_executed;
1622
 
1623
  // Go out if a registrered user action
1624
  if (ct_is_user_enable() === false) {
1700
 
1701
  $ct_result = ct_change_plugin_resonse($ct_result, $checkjs);
1702
 
1703
+ $cleantalk_executed = true;
1704
+
1705
  if ($ct_result->inactive != 0) {
1706
  ct_send_error_notice($ct_result->comment);
1707
  return $errors;
1949
  * @param type $tags
1950
  * @return type
1951
  */
1952
+ function apbct_form__contactForm7__tesSpam__before_validate($result = null, $tags = null) {
1953
  global $apbct;
1954
+
1955
+ if ($result && method_exists($result, 'get_invalid_fields')){
1956
+ $invalid_fields = $result->get_invalid_fields();
1957
+ if(!empty($invalid_fields) && is_array($invalid_fields)){
1958
+ $apbct->validation_error = $invalid_fields[key($invalid_fields)]['reason'];
1959
+ apbct_form__contactForm7__testSpam(false);
1960
+ }
1961
  }
1962
+
1963
  return $result;
1964
  }
1965
 
inc/cleantalk-settings.php CHANGED
@@ -62,7 +62,7 @@ function apbct_settings__add_page() {
62
  'callback' => 'apbct_settings__field__api_key',
63
  ),
64
  'connection_reports' => array(
65
- 'callback' => 'apbct_settings__field__connection_reports',
66
  ),
67
  ),
68
  ),
@@ -143,6 +143,10 @@ function apbct_settings__add_page() {
143
  'title' => __('WooCommerce checkout form', 'cleantalk'),
144
  'description' => __('Anti spam test for WooCommerce checkout form.', 'cleantalk'),
145
  ),
 
 
 
 
146
  'check_external' => array(
147
  'title' => __('Protect external forms', 'cleantalk'),
148
  'description' => __('Turn this option on to protect forms on your WordPress that send data to third-part servers (like MailChimp).', 'cleantalk'),
@@ -168,7 +172,7 @@ function apbct_settings__add_page() {
168
  ),
169
  'check_comments_number' => array(
170
  'title' => __("Don't check trusted user's comments", 'cleantalk'),
171
- 'description' => sprintf(__("Dont't check comments for users with above % comments.", 'cleantalk'), defined('CLEANTALK_CHECK_COMMENTS_NUMBER') ? CLEANTALK_CHECK_COMMENTS_NUMBER : 3),
172
  ),
173
  'remove_old_spam' => array(
174
  'title' => __('Automatically delete spam comments', 'cleantalk'),
@@ -463,6 +467,7 @@ function apbct_settings_page() {
463
  if(!$apbct->white_label){
464
  // Translate banner for non EN locale
465
  if(substr(get_locale(), 0, 2) != 'en'){
 
466
  require_once(CLEANTALK_PLUGIN_DIR.'templates/translate_banner.php');
467
  printf($ct_translate_banner_template, substr(get_locale(), 0, 2));
468
  }
@@ -526,7 +531,7 @@ function apbct_settings__error__output($return = false){
526
  $out .= '<h4>'.$value.'</h4>';
527
  }
528
  $out .= !$apbct->white_label
529
- ? '<h4 style="text-align: none;">'.sprintf(__('You can get support any time here: %s.', 'cleantalk'), '<a target="blank" href="https://wordpress.org/support/plugin/cleantalk-spam-protect">https://wordpress.org/support/plugin/cleantalk-spam-protect</a>').'</h4>'
530
  : '';
531
  $out .= '</div>';
532
  }
@@ -613,14 +618,7 @@ function apbct_settings__field__state(){
613
  .__('Custom contact forms', 'cleantalk');
614
  echo '<img class="apbct_status_icon" src="'.($apbct->data['moderate'] == 1 || $apbct->moderate_ip ? $img : $img_no).'"/>'
615
  .'<a style="color: black" href="https://blog.cleantalk.org/real-time-email-address-existence-validation/">'.__('Validate email for existence', 'cleantalk').'</a>';
616
-
617
- // SFW + current network count
618
- /*
619
- $sfw_netwoks_amount = $wpdb->get_results("SELECT count(*) AS cnt FROM `".$wpdb->base_prefix."cleantalk_sfw`", ARRAY_A);
620
- $alt_for_sfw = sprintf(__('Networks in database: %d.', 'cleantalk'), $sfw_netwoks_amount[0]['cnt']);
621
- echo '<img class="apbct_status_icon" src="'.($apbct->settings['spam_firewall']==1 || $apbct->moderate_ip ? $img : $img_no).'" title="'.($apbct->settings['spam_firewall']==1 || $apbct->moderate_ip ? $alt_for_sfw : '').'"/>'.__('SpamFireWall', 'cleantalk');
622
- */
623
-
624
  // Autoupdate status
625
  if($apbct->notice_auto_update){
626
  echo '<img class="apbct_status_icon" src="'.($apbct->auto_update == 1 ? $img : ($apbct->auto_update == -1 ? $img_no : $img_no_gray)).'"/>'.__('Auto update', 'cleantalk')
@@ -751,7 +749,7 @@ function apbct_settings__field__action_buttons(){
751
  .'<a href="users.php?page=ct_check_users" class="ct_support_link">' . __('Check users for spam', 'cleantalk') . '</a>'
752
  .'&nbsp;&nbsp;'
753
  .'&nbsp;&nbsp;'
754
- .'<a href="#" class="ct_support_link" onclick="apbct_show_hide_elem(\'#apbct_connection_reports\')">' . __('Negative report', 'cleantalk') . '</a>'
755
  .'</div>';
756
 
757
  }
@@ -759,12 +757,55 @@ function apbct_settings__field__action_buttons(){
759
  echo '</div>';
760
  }
761
 
762
- function apbct_settings__field__connection_reports() {
763
 
764
- global $apbct;
765
-
766
- echo '<div id="apbct_connection_reports" class="apbct_settings-field_wrapper" style="display: none;">';
767
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
768
  if ($apbct->connection_reports){
769
 
770
  if ($apbct->connection_reports['negative'] == 0){
@@ -929,6 +970,7 @@ function apbct_settings__validate($settings) {
929
 
930
  // validating API key
931
  $settings['apikey'] = isset($settings['apikey']) ? trim($settings['apikey']) : '';
 
932
  $settings['apikey'] = $apbct->white_label ? $apbct->settings['apikey'] : $settings['apikey'];
933
 
934
  // Drop debug data
62
  'callback' => 'apbct_settings__field__api_key',
63
  ),
64
  'connection_reports' => array(
65
+ 'callback' => 'apbct_settings__field__statistics',
66
  ),
67
  ),
68
  ),
143
  'title' => __('WooCommerce checkout form', 'cleantalk'),
144
  'description' => __('Anti spam test for WooCommerce checkout form.', 'cleantalk'),
145
  ),
146
+ 'search_test' => array(
147
+ 'title' => __('Test default Wordpress search form fro spam', 'cleantalk'),
148
+ 'description' => __('Some description.', 'cleantalk'),
149
+ ),
150
  'check_external' => array(
151
  'title' => __('Protect external forms', 'cleantalk'),
152
  'description' => __('Turn this option on to protect forms on your WordPress that send data to third-part servers (like MailChimp).', 'cleantalk'),
172
  ),
173
  'check_comments_number' => array(
174
  'title' => __("Don't check trusted user's comments", 'cleantalk'),
175
+ 'description' => sprintf(__("Don't check comments for users with above % comments.", 'cleantalk'), defined('CLEANTALK_CHECK_COMMENTS_NUMBER') ? CLEANTALK_CHECK_COMMENTS_NUMBER : 3),
176
  ),
177
  'remove_old_spam' => array(
178
  'title' => __('Automatically delete spam comments', 'cleantalk'),
467
  if(!$apbct->white_label){
468
  // Translate banner for non EN locale
469
  if(substr(get_locale(), 0, 2) != 'en'){
470
+ global $ct_translate_banner_template;
471
  require_once(CLEANTALK_PLUGIN_DIR.'templates/translate_banner.php');
472
  printf($ct_translate_banner_template, substr(get_locale(), 0, 2));
473
  }
531
  $out .= '<h4>'.$value.'</h4>';
532
  }
533
  $out .= !$apbct->white_label
534
+ ? '<h4 style="text-align: unset;">'.sprintf(__('You can get support any time here: %s.', 'cleantalk'), '<a target="blank" href="https://wordpress.org/support/plugin/cleantalk-spam-protect">https://wordpress.org/support/plugin/cleantalk-spam-protect</a>').'</h4>'
535
  : '';
536
  $out .= '</div>';
537
  }
618
  .__('Custom contact forms', 'cleantalk');
619
  echo '<img class="apbct_status_icon" src="'.($apbct->data['moderate'] == 1 || $apbct->moderate_ip ? $img : $img_no).'"/>'
620
  .'<a style="color: black" href="https://blog.cleantalk.org/real-time-email-address-existence-validation/">'.__('Validate email for existence', 'cleantalk').'</a>';
621
+
 
 
 
 
 
 
 
622
  // Autoupdate status
623
  if($apbct->notice_auto_update){
624
  echo '<img class="apbct_status_icon" src="'.($apbct->auto_update == 1 ? $img : ($apbct->auto_update == -1 ? $img_no : $img_no_gray)).'"/>'.__('Auto update', 'cleantalk')
749
  .'<a href="users.php?page=ct_check_users" class="ct_support_link">' . __('Check users for spam', 'cleantalk') . '</a>'
750
  .'&nbsp;&nbsp;'
751
  .'&nbsp;&nbsp;'
752
+ .'<a href="#" class="ct_support_link" onclick="apbct_show_hide_elem(\'#apbct_statistics\')">' . __('Statistics & Reports', 'cleantalk') . '</a>'
753
  .'</div>';
754
 
755
  }
757
  echo '</div>';
758
  }
759
 
760
+ function apbct_settings__field__statistics() {
761
 
762
+ global $apbct, $wpdb;
 
 
763
 
764
+ echo '<div id="apbct_statistics" class="apbct_settings-field_wrapper" style="display: none;">';
765
+
766
+ // Last request
767
+ printf(
768
+ __('Last spam check request to %s server was at %s.', 'cleantalk'),
769
+ $apbct->stats['last_request']['server'] ? $apbct->stats['last_request']['server'] : __('unknown', 'cleantalk'),
770
+ $apbct->stats['last_request']['time'] ? date('Y-m-d H:i:s', $apbct->stats['last_request']['time']) : __('unknown', 'cleantalk')
771
+ );
772
+ echo '<br>';
773
+
774
+ // Avarage time request
775
+ printf(
776
+ __('Average request time for past 7 days: %s seconds.', 'cleantalk'),
777
+ $apbct->stats['requests'][min(array_keys($apbct->stats['requests']))]['average_time']
778
+ ? round($apbct->stats['requests'][min(array_keys($apbct->stats['requests']))]['average_time'], 3)
779
+ : __('unknown', 'cleantalk')
780
+ );
781
+ echo '<br>';
782
+
783
+ // SFW last die
784
+ printf(
785
+ __('Last SpamFireWall blocking page was showed to %s IP at %s.', 'cleantalk'),
786
+ $apbct->stats['last_sfw_block']['ip'] ? $apbct->stats['last_sfw_block']['ip'] : __('unknown', 'cleantalk'),
787
+ $apbct->stats['last_sfw_block']['time'] ? date('Y-m-d H:i:s', $apbct->stats['last_sfw_block']['time']) : __('unknown', 'cleantalk')
788
+ );
789
+ echo '<br>';
790
+
791
+ // SFW last update
792
+ $sfw_netwoks_amount = $wpdb->get_results("SELECT count(*) AS cnt FROM `".$wpdb->base_prefix."cleantalk_sfw`", ARRAY_A);
793
+ printf(
794
+ __('SpamFireWall was updated %s. Now contains %s entries.', 'cleantalk'),
795
+ $apbct->stats['sfw']['last_update_time'] ? date('Y-m-d H:i:s', $apbct->stats['sfw']['last_update_time']) : __('unknown', 'cleantalk'),
796
+ isset($sfw_netwoks_amount[0]['cnt']) ? $sfw_netwoks_amount[0]['cnt'] : __('unknown', 'cleantalk')
797
+ );
798
+ echo '<br>';
799
+
800
+ // SFW last sent logs
801
+ printf(
802
+ __('SpamFireWall sent %s events at %s.', 'cleantalk'),
803
+ $apbct->stats['sfw']['last_send_amount'] ? $apbct->stats['sfw']['last_send_amount'] : __('unknown', 'cleantalk'),
804
+ $apbct->stats['sfw']['last_send_time'] ? date('Y-m-d H:i:s', $apbct->stats['sfw']['last_send_time']) : __('unknown', 'cleantalk')
805
+ );
806
+ echo '<br>';
807
+
808
+ // Connection reports
809
  if ($apbct->connection_reports){
810
 
811
  if ($apbct->connection_reports['negative'] == 0){
970
 
971
  // validating API key
972
  $settings['apikey'] = isset($settings['apikey']) ? trim($settings['apikey']) : '';
973
+ $settings['apikey'] = defined('CLEANTALK_ACCESS_KEY') ? CLEANTALK_ACCESS_KEY : $settings['apikey'];
974
  $settings['apikey'] = $apbct->white_label ? $apbct->settings['apikey'] : $settings['apikey'];
975
 
976
  // Drop debug data
inc/cleantalk-updater.php CHANGED
@@ -221,4 +221,61 @@ function apbct_update_to_5_118_2(){
221
  $apbct->data['connection_reports'] = $apbct->def_data['connection_reports'];
222
  $apbct->data['connection_reports']['since'] = date('d M');
223
  $apbct->saveData();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  }
221
  $apbct->data['connection_reports'] = $apbct->def_data['connection_reports'];
222
  $apbct->data['connection_reports']['since'] = date('d M');
223
  $apbct->saveData();
224
+ }
225
+
226
+ function apbct_update_to_5_119(){
227
+
228
+ global $wpdb;
229
+
230
+ $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_sessions`;'); // Deleting session table
231
+
232
+ // SFW data
233
+ $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_sfw` (
234
+ `network` int(11) unsigned NOT NULL,
235
+ `mask` int(11) unsigned NOT NULL,
236
+ INDEX ( `network` , `mask` )
237
+ ) ENGINE = MYISAM ;';
238
+
239
+ // SFW log
240
+ $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_sfw_logs` (
241
+ `ip` VARCHAR(15) NOT NULL,
242
+ `all_entries` INT NOT NULL,
243
+ `blocked_entries` INT NOT NULL,
244
+ `entries_timestamp` INT NOT NULL,
245
+ PRIMARY KEY (`ip`))
246
+ ENGINE = MYISAM;';
247
+
248
+ // Sessions
249
+ $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_sessions` (
250
+ `id` VARCHAR(64) NOT NULL,
251
+ `name` VARCHAR(64) NOT NULL,
252
+ `value` TEXT NULL DEFAULT NULL,
253
+ `last_update` DATETIME NULL DEFAULT NULL,
254
+ PRIMARY KEY (`id`(64), `name`(64)))
255
+ ENGINE = MYISAM;';
256
+
257
+ apbct_activation__create_tables($sqls);
258
+
259
+ // WPMS
260
+ if(is_multisite()){
261
+ global $wpdb;
262
+ $initial_blog = get_current_blog_id();
263
+ $blogs = array_keys($wpdb->get_results('SELECT blog_id FROM '. $wpdb->blogs, OBJECT_K));
264
+ foreach ($blogs as $blog) {
265
+ switch_to_blog($blog);
266
+ $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_sessions`;'); // Deleting session table
267
+ apbct_activation__create_tables($sqls);
268
+ }
269
+ switch_to_blog($initial_blog);
270
+ }
271
+
272
+ // Drop work url
273
+ update_option(
274
+ 'cleantalk_server',
275
+ array(
276
+ 'ct_work_url' => null,
277
+ 'ct_server_ttl' => 0,
278
+ 'ct_server_changed' => 0,
279
+ )
280
+ );
281
  }
inc/sfw_die_page.html CHANGED
@@ -41,6 +41,9 @@
41
  <div class='container'>
42
  <h1 class='main'>{SFW_DIE_NOTICE_IP}<a href='https://cleantalk.org/blacklists/{REMOTE_ADDRESS}' target='_blank'>{REMOTE_ADDRESS}</a></h1>
43
 
 
 
 
44
  <h2>{TEST_TITLE}</h2>
45
 
46
  <div id='js_info'><br />{SFW_DIE_MAKE_SURE_JS_ENABLED}</div>
41
  <div class='container'>
42
  <h1 class='main'>{SFW_DIE_NOTICE_IP}<a href='https://cleantalk.org/blacklists/{REMOTE_ADDRESS}' target='_blank'>{REMOTE_ADDRESS}</a></h1>
43
 
44
+ <h3>Real IP: {REAL_IP} {REAL_IP_BLOCKED}</h3>
45
+ <h3>Test IP: {TEST_IP} {TEST_IP_BLOCKED}</h3>
46
+
47
  <h2>{TEST_TITLE}</h2>
48
 
49
  <div id='js_info'><br />{SFW_DIE_MAKE_SURE_JS_ENABLED}</div>
lib/Cleantalk.php CHANGED
@@ -251,8 +251,12 @@ class Cleantalk {
251
 
252
  // Loop until find work server
253
  foreach ($servers as $server) {
254
-
255
- $this->work_url = $url_protocol . $server['ip'] . $url_suffix;
 
 
 
 
256
  $this->server_ttl = $server['ttl'];
257
 
258
  $result = $this->sendRequest($msg, $this->work_url, $this->server_timeout);
@@ -410,6 +414,11 @@ class Cleantalk {
410
  $result = false;
411
  $curl_error = null;
412
 
 
 
 
 
 
413
  if($this->use_bultin_api){
414
 
415
  $args = array(
@@ -429,12 +438,6 @@ class Cleantalk {
429
 
430
  }else{
431
 
432
-
433
- // Switching to secure connection
434
- if ($this->ssl_on && !preg_match("/^https:/", $url)){
435
- $url = preg_replace("/^(http)/i", "$1s", $url);
436
- }
437
-
438
  if(function_exists('curl_init')) {
439
 
440
  $ch = curl_init();
251
 
252
  // Loop until find work server
253
  foreach ($servers as $server) {
254
+
255
+ $dns = CleantalkHelper::ip__resolve__cleantalks($server['ip']);
256
+ if(!$dns)
257
+ continue;
258
+
259
+ $this->work_url = $url_protocol.$dns.$url_suffix;
260
  $this->server_ttl = $server['ttl'];
261
 
262
  $result = $this->sendRequest($msg, $this->work_url, $this->server_timeout);
414
  $result = false;
415
  $curl_error = null;
416
 
417
+ // Switching to secure connection
418
+ if ($this->ssl_on && !preg_match("/^https:/", $url)){
419
+ $url = preg_replace("/^(http)/i", "$1s", $url);
420
+ }
421
+
422
  if($this->use_bultin_api){
423
 
424
  $args = array(
438
 
439
  }else{
440
 
 
 
 
 
 
 
441
  if(function_exists('curl_init')) {
442
 
443
  $ch = curl_init();
lib/CleantalkHelper.php CHANGED
@@ -29,6 +29,20 @@ class CleantalkHelper
29
  ),
30
  );
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  /*
33
  * Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
34
  * reutrns array('remote_addr' => 'val', ['x_forwarded_for' => 'val', ['x_real_ip' => 'val', ['cloud_flare' => 'val']]])
@@ -72,7 +86,7 @@ class CleantalkHelper
72
 
73
  // Cloud Flare
74
  if(isset($ips['cloud_flare'])){
75
- if(isset($headers['CF-Connecting-IP'], $headers['CF-IPСountry'], $headers['CF-RAY']) || isset($headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'])){
76
  $tmp = isset($headers['CF-Connecting-IP']) ? $headers['CF-Connecting-IP'] : $headers['Cf-Connecting-Ip'];
77
  $tmp = strpos($tmp, ',') !== false ? explode(',', $tmp) : (array)$tmp;
78
  $ip_type = self::ip__validate(trim($tmp[0]));
@@ -118,7 +132,7 @@ class CleantalkHelper
118
  }
119
 
120
  // Is private network
121
- if($ip_type === false || ($ip_type && (self::ip__is_private_network($ips['real'], $ip_type)) || (self::ip__mask_match($ips['real'], filter_input(INPUT_SERVER, 'SERVER_ADDR').'/24', $ip_type)))){
122
 
123
  // X-Forwarded-For
124
  if(isset($headers['X-Forwarded-For'])){
@@ -157,7 +171,7 @@ class CleantalkHelper
157
  }
158
 
159
  static function ip__is_private_network($ip, $ip_type = 'v4'){
160
- return self::ip__mask_match($ip, self::$private_networks[$ip_type]);
161
  }
162
 
163
  /*
@@ -170,7 +184,7 @@ class CleantalkHelper
170
  * @param cird mixed (string|array of strings)
171
  */
172
  static public function ip__mask_match($ip, $cidr, $ip_type = 'v4', $xtet_count = 0)
173
- {
174
  if(is_array($cidr)){
175
  foreach($cidr as $curr_mask){
176
  if(self::ip__mask_match($ip, $curr_mask, $ip_type)){
@@ -220,6 +234,16 @@ class CleantalkHelper
220
 
221
  }
222
 
 
 
 
 
 
 
 
 
 
 
223
  /*
224
  * Validating IPv4, IPv6
225
  * param (string) $ip
@@ -273,6 +297,47 @@ class CleantalkHelper
273
  return $ip;
274
  }
275
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  /**
277
  * Function sends raw http request
278
  *
@@ -302,7 +367,7 @@ class CleantalkHelper
302
  CURLOPT_RETURNTRANSFER => true,
303
  CURLOPT_CONNECTTIMEOUT_MS => 3000,
304
  CURLOPT_FORBID_REUSE => true,
305
- CURLOPT_USERAGENT => 'APBCT('.(defined('CLEANTALK_AGENT') ? CLEANTALK_AGENT : 'UNKNOWN_AGENT').')',
306
  CURLOPT_POST => true,
307
  CURLOPT_POSTFIELDS => str_replace("&amp;", "&", http_build_query($data)),
308
  CURLOPT_SSL_VERIFYPEER => false,
@@ -470,7 +535,7 @@ class CleantalkHelper
470
  $encoding = mb_detect_encoding($obj);
471
  $encoding = $encoding ? $encoding : $data_codepage;
472
  if ($encoding)
473
- $obj = mb_convert_encoding($str, 'UTF-8', $encoding);
474
  }
475
  }
476
  return $obj;
@@ -508,4 +573,17 @@ class CleantalkHelper
508
  {
509
  return is_string($string) && is_array(json_decode($string, true)) ? true : false;
510
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
511
  }
29
  ),
30
  );
31
 
32
+ public static $cleantalks_servers = array(
33
+ // MODERATE
34
+ 'moderate1.cleantalk.org' => '162.243.144.175',
35
+ 'moderate2.cleantalk.org' => '159.203.121.181',
36
+ 'moderate3.cleantalk.org' => '88.198.153.60',
37
+ 'moderate4.cleantalk.org' => '159.69.51.30',
38
+ 'moderate5.cleantalk.org' => '95.216.200.119',
39
+ 'moderate6.cleantalk.org' => '138.68.234.8',
40
+ // APIX
41
+ 'apix1.cleantalk.org' => '35.158.52.161',
42
+ 'apix2.cleantalk.org' => '18.206.49.217',
43
+ 'apix3.cleantalk.org' => '3.18.23.246',
44
+ );
45
+
46
  /*
47
  * Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
48
  * reutrns array('remote_addr' => 'val', ['x_forwarded_for' => 'val', ['x_real_ip' => 'val', ['cloud_flare' => 'val']]])
86
 
87
  // Cloud Flare
88
  if(isset($ips['cloud_flare'])){
89
+ if(isset($headers['CF-Connecting-IP'], $headers['CF-IPCountry'], $headers['CF-RAY']) || isset($headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'])){
90
  $tmp = isset($headers['CF-Connecting-IP']) ? $headers['CF-Connecting-IP'] : $headers['Cf-Connecting-Ip'];
91
  $tmp = strpos($tmp, ',') !== false ? explode(',', $tmp) : (array)$tmp;
92
  $ip_type = self::ip__validate(trim($tmp[0]));
132
  }
133
 
134
  // Is private network
135
+ if($ip_type === false || ($ip_type && (self::ip__is_private_network($ips['real'], $ip_type) || self::ip__mask_match($ips['real'], filter_input(INPUT_SERVER, 'SERVER_ADDR').'/24', $ip_type)))){
136
 
137
  // X-Forwarded-For
138
  if(isset($headers['X-Forwarded-For'])){
171
  }
172
 
173
  static function ip__is_private_network($ip, $ip_type = 'v4'){
174
+ return self::ip__mask_match($ip, self::$private_networks[$ip_type], $ip_type);
175
  }
176
 
177
  /*
184
  * @param cird mixed (string|array of strings)
185
  */
186
  static public function ip__mask_match($ip, $cidr, $ip_type = 'v4', $xtet_count = 0)
187
+ {
188
  if(is_array($cidr)){
189
  foreach($cidr as $curr_mask){
190
  if(self::ip__mask_match($ip, $curr_mask, $ip_type)){
234
 
235
  }
236
 
237
+ /**
238
+ * Converts long mask like 4294967295 to number like 32
239
+ *
240
+ * @param type $long_mask
241
+ */
242
+ static function ip__mask__long_to_number($long_mask){
243
+ $num_mask = strpos((string)decbin($long_mask), '0');
244
+ return $num_mask === false ? 32 : $num_mask;
245
+ }
246
+
247
  /*
248
  * Validating IPv4, IPv6
249
  * param (string) $ip
297
  return $ip;
298
  }
299
 
300
+ static public function ip__resolve__cleantalks($ip){
301
+ if(SpbcHelper::ip__validate($ip)){
302
+ $url = array_search($ip, self::$cleantalks_servers);
303
+ return $url
304
+ ? $url
305
+ : self::ip__resolve($ip);
306
+ }else
307
+ return $ip;
308
+ }
309
+
310
+ static public function ip__resolve($ip){
311
+ if(SpbcHelper::ip__validate($ip)){
312
+ $url = gethostbyaddr($ip);
313
+ if($url)
314
+ return $url;
315
+ }
316
+ return $ip;
317
+ }
318
+
319
+ static public function dns__resolve($host, $out = false){
320
+
321
+ // Get DNS records about URL
322
+ if(function_exists('dns_get_record')){
323
+ $records = dns_get_record($host, DNS_A);
324
+ if($records !== false) {
325
+ $out = $records[0]['ip'];
326
+ }
327
+ }
328
+
329
+ // Another try if first failed
330
+ if(!$out && function_exists('gethostbynamel')){
331
+ $records = gethostbynamel($host);
332
+ if($records !== false){
333
+ $out = $records[0];
334
+ }
335
+ }
336
+
337
+ return $out;
338
+
339
+ }
340
+
341
  /**
342
  * Function sends raw http request
343
  *
367
  CURLOPT_RETURNTRANSFER => true,
368
  CURLOPT_CONNECTTIMEOUT_MS => 3000,
369
  CURLOPT_FORBID_REUSE => true,
370
+ CURLOPT_USERAGENT => 'APBCT-wordpress/'.(defined('APBCT_VERSION') ? APBCT_VERSION : 'unknown').'; '.get_bloginfo('url'),
371
  CURLOPT_POST => true,
372
  CURLOPT_POSTFIELDS => str_replace("&amp;", "&", http_build_query($data)),
373
  CURLOPT_SSL_VERIFYPEER => false,
535
  $encoding = mb_detect_encoding($obj);
536
  $encoding = $encoding ? $encoding : $data_codepage;
537
  if ($encoding)
538
+ $obj = mb_convert_encoding($obj, 'UTF-8', $encoding);
539
  }
540
  }
541
  return $obj;
573
  {
574
  return is_string($string) && is_array(json_decode($string, true)) ? true : false;
575
  }
576
+
577
+ // Escapes MySQL params
578
+ public static function db__prepare_param($param, $quotes = '\''){
579
+ if(is_array($param)){
580
+ foreach($param as &$par){
581
+ $par = self::db__prepare_param($par);
582
+ }
583
+ }
584
+ global $wpdb;
585
+ if(is_numeric($param)) $param = intval($param);
586
+ if(is_string($param)) $param = $quotes.$wpdb->_real_escape($param).$quotes;
587
+ return $param;
588
+ }
589
  }
lib/CleantalkSFW.php CHANGED
@@ -21,8 +21,9 @@ class CleantalkSFW extends CleantalkSFW_Base
21
  // Use default tables if not specified
22
  $this->data_table = defined('APBCT_TBL_FIREWALL_DATA') ? APBCT_TBL_FIREWALL_DATA : $this->db->prefix . 'cleantalk_sfw';
23
  $this->log_table = defined('APBCT_TBL_FIREWALL_LOG') ? APBCT_TBL_FIREWALL_LOG : $this->db->prefix . 'cleantalk_sfw_logs';
 
 
24
 
25
- $this->debug = isset($_GET['show_debug']) && intval($_GET['show_debug']) === 1 ? true : false;
26
  }
27
 
28
  /*
@@ -30,17 +31,24 @@ class CleantalkSFW extends CleantalkSFW_Base
30
  *
31
  * Stops script executing
32
  */
33
- public function sfw_die($api_key, $cookie_prefix = '', $cookie_domain = ''){
34
 
35
  global $apbct;
36
-
 
 
 
 
 
 
 
37
  // File exists?
38
  if(file_exists(CLEANTALK_PLUGIN_DIR . "inc/sfw_die_page.html")){
39
  $sfw_die_page = file_get_contents(CLEANTALK_PLUGIN_DIR . "inc/sfw_die_page.html");
40
  }else{
41
  wp_die("IP BLACKLISTED", "Blacklisted", Array('response'=>403), true);
42
  }
43
-
44
  // Translation
45
  $request_uri = $_SERVER['REQUEST_URI'];
46
  $sfw_die_page = str_replace('{SFW_DIE_NOTICE_IP}', __('SpamFireWall is activated for your IP ', 'cleantalk'), $sfw_die_page);
@@ -48,10 +56,23 @@ class CleantalkSFW extends CleantalkSFW_Base
48
  $sfw_die_page = str_replace('{SFW_DIE_CLICK_TO_PASS}', __('Please click below to pass protection,', 'cleantalk'), $sfw_die_page);
49
  $sfw_die_page = str_replace('{SFW_DIE_YOU_WILL_BE_REDIRECTED}', sprintf(__('Or you will be automatically redirected to the requested page after %d seconds.', 'cleantalk'), 1), $sfw_die_page);
50
  $sfw_die_page = str_replace('{CLEANTALK_TITLE}', __('Antispam by CleanTalk', 'cleantalk'), $sfw_die_page);
51
- $sfw_die_page = str_replace('{TEST_TITLE}', ($this->is_test ? __('This is the testing page for SpamFireWall', 'cleantalk') : ''), $sfw_die_page);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  // Service info
54
- $sfw_die_page = str_replace('{REMOTE_ADDRESS}', $this->blocked_ip, $sfw_die_page);
55
  $sfw_die_page = str_replace('{REQUEST_URI}', $request_uri, $sfw_die_page);
56
  $sfw_die_page = str_replace('{COOKIE_PREFIX}', $cookie_prefix, $sfw_die_page);
57
  $sfw_die_page = str_replace('{COOKIE_DOMAIN}', $cookie_domain, $sfw_die_page);
@@ -60,8 +81,8 @@ class CleantalkSFW extends CleantalkSFW_Base
60
  $sfw_die_page = str_replace('{HOST}', $_SERVER['HTTP_HOST'], $sfw_die_page);
61
 
62
  if($this->debug){
63
- $debug = '<h1>Networks</h1>'
64
- . var_export($this->debug_networks, true)
65
  . '<h1>Headers</h1>'
66
  . var_export(apache_request_headers(), true)
67
  . '<h1>REMOTE_ADDR</h1>'
21
  // Use default tables if not specified
22
  $this->data_table = defined('APBCT_TBL_FIREWALL_DATA') ? APBCT_TBL_FIREWALL_DATA : $this->db->prefix . 'cleantalk_sfw';
23
  $this->log_table = defined('APBCT_TBL_FIREWALL_LOG') ? APBCT_TBL_FIREWALL_LOG : $this->db->prefix . 'cleantalk_sfw_logs';
24
+
25
+ parent::__construct();
26
 
 
27
  }
28
 
29
  /*
31
  *
32
  * Stops script executing
33
  */
34
+ public function sfw_die($api_key, $cookie_prefix = '', $cookie_domain = '', $test = false){
35
 
36
  global $apbct;
37
+
38
+ // Statistics
39
+ if(!empty($this->blocked_ips)){
40
+ $apbct->stats['last_sfw_block']['time'] = time();
41
+ $apbct->stats['last_sfw_block']['ip'] = $this->blocked_ips[key($this->blocked_ips)]['ip'];
42
+ $apbct->save('stats');
43
+ }
44
+
45
  // File exists?
46
  if(file_exists(CLEANTALK_PLUGIN_DIR . "inc/sfw_die_page.html")){
47
  $sfw_die_page = file_get_contents(CLEANTALK_PLUGIN_DIR . "inc/sfw_die_page.html");
48
  }else{
49
  wp_die("IP BLACKLISTED", "Blacklisted", Array('response'=>403), true);
50
  }
51
+
52
  // Translation
53
  $request_uri = $_SERVER['REQUEST_URI'];
54
  $sfw_die_page = str_replace('{SFW_DIE_NOTICE_IP}', __('SpamFireWall is activated for your IP ', 'cleantalk'), $sfw_die_page);
56
  $sfw_die_page = str_replace('{SFW_DIE_CLICK_TO_PASS}', __('Please click below to pass protection,', 'cleantalk'), $sfw_die_page);
57
  $sfw_die_page = str_replace('{SFW_DIE_YOU_WILL_BE_REDIRECTED}', sprintf(__('Or you will be automatically redirected to the requested page after %d seconds.', 'cleantalk'), 1), $sfw_die_page);
58
  $sfw_die_page = str_replace('{CLEANTALK_TITLE}', __('Antispam by CleanTalk', 'cleantalk'), $sfw_die_page);
59
+ $sfw_die_page = str_replace('{TEST_TITLE}', ($this->test ? __('This is the testing page for SpamFireWall', 'cleantalk') : ''), $sfw_die_page);
60
+
61
+ if($this->test){
62
+ $sfw_die_page = str_replace('{TEST_IP}', $this->all_ips['sfw_test']['ip'], $sfw_die_page);
63
+ $sfw_die_page = str_replace('{REAL_IP}', $this->all_ips['real']['ip'], $sfw_die_page);
64
+ $sfw_die_page = str_replace('{TEST_IP_BLOCKED}', $this->all_ips['sfw_test']['status'] == 1 ? 'Passed' : 'Blocked', $sfw_die_page);
65
+ $sfw_die_page = str_replace('{REAL_IP_BLOCKED}', $this->all_ips['real']['status'] == 1 ? 'Passed' : 'Blocked', $sfw_die_page);
66
+ }else{
67
+ $sfw_die_page = str_replace('{TEST_IP}', '', $sfw_die_page);
68
+ $sfw_die_page = str_replace('{REAL_IP}', '', $sfw_die_page);
69
+ $sfw_die_page = str_replace('{TEST_IP_BLOCKED}', '', $sfw_die_page);
70
+ $sfw_die_page = str_replace('{REAL_IP_BLOCKED}', '', $sfw_die_page);
71
+ }
72
+
73
+ $sfw_die_page = str_replace('{REMOTE_ADDRESS}', $this->blocked_ips ? $this->blocked_ips[key($this->blocked_ips)]['ip'] : '', $sfw_die_page);
74
 
75
  // Service info
 
76
  $sfw_die_page = str_replace('{REQUEST_URI}', $request_uri, $sfw_die_page);
77
  $sfw_die_page = str_replace('{COOKIE_PREFIX}', $cookie_prefix, $sfw_die_page);
78
  $sfw_die_page = str_replace('{COOKIE_DOMAIN}', $cookie_domain, $sfw_die_page);
81
  $sfw_die_page = str_replace('{HOST}', $_SERVER['HTTP_HOST'], $sfw_die_page);
82
 
83
  if($this->debug){
84
+ $debug = '<h1>IP and Networks</h1>'
85
+ . var_export($this->all_ips, true)
86
  . '<h1>Headers</h1>'
87
  . var_export(apache_request_headers(), true)
88
  . '<h1>REMOTE_ADDR</h1>'
lib/CleantalkSFW_Base.php CHANGED
@@ -19,15 +19,24 @@ class CleantalkSFW_Base
19
  public $ip_str = '';
20
  public $ip_array = Array();
21
  public $ip_str_array = Array();
 
22
  public $blocked_ip = '';
23
  public $passed_ip = '';
24
  public $result = false;
 
25
 
26
- public $is_test = false;
27
-
 
 
 
 
 
 
28
  protected $data_table;
29
  protected $log_table;
30
 
 
31
  public $debug;
32
  public $debug_data = '';
33
  public $debug_networks = array();
@@ -44,12 +53,7 @@ class CleantalkSFW_Base
44
  */
45
  public function __construct()
46
  {
47
- // Creating database object
48
- $this->db = new ClentalkDB();
49
-
50
- // Use default tables if not specified
51
- $this->data_table = $this->db->table_prefix . 'cleantalk_sfw';
52
- $this->log_table = $this->db->table_prefix . 'cleantalk_sfw_logs';
53
  }
54
 
55
  /*
@@ -58,14 +62,14 @@ class CleantalkSFW_Base
58
  */
59
  public function ip__get($ips_input = array('real', 'remote_addr', 'x_forwarded_for', 'x_real_ip', 'cloud_flare'), $v4_only = true){
60
 
61
- $result = (array)CleantalkHelper::ip__get($ips_input, $v4_only);
62
 
63
- $result = !empty($result) ? $result : array();
64
 
65
  if(isset($_GET['sfw_test_ip'])){
66
  if(CleantalkHelper::ip__validate($_GET['sfw_test_ip']) !== false){
67
  $result['sfw_test'] = $_GET['sfw_test_ip'];
68
- $this->is_test = true;
69
  }
70
  }
71
 
@@ -76,23 +80,39 @@ class CleantalkSFW_Base
76
  /*
77
  * Checks IP via Database
78
  */
79
- public function ip_check(){
80
-
81
- foreach($this->ip_array as $current_ip){
82
-
83
  $query = "SELECT
84
  COUNT(network) AS cnt, network, mask
85
  FROM ".$this->data_table."
86
  WHERE network = ".sprintf("%u", ip2long($current_ip))." & mask;";
 
87
  $this->db->query($query)->fetch();
 
88
  if($this->db->result['cnt']){
89
- $this->result = true;
90
- $this->blocked_ip = $current_ip;
91
- $this->debug_networks[] = long2ip($this->db->result['network']).'/'.$this->db->result['mask'];
 
 
 
 
 
 
 
 
 
92
  }else{
93
- $this->passed_ip = $current_ip;
94
- }
95
-
 
 
 
 
 
96
  }
97
  }
98
 
@@ -150,7 +170,7 @@ class CleantalkSFW_Base
150
  if(empty($result['error'])){
151
  if($result['rows'] == count($data)){
152
  $this->db->query("DELETE FROM ".$this->log_table.";", true);
153
- return true;
154
  }
155
  }else{
156
  return $result;
@@ -202,50 +222,54 @@ class CleantalkSFW_Base
202
 
203
  if(CleantalkHelper::http__request($file_url, array(), 'get_code') === 200){ // Check if it's there
204
 
205
- $gf = gzopen($file_url, 'rb');
206
-
207
- if($gf){
208
 
209
- if(!gzeof($gf)){
210
-
211
- $this->db->query("DELETE FROM ".$this->data_table.";", true);
212
 
213
- for($count_result = 0; !gzeof($gf); ){
214
-
215
- $query = "INSERT INTO ".$this->data_table." VALUES %s";
216
-
217
- for($i=0, $values = array(); APBCT_WRITE_LIMIT !== $i && !gzeof($gf); $i++, $count_result++){
218
-
219
- $entry = trim(gzgets($gf, 1024));
220
-
221
- if(empty($entry)) continue;
222
-
223
- $entry = explode(',', $entry);
224
-
225
- // Cast result to int
226
- $ip = preg_replace('/[^\d]*/', '', $entry[0]);
227
- $mask = preg_replace('/[^\d]*/', '', $entry[1]);
228
-
229
- if(!$ip || !$mask) continue;
230
-
231
- $values[] = '('. $ip .','. $mask .')';
232
-
233
- }
234
 
235
- if(!empty($values)){
236
- $query = sprintf($query, implode(',', $values).';');
237
- $this->db->query($query, true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  }
239
 
240
- }
241
-
242
- gzclose($gf);
243
- return $count_result;
244
-
245
  }else
246
- return array('error' => true, 'error_string' => 'ERROR_GZ_EMPTY');
247
  }else
248
- return array('error' => true, 'error_string' => 'ERROR_OPEN_GZ_FILE');
249
  }else
250
  return array('error' => true, 'error_string' => 'NO_REMOTE_FILE_FOUND');
251
  }
19
  public $ip_str = '';
20
  public $ip_array = Array();
21
  public $ip_str_array = Array();
22
+ public $results = array();
23
  public $blocked_ip = '';
24
  public $passed_ip = '';
25
  public $result = false;
26
+ public $pass = true;
27
 
28
+ public $test = false;
29
+
30
+ public $all_ips = array();
31
+ public $passed_ips = array();
32
+ public $blocked_ips = array();
33
+
34
+ // Database
35
+ protected $db;
36
  protected $data_table;
37
  protected $log_table;
38
 
39
+ //Debug
40
  public $debug;
41
  public $debug_data = '';
42
  public $debug_networks = array();
53
  */
54
  public function __construct()
55
  {
56
+ $this->debug = isset($_GET['debug']) && intval($_GET['debug']) === 1 ? true : false;
 
 
 
 
 
57
  }
58
 
59
  /*
62
  */
63
  public function ip__get($ips_input = array('real', 'remote_addr', 'x_forwarded_for', 'x_real_ip', 'cloud_flare'), $v4_only = true){
64
 
65
+ $result = CleantalkHelper::ip__get($ips_input, $v4_only);
66
 
67
+ $result = !empty($result) ? array('real' => $result) : array();
68
 
69
  if(isset($_GET['sfw_test_ip'])){
70
  if(CleantalkHelper::ip__validate($_GET['sfw_test_ip']) !== false){
71
  $result['sfw_test'] = $_GET['sfw_test_ip'];
72
+ $this->test = true;
73
  }
74
  }
75
 
80
  /*
81
  * Checks IP via Database
82
  */
83
+ public function ip_check()
84
+ {
85
+ foreach($this->ip_array as $origin => $current_ip){
86
+
87
  $query = "SELECT
88
  COUNT(network) AS cnt, network, mask
89
  FROM ".$this->data_table."
90
  WHERE network = ".sprintf("%u", ip2long($current_ip))." & mask;";
91
+
92
  $this->db->query($query)->fetch();
93
+
94
  if($this->db->result['cnt']){
95
+ $this->pass = false;
96
+ $this->blocked_ips[$origin] = array(
97
+ 'ip' => $current_ip,
98
+ 'network' => long2ip($this->db->result['network']),
99
+ 'mask' => CleantalkHelper::ip__mask__long_to_number($this->db->result['mask']),
100
+ );
101
+ $this->all_ips[$origin] = array(
102
+ 'ip' => $current_ip,
103
+ 'network' => long2ip($this->db->result['network']),
104
+ 'mask' => CleantalkHelper::ip__mask__long_to_number($this->db->result['mask']),
105
+ 'status' => -1,
106
+ );
107
  }else{
108
+ $this->passed_ips[$origin] = array(
109
+ 'ip' => $current_ip,
110
+ );
111
+ $this->all_ips[$origin] = array(
112
+ 'ip' => $current_ip,
113
+ 'status' => 1,
114
+ );
115
+ }
116
  }
117
  }
118
 
170
  if(empty($result['error'])){
171
  if($result['rows'] == count($data)){
172
  $this->db->query("DELETE FROM ".$this->log_table.";", true);
173
+ return $result;
174
  }
175
  }else{
176
  return $result;
222
 
223
  if(CleantalkHelper::http__request($file_url, array(), 'get_code') === 200){ // Check if it's there
224
 
225
+ if(ini_get('allow_url_fopen')){
 
 
226
 
227
+ $gf = gzopen($file_url, 'rb');
228
+
229
+ if($gf){
230
 
231
+ if(!gzeof($gf)){
232
+
233
+ $this->db->query("DELETE FROM ".$this->data_table.";", true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
 
235
+ for($count_result = 0; !gzeof($gf); ){
236
+
237
+ $query = "INSERT INTO ".$this->data_table." VALUES %s";
238
+
239
+ for($i=0, $values = array(); APBCT_WRITE_LIMIT !== $i && !gzeof($gf); $i++, $count_result++){
240
+
241
+ $entry = trim(gzgets($gf, 1024));
242
+
243
+ if(empty($entry)) continue;
244
+
245
+ $entry = explode(',', $entry);
246
+
247
+ // Cast result to int
248
+ $ip = preg_replace('/[^\d]*/', '', $entry[0]);
249
+ $mask = preg_replace('/[^\d]*/', '', $entry[1]);
250
+
251
+ if(!$ip || !$mask) continue;
252
+
253
+ $values[] = '('. $ip .','. $mask .')';
254
+
255
+ }
256
+
257
+ if(!empty($values)){
258
+ $query = sprintf($query, implode(',', $values).';');
259
+ $this->db->query($query, true);
260
+ }
261
+
262
  }
263
 
264
+ gzclose($gf);
265
+ return $count_result;
266
+
267
+ }else
268
+ return array('error' => true, 'error_string' => 'ERROR_GZ_EMPTY');
269
  }else
270
+ return array('error' => true, 'error_string' => 'ERROR_OPEN_GZ_FILE');
271
  }else
272
+ return array('error' => true, 'error_string' => 'ERROR_ALLOW_URL_FOPEN_DISABLED');
273
  }else
274
  return array('error' => true, 'error_string' => 'NO_REMOTE_FILE_FOUND');
275
  }
lib/CleantalkState.php CHANGED
@@ -30,7 +30,8 @@ class CleantalkState
30
  'comments_test' => 1,
31
  'contact_forms_test' => 1,
32
  'general_contact_forms_test' => 1, // Antispam test for unsupported and untested contact forms
33
- 'wc_checkout_test' => 0, //WooCommerce checkout default test => OFF
 
34
  'check_external' => 0,
35
  'check_internal' => 0,
36
  // 'validate_email_existence' => 1,
@@ -175,7 +176,32 @@ class CleantalkState
175
  'last_call' => 0,
176
  ),
177
  );
178
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  public function __construct($option_prefix, $options = array('settings'), $wpms = false)
180
  {
181
  $this->option_prefix = $option_prefix;
@@ -209,6 +235,11 @@ class CleantalkState
209
  if($this->option_prefix.'_'.$option_name === 'cleantalk_remote_calls'){
210
  $option = is_array($option) ? array_merge($this->def_remote_calls, $option) : $this->def_remote_calls;
211
  }
 
 
 
 
 
212
 
213
  $this->$option_name = is_array($option) ? new ArrayObject($option) : $option;
214
  }
30
  'comments_test' => 1,
31
  'contact_forms_test' => 1,
32
  'general_contact_forms_test' => 1, // Antispam test for unsupported and untested contact forms
33
+ 'wc_checkout_test' => 0, // WooCommerce checkout default test => OFF
34
+ 'search_test' => 1, // Test deafult Wordpress form
35
  'check_external' => 0,
36
  'check_internal' => 0,
37
  // 'validate_email_existence' => 1,
176
  'last_call' => 0,
177
  ),
178
  );
179
+
180
+ public $def_stats = array(
181
+ 'sfw' => array(
182
+ 'last_send_time' => 0,
183
+ 'last_send_amount' => 0,
184
+ 'last_update_time' => 0,
185
+ 'entries' => 0,
186
+ ),
187
+ 'last_sfw_block' => array(
188
+ 'time' => 0,
189
+ 'ip' => '',
190
+ ),
191
+ 'last_request' => array(
192
+ 'time' => 0,
193
+ 'server' => '',
194
+ ),
195
+ 'requests' => array(
196
+ '0' => array(
197
+ 'amount' => 1,
198
+ 'average_time' => 0,
199
+ ),
200
+ )
201
+ );
202
+
203
+
204
+
205
  public function __construct($option_prefix, $options = array('settings'), $wpms = false)
206
  {
207
  $this->option_prefix = $option_prefix;
235
  if($this->option_prefix.'_'.$option_name === 'cleantalk_remote_calls'){
236
  $option = is_array($option) ? array_merge($this->def_remote_calls, $option) : $this->def_remote_calls;
237
  }
238
+
239
+ // Default statistics
240
+ if($this->option_prefix.'_'.$option_name === 'cleantalk_stats'){
241
+ $option = is_array($option) ? array_merge($this->def_stats, $option) : $this->def_stats;
242
+ }
243
 
244
  $this->$option_name = is_array($option) ? new ArrayObject($option) : $option;
245
  }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: safronik
3
  Tags: spam, antispam, protection, comments, firewall
4
  Requires at least: 3.0
5
  Tested up to: 5.2
6
- Stable tag: 5.118.4
7
  License: GPLv2
8
 
9
  Spam protection, antispam, all-in-one, premium plugin. No spam comments & users, no spam contact form & WooCommerce anti-spam.
@@ -558,6 +558,18 @@ If your website has forms that send data to external sources, you can enable opt
558
  10. Website's options.
559
 
560
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
561
  = 5.118.4 May 13 2019 =
562
  * Fix: SFW cookie. Set correct domain for subdomains.
563
  * Fix: SFW update.
@@ -1878,6 +1890,18 @@ If your website has forms that send data to external sources, you can enable opt
1878
  * First version
1879
 
1880
  == Upgrade Notice ==
 
 
 
 
 
 
 
 
 
 
 
 
1881
  = 5.118.4 May 13 2019 =
1882
  * Fix: SFW cookie. Set correct domain for subdomains.
1883
  * Fix: SFW update.
3
  Tags: spam, antispam, protection, comments, firewall
4
  Requires at least: 3.0
5
  Tested up to: 5.2
6
+ Stable tag: 5.119
7
  License: GPLv2
8
 
9
  Spam protection, antispam, all-in-one, premium plugin. No spam comments & users, no spam contact form & WooCommerce anti-spam.
558
  10. Website's options.
559
 
560
  == Changelog ==
561
+ = 5.119 May 30 2019 =
562
+ * Fix: No more second request after registration.
563
+ * Fix: Activation hook.
564
+ * Fix: Alternative sessions. Clear table.
565
+ * Fix: Stop capchuring AJAX requests in admin area.
566
+ * Fix: Spelling.
567
+ * Fix: Registration cookies set.
568
+ * Mod: SFW exdtended die page when testing.
569
+ * Mod: User-agent modified.
570
+ * New: Test search queries for spam.
571
+ * New: Gathering and output statistics.
572
+
573
  = 5.118.4 May 13 2019 =
574
  * Fix: SFW cookie. Set correct domain for subdomains.
575
  * Fix: SFW update.
1890
  * First version
1891
 
1892
  == Upgrade Notice ==
1893
+ = 5.119 May 30 2019 =
1894
+ * Fix: No more second request after registration.
1895
+ * Fix: Activation hook.
1896
+ * Fix: Alternative sessions. Clear table.
1897
+ * Fix: Stop capchuring AJAX requests in admin area.
1898
+ * Fix: Spelling.
1899
+ * Fix: Registration cookies set.
1900
+ * Mod: SFW exdtended die page when testing.
1901
+ * Mod: User-agent modified.
1902
+ * New: Test search queries for spam.
1903
+ * New: Gathering and output statistics.
1904
+
1905
  = 5.118.4 May 13 2019 =
1906
  * Fix: SFW cookie. Set correct domain for subdomains.
1907
  * Fix: SFW update.