Spam protection, AntiSpam, FireWall by CleanTalk - Version 5.150

Version Description

Dec 3 2020 = * Fix: Prevent skip checking woocommerce registration during checkout. * Fix: skip gravity multipage checking. * New: AC UA checking implemented. * Fix: skip buffer replace for rss feeds. * Fix: Easy Registration Forms login form skip. * Fix: Quotas in hidden fields. * Fix: skip tinkoff payment form fields collection. * New: Helper prepare_param added. * Fix: erforms internal request skip. * Integration: Landing Page Builder integration implemented. * Upd: Easy Registration Form block message implemented. * Integration: Profile Builder. * Fix: Skip connector mysql request. * New: AC UA - new option implemented.

Download this release

Release Info

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

Code changes from version 5.149 to 5.150

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.149
7
  Author: СleanTalk <welcome@cleantalk.org>
8
  Author URI: https://cleantalk.org
9
  Text Domain: cleantalk-spam-protect
@@ -108,7 +108,8 @@ if( !defined( 'CLEANTALK_PLUGIN_DIR' ) ){
108
  // Database constants
109
  define('APBCT_TBL_FIREWALL_DATA', $apbct->db_prefix . 'cleantalk_sfw'); // Table with firewall data.
110
  define('APBCT_TBL_FIREWALL_LOG', $apbct->db_prefix . 'cleantalk_sfw_logs'); // Table with firewall logs.
111
- define('APBCT_TBL_AC_LOG', $apbct->db_prefix . 'cleantalk_ac_log'); // Table with firewall logs.
 
112
  define('APBCT_TBL_SESSIONS', $apbct->db_prefix . 'cleantalk_sessions'); // Table with session data.
113
  define('APBCT_SPAMSCAN_LOGS', $apbct->db_prefix . 'cleantalk_spamscan_logs'); // Table with session data.
114
  define('APBCT_SELECT_LIMIT', 5000); // Select limit for logs.
@@ -181,6 +182,7 @@ if( !defined( 'CLEANTALK_PLUGIN_DIR' ) ){
181
  'ElfsightContactForm' => array( 'hook' => 'elfsight_contact_form_mail', 'ajax' => true ),
182
  'SimpleMembership' => array( 'hook' => 'swpm_front_end_registration_complete_user_data', 'ajax' => false ),
183
  'EstimationForm' => array( 'hook' => 'send_email', 'ajax' => true ),
 
184
  );
185
  new \Cleantalk\Antispam\Integrations( $apbct_active_integrations );
186
 
@@ -224,6 +226,9 @@ if( !defined( 'CLEANTALK_PLUGIN_DIR' ) ){
224
  // Enfold Theme contact form
225
  add_filter( 'avf_form_send', 'apbct_form__enfold_contact_form__test_spam', 4, 10 );
226
 
 
 
 
227
  //Hooks for updating/adding settings
228
  //add_action ('added_option', 'apbct_after_options_added', 10, 2);
229
  //add_action ('updated_option', 'apbct_after_options_updated', 10, 3);
@@ -676,15 +681,26 @@ function apbct_activation( $network = false ) {
676
  PRIMARY KEY (`id`),
677
  INDEX ( `network` , `mask` )
678
  );';
 
 
 
 
 
 
 
 
 
679
 
680
  // SFW log
681
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_sfw_logs` (
682
  `id` VARCHAR(40) NOT NULL,
683
  `ip` VARCHAR(15) NOT NULL,
684
- `status` ENUM(\'PASS_SFW\',\'DENY_SFW\',\'PASS_SFW__BY_WHITELIST\',\'PASS_SFW__BY_COOKIE\',\'DENY_ANTICRAWLER\',\'PASS_ANTICRAWLER\',\'DENY_ANTIFLOOD\',\'PASS_ANTIFLOOD\') NULL DEFAULT NULL,
685
  `all_entries` INT NOT NULL,
686
  `blocked_entries` INT NOT NULL,
687
  `entries_timestamp` INT NOT NULL,
 
 
688
  PRIMARY KEY (`id`));';
689
 
690
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ac_log` (
@@ -788,15 +804,27 @@ function apbct_activation__new_blog($blog_id, $user_id, $domain, $path, $site_id
788
  PRIMARY KEY (`id`),
789
  INDEX ( `network` , `mask` )
790
  );';
 
 
 
 
 
 
 
 
 
 
791
 
792
  // SFW log
793
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_sfw_logs` (
794
  `id` VARCHAR(40) NOT NULL,
795
  `ip` VARCHAR(15) NOT NULL,
796
- `status` ENUM(\'PASS_SFW\',\'DENY_SFW\',\'PASS_SFW__BY_WHITELIST\',\'PASS_SFW__BY_COOKIE\',\'DENY_ANTICRAWLER\',\'PASS_ANTICRAWLER\',\'DENY_ANTIFLOOD\',\'PASS_ANTIFLOOD\') NULL DEFAULT NULL,
797
  `all_entries` INT NOT NULL,
798
  `blocked_entries` INT NOT NULL,
799
  `entries_timestamp` INT NOT NULL,
 
 
800
  PRIMARY KEY (`id`));';
801
 
802
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ac_log` (
@@ -926,6 +954,7 @@ function apbct_deactivation__delete_common_tables() {
926
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_ac_log`;'); // Deleting SFW logs
927
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_sessions`;'); // Deleting session table
928
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_spamscan_logs`;'); // Deleting user/comments scan result table
 
929
  }
930
 
931
  function apbct_deactivation__delete_blog_tables() {
@@ -935,6 +964,7 @@ function apbct_deactivation__delete_blog_tables() {
935
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_ac_log`;'); // Deleting SFW logs
936
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_sessions`;'); // Deleting session table
937
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_spamscan_logs`;'); // Deleting user/comments scan result table
 
938
  }
939
 
940
  function apbct_deactivation__delete_meta(){
@@ -2007,6 +2037,7 @@ function apbct_sfw__delete_tables( $blog_id, $drop ) {
2007
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_sfw`;'); // Deleting SFW data
2008
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_sfw_logs`;'); // Deleting SFW logs
2009
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_ac_log`;'); // Deleting SFW logs
 
2010
 
2011
  switch_to_blog($initial_blog);
2012
  }
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.150
7
  Author: СleanTalk <welcome@cleantalk.org>
8
  Author URI: https://cleantalk.org
9
  Text Domain: cleantalk-spam-protect
108
  // Database constants
109
  define('APBCT_TBL_FIREWALL_DATA', $apbct->db_prefix . 'cleantalk_sfw'); // Table with firewall data.
110
  define('APBCT_TBL_FIREWALL_LOG', $apbct->db_prefix . 'cleantalk_sfw_logs'); // Table with firewall logs.
111
+ define('APBCT_TBL_AC_LOG', $apbct->db_prefix . 'cleantalk_ac_log'); // Table with firewall logs.
112
+ define('APBCT_TBL_AC_UA_BL', $apbct->db_prefix . 'cleantalk_ua_bl'); // Table with User Agents blacklist.
113
  define('APBCT_TBL_SESSIONS', $apbct->db_prefix . 'cleantalk_sessions'); // Table with session data.
114
  define('APBCT_SPAMSCAN_LOGS', $apbct->db_prefix . 'cleantalk_spamscan_logs'); // Table with session data.
115
  define('APBCT_SELECT_LIMIT', 5000); // Select limit for logs.
182
  'ElfsightContactForm' => array( 'hook' => 'elfsight_contact_form_mail', 'ajax' => true ),
183
  'SimpleMembership' => array( 'hook' => 'swpm_front_end_registration_complete_user_data', 'ajax' => false ),
184
  'EstimationForm' => array( 'hook' => 'send_email', 'ajax' => true ),
185
+ 'LandingPageBuilder' => array( 'hook' => 'ulpb_formBuilderEmail_ajax', 'ajax' => true ),
186
  );
187
  new \Cleantalk\Antispam\Integrations( $apbct_active_integrations );
188
 
226
  // Enfold Theme contact form
227
  add_filter( 'avf_form_send', 'apbct_form__enfold_contact_form__test_spam', 4, 10 );
228
 
229
+ // Profile Builder integration
230
+ add_filter( 'wppb_output_field_errors_filter', 'apbct_form_profile_builder__check_register', 1, 3 );
231
+
232
  //Hooks for updating/adding settings
233
  //add_action ('added_option', 'apbct_after_options_added', 10, 2);
234
  //add_action ('updated_option', 'apbct_after_options_updated', 10, 3);
681
  PRIMARY KEY (`id`),
682
  INDEX ( `network` , `mask` )
683
  );';
684
+
685
+ // UA BL
686
+ $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ua_bl` (
687
+ `id` INT(11) NOT NULL,
688
+ `ua_template` VARCHAR(512) NULL DEFAULT NULL,
689
+ `ua_status` TINYINT(1) NULL DEFAULT NULL,
690
+ PRIMARY KEY ( `id` ),
691
+ INDEX ( `ua_template` )
692
+ );';
693
 
694
  // SFW log
695
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_sfw_logs` (
696
  `id` VARCHAR(40) NOT NULL,
697
  `ip` VARCHAR(15) NOT NULL,
698
+ `status` ENUM(\'PASS_SFW\',\'DENY_SFW\',\'PASS_SFW__BY_WHITELIST\',\'PASS_SFW__BY_COOKIE\',\'DENY_ANTICRAWLER\',\'PASS_ANTICRAWLER\',\'DENY_ANTICRAWLER_UA\',\'PASS_ANTICRAWLER_UA\',\'DENY_ANTIFLOOD\',\'PASS_ANTIFLOOD\') NULL DEFAULT NULL,
699
  `all_entries` INT NOT NULL,
700
  `blocked_entries` INT NOT NULL,
701
  `entries_timestamp` INT NOT NULL,
702
+ `ua_id` INT(11) NULL DEFAULT NULL,
703
+ `ua_name` VARCHAR(1024) NOT NULL,
704
  PRIMARY KEY (`id`));';
705
 
706
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ac_log` (
804
  PRIMARY KEY (`id`),
805
  INDEX ( `network` , `mask` )
806
  );';
807
+
808
+ // UA BL
809
+ $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ua_bl` (
810
+ `id` INT(11) NOT NULL,
811
+ `ua_template` VARCHAR(512) NULL DEFAULT NULL,
812
+ `ua_status` TINYINT(1) NULL DEFAULT NULL,
813
+ PRIMARY KEY ( `id` ),
814
+ INDEX ( `ua_template` )
815
+ );';
816
+
817
 
818
  // SFW log
819
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_sfw_logs` (
820
  `id` VARCHAR(40) NOT NULL,
821
  `ip` VARCHAR(15) NOT NULL,
822
+ `status` ENUM(\'PASS_SFW\',\'DENY_SFW\',\'PASS_SFW__BY_WHITELIST\',\'PASS_SFW__BY_COOKIE\',\'DENY_ANTICRAWLER\',\'PASS_ANTICRAWLER\',\'DENY_ANTICRAWLER_UA\',\'PASS_ANTICRAWLER_UA\',\'DENY_ANTIFLOOD\',\'PASS_ANTIFLOOD\') NULL DEFAULT NULL,
823
  `all_entries` INT NOT NULL,
824
  `blocked_entries` INT NOT NULL,
825
  `entries_timestamp` INT NOT NULL,
826
+ `ua_id` INT(11) NULL DEFAULT NULL,
827
+ `ua_name` VARCHAR(1024) NOT NULL,
828
  PRIMARY KEY (`id`));';
829
 
830
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ac_log` (
954
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_ac_log`;'); // Deleting SFW logs
955
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_sessions`;'); // Deleting session table
956
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_spamscan_logs`;'); // Deleting user/comments scan result table
957
+ $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_ua_bl`;'); // Deleting AC UA black lists
958
  }
959
 
960
  function apbct_deactivation__delete_blog_tables() {
964
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_ac_log`;'); // Deleting SFW logs
965
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_sessions`;'); // Deleting session table
966
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_spamscan_logs`;'); // Deleting user/comments scan result table
967
+ $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_ua_bl`;'); // Deleting AC UA black lists
968
  }
969
 
970
  function apbct_deactivation__delete_meta(){
2037
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_sfw`;'); // Deleting SFW data
2038
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_sfw_logs`;'); // Deleting SFW logs
2039
  $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_ac_log`;'); // Deleting SFW logs
2040
+ $wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->prefix.'cleantalk_ua_bl`;'); // Deleting AC UA black lists
2041
 
2042
  switch_to_blog($initial_blog);
2043
  }
inc/cleantalk-admin.php CHANGED
@@ -401,7 +401,7 @@ function apbct_admin__notice_message(){
401
  }
402
 
403
  //key == "" || "enter key"
404
- if (!apbct_api_key__is_correct() && $apbct->moderate_ip == 0){
405
  echo "<div class='error'>"
406
  ."<h3>"
407
  .sprintf(__("Please enter Access Key in %s settings to enable anti spam protection!", 'cleantalk-spam-protect'), "<a href='{$settings_link}'>$apbct->plugin_name</a>")
401
  }
402
 
403
  //key == "" || "enter key"
404
+ if ( ( ! apbct_api_key__is_correct() && $apbct->moderate_ip == 0 ) && ! $apbct->white_label ){
405
  echo "<div class='error'>"
406
  ."<h3>"
407
  .sprintf(__("Please enter Access Key in %s settings to enable anti spam protection!", 'cleantalk-spam-protect'), "<a href='{$settings_link}'>$apbct->plugin_name</a>")
inc/cleantalk-ajax.php CHANGED
@@ -320,6 +320,8 @@ function ct_ajax_hook($message_obj = false, $additional = false)
320
  'wfu_ajax_action_ask_server', //WFU skip ask server
321
  'wcap_save_guest_data', //WooCommerce skip
322
  'ajaxlogin', //Skip ajax login redirect
 
 
323
  );
324
 
325
  // Skip test if
@@ -338,7 +340,8 @@ function ct_ajax_hook($message_obj = false, $additional = false)
338
  (isset($message_obj['post_author']) && intval($message_obj['post_author']) == 0)
339
  )
340
  ) ||
341
- (isset($_POST['action'], $_POST['arm_action']) && $_POST['action'] == 'arm_shortcode_form_ajax_action' && $_POST['arm_action'] == 'please-login') //arm forms skip login
 
342
  )
343
  {
344
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
@@ -781,6 +784,10 @@ function ct_ajax_hook($message_obj = false, $additional = false)
781
  )
782
  );
783
  }
 
 
 
 
784
  else
785
  {
786
  die(json_encode(array( 'apbct' => array(
320
  'wfu_ajax_action_ask_server', //WFU skip ask server
321
  'wcap_save_guest_data', //WooCommerce skip
322
  'ajaxlogin', //Skip ajax login redirect
323
+ 'heartbeat', //Gravity multipage
324
+ 'erforms_field_change_command', //ERForms internal request
325
  );
326
 
327
  // Skip test if
340
  (isset($message_obj['post_author']) && intval($message_obj['post_author']) == 0)
341
  )
342
  ) ||
343
+ (isset($_POST['action'], $_POST['arm_action']) && $_POST['action'] == 'arm_shortcode_form_ajax_action' && $_POST['arm_action'] == 'please-login') || //arm forms skip login
344
+ ( isset($_POST['action']) && $_POST['action'] == 'erf_login_user' && in_array( 'easy-registration-forms/erforms.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) //Easy Registration Forms login form skip
345
  )
346
  {
347
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
784
  )
785
  );
786
  }
787
+ // Easy Registration Form
788
+ elseif( isset( $_POST['action'] ) && strpos($_POST['action'], 'erf_submit_form') !== false ) {
789
+ wp_send_json_error( array( 0 => array( 'username_error', $ct_result->comment ) ) );
790
+ }
791
  else
792
  {
793
  die(json_encode(array( 'apbct' => array(
inc/cleantalk-common.php CHANGED
@@ -105,7 +105,9 @@ function apbct_base_call($params = array(), $reg_flag = false){
105
  $apbct->save('plugin_request_ids');
106
 
107
  // Skip duplicate requests
108
- if( key_exists( $apbct->plugin_request_id, $apbct->plugin_request_ids ) ){
 
 
109
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
110
  return array( 'ct_result' => new CleantalkResponse() );
111
  }
@@ -237,7 +239,7 @@ function apbct_base_call($params = array(), $reg_flag = false){
237
  function apbct_exclusions_check($func = null){
238
 
239
  global $apbct, $cleantalk_executed;
240
-
241
  // Common exclusions
242
  if(
243
  apbct_exclusions_check__ip() ||
105
  $apbct->save('plugin_request_ids');
106
 
107
  // Skip duplicate requests
108
+ if( key_exists( $apbct->plugin_request_id, $apbct->plugin_request_ids ) &&
109
+ current_filter() !== 'woocommerce_registration_errors' ) //Prevent skip checking woocommerce registration during checkout
110
+ {
111
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
112
  return array( 'ct_result' => new CleantalkResponse() );
113
  }
239
  function apbct_exclusions_check($func = null){
240
 
241
  global $apbct, $cleantalk_executed;
242
+
243
  // Common exclusions
244
  if(
245
  apbct_exclusions_check__ip() ||
inc/cleantalk-public.php CHANGED
@@ -388,7 +388,7 @@ function apbct_buffer__output(){
388
 
389
  $html = $dom->getElementsByTagName('html');
390
 
391
- $output = gettype($html) == 'object' && isset($html[0], $html[0]->childNodes, $html[0]->childNodes[0])
392
  ? $dom->saveHTML()
393
  : $apbct->buffer;
394
 
@@ -934,7 +934,7 @@ function ct_add_hidden_fields($field_name = 'ct_checkjs', $return_string = false
934
  // Using only cookies
935
  if ($cookie_check && $apbct->settings['set_cookies'] == 1) {
936
 
937
- $html = "<script type='text/javascript' " . ( class_exists('Cookiebot_WP') ? 'data-cookieconsent="ignore"' : '' ) . ">
938
  function ctSetCookie___from_backend(c_name, value) {
939
  document.cookie = c_name + \"=\" + encodeURIComponent(value) + \"; path=/; samesite=lax\";
940
  }
@@ -950,13 +950,13 @@ function ct_add_hidden_fields($field_name = 'ct_checkjs', $return_string = false
950
 
951
  $ct_input_challenge = sprintf("'%s'", $ct_checkjs_key);
952
  $field_id = $field_name . '_' . $field_id_hash;
953
- $html = "<input type='hidden' id='{$field_id}' name='{$field_name}' value='{$ct_checkjs_def}' />
954
- <script type='text/javascript' " . ( class_exists('Cookiebot_WP') ? 'data-cookieconsent="ignore"' : '' ) . ">
955
- window.addEventListener('DOMContentLoaded', function () {
956
  setTimeout(function(){
957
  apbct_public_sendAJAX(
958
- {action: 'apbct_js_keys__get'},
959
- {callback: apbct_js_keys__set_input_value, input_name: '{$field_id}',silent: true, no_nonce: true}
960
  );
961
  }, 1000);
962
  });
@@ -970,10 +970,10 @@ function ct_add_hidden_fields($field_name = 'ct_checkjs', $return_string = false
970
 
971
  $ct_input_challenge = sprintf("'%s'", $ct_checkjs_key);
972
  $field_id = $field_name . '_' . $field_id_hash;
973
- $html = "<input type='hidden' id='{$field_id}' name='{$field_name}' value='{$ct_checkjs_def}' />
974
- <script type='text/javascript' " . ( class_exists('Cookiebot_WP') ? 'data-cookieconsent="ignore"' : '' ) . ">
975
  setTimeout(function(){
976
- var ct_input_name = '{$field_id}';
977
  if (document.getElementById(ct_input_name) !== null) {
978
  var ct_input_value = document.getElementById(ct_input_name).value;
979
  document.getElementById(ct_input_name).value = document.getElementById(ct_input_name).value.replace(ct_input_value, {$ct_input_challenge});
@@ -3342,7 +3342,8 @@ function ct_contact_form_validate() {
3342
  ( isset( $_POST['somfrp_action'], $_POST['submitted'] ) && $_POST['somfrp_action'] == 'somfrp_lost_pass' ) || // Frontend Reset Password exclusion
3343
  ( isset( $_POST['action'] ) && $_POST['action'] == 'dokan_save_account_details' ) ||
3344
  \Cleantalk\Variables\Post::get('action') === 'frm_get_lookup_text_value' || // Exception for Formidable multilevel form
3345
- ( isset( $_POST['ihcaction'] ) && $_POST['ihcaction'] == 'reset_pass') //Reset pass exclusion
 
3346
  ) {
3347
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
3348
  return null;
@@ -3568,7 +3569,8 @@ function ct_contact_form_validate_postdata() {
3568
  (isset($_POST['action']) && $_POST['action'] == 'infinite_scroll') || //Scroll
3569
  isset($_POST['gform_submit']) || //Skip gravity checking because of direct integration
3570
  (isset($_POST['lrm_action']) && $_POST['lrm_action'] == 'login') || //Skip login form
3571
- apbct_is_in_uri( 'xmlrpc.php?for=jetpack' )
 
3572
  ) {
3573
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
3574
  return null;
@@ -3948,3 +3950,36 @@ function apbct_form__enfold_contact_form__test_spam( $send, $new_post, $form_par
3948
  return $send;
3949
 
3950
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
 
389
  $html = $dom->getElementsByTagName('html');
390
 
391
+ $output = gettype($html) == 'object' && isset($html[0], $html[0]->childNodes, $html[0]->childNodes[0]) && $dom->getElementsByTagName('rss')->length == 0
392
  ? $dom->saveHTML()
393
  : $apbct->buffer;
394
 
934
  // Using only cookies
935
  if ($cookie_check && $apbct->settings['set_cookies'] == 1) {
936
 
937
+ $html = "<script type=\"text/javascript\" " . ( class_exists('Cookiebot_WP') ? 'data-cookieconsent="ignore"' : '' ) . ">
938
  function ctSetCookie___from_backend(c_name, value) {
939
  document.cookie = c_name + \"=\" + encodeURIComponent(value) + \"; path=/; samesite=lax\";
940
  }
950
 
951
  $ct_input_challenge = sprintf("'%s'", $ct_checkjs_key);
952
  $field_id = $field_name . '_' . $field_id_hash;
953
+ $html = "<input type=\"hidden\" id=\"{$field_id}\" name=\"{$field_name}\" value=\"{$ct_checkjs_def}\" />
954
+ <script type=\"text/javascript\" " . ( class_exists('Cookiebot_WP') ? 'data-cookieconsent="ignore"' : '' ) . ">
955
+ window.addEventListener(\"DOMContentLoaded\", function () {
956
  setTimeout(function(){
957
  apbct_public_sendAJAX(
958
+ {action: \"apbct_js_keys__get\"},
959
+ {callback: apbct_js_keys__set_input_value, input_name: \"{$field_id}\",silent: true, no_nonce: true}
960
  );
961
  }, 1000);
962
  });
970
 
971
  $ct_input_challenge = sprintf("'%s'", $ct_checkjs_key);
972
  $field_id = $field_name . '_' . $field_id_hash;
973
+ $html = "<input type=\"hidden\" id=\"{$field_id}\" name=\"{$field_name}\" value=\"{$ct_checkjs_def}\" />
974
+ <script type=\"text/javascript\" " . ( class_exists('Cookiebot_WP') ? 'data-cookieconsent="ignore"' : '' ) . ">
975
  setTimeout(function(){
976
+ var ct_input_name = \"{$field_id}\";
977
  if (document.getElementById(ct_input_name) !== null) {
978
  var ct_input_value = document.getElementById(ct_input_name).value;
979
  document.getElementById(ct_input_name).value = document.getElementById(ct_input_name).value.replace(ct_input_value, {$ct_input_challenge});
3342
  ( isset( $_POST['somfrp_action'], $_POST['submitted'] ) && $_POST['somfrp_action'] == 'somfrp_lost_pass' ) || // Frontend Reset Password exclusion
3343
  ( isset( $_POST['action'] ) && $_POST['action'] == 'dokan_save_account_details' ) ||
3344
  \Cleantalk\Variables\Post::get('action') === 'frm_get_lookup_text_value' || // Exception for Formidable multilevel form
3345
+ ( isset( $_POST['ihcaction'] ) && $_POST['ihcaction'] == 'reset_pass') || //Reset pass exclusion
3346
+ ( isset( $_POST['action'], $_POST['register_unspecified_nonce_field'] ) && $_POST['action'] == 'register' ) // Profile Builder have a direct integration
3347
  ) {
3348
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
3349
  return null;
3569
  (isset($_POST['action']) && $_POST['action'] == 'infinite_scroll') || //Scroll
3570
  isset($_POST['gform_submit']) || //Skip gravity checking because of direct integration
3571
  (isset($_POST['lrm_action']) && $_POST['lrm_action'] == 'login') || //Skip login form
3572
+ apbct_is_in_uri( 'xmlrpc.php?for=jetpack' ) ||
3573
+ apbct_is_in_uri( 'connector=bridge&task=put_sql' )
3574
  ) {
3575
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
3576
  return null;
3950
  return $send;
3951
 
3952
  }
3953
+
3954
+ // Profile Builder integration
3955
+ function apbct_form_profile_builder__check_register ( $errors, $fields, $global_request ){
3956
+
3957
+ if( isset( $global_request['action'] ) && $global_request['action'] == 'register' ) {
3958
+
3959
+ global $cleantalk_executed;
3960
+
3961
+ $data = ct_get_fields_any( $global_request );
3962
+
3963
+ $base_call_result = apbct_base_call(
3964
+ array(
3965
+ 'message' => !empty( $data['message'] ) ? json_encode( $data['message'] ) : '',
3966
+ 'sender_email' => !empty( $data['email'] ) ? $data['email'] : '',
3967
+ 'sender_nickname' => !empty( $data['nickname'] ) ? $data['nickname'] : '',
3968
+ 'post_info' => array(
3969
+ 'comment_type' => 'register_profile_builder'
3970
+ ),
3971
+ ), true
3972
+ );
3973
+
3974
+ $ct_result = $base_call_result['ct_result'];
3975
+
3976
+ $cleantalk_executed = true;
3977
+
3978
+ if( $ct_result->allow == 0 ) {
3979
+ $errors['error'] = $ct_result->comment;
3980
+ }
3981
+
3982
+ }
3983
+ return $errors;
3984
+
3985
+ }
inc/cleantalk-settings.php CHANGED
@@ -110,7 +110,10 @@ function apbct_settings__set_fileds( $fields ){
110
  'title' => __('Anti-Crawler', 'cleantalk-spam-protect'),
111
  'class' => 'apbct_settings-field_wrapper--sub',
112
  'parent' => 'spam_firewall',
113
- 'description' => __('Plugin shows SpamFireWall stop page for any bot, except allowed bots (Google, Yahoo and etc).', 'cleantalk-spam-protect'),
 
 
 
114
  ),
115
  ),
116
  ),
@@ -434,6 +437,14 @@ function apbct_settings__set_fileds( $fields ){
434
  'options_callback_params' => array(true),
435
  'class' => 'apbct_settings-field_wrapper--sub',
436
  ),
 
 
 
 
 
 
 
 
437
  'sfw__anti_flood__view_limit' => array(
438
  'type' => 'text',
439
  'title' => __('Anti-Flood Page Views Limit', 'cleantalk-spam-protect'),
110
  'title' => __('Anti-Crawler', 'cleantalk-spam-protect'),
111
  'class' => 'apbct_settings-field_wrapper--sub',
112
  'parent' => 'spam_firewall',
113
+ 'childrens' => array('sfw__anti_crawler_ua'),
114
+ 'description' => __('Plugin shows SpamFireWall stop page for any bot, except allowed bots (Google, Yahoo and etc).', 'cleantalk-spam-protect')
115
+ . '<br>'
116
+ . __( 'Anti-Crawler includes blocking bots by the User-Agent. To enable/disable, open the Advanced settings, and turn on/off "Block by User-Agent".', 'cleantalk-spam-protect' ),
117
  ),
118
  ),
119
  ),
437
  'options_callback_params' => array(true),
438
  'class' => 'apbct_settings-field_wrapper--sub',
439
  ),
440
+ 'sfw__anti_crawler_ua' => array(
441
+ 'type' => 'checkbox',
442
+ 'title' => __('Block bots by User Agents', 'cleantalk-spam-protect'),
443
+ 'parent' => 'sfw__anti_crawler',
444
+ 'description' => __('The option allows you to block or allow bots by their User Agents. Supports black and white lists.', 'cleantalk-spam-protect')
445
+ . '<br>'
446
+ . __( 'This option improves the accuracy of Anti-Crawler and allows you to manage rules for specific bots.', 'cleantalk-spam-protect' ),
447
+ ),
448
  'sfw__anti_flood__view_limit' => array(
449
  'type' => 'text',
450
  'title' => __('Anti-Flood Page Views Limit', 'cleantalk-spam-protect'),
inc/cleantalk-updater.php CHANGED
@@ -633,3 +633,59 @@ function apbct_update_to_5_146_4() {
633
  function apbct_update_to_5_148_0() {
634
  Cron::updateTask('antiflood__clear_table', 'apbct_antiflood__clear_table', 86400);
635
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
633
  function apbct_update_to_5_148_0() {
634
  Cron::updateTask('antiflood__clear_table', 'apbct_antiflood__clear_table', 86400);
635
  }
636
+
637
+ function apbct_update_to_5_149_2() {
638
+
639
+ global $apbct;
640
+
641
+ $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ua_bl` (
642
+ `id` INT(11) NOT NULL,
643
+ `ua_template` VARCHAR(512) NULL DEFAULT NULL,
644
+ `ua_status` TINYINT(1) NULL DEFAULT NULL,
645
+ PRIMARY KEY ( `id` ),
646
+ INDEX ( `ua_template` )
647
+ );';
648
+
649
+ $sqls[] = 'DROP TABLE IF EXISTS `%scleantalk_sfw_logs`;';
650
+
651
+ $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_sfw_logs` (
652
+ `id` VARCHAR(40) NOT NULL,
653
+ `ip` VARCHAR(15) NOT NULL,
654
+ `status` ENUM(\'PASS_SFW\',\'DENY_SFW\',\'PASS_SFW__BY_WHITELIST\',\'PASS_SFW__BY_COOKIE\',\'DENY_ANTICRAWLER\',\'PASS_ANTICRAWLER\',\'DENY_ANTICRAWLER_UA\',\'PASS_ANTICRAWLER_UA\',\'DENY_ANTIFLOOD\',\'PASS_ANTIFLOOD\') NULL DEFAULT NULL,
655
+ `all_entries` INT NOT NULL,
656
+ `blocked_entries` INT NOT NULL,
657
+ `entries_timestamp` INT NOT NULL,
658
+ `ua_id` INT(11) NULL DEFAULT NULL,
659
+ `ua_name` VARCHAR(1024) NOT NULL,
660
+ PRIMARY KEY (`id`));';
661
+
662
+ apbct_activation__create_tables( $sqls, $apbct->db_prefix );
663
+
664
+ $apbct->settings['sfw__anti_crawler_ua'] = 0;
665
+ $apbct->saveSettings();
666
+
667
+ }
668
+
669
+ function apbct_update_to_5_150_0() {
670
+
671
+ global $wpdb;
672
+
673
+ // Actions for WPMS
674
+ if( APBCT_WPMS ){
675
+ // Getting all blog ids
676
+ $initial_blog = get_current_blog_id();
677
+ $blogs = array_keys($wpdb->get_results('SELECT blog_id FROM '. $wpdb->blogs, OBJECT_K));
678
+
679
+ foreach ($blogs as $blog) {
680
+
681
+ switch_to_blog($blog);
682
+
683
+ update_option( 'cleantalk_plugin_request_ids', array() );
684
+
685
+ }
686
+
687
+ // Restoring initial blog
688
+ switch_to_blog($initial_blog);
689
+ }
690
+
691
+ }
js/apbct-public.min.js CHANGED
@@ -1,2 +1 @@
1
- function ctSetCookie(e,t){document.cookie=e+"="+encodeURIComponent(t)+"; path=/; samesite=lax"}function apbct_collect_visible_fields(e){var t=[],o="",n=0,i=[];for(var a in e.elements)isNaN(+a)||(t[a]=e.elements[a]);return(t=t.filter(function(e){return"none"!==getComputedStyle(e).display&&"hidden"!==getComputedStyle(e).visibility&&"0"!==getComputedStyle(e).opacity&&"hidden"!==e.getAttribute("type")&&"submit"!==e.getAttribute("type")&&null!==e.getAttribute("name")&&-1===i.indexOf(e.getAttribute("name"))&&(n++,-1===["radio","checkbox"].indexOf(e.getAttribute("type"))||(i.push(e.getAttribute("name")),!1))})).forEach(function(e,t,n){o+=" "+e.getAttribute("name")}),{visible_fields:o=o.trim(),visible_fields_count:n}}function apbct_visible_fields_set_cookie(e){var t="object"==typeof e&&null!==e?e:{};ctSetCookie("apbct_visible_fields",JSON.stringify(t))}function apbct_js_keys__set_input_value(e,t,n,o){var i;null!==document.getElementById(n.input_name)&&(i=document.getElementById(n.input_name).value,document.getElementById(n.input_name).value=document.getElementById(n.input_name).value.replace(i,e.js_key))}function apbct_public_sendAJAX(t,n,o){var i=n.callback||null,a=n.callback_context||null,c=n.callback_params||null,e=n.async||!0,s=n.notJson||null,l=n.timeout||15e3,o=o||null,r=n.button||null,u=n.spinner||null,p=n.progressbar||null,d=n.silent||null,m=n.no_nonce||null;"string"==typeof t?(m||(t=t+"&_ajax_nonce="+ctPublic._ajax_nonce),t=t+"&no_cache="+Math.random()):(m||(t._ajax_nonce=ctPublic._ajax_nonce),t.no_cache=Math.random()),r&&(r.setAttribute("disabled","disabled"),r.style.cursor="not-allowed"),u&&jQuery(u).css("display","inline"),jQuery.ajax({type:"POST",url:ctPublic._ajax_url,data:t,async:e,success:function(e){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),s||(e=JSON.parse(e)),e.error?(setTimeout(function(){p&&p.fadeOut("slow")},1e3),alert("Error happens: "+(e.error||"Unkown"))):i&&(c?i.apply(a,c.concat(e,t,n,o)):i(e,t,n,o))},error:function(e,t,n){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),n&&!d&&(console.log("APBCT_AJAX_ERROR"),console.log(e),console.log(t),console.log("Anti-spam by Cleantalk plugin error: "+n+"Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"),alert("Anti-spam by Cleantalk plugin error: "+n+"Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"))},timeout:l})}!function(){var e=new Date,t=(new Date).getTime(),n=!0,o=[],i=0;function a(e,t,n){"function"==typeof window.addEventListener?e.addEventListener(t,n):e.attachEvent(t,n)}function c(e,t,n){"function"==typeof window.removeEventListener?e.removeEventListener(t,n):e.detachEvent(t,n)}ctSetCookie("ct_ps_timestamp",Math.floor((new Date).getTime()/1e3)),ctSetCookie("ct_fkp_timestamp","0"),ctSetCookie("ct_pointer_data","0"),ctSetCookie("ct_timezone","0"),setTimeout(function(){ctSetCookie("ct_timezone",e.getTimezoneOffset()/60*-1)},1e3);var s=function(){ctSetCookie("ct_fkp_timestamp",Math.floor((new Date).getTime()/1e3)),c(window,"mousedown",s),c(window,"keydown",s)},l=setInterval(function(){n=!0},150),r=setInterval(function(){ctSetCookie("ct_pointer_data",JSON.stringify(o))},1200),u=function(e){!0===n&&(o.push([Math.round(e.clientY),Math.round(e.clientX),Math.round((new Date).getTime()-t)]),n=!1,50<=++i&&(c(window,"mousemove",u),clearInterval(l),clearInterval(r)))};a(window,"mousemove",u),a(window,"mousedown",s),a(window,"keydown",s),a(window,"DOMContentLoaded",function(){ctSetCookie("apbct_visible_fields",0),setTimeout(function(){for(var e={},t=0;t<document.forms.length;t++){var n=document.forms[t];n.classList.contains("slp_search_form")||n.parentElement.classList.contains("mec-booking")||-1!==n.action.toString().indexOf("activehosted.com")||n.id&&"caspioform"==n.id||(e[t]=apbct_collect_visible_fields(n),n.onsubmit_prev=n.onsubmit,n.onsubmit=function(e){var t={};t[0]=apbct_collect_visible_fields(this),apbct_visible_fields_set_cookie(t),e.target.onsubmit_prev instanceof Function&&setTimeout(function(){e.target.onsubmit_prev.call(e.target,e)},500)})}apbct_visible_fields_set_cookie(e)},1e3)})}(),"undefined"!=typeof jQuery&&jQuery(document).ajaxComplete(function(e,t,n){var o;!t.responseText||-1===t.responseText.indexOf('"apbct')||void 0!==(o=JSON.parse(t.responseText)).apbct&&(o=o.apbct).blocked&&(document.dispatchEvent(new CustomEvent("apbctAjaxBockAlert",{bubbles:!0,detail:{message:o.comment}})),alert(o.comment),1==+o.stop_script&&window.stop())});
2
- //# sourceMappingURL=apbct-public.min.js.map
1
+ function ctSetCookie(e,t){document.cookie=e+"="+encodeURIComponent(t)+"; path=/; samesite=lax"}function apbct_collect_visible_fields(e){var t=[],o="",n=0,i=[];for(var a in e.elements)isNaN(+a)||(t[a]=e.elements[a]);return(t=t.filter(function(e){return"none"!==getComputedStyle(e).display&&"hidden"!==getComputedStyle(e).visibility&&"0"!==getComputedStyle(e).opacity&&"hidden"!==e.getAttribute("type")&&"submit"!==e.getAttribute("type")&&null!==e.getAttribute("name")&&-1===i.indexOf(e.getAttribute("name"))&&(n++,-1===["radio","checkbox"].indexOf(e.getAttribute("type"))||(i.push(e.getAttribute("name")),!1))})).forEach(function(e,t,n){o+=" "+e.getAttribute("name")}),{visible_fields:o=o.trim(),visible_fields_count:n}}function apbct_visible_fields_set_cookie(e){var t="object"==typeof e&&null!==e?e:{};ctSetCookie("apbct_visible_fields",JSON.stringify(t))}function apbct_js_keys__set_input_value(e,t,n,o){if(null!==document.getElementById(n.input_name)){var i=document.getElementById(n.input_name).value;document.getElementById(n.input_name).value=document.getElementById(n.input_name).value.replace(i,e.js_key)}}function apbct_public_sendAJAX(t,n,o){var i=n.callback||null,a=n.callback_context||null,c=n.callback_params||null,e=n.async||!0,s=n.notJson||null,l=n.timeout||15e3,r=(o=o||null,n.button||null),u=n.spinner||null,p=n.progressbar||null,d=n.silent||null,m=n.no_nonce||null;"string"==typeof t?(m||(t=t+"&_ajax_nonce="+ctPublic._ajax_nonce),t=t+"&no_cache="+Math.random()):(m||(t._ajax_nonce=ctPublic._ajax_nonce),t.no_cache=Math.random()),r&&(r.setAttribute("disabled","disabled"),r.style.cursor="not-allowed"),u&&jQuery(u).css("display","inline"),jQuery.ajax({type:"POST",url:ctPublic._ajax_url,data:t,async:e,success:function(e){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),s||(e=JSON.parse(e)),e.error?(setTimeout(function(){p&&p.fadeOut("slow")},1e3),alert("Error happens: "+(e.error||"Unkown"))):i&&(c?i.apply(a,c.concat(e,t,n,o)):i(e,t,n,o))},error:function(e,t,n){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),n&&!d&&(console.log("APBCT_AJAX_ERROR"),console.log(e),console.log(t),console.log("Anti-spam by Cleantalk plugin error: "+n+"Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"),alert("Anti-spam by Cleantalk plugin error: "+n+"Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"))},timeout:l})}!function(){var e=new Date,t=(new Date).getTime(),n=!0,o=[],i=0;function a(e,t,n){"function"==typeof window.addEventListener?e.addEventListener(t,n):e.attachEvent(t,n)}function c(e,t,n){"function"==typeof window.removeEventListener?e.removeEventListener(t,n):e.detachEvent(t,n)}ctSetCookie("ct_ps_timestamp",Math.floor((new Date).getTime()/1e3)),ctSetCookie("ct_fkp_timestamp","0"),ctSetCookie("ct_pointer_data","0"),ctSetCookie("ct_timezone","0"),setTimeout(function(){ctSetCookie("ct_timezone",e.getTimezoneOffset()/60*-1)},1e3);var s=function(){ctSetCookie("ct_fkp_timestamp",Math.floor((new Date).getTime()/1e3)),c(window,"mousedown",s),c(window,"keydown",s)},l=setInterval(function(){n=!0},150),r=setInterval(function(){ctSetCookie("ct_pointer_data",JSON.stringify(o))},1200),u=function(e){!0===n&&(o.push([Math.round(e.clientY),Math.round(e.clientX),Math.round((new Date).getTime()-t)]),n=!1,50<=++i&&(c(window,"mousemove",u),clearInterval(l),clearInterval(r)))};a(window,"mousemove",u),a(window,"mousedown",s),a(window,"keydown",s),a(window,"DOMContentLoaded",function(){ctSetCookie("apbct_visible_fields",0),setTimeout(function(){for(var e={},t=0;t<document.forms.length;t++){var n=document.forms[t];n.classList.contains("slp_search_form")||n.parentElement.classList.contains("mec-booking")||-1!==n.action.toString().indexOf("activehosted.com")||n.id&&"caspioform"==n.id||n.name.classList&&n.name.classList.contains("tinkoffPayRow")||(e[t]=apbct_collect_visible_fields(n),n.onsubmit_prev=n.onsubmit,n.onsubmit=function(e){var t={};t[0]=apbct_collect_visible_fields(this),apbct_visible_fields_set_cookie(t),e.target.onsubmit_prev instanceof Function&&setTimeout(function(){e.target.onsubmit_prev.call(e.target,e)},500)})}apbct_visible_fields_set_cookie(e)},1e3)})}(),"undefined"!=typeof jQuery&&jQuery(document).ajaxComplete(function(e,t,n){if(t.responseText&&-1!==t.responseText.indexOf('"apbct')){var o=JSON.parse(t.responseText);void 0!==o.apbct&&(o=o.apbct).blocked&&(document.dispatchEvent(new CustomEvent("apbctAjaxBockAlert",{bubbles:!0,detail:{message:o.comment}})),alert(o.comment),1==+o.stop_script&&window.stop())}});
 
js/apbct-public.min.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"apbct-public.min.js","sources":["apbct-public.js"],"sourcesContent":["(function() {\n\n\tvar ct_date = new Date(),\n\t\tctTimeMs = new Date().getTime(),\n\t\tctMouseEventTimerFlag = true, //Reading interval flag\n\t\tctMouseData = [],\n\t\tctMouseDataCounter = 0;\n\n\tfunction apbct_attach_event_handler(elem, event, callback){\n\t\tif(typeof window.addEventListener === \"function\") elem.addEventListener(event, callback);\n\t\telse elem.attachEvent(event, callback);\n\t}\n\n\tfunction apbct_remove_event_handler(elem, event, callback){\n\t\tif(typeof window.removeEventListener === \"function\") elem.removeEventListener(event, callback);\n\t\telse elem.detachEvent(event, callback);\n\t}\n\n\tctSetCookie(\"ct_ps_timestamp\", Math.floor(new Date().getTime()/1000));\n\tctSetCookie(\"ct_fkp_timestamp\", \"0\");\n\tctSetCookie(\"ct_pointer_data\", \"0\");\n\tctSetCookie(\"ct_timezone\", \"0\");\n\n\tsetTimeout(function(){\n\t\tctSetCookie(\"ct_timezone\", ct_date.getTimezoneOffset()/60*(-1));\n\t},1000);\n\n\t//Writing first key press timestamp\n\tvar ctFunctionFirstKey = function output(event){\n\t\tvar KeyTimestamp = Math.floor(new Date().getTime()/1000);\n\t\tctSetCookie(\"ct_fkp_timestamp\", KeyTimestamp);\n\t\tctKeyStopStopListening();\n\t};\n\n\t//Reading interval\n\tvar ctMouseReadInterval = setInterval(function(){\n\t\tctMouseEventTimerFlag = true;\n\t}, 150);\n\n\t//Writting interval\n\tvar ctMouseWriteDataInterval = setInterval(function(){\n\t\tctSetCookie(\"ct_pointer_data\", JSON.stringify(ctMouseData));\n\t}, 1200);\n\n\t//Logging mouse position each 150 ms\n\tvar ctFunctionMouseMove = function output(event){\n\t\tif(ctMouseEventTimerFlag === true){\n\n\t\t\tctMouseData.push([\n\t\t\t\tMath.round(event.clientY),\n\t\t\t\tMath.round(event.clientX),\n\t\t\t\tMath.round(new Date().getTime() - ctTimeMs)\n\t\t\t]);\n\n\t\t\tctMouseDataCounter++;\n\t\t\tctMouseEventTimerFlag = false;\n\t\t\tif(ctMouseDataCounter >= 50){\n\t\t\t\tctMouseStopData();\n\t\t\t}\n\t\t}\n\t};\n\n\t//Stop mouse observing function\n\tfunction ctMouseStopData(){\n\t\tapbct_remove_event_handler(window, \"mousemove\", ctFunctionMouseMove);\n\t\tclearInterval(ctMouseReadInterval);\n\t\tclearInterval(ctMouseWriteDataInterval);\n\t}\n\n\t//Stop key listening function\n\tfunction ctKeyStopStopListening(){\n\t\tapbct_remove_event_handler(window, \"mousedown\", ctFunctionFirstKey);\n\t\tapbct_remove_event_handler(window, \"keydown\", ctFunctionFirstKey);\n\t}\n\n\tapbct_attach_event_handler(window, \"mousemove\", ctFunctionMouseMove);\n\tapbct_attach_event_handler(window, \"mousedown\", ctFunctionFirstKey);\n\tapbct_attach_event_handler(window, \"keydown\", ctFunctionFirstKey);\n\n\t// Ready function\n\tfunction apbct_ready(){\n\n\t\tctSetCookie(\"apbct_visible_fields\", 0);\n\n\t\tsetTimeout(function(){\n\n\t\t\tvar visible_fields_collection = {};\n\n\t\t\tfor(var i = 0; i < document.forms.length; i++){\n\t\t\t\tvar form = document.forms[i];\n\n\t\t\t\t//Exclusion for forms\n\t\t\t\tif (\n\t\t\t\t\tform.classList.contains('slp_search_form') || //StoreLocatorPlus form\n\t\t\t\t\tform.parentElement.classList.contains('mec-booking') ||\n\t\t\t\t\tform.action.toString().indexOf('activehosted.com') !== -1 || // Active Campaign\n\t\t\t\t\t(form.id && form.id == 'caspioform') //Caspio Form\n\t\t\t\t)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvisible_fields_collection[i] = apbct_collect_visible_fields( form );\n\n\t\t\t\tform.onsubmit_prev = form.onsubmit;\n\t\t\t\tform.onsubmit = function (event) {\n\n\t\t\t\t\tvar visible_fields = {};\n\t\t\t\t\tvisible_fields[0] = apbct_collect_visible_fields(this);\n\t\t\t\t\tapbct_visible_fields_set_cookie( visible_fields );\n\n\t\t\t\t\t// Call previous submit action\n\t\t\t\t\tif (event.target.onsubmit_prev instanceof Function) {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\tevent.target.onsubmit_prev.call(event.target, event);\n\t\t\t\t\t\t}, 500);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tapbct_visible_fields_set_cookie( visible_fields_collection );\n\n\t\t}, 1000);\n\t}\n\tapbct_attach_event_handler(window, \"DOMContentLoaded\", apbct_ready);\n\n}());\n\nfunction ctSetCookie(c_name, value) {\n\tdocument.cookie = c_name + \"=\" + encodeURIComponent(value) + \"; path=/; samesite=lax\";\n}\n\nfunction apbct_collect_visible_fields( form ) {\n\n\t// Get only fields\n\tvar inputs = [],\n\t\tinputs_visible = '',\n\t\tinputs_visible_count = 0,\n\t\tinputs_with_duplicate_names = [];\n\n\tfor(var key in form.elements){\n\t\tif(!isNaN(+key))\n\t\t\tinputs[key] = form.elements[key];\n\t}\n\n\t// Filter fields\n\tinputs = inputs.filter(function(elem){\n\n\t\t// Filter fields\n\t\tif( getComputedStyle(elem).display === \"none\" || // hidden\n\t\t\tgetComputedStyle(elem).visibility === \"hidden\" || // hidden\n\t\t\tgetComputedStyle(elem).opacity === \"0\" || // hidden\n\t\t\telem.getAttribute(\"type\") === \"hidden\" || // type == hidden\n\t\t\telem.getAttribute(\"type\") === \"submit\" || // type == submit\n\t\t\t//elem.value === \"\" || // empty value\n\t\t\telem.getAttribute('name') === null ||\n\t\t\tinputs_with_duplicate_names.indexOf( elem.getAttribute('name') ) !== -1 // name already added\n\t\t){\n\t\t\treturn false;\n\t\t}\n\n\t\t// Visible fields count\n\t\tinputs_visible_count++;\n\n\t\t// Filter inputs with same names for type == radio\n\t\tif( -1 !== ['radio', 'checkbox'].indexOf( elem.getAttribute(\"type\") )){\n\t\t\tinputs_with_duplicate_names.push( elem.getAttribute('name') );\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t});\n\n\t// Visible fields\n\tinputs.forEach(function(elem, i, elements){\n\t\tinputs_visible += \" \" + elem.getAttribute(\"name\");\n\t});\n\tinputs_visible = inputs_visible.trim();\n\n\treturn {\n\t\tvisible_fields : inputs_visible,\n\t\tvisible_fields_count : inputs_visible_count,\n\t}\n\n}\n\nfunction apbct_visible_fields_set_cookie( visible_fields_collection ) {\n\n\tvar collection = typeof visible_fields_collection === 'object' && visible_fields_collection !== null ? visible_fields_collection : {};\n\n\tctSetCookie(\"apbct_visible_fields\", JSON.stringify( collection ) );\n\n}\n\nfunction apbct_js_keys__set_input_value(result, data, params, obj){\n\tif (document.getElementById(params.input_name) !== null) {\n\t\tvar ct_input_value = document.getElementById(params.input_name).value;\n\t\tdocument.getElementById(params.input_name).value = document.getElementById(params.input_name).value.replace(ct_input_value, result.js_key);\n\t}\n}\nfunction apbct_public_sendAJAX(data, params, obj){\n\n\t// Default params\n\tvar callback = params.callback || null;\n\tvar callback_context = params.callback_context || null;\n\tvar callback_params = params.callback_params || null;\n\tvar async = params.async || true;\n\tvar notJson = params.notJson || null;\n\tvar timeout = params.timeout || 15000;\n\tvar obj = obj || null;\n\tvar button = params.button || null;\n\tvar spinner = params.spinner || null;\n\tvar progressbar = params.progressbar || null;\n\tvar silent = params.silent || null;\n\tvar no_nonce = params.no_nonce || null;\n\n\tif(typeof (data) === 'string') {\n\t\tif( ! no_nonce )\n\t\t\tdata = data + '&_ajax_nonce=' + ctPublic._ajax_nonce;\n\t\tdata = data + '&no_cache=' + Math.random()\n\t} else {\n\t\tif( ! no_nonce )\n\t\t\tdata._ajax_nonce = ctPublic._ajax_nonce;\n\t\tdata.no_cache = Math.random();\n\t}\n\t// Button and spinner\n\tif(button) {button.setAttribute('disabled', 'disabled'); button.style.cursor = 'not-allowed'; }\n\tif(spinner) jQuery(spinner).css('display', 'inline');\n\n\tjQuery.ajax({\n\t\ttype: \"POST\",\n\t\turl: ctPublic._ajax_url,\n\t\tdata: data,\n\t\tasync: async,\n\t\tsuccess: function(result){\n\t\t\tif(button){ button.removeAttribute('disabled'); button.style.cursor = 'pointer'; }\n\t\t\tif(spinner) jQuery(spinner).css('display', 'none');\n\t\t\tif(!notJson) result = JSON.parse(result);\n\t\t\tif(result.error){\n\t\t\t\tsetTimeout(function(){ if(progressbar) progressbar.fadeOut('slow'); }, 1000);\n\t\t\t\talert('Error happens: ' + (result.error || 'Unkown'));\n\t\t\t}else{\n\t\t\t\tif(callback) {\n\t\t\t\t\tif (callback_params)\n\t\t\t\t\t\tcallback.apply( callback_context, callback_params.concat( result, data, params, obj ) );\n\t\t\t\t\telse\n\t\t\t\t\t\tcallback(result, data, params, obj);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\terror: function(jqXHR, textStatus, errorThrown){\n\t\t\tif(button){ button.removeAttribute('disabled'); button.style.cursor = 'pointer'; }\n\t\t\tif(spinner) jQuery(spinner).css('display', 'none');\n\t\t\tif( errorThrown && ! silent ) {\n\t\t\t\tconsole.log('APBCT_AJAX_ERROR');\n\t\t\t\tconsole.log(jqXHR);\n\t\t\t\tconsole.log(textStatus);\n\t\t\t\tconsole.log('Anti-spam by Cleantalk plugin error: ' + errorThrown + 'Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/');\n\t\t\t\talert('Anti-spam by Cleantalk plugin error: ' + errorThrown + 'Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/');\n\t\t\t}\n\t\t},\n\t\ttimeout: timeout,\n\t});\n}\nif(typeof jQuery !== 'undefined') {\n\n\t// Capturing responses and output block message for unknown AJAX forms\n\tjQuery(document).ajaxComplete(function (event, xhr, settings) {\n\t\tif (xhr.responseText && xhr.responseText.indexOf('\"apbct') !== -1) {\n\t\t\tvar response = JSON.parse(xhr.responseText);\n\t\t\tif (typeof response.apbct !== 'undefined') {\n\t\t\t\tresponse = response.apbct;\n\t\t\t\tif (response.blocked) {\n\t\t\t\t\tdocument.dispatchEvent(\n\t\t\t\t\t\tnew CustomEvent( \"apbctAjaxBockAlert\", {\n\t\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\t\tdetail: { message: response.comment }\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\t\t\t\t\talert(response.comment);\n\t\t\t\t\tif(+response.stop_script == 1)\n\t\t\t\t\t\twindow.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n}"],"names":["ctSetCookie","c_name","value","document","cookie","encodeURIComponent","apbct_collect_visible_fields","form","inputs","inputs_visible","inputs_visible_count","inputs_with_duplicate_names","key","elements","isNaN","filter","elem","getComputedStyle","display","visibility","opacity","getAttribute","indexOf","push","forEach","i","visible_fields","trim","visible_fields_count","apbct_visible_fields_set_cookie","visible_fields_collection","collection","JSON","stringify","apbct_js_keys__set_input_value","result","data","params","obj","ct_input_value","getElementById","input_name","replace","js_key","apbct_public_sendAJAX","callback","callback_context","callback_params","async","notJson","timeout","button","spinner","progressbar","silent","no_nonce","ctPublic","_ajax_nonce","Math","random","no_cache","setAttribute","style","cursor","jQuery","css","ajax","type","url","_ajax_url","success","removeAttribute","parse","error","setTimeout","fadeOut","alert","apply","concat","jqXHR","textStatus","errorThrown","console","log","ct_date","Date","ctTimeMs","getTime","ctMouseEventTimerFlag","ctMouseData","ctMouseDataCounter","apbct_attach_event_handler","event","window","addEventListener","attachEvent","apbct_remove_event_handler","removeEventListener","detachEvent","floor","getTimezoneOffset","ctFunctionFirstKey","ctMouseReadInterval","setInterval","ctMouseWriteDataInterval","ctFunctionMouseMove","round","clientY","clientX","clearInterval","forms","length","classList","contains","parentElement","action","toString","id","onsubmit_prev","onsubmit","this","target","Function","call","ajaxComplete","xhr","settings","response","responseText","apbct","blocked","dispatchEvent","CustomEvent","bubbles","detail","message","comment","stop_script","stop"],"mappings":"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"}
1
+ {"version":3,"sources":["apbct-public.js"],"names":["ctSetCookie","c_name","value","document","cookie","encodeURIComponent","apbct_collect_visible_fields","form","inputs","inputs_visible","inputs_visible_count","inputs_with_duplicate_names","key","elements","isNaN","filter","elem","getComputedStyle","display","visibility","opacity","getAttribute","indexOf","push","forEach","i","visible_fields","trim","visible_fields_count","apbct_visible_fields_set_cookie","visible_fields_collection","collection","JSON","stringify","apbct_js_keys__set_input_value","result","data","params","obj","getElementById","input_name","ct_input_value","replace","js_key","apbct_public_sendAJAX","callback","callback_context","callback_params","async","notJson","timeout","button","spinner","progressbar","silent","no_nonce","ctPublic","_ajax_nonce","Math","random","no_cache","setAttribute","style","cursor","jQuery","css","ajax","type","url","_ajax_url","success","removeAttribute","parse","error","setTimeout","fadeOut","alert","apply","concat","jqXHR","textStatus","errorThrown","console","log","ct_date","Date","ctTimeMs","getTime","ctMouseEventTimerFlag","ctMouseData","ctMouseDataCounter","apbct_attach_event_handler","event","window","addEventListener","attachEvent","apbct_remove_event_handler","removeEventListener","detachEvent","floor","getTimezoneOffset","ctFunctionFirstKey","ctMouseReadInterval","setInterval","ctMouseWriteDataInterval","ctFunctionMouseMove","round","clientY","clientX","clearInterval","forms","length","classList","contains","parentElement","action","toString","id","name","onsubmit_prev","onsubmit","this","target","Function","call","ajaxComplete","xhr","settings","responseText","response","apbct","blocked","dispatchEvent","CustomEvent","bubbles","detail","message","comment","stop_script","stop"],"mappings":"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"}
lib/Cleantalk/Antispam/Integrations.php CHANGED
@@ -1,87 +1,87 @@
1
- <?php
2
-
3
-
4
- namespace Cleantalk\Antispam;
5
-
6
-
7
- class Integrations
8
- {
9
-
10
- private $integrations = array();
11
-
12
- private $integration;
13
-
14
- public function __construct( $integrations )
15
- {
16
- $this->integrations = $integrations;
17
-
18
- foreach( $this->integrations as $integration_name => $integration_info ) {
19
- if( $integration_info['ajax'] ) {
20
- add_action( 'wp_ajax_' . $integration_info['hook'], array( $this, 'checkSpam' ), 1 );
21
- add_action( 'wp_ajax_nopriv_' . $integration_info['hook'], array( $this, 'checkSpam' ), 1 );
22
- } else {
23
- add_action( $integration_info['hook'], array( $this, 'checkSpam' ) );
24
- }
25
- }
26
- }
27
-
28
- public function checkSpam( $argument )
29
- {
30
- global $cleantalk_executed;
31
-
32
- // Getting current integration name
33
- $current_integration = $this->get_current_integration_triggered( current_filter() );
34
- if( $current_integration ) {
35
- // Instantiate the integration object
36
- $class = '\\Cleantalk\\Antispam\\Integrations\\' . $current_integration;
37
- if( class_exists( $class )) {
38
- $this->integration = new $class();
39
- if( ! ( $this->integration instanceof \Cleantalk\Antispam\Integrations\IntegrationBase ) ) {
40
- // @ToDo have to handle an error
41
- do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, array('Integration is not instanse of IntegrationBase class.') );
42
- return;
43
- }
44
- // Run data collecting for spam checking
45
- $data = $this->integration->getDataForChecking( $argument );
46
- if( ! is_null( $data ) ) {
47
- // Go spam checking
48
- $base_call_result = apbct_base_call(
49
- array(
50
- 'message' => !empty( $data['message'] ) ? json_encode( $data['message'] ) : '',
51
- 'sender_email' => !empty( $data['email'] ) ? $data['email'] : '',
52
- 'sender_nickname' => !empty( $data['nickname'] ) ? $data['nickname'] : '',
53
- 'post_info' => array(
54
- 'comment_type' => 'contact_form_wordpress_' . strtolower($current_integration),
55
- 'post_url' => apbct_get_server_variable( 'HTTP_REFERER' ), // Page URL must be an previous page
56
- ),
57
- )
58
- );
59
-
60
- $ct_result = $base_call_result['ct_result'];
61
-
62
- $cleantalk_executed = true;
63
-
64
- if ($ct_result->allow == 0) {
65
- // Do blocking if it is a spam
66
- $this->integration->doBlock( $ct_result->comment );
67
- }
68
- } else {
69
- // @ToDo have to handle an error
70
- return;
71
- }
72
- }
73
- }
74
- }
75
-
76
- private function get_current_integration_triggered( $hook )
77
- {
78
- if( $hook !== false ) {
79
- foreach( $this->integrations as $integration_name => $integration_info ) {
80
- if( strpos( $hook, $integration_info['hook'] ) !== false ) {
81
- return $integration_name;
82
- }
83
- }
84
- }
85
- return false;
86
- }
87
  }
1
+ <?php
2
+
3
+
4
+ namespace Cleantalk\Antispam;
5
+
6
+
7
+ class Integrations
8
+ {
9
+
10
+ private $integrations = array();
11
+
12
+ private $integration;
13
+
14
+ public function __construct( $integrations )
15
+ {
16
+ $this->integrations = $integrations;
17
+
18
+ foreach( $this->integrations as $integration_name => $integration_info ) {
19
+ if( $integration_info['ajax'] ) {
20
+ add_action( 'wp_ajax_' . $integration_info['hook'], array( $this, 'checkSpam' ), 1 );
21
+ add_action( 'wp_ajax_nopriv_' . $integration_info['hook'], array( $this, 'checkSpam' ), 1 );
22
+ } else {
23
+ add_action( $integration_info['hook'], array( $this, 'checkSpam' ) );
24
+ }
25
+ }
26
+ }
27
+
28
+ public function checkSpam( $argument )
29
+ {
30
+ global $cleantalk_executed;
31
+
32
+ // Getting current integration name
33
+ $current_integration = $this->get_current_integration_triggered( current_filter() );
34
+ if( $current_integration ) {
35
+ // Instantiate the integration object
36
+ $class = '\\Cleantalk\\Antispam\\Integrations\\' . $current_integration;
37
+ if( class_exists( $class )) {
38
+ $this->integration = new $class();
39
+ if( ! ( $this->integration instanceof \Cleantalk\Antispam\Integrations\IntegrationBase ) ) {
40
+ // @ToDo have to handle an error
41
+ do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, array('Integration is not instanse of IntegrationBase class.') );
42
+ return;
43
+ }
44
+ // Run data collecting for spam checking
45
+ $data = $this->integration->getDataForChecking( $argument );
46
+ if( ! is_null( $data ) ) {
47
+ // Go spam checking
48
+ $base_call_result = apbct_base_call(
49
+ array(
50
+ 'message' => !empty( $data['message'] ) ? json_encode( $data['message'] ) : '',
51
+ 'sender_email' => !empty( $data['email'] ) ? $data['email'] : '',
52
+ 'sender_nickname' => !empty( $data['nickname'] ) ? $data['nickname'] : '',
53
+ 'post_info' => array(
54
+ 'comment_type' => 'contact_form_wordpress_' . strtolower($current_integration),
55
+ 'post_url' => apbct_get_server_variable( 'HTTP_REFERER' ), // Page URL must be an previous page
56
+ ),
57
+ )
58
+ );
59
+
60
+ $ct_result = $base_call_result['ct_result'];
61
+
62
+ $cleantalk_executed = true;
63
+
64
+ if ($ct_result->allow == 0) {
65
+ // Do blocking if it is a spam
66
+ $this->integration->doBlock( $ct_result->comment );
67
+ }
68
+ } else {
69
+ // @ToDo have to handle an error
70
+ return;
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ private function get_current_integration_triggered( $hook )
77
+ {
78
+ if( $hook !== false ) {
79
+ foreach( $this->integrations as $integration_name => $integration_info ) {
80
+ if( strpos( $hook, $integration_info['hook'] ) !== false ) {
81
+ return $integration_name;
82
+ }
83
+ }
84
+ }
85
+ return false;
86
+ }
87
  }
lib/Cleantalk/Antispam/Integrations/LandingPageBuilder.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ namespace Cleantalk\Antispam\Integrations;
5
+
6
+
7
+ class LandingPageBuilder extends IntegrationBase
8
+ {
9
+
10
+ function getDataForChecking( $argument )
11
+ {
12
+ if( isset( $_POST ) ) {
13
+ return ct_get_fields_any( $_POST );
14
+ }
15
+ return null;
16
+ }
17
+
18
+ function doBlock( $message )
19
+ {
20
+ $return['Error'] = $message;
21
+ $return['database'] = 'false';
22
+ echo json_encode( $return );
23
+ exit;
24
+ }
25
+ }
lib/Cleantalk/ApbctWP/Firewall/AntiCrawler.php CHANGED
@@ -11,11 +11,13 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
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;
@@ -33,6 +35,7 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
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
 
@@ -43,8 +46,100 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
43
  $this->isExcluded = $this->check_exclusions();
44
 
45
  }
46
-
47
- /**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  * Use this method to execute main logic of the module.
49
  *
50
  * @return array Array of the check results
@@ -60,6 +155,47 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
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'] ) ) {
@@ -77,7 +213,8 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
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 . '`'
@@ -113,6 +250,7 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
113
  add_action( 'wp_head', array( '\Cleantalk\ApbctWP\Firewall\AntiCrawler', 'set_cookie' ) );
114
 
115
  }
 
116
  }
117
 
118
  return $results;
@@ -126,7 +264,7 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
126
  // @todo Rename ip column to sign. Use IP + UserAgent for it.
127
 
128
  foreach( $this->ip_array as $ip_origin => $current_ip ){
129
- $id = md5( $current_ip . $this->ua. $interval_time );
130
  $this->db->execute(
131
  "INSERT INTO " . $this->db__table__ac_logs . " SET
132
  id = '$id',
@@ -158,7 +296,7 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
158
  */
159
  public function update_log( $ip, $status ) {
160
 
161
- $id = md5( $ip . $this->module_name );
162
  $time = time();
163
 
164
  $query = "INSERT INTO " . $this->db__table__logs . "
@@ -168,13 +306,16 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
168
  status = '$status',
169
  all_entries = 1,
170
  blocked_entries = 1,
171
- entries_timestamp = '" . intval( $time ) . "'
 
 
172
  ON DUPLICATE KEY
173
  UPDATE
174
- status = '$status',
175
  all_entries = all_entries + 1,
176
  blocked_entries = blocked_entries" . ( strpos( $status, 'DENY' ) !== false ? ' + 1' : '' ) . ",
177
- entries_timestamp = '" . intval( $time ) . "'";
 
 
178
 
179
  $this->db->execute( $query );
180
  }
11
  public $module_name = 'ANTICRAWLER';
12
 
13
  private $db__table__ac_logs = null;
14
+ private $db__table__ac_ua_bl = null;
15
  private $api_key = '';
16
  private $apbct = false;
17
  private $store_interval = 60;
18
  private $ua; //User-Agent
19
+ private $ua_id = 'null'; //User-Agent
20
+
21
  private $ac_log_result = '';
22
 
23
  public $isExcluded = false;
35
  $this->apbct = $apbct;
36
  $this->db__table__logs = $log_table ?: null;
37
  $this->db__table__ac_logs = $ac_logs_table ?: null;
38
+ $this->db__table__ac_ua_bl= defined('APBCT_TBL_AC_UA_BL') ? APBCT_TBL_AC_UA_BL : null;
39
  $this->ua = md5( Server::get('HTTP_USER_AGENT') );
40
 
41
 
46
  $this->isExcluded = $this->check_exclusions();
47
 
48
  }
49
+
50
+ public static function update( $file_url_ua ) {
51
+
52
+ $response_code = \Cleantalk\ApbctWP\Helper::http__request__get_response_code( $file_url_ua );
53
+
54
+ if( empty( $response_code['error'] ) ){
55
+
56
+ if( $response_code == 200 || $response_code == 501 ){
57
+
58
+ $gz_data = \Cleantalk\ApbctWP\Helper::http__request__get_content( $file_url_ua );
59
+
60
+ if( empty( $gz_data['error'] ) ){
61
+
62
+ if( Helper::get_mime_type( $gz_data, 'application/x-gzip' ) ){
63
+
64
+ if( function_exists( 'gzdecode' ) ){
65
+
66
+ $data = gzdecode( $gz_data );
67
+
68
+ if( $data !== false ){
69
+
70
+ $result__clear_db = self::clear_data_table( \Cleantalk\ApbctWP\DB::getInstance(), APBCT_TBL_AC_UA_BL );
71
+
72
+ if( empty( $result__clear_db['error'] ) ){
73
+
74
+ $lines = Helper::buffer__parse__csv( $data );
75
+
76
+ reset( $lines );
77
+
78
+ for( $count_result = 0; current($lines) !== false; ) {
79
+
80
+ $query = "INSERT INTO " . APBCT_TBL_AC_UA_BL . " (id, ua_template, ua_status) VALUES ";
81
+
82
+ for( $i = 0, $values = array(); APBCT_WRITE_LIMIT !== $i && current( $lines ) !== false; $i ++, $count_result ++, next( $lines ) ){
83
+
84
+ $entry = current($lines);
85
+
86
+ if(empty($entry))
87
+ continue;
88
+
89
+ if ( APBCT_WRITE_LIMIT !== $i ) {
90
+
91
+ // Cast result to int
92
+ // @ToDo check the output $entry
93
+ $ua_id = preg_replace('/[^\d]*/', '', $entry[0]);
94
+ $ua_template = isset($entry[1]) && apbct_is_regexp($entry[1]) ? Helper::db__prepare_param( $entry[1] ) : 0;
95
+ $ua_status = isset($entry[2]) ? $entry[2] : 0;
96
+
97
+ }
98
+
99
+ $values[] = '('. $ua_id .','. $ua_template .','. $ua_status .')';
100
+
101
+ }
102
+
103
+ if( ! empty( $values ) ){
104
+ $query = $query . implode( ',', $values ) . ';';
105
+ \Cleantalk\ApbctWP\DB::getInstance()->execute( $query );
106
+ }
107
+
108
+ }
109
+ return $count_result;
110
+ }else
111
+ return $result__clear_db;
112
+ }else
113
+ return array('error' => 'COULD_DECODE_MULTIFILE');
114
+ }else
115
+ return array('error' => 'FUNCTION_GZ_DECODE_DOES_NOT_EXIST');
116
+ }else
117
+ return array('error' => 'WRONG_MULTIFILE_MIME_TYPE');
118
+ }else
119
+ return array('error' => 'COULD_NOT_GET_MULTIFILE: ' . $gz_data['error'] );
120
+ }else
121
+ return array('error' => 'MULTIFILE_BAD_RESPONSE_CODE: '. (int) $response_code );
122
+ }else
123
+ return array('error' => 'MULTIFILE_COULD_NOT_GET_RESPONSE_CODE: '. $response_code['error'] );
124
+
125
+ }
126
+
127
+ private static function clear_data_table($db, $db__table__data) {
128
+
129
+ $db->execute( "TRUNCATE TABLE {$db__table__data};" );
130
+ $db->set_query( "SELECT COUNT(*) as cnt FROM {$db__table__data};" )->fetch(); // Check if it is clear
131
+ if( $db->result['cnt'] != 0 ){
132
+ $db->execute( "DELETE FROM {$db__table__data};" ); // Truncate table
133
+ $db->set_query( "SELECT COUNT(*) as cnt FROM {$db__table__data};" )->fetch(); // Check if it is clear
134
+ if( $db->result['cnt'] != 0 ){
135
+ return array( 'error' => 'COULD_NOT_CLEAR_UA_BL_TABLE' ); // throw an error
136
+ }
137
+ }
138
+ $db->execute( "ALTER TABLE {$db__table__data} AUTO_INCREMENT = 1;" ); // Drop AUTO INCREMENT
139
+
140
+ }
141
+
142
+ /**
143
  * Use this method to execute main logic of the module.
144
  *
145
  * @return array Array of the check results
155
  $results[] = array( 'ip' => $current_ip, 'is_personal' => false, 'status' => 'PASS_ANTICRAWLER', );
156
  return $results;
157
  }
158
+
159
+ // UA check
160
+ if( $this->apbct->settings['sfw__anti_crawler_ua'] ) {
161
+
162
+ $ua_bl_results = $this->db->fetch_all(
163
+ "SELECT * FROM " . $this->db__table__ac_ua_bl . " ORDER BY `ua_status` DESC;"
164
+ );
165
+
166
+ if( ! empty( $ua_bl_results ) ){
167
+
168
+ $is_blocked = false;
169
+
170
+ foreach( $ua_bl_results as $ua_bl_result ){
171
+
172
+ if( ! empty( $ua_bl_result['ua_template'] ) && preg_match( "$". str_replace( '"', '', $ua_bl_result['ua_template'] ) ."$", Server::get('HTTP_USER_AGENT') ) ) {
173
+
174
+ $this->ua_id = $ua_bl_result['id'];
175
+
176
+ if( $ua_bl_result['ua_status'] == 1 ) {
177
+ // Whitelisted
178
+ $results[] = array('ip' => $current_ip, 'is_personal' => false, 'status' => 'PASS_ANTICRAWLER_UA',);
179
+ return $results;
180
+ break;
181
+ } else {
182
+ // Blacklisted
183
+ $results[] = array('ip' => $current_ip, 'is_personal' => false, 'status' => 'DENY_ANTICRAWLER_UA',);
184
+ $is_blocked = true;
185
+ break;
186
+ }
187
+
188
+ }
189
+
190
+ }
191
+
192
+ if( ! $is_blocked ) {
193
+ $results[] = array('ip' => $current_ip, 'is_personal' => false, 'status' => 'PASS_ANTICRAWLER_UA',);
194
+ }
195
+
196
+ }
197
+
198
+ }
199
 
200
  // Skip by cookie
201
  if( Cookie::get('apbct_antibot') == hash( 'sha256', $this->api_key . $this->apbct->data['salt'] ) ) {
213
 
214
  // Common check
215
  foreach( $this->ip_array as $ip_origin => $current_ip ){
216
+
217
+ // IP check
218
  $result = $this->db->fetch(
219
  "SELECT ip"
220
  . ' FROM `' . $this->db__table__ac_logs . '`'
250
  add_action( 'wp_head', array( '\Cleantalk\ApbctWP\Firewall\AntiCrawler', 'set_cookie' ) );
251
 
252
  }
253
+
254
  }
255
 
256
  return $results;
264
  // @todo Rename ip column to sign. Use IP + UserAgent for it.
265
 
266
  foreach( $this->ip_array as $ip_origin => $current_ip ){
267
+ $id = md5( $current_ip . $this->ua . $interval_time );
268
  $this->db->execute(
269
  "INSERT INTO " . $this->db__table__ac_logs . " SET
270
  id = '$id',
296
  */
297
  public function update_log( $ip, $status ) {
298
 
299
+ $id = md5( $ip . $status . $this->module_name );
300
  $time = time();
301
 
302
  $query = "INSERT INTO " . $this->db__table__logs . "
306
  status = '$status',
307
  all_entries = 1,
308
  blocked_entries = 1,
309
+ entries_timestamp = '" . intval( $time ) . "',
310
+ ua_id = " . $this->ua_id . ",
311
+ ua_name = '" . Server::get('HTTP_USER_AGENT') . "'
312
  ON DUPLICATE KEY
313
  UPDATE
 
314
  all_entries = all_entries + 1,
315
  blocked_entries = blocked_entries" . ( strpos( $status, 'DENY' ) !== false ? ' + 1' : '' ) . ",
316
+ entries_timestamp = '" . intval( $time ) . "',
317
+ ua_id = " . $this->ua_id . ",
318
+ ua_name = '" . Server::get('HTTP_USER_AGENT') . "'";
319
 
320
  $this->db->execute( $query );
321
  }
lib/Cleantalk/ApbctWP/Firewall/SFW.php CHANGED
@@ -314,6 +314,8 @@ class SFW extends \Cleantalk\Common\Firewall\FirewallModule {
314
  // Converting statuses to API format
315
  $value['status'] = $value['status'] === 'DENY_ANTICRAWLER' ? 'BOT_PROTECTION' : $value['status'];
316
  $value['status'] = $value['status'] === 'PASS_ANTICRAWLER' ? 'BOT_PROTECTION' : $value['status'];
 
 
317
 
318
  $value['status'] = $value['status'] === 'DENY_ANTIFLOOD' ? 'FLOOD_PROTECTION' : $value['status'];
319
  $value['status'] = $value['status'] === 'PASS_ANTIFLOOD' ? 'FLOOD_PROTECTION' : $value['status'];
@@ -330,7 +332,10 @@ class SFW extends \Cleantalk\Common\Firewall\FirewallModule {
330
 
331
  if( $value['status'] )
332
  $row[] = $value['status'];
333
-
 
 
 
334
  $data[] = $row;
335
 
336
  }
@@ -369,16 +374,26 @@ class SFW extends \Cleantalk\Common\Firewall\FirewallModule {
369
  * @return array|bool array('error' => STRING)
370
  */
371
  public static function update( $db, $db__table__data, $ct_key, $file_url = null, $immediate = false){
372
-
 
 
373
  // Getting remote file name
374
  if(!$file_url){
375
 
376
- $result = \Cleantalk\Common\API::method__get_2s_blacklists_db($ct_key, 'multifiles', '2_0');
377
 
378
  sleep(4);
379
 
380
  if( empty( $result['error'] ) ){
381
-
 
 
 
 
 
 
 
 
382
  if( ! empty( $result['file_url'] ) ){
383
 
384
  $file_url = trim( $result['file_url'] );
314
  // Converting statuses to API format
315
  $value['status'] = $value['status'] === 'DENY_ANTICRAWLER' ? 'BOT_PROTECTION' : $value['status'];
316
  $value['status'] = $value['status'] === 'PASS_ANTICRAWLER' ? 'BOT_PROTECTION' : $value['status'];
317
+ $value['status'] = $value['status'] === 'DENY_ANTICRAWLER_UA' ? 'BOT_PROTECTION' : $value['status'];
318
+ $value['status'] = $value['status'] === 'PASS_ANTICRAWLER_UA' ? 'BOT_PROTECTION' : $value['status'];
319
 
320
  $value['status'] = $value['status'] === 'DENY_ANTIFLOOD' ? 'FLOOD_PROTECTION' : $value['status'];
321
  $value['status'] = $value['status'] === 'PASS_ANTIFLOOD' ? 'FLOOD_PROTECTION' : $value['status'];
332
 
333
  if( $value['status'] )
334
  $row[] = $value['status'];
335
+
336
+ $row[] = $value['ua_name']; // User-Agent name
337
+ $row[] = $value['ua_id']; // User-Agent ID
338
+
339
  $data[] = $row;
340
 
341
  }
374
  * @return array|bool array('error' => STRING)
375
  */
376
  public static function update( $db, $db__table__data, $ct_key, $file_url = null, $immediate = false){
377
+
378
+ global $apbct;
379
+
380
  // Getting remote file name
381
  if(!$file_url){
382
 
383
+ $result = \Cleantalk\Common\API::method__get_2s_blacklists_db($ct_key, 'multifiles', '3_0');
384
 
385
  sleep(4);
386
 
387
  if( empty( $result['error'] ) ){
388
+
389
+ // User Agents blacklist
390
+ if( ! empty( $result['file_ua_url'] ) && $apbct->settings['sfw__anti_crawler'] ){
391
+ $ua_bl_res = AntiCrawler::update( trim( $result['file_ua_url'] ) );
392
+ if( ! empty( $ua_bl_res['error'] ) )
393
+ $apbct->error_add( 'sfw_update', $ua_bl_res['error'] );
394
+ }
395
+
396
+ // Common blacklist
397
  if( ! empty( $result['file_url'] ) ){
398
 
399
  $file_url = trim( $result['file_url'] );
lib/Cleantalk/ApbctWP/State.php CHANGED
@@ -61,6 +61,7 @@ class State
61
  'sfw__anti_flood' => 0,
62
  'sfw__anti_flood__view_limit' => 10,
63
  'sfw__anti_crawler' => 0,
 
64
  'apikey' => '',
65
  'autoPubRevelantMess' => 0,
66
 
61
  'sfw__anti_flood' => 0,
62
  'sfw__anti_flood__view_limit' => 10,
63
  'sfw__anti_crawler' => 0,
64
+ 'sfw__anti_crawler_ua' => 0,
65
  'apikey' => '',
66
  'autoPubRevelantMess' => 0,
67
 
lib/Cleantalk/Common/API.php CHANGED
@@ -1,796 +1,796 @@
1
- <?php
2
-
3
- namespace Cleantalk\Common;
4
-
5
- /**
6
- * CleanTalk API class.
7
- * Mostly contains wrappers for API methods. Check and send mehods.
8
- * Compatible with any CMS.
9
- *
10
- * @version 3.3
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
- class API
17
- {
18
- /* Default params */
19
- const URL = 'https://api.cleantalk.org';
20
- const AGENT = 'ct-api-3.2';
21
-
22
- /**
23
- * Wrapper for 2s_blacklists_db API method.
24
- * Gets data for SpamFireWall.
25
- *
26
- * @param string $api_key
27
- * @param null|string $out Data output type (JSON or file URL)
28
- * @param string $version API method version
29
- * @param boolean $do_check
30
- *
31
- * @return mixed|string|array('error' => STRING)
32
- */
33
- static public function method__get_2s_blacklists_db($api_key, $out = null, $version = '1_0', $do_check = true)
34
- {
35
- $request = array(
36
- 'method_name' => '2s_blacklists_db',
37
- 'auth_key' => $api_key,
38
- 'out' => $out,
39
- 'version' => $version,
40
- );
41
-
42
- $result = static::send_request($request);
43
- $result = $do_check ? static::check_response($result, '2s_blacklists_db') : $result;
44
-
45
- return $result;
46
- }
47
-
48
- /**
49
- * Wrapper for get_api_key API method.
50
- * Gets access key automatically.
51
- *
52
- * @param string $product_name Type of product
53
- * @param string $email Website admin email
54
- * @param string $website Website host
55
- * @param string $platform Website platform
56
- * @param string|null $timezone
57
- * @param string|null $language
58
- * @param string|null $user_ip
59
- * @param bool $wpms
60
- * @param bool $white_label
61
- * @param string $hoster_api_key
62
- * @param bool $do_check
63
- *
64
- * @return array|bool|mixed
65
- */
66
- static public function method__get_api_key($product_name, $email, $website, $platform, $timezone = null, $language = null, $user_ip = null, $wpms = false, $white_label = false, $hoster_api_key = '', $do_check = true)
67
- {
68
- $request = array(
69
- 'method_name' => 'get_api_key',
70
- 'product_name' => $product_name,
71
- 'email' => $email,
72
- 'website' => $website,
73
- 'platform' => $platform,
74
- 'timezone' => $timezone,
75
- 'http_accept_language' => $language,
76
- 'user_ip' => $user_ip,
77
- 'wpms_setup' => $wpms,
78
- 'hoster_whitelabel' => $white_label,
79
- 'hoster_api_key' => $hoster_api_key,
80
- );
81
-
82
- $result = static::send_request($request);
83
- $result = $do_check ? static::check_response($result, 'get_api_key') : $result;
84
-
85
- return $result;
86
- }
87
-
88
- /**
89
- * Wrapper for get_antispam_report API method.
90
- * Gets spam report.
91
- *
92
- * @param string $host website host
93
- * @param integer $period report days
94
- * @param boolean $do_check
95
- *
96
- * @return array|bool|mixed
97
- */
98
- static public function method__get_antispam_report($host, $period = 1, $do_check = true)
99
- {
100
- $request = Array(
101
- 'method_name' => 'get_antispam_report',
102
- 'hostname' => $host,
103
- 'period' => $period
104
- );
105
-
106
- $result = static::send_request($request);
107
- $result = $do_check ? static::check_response($result, 'get_antispam_report') : $result;
108
-
109
- return $result;
110
- }
111
-
112
- /**
113
- * Wrapper for get_antispam_report_breif API method.
114
- * Ggets spam statistics.
115
- *
116
- * @param string $api_key
117
- * @param bool $do_check
118
- *
119
- * @return array|bool|mixed
120
- */
121
- static public function method__get_antispam_report_breif($api_key, $do_check = true)
122
- {
123
- $request = array(
124
- 'method_name' => 'get_antispam_report_breif',
125
- 'auth_key' => $api_key,
126
- );
127
-
128
- $result = static::send_request($request);
129
- $result = $do_check ? static::check_response($result, 'get_antispam_report_breif') : $result;
130
-
131
- return $result;
132
- }
133
-
134
- /**
135
- * Wrapper for notice_paid_till API method.
136
- * Gets information about renew notice.
137
- *
138
- * @param string $api_key API key
139
- * @param string $path_to_cms Website URL
140
- * @param string $product_name
141
- * @param bool $do_check
142
- *
143
- * @return array|bool|mixed
144
- */
145
- static public function method__notice_paid_till($api_key, $path_to_cms, $product_name = 'antispam', $do_check = true)
146
- {
147
- $request = array(
148
- 'method_name' => 'notice_paid_till',
149
- 'path_to_cms' => $path_to_cms,
150
- 'auth_key' => $api_key,
151
- );
152
-
153
- $product_id = null;
154
- $product_id = $product_name == 'antispam' ? 1 : $product_id;
155
- $product_id = $product_name == 'anti-spam-hosting' ? 3 : $product_id;
156
- $product_id = $product_name == 'security' ? 4 : $product_id;
157
- if($product_id)
158
- $request['product_id'] = $product_id;
159
-
160
- $result = static::send_request($request);
161
- $result = $do_check ? static::check_response($result, 'notice_paid_till') : $result;
162
-
163
- return $result;
164
- }
165
-
166
- /**
167
- * Wrapper for ip_info API method.
168
- * Gets IP country.
169
- *
170
- * @param string $data
171
- * @param bool $do_check
172
- *
173
- * @return array|bool|mixed
174
- */
175
- static public function method__ip_info($data, $do_check = true)
176
- {
177
- $request = array(
178
- 'method_name' => 'ip_info',
179
- 'data' => $data
180
- );
181
-
182
- $result = static::send_request($request);
183
- $result = $do_check ? static::check_response($result, 'ip_info') : $result;
184
- return $result;
185
- }
186
-
187
- /**
188
- * Wrapper for spam_check_cms API method.
189
- * Checks IP|email via CleanTalk's database.
190
- *
191
- * @param string $api_key
192
- * @param array $data
193
- * @param null|string $date
194
- * @param bool $do_check
195
- *
196
- * @return array|bool|mixed
197
- */
198
- static public function method__spam_check_cms($api_key, $data, $date = null, $do_check = true)
199
- {
200
- $request = Array(
201
- 'method_name' => 'spam_check_cms',
202
- 'auth_key' => $api_key,
203
- 'data' => is_array($data) ? implode(',', $data) : $data,
204
- );
205
-
206
- if($date) $request['date'] = $date;
207
-
208
- $result = static::send_request($request, self::URL, 20);
209
- $result = $do_check ? static::check_response($result, 'spam_check_cms') : $result;
210
-
211
- return $result;
212
- }
213
-
214
- /**
215
- * Wrapper for spam_check API method.
216
- * Checks IP|email via CleanTalk's database.
217
- *
218
- * @param string $api_key
219
- * @param array $data
220
- * @param null|string $date
221
- * @param bool $do_check
222
- *
223
- * @return array|bool|mixed
224
- */
225
- static public function method__spam_check($api_key, $data, $date = null, $do_check = true)
226
- {
227
- $request = Array(
228
- 'method_name' => 'spam_check',
229
- 'auth_key' => $api_key,
230
- 'data' => is_array($data) ? implode(',', $data) : $data,
231
- );
232
-
233
- if($date) $request['date'] = $date;
234
-
235
- $result = static::send_request($request, self::URL, 10);
236
- $result = $do_check ? static::check_response($result, 'spam_check') : $result;
237
-
238
- return $result;
239
- }
240
-
241
- /**
242
- * Wrapper for sfw_logs API method.
243
- * Sends SpamFireWall logs to the cloud.
244
- *
245
- * @param string $api_key
246
- * @param array $data
247
- * @param bool $do_check
248
- *
249
- * @return array|bool|mixed
250
- */
251
- static public function method__sfw_logs($api_key, $data, $do_check = true)
252
- {
253
-
254
- $request = array(
255
- 'auth_key' => $api_key,
256
- 'method_name' => 'sfw_logs',
257
- 'data' => json_encode($data),
258
- 'rows' => count($data),
259
- 'timestamp' => time()
260
- );
261
-
262
- $result = static::send_request($request);
263
- $result = $do_check ? static::check_response($result, 'sfw_logs') : $result;
264
-
265
- return $result;
266
- }
267
-
268
- /**
269
- * Wrapper for security_logs API method.
270
- * Sends security logs to the cloud.
271
- *
272
- * @param string $api_key
273
- * @param array $data
274
- * @param bool $do_check
275
- *
276
- * @return array|bool|mixed
277
- */
278
- static public function method__security_logs($api_key, $data, $do_check = true)
279
- {
280
- $request = array(
281
- 'auth_key' => $api_key,
282
- 'method_name' => 'security_logs',
283
- 'timestamp' => current_time('timestamp'),
284
- 'data' => json_encode($data),
285
- 'rows' => count($data),
286
- );
287
-
288
- $result = static::send_request($request);
289
- $result = $do_check ? static::check_response($result, 'security_logs') : $result;
290
-
291
- return $result;
292
- }
293
-
294
- /**
295
- * Wrapper for security_logs API method.
296
- * Sends Securitty Firewall logs to the cloud.
297
- *
298
- * @param string $api_key
299
- * @param array $data
300
- * @param bool $do_check
301
- *
302
- * @return array|bool|mixed
303
- */
304
- static public function method__security_logs__sendFWData($api_key, $data, $do_check = true)
305
- {
306
-
307
- $request = array(
308
- 'auth_key' => $api_key,
309
- 'method_name' => 'security_logs',
310
- 'timestamp' => current_time('timestamp'),
311
- 'data_fw' => json_encode($data),
312
- 'rows_fw' => count($data),
313
- );
314
-
315
- $result = static::send_request($request);
316
- $result = $do_check ? static::check_response($result, 'security_logs') : $result;
317
-
318
- return $result;
319
- }
320
-
321
- /**
322
- * Wrapper for security_logs API method.
323
- * Sends empty data to the cloud to syncronize version.
324
- *
325
- * @param string $api_key
326
- * @param bool $do_check
327
- *
328
- * @return array|bool|mixed
329
- */
330
- static public function method__security_logs__feedback($api_key, $do_check = true)
331
- {
332
- $request = array(
333
- 'auth_key' => $api_key,
334
- 'method_name' => 'security_logs',
335
- 'data' => '0',
336
- );
337
-
338
- $result = static::send_request($request);
339
- $result = $do_check ? static::check_response($result, 'security_logs') : $result;
340
-
341
- return $result;
342
- }
343
-
344
- /**
345
- * Wrapper for security_firewall_data API method.
346
- * Gets Securitty Firewall data to write to the local database.
347
- *
348
- * @param string $api_key
349
- * @param bool $do_check
350
- *
351
- * @return array|bool|mixed
352
- */
353
- static public function method__security_firewall_data($api_key, $do_check = true)
354
- {
355
-
356
- $request = array(
357
- 'auth_key' => $api_key,
358
- 'method_name' => 'security_firewall_data',
359
- );
360
-
361
- $result = static::send_request($request);
362
- $result = $do_check ? static::check_response($result, 'security_firewall_data') : $result;
363
-
364
- return $result;
365
- }
366
-
367
- /**
368
- * Wrapper for security_firewall_data_file API method.
369
- * Gets URI with security firewall data in .csv.gz file to write to the local database.
370
- *
371
- * @param string $api_key
372
- * @param bool $do_check
373
- *
374
- * @return array|bool|mixed
375
- */
376
- static public function method__security_firewall_data_file($api_key, $do_check = true)
377
- {
378
-
379
- $request = array(
380
- 'auth_key' => $api_key,
381
- 'method_name' => 'security_firewall_data_file',
382
- );
383
-
384
- $result = static::send_request($request);
385
- $result = $do_check ? static::check_response($result, 'security_firewall_data_file') : $result;
386
-
387
- return $result;
388
- }
389
-
390
- /**
391
- * Wrapper for security_linksscan_logs API method.
392
- * Send data to the cloud about scanned links.
393
- *
394
- * @param string $api_key
395
- * @param string $scan_time Datetime of scan
396
- * @param bool $scan_result
397
- * @param int $links_total
398
- * @param array $links_list
399
- * @param bool $do_check
400
- *
401
- * @return array|bool|mixed
402
- */
403
- static public function method__security_linksscan_logs($api_key, $scan_time, $scan_result, $links_total, $links_list, $do_check = true)
404
- {
405
- $request = array(
406
- 'auth_key' => $api_key,
407
- 'method_name' => 'security_linksscan_logs',
408
- 'started' => $scan_time,
409
- 'result' => $scan_result,
410
- 'total_links_found' => $links_total,
411
- 'links_list' => $links_list,
412
- );
413
-
414
- $result = static::send_request($request);
415
- $result = $do_check ? static::check_response($result, 'security_linksscan_logs') : $result;
416
-
417
- return $result;
418
- }
419
-
420
- /**
421
- * Wrapper for security_mscan_logs API method.
422
- * Sends result of file scan to the cloud.
423
- *
424
- * @param string $api_key
425
- * @param int $service_id
426
- * @param string $scan_time Datetime of scan
427
- * @param bool $scan_result
428
- * @param int $scanned_total
429
- * @param array $modified List of modified files with details
430
- * @param array $unknown List of modified files with details
431
- * @param bool $do_check
432
- *
433
- * @return array|bool|mixed
434
- */
435
- static public function method__security_mscan_logs($api_key, $service_id, $scan_time, $scan_result, $scanned_total, $modified, $unknown, $do_check = true)
436
- {
437
- $request = array(
438
- 'method_name' => 'security_mscan_logs',
439
- 'auth_key' => $api_key,
440
- 'service_id' => $service_id,
441
- 'started' => $scan_time,
442
- 'result' => $scan_result,
443
- 'total_core_files' => $scanned_total,
444
- );
445
-
446
- if(!empty($modified)){
447
- $request['failed_files'] = json_encode($modified);
448
- $request['failed_files_rows'] = count($modified);
449
- }
450
- if(!empty($unknown)){
451
- $request['unknown_files'] = json_encode($unknown);
452
- $request['unknown_files_rows'] = count($unknown);
453
- }
454
-
455
- $result = static::send_request($request);
456
- $result = $do_check ? static::check_response($result, 'security_mscan_logs') : $result;
457
-
458
- return $result;
459
- }
460
-
461
- /**
462
- * Wrapper for security_mscan_files API method.
463
- * Sends file to the cloud for analysis.
464
- *
465
- * @param string $api_key
466
- * @param string $file_path Path to the file
467
- * @param array $file File itself
468
- * @param string $file_md5 MD5 hash of file
469
- * @param array $weak_spots List of weak spots found in file
470
- * @param bool $do_check
471
- *
472
- * @return array|bool|mixed
473
- */
474
- static public function method__security_mscan_files($api_key, $file_path, $file, $file_md5, $weak_spots, $do_check = true)
475
- {
476
- $request = array(
477
- 'method_name' => 'security_mscan_files',
478
- 'auth_key' => $api_key,
479
- 'path_to_sfile' => $file_path,
480
- 'attached_sfile' => $file,
481
- 'md5sum_sfile' => $file_md5,
482
- 'dangerous_code' => $weak_spots,
483
- );
484
-
485
- $result = static::send_request($request);
486
- $result = $do_check ? static::check_response($result, 'security_mscan_files') : $result;
487
-
488
- return $result;
489
- }
490
-
491
- /**
492
- * Wrapper for get_antispam_report API method.
493
- * Function gets spam domains report.
494
- *
495
- * @param string $api_key
496
- * @param array|string|mixed $data
497
- * @param string $date
498
- * @param bool $do_check
499
- *
500
- * @return array|bool|mixed
501
- */
502
- static public function method__backlinks_check_cms($api_key, $data, $date = null, $do_check = true)
503
- {
504
- $request = array(
505
- 'method_name' => 'backlinks_check_cms',
506
- 'auth_key' => $api_key,
507
- 'data' => is_array($data) ? implode(',', $data) : $data,
508
- );
509
-
510
- if($date) $request['date'] = $date;
511
-
512
- $result = static::send_request($request);
513
- $result = $do_check ? static::check_response($result, 'backlinks_check_cms') : $result;
514
-
515
- return $result;
516
- }
517
-
518
- /**
519
- * Wrapper for get_antispam_report API method.
520
- * Function gets spam domains report
521
- *
522
- * @param string $api_key
523
- * @param array $logs
524
- * @param bool $do_check
525
- *
526
- * @return array|bool|mixed
527
- */
528
- static public function method__security_backend_logs($api_key, $logs, $do_check = true)
529
- {
530
- $request = array(
531
- 'method_name' => 'security_backend_logs',
532
- 'auth_key' => $api_key,
533
- 'logs' => json_encode($logs),
534
- 'total_logs' => count($logs),
535
- );
536
-
537
- $result = static::send_request($request);
538
- $result = $do_check ? static::check_response($result, 'security_backend_logs') : $result;
539
-
540
- return $result;
541
- }
542
-
543
- /**
544
- * Wrapper for get_antispam_report API method.
545
- * Sends data about auto repairs
546
- *
547
- * @param string $api_key
548
- * @param bool $repair_result
549
- * @param string $repair_comment
550
- * @param $repaired_processed_files
551
- * @param $repaired_total_files_proccessed
552
- * @param $backup_id
553
- * @param bool $do_check
554
- *
555
- * @return array|bool|mixed
556
- */
557
- static public function method__security_mscan_repairs($api_key, $repair_result, $repair_comment, $repaired_processed_files, $repaired_total_files_proccessed, $backup_id, $do_check = true)
558
- {
559
- $request = array(
560
- 'method_name' => 'security_mscan_repairs',
561
- 'auth_key' => $api_key,
562
- 'repair_result' => $repair_result,
563
- 'repair_comment' => $repair_comment,
564
- 'repair_processed_files' => json_encode($repaired_processed_files),
565
- 'repair_total_files_processed' => $repaired_total_files_proccessed,
566
- 'backup_id' => $backup_id,
567
- 'mscan_log_id' => 1,
568
- );
569
-
570
- $result = static::send_request($request);
571
- $result = $do_check ? static::check_response($result, 'security_mscan_repairs') : $result;
572
-
573
- return $result;
574
- }
575
-
576
- /**
577
- * Wrapper for get_antispam_report API method.
578
- * Force server to update checksums for specific plugin\theme
579
- *
580
- * @param string $api_key
581
- * @param string $plugins_and_themes_to_refresh
582
- * @param bool $do_check
583
- *
584
- * @return array|bool|mixed
585
- */
586
- static public function method__request_checksums($api_key, $plugins_and_themes_to_refresh, $do_check = true)
587
- {
588
- $request = array(
589
- 'method_name' => 'request_checksums',
590
- 'auth_key' => $api_key,
591
- 'data' => $plugins_and_themes_to_refresh
592
- );
593
-
594
- $result = static::send_request($request);
595
- $result = $do_check ? static::check_response($result, 'request_checksums') : $result;
596
-
597
- return $result;
598
- }
599
-
600
- /**
601
- * Function sends raw request to API server
602
- *
603
- * @param array $data to send
604
- * @param string $url of API server
605
- * @param integer $timeout timeout in seconds
606
- * @param boolean $ssl use ssl on not
607
- *
608
- * @return array|bool
609
- */
610
- static public function send_request($data, $url = self::URL, $timeout = 10, $ssl = false, $ssl_path = '')
611
- {
612
- // Possibility to switch agent vaersion
613
- $data['agent'] = !empty($data['agent'])
614
- ? $data['agent']
615
- : (defined('CLEANTALK_AGENT') ? CLEANTALK_AGENT : self::AGENT);
616
-
617
- // Make URL string
618
- $data_string = http_build_query($data);
619
- $data_string = str_replace("&amp;", "&", $data_string);
620
-
621
- // For debug purposes
622
- if(defined('CLEANTALK_DEBUG') && CLEANTALK_DEBUG){
623
- global $apbct_debug;
624
- $apbct_debug['sent_data'] = $data;
625
- $apbct_debug['request_string'] = $data_string;
626
- }
627
-
628
- // Possibility to switch API url
629
- $url = defined('CLEANTALK_API_URL') ? CLEANTALK_API_URL : $url;
630
-
631
- if(function_exists('curl_init')){
632
-
633
- $ch = curl_init();
634
-
635
- // Set diff options
636
- curl_setopt($ch, CURLOPT_URL, $url);
637
- curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
638
- curl_setopt($ch, CURLOPT_POST, true);
639
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
640
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
641
- curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
642
-
643
- $ssl_path = $ssl_path
644
- ? $ssl_path
645
- : (defined('CLEANTALK_CASERT_PATH') ? CLEANTALK_CASERT_PATH : '');
646
-
647
- // Switch on/off SSL
648
- if($ssl && $ssl_path){
649
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
650
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
651
- curl_setopt($ch, CURLOPT_CAINFO, $ssl_path);
652
- }else{
653
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
654
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
655
- }
656
-
657
- // Make a request
658
- $result = curl_exec($ch);
659
- $errors = curl_error($ch);
660
- curl_close($ch);
661
-
662
- // Retry with SSL enabled if failed
663
- if($result === false){
664
- if($ssl === false){
665
- return self::send_request($data, $url, $timeout, true, $ssl_path);
666
- }
667
- if (function_exists('gethostbynamel')) {
668
- $server_ips = gethostbynamel('api.cleantalk.org');
669
- if ($server_ips !== false && is_array($server_ips) && count($server_ips)) {
670
- foreach ($server_ips as $ip) {
671
- if( strpos( $url, $ip ) === false ) {
672
- return self::send_request($data, 'https://'.$ip);
673
- }
674
- }
675
- }
676
- }
677
- }
678
-
679
- }else{
680
- $errors = 'CURL_NOT_INSTALLED';
681
- }
682
-
683
- // Trying to use file_get_contents() to make a API call
684
- if(!empty($errors)){
685
- if(ini_get('allow_url_fopen')){
686
- $opts = array(
687
- 'http' => array(
688
- 'method' => "POST",
689
- 'timeout' => $timeout,
690
- 'content' => $data_string,
691
- ),
692
- );
693
- $context = stream_context_create($opts);
694
- $result = @file_get_contents($url, 0, $context);
695
-
696
- $errors = $result === false
697
- ? $errors . '_FAILED_TO_USE_FILE_GET_CONTENTS'
698
- : false;
699
-
700
- }else{
701
- $errors .= '_AND_ALLOW_URL_FOPEN_IS_DISABLED';
702
- }
703
- }
704
-
705
- return empty($result) || !empty($errors)
706
- ? array('error' => $errors)
707
- : $result;
708
- }
709
-
710
- /**
711
- * Function checks server response
712
- *
713
- * @param array|string $result
714
- * @param string $method_name
715
- *
716
- * @return mixed (array || array('error' => true))
717
- */
718
- static public function check_response($result, $method_name = null)
719
- {
720
- // Errors handling
721
- // Bad connection
722
- if(isset($result['error'])){
723
- $last = error_get_last();
724
- $out = ! empty( $result['error'] )
725
- ? array( 'error' => 'CONNECTION_ERROR : "' . $result['error'] . '"' )
726
- : array( 'error' => 'CONNECTION_ERROR : "Unknown Error. Last error: ' . $last['message'] );
727
- return $out;
728
- }
729
-
730
- // JSON decode errors
731
- $result = json_decode($result, true);
732
- if(empty($result)){
733
- return array(
734
- 'error' => 'JSON_DECODE_ERROR',
735
- );
736
- }
737
-
738
- // Server errors
739
- if( $result && ( isset( $result['error_no'], $result['error_message'] ) ) ){
740
-
741
- if( $result['error_no'] != 12 ){
742
- return array(
743
- 'error' => "SERVER_ERROR NO: {$result['error_no']} MSG: {$result['error_message']}",
744
- 'error_no' => $result['error_no'],
745
- 'error_message' => $result['error_message'],
746
- );
747
- }
748
- }
749
-
750
- // Pathces for different methods
751
- switch($method_name){
752
-
753
- // notice_paid_till
754
- case 'notice_paid_till':
755
-
756
- $result = isset($result['data']) ? $result['data'] : $result;
757
-
758
- if((isset($result['error_no']) && $result['error_no'] == 12) ||
759
- (
760
- !(isset($result['service_id']) && is_int($result['service_id'])) &&
761
- empty($result['moderate_ip'])
762
- )
763
- )
764
- $result['valid'] = 0;
765
- else
766
- $result['valid'] = 1;
767
-
768
- return $result;
769
-
770
- break;
771
-
772
- // get_antispam_report_breif
773
- case 'get_antispam_report_breif':
774
-
775
- $out = isset($result['data']) && is_array($result['data'])
776
- ? $result['data']
777
- : array('error' => 'NO_DATA');
778
-
779
- for($tmp = array(), $i = 0; $i < 7; $i++){
780
- $tmp[date('Y-m-d', time() - 86400 * 7 + 86400 * $i)] = 0;
781
- }
782
- $out['spam_stat'] = (array)array_merge($tmp, isset($out['spam_stat']) ? $out['spam_stat'] : array());
783
- $out['top5_spam_ip'] = isset($out['top5_spam_ip']) ? $out['top5_spam_ip'] : array();
784
-
785
- return $out;
786
-
787
- break;
788
-
789
- default:
790
- return isset($result['data']) && is_array($result['data'])
791
- ? $result['data']
792
- : array('error' => 'NO_DATA');
793
- break;
794
- }
795
- }
796
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\Common;
4
+
5
+ /**
6
+ * CleanTalk API class.
7
+ * Mostly contains wrappers for API methods. Check and send mehods.
8
+ * Compatible with any CMS.
9
+ *
10
+ * @version 3.3
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
+ class API
17
+ {
18
+ /* Default params */
19
+ const URL = 'https://api.cleantalk.org';
20
+ const AGENT = 'ct-api-3.2';
21
+
22
+ /**
23
+ * Wrapper for 2s_blacklists_db API method.
24
+ * Gets data for SpamFireWall.
25
+ *
26
+ * @param string $api_key
27
+ * @param null|string $out Data output type (JSON or file URL)
28
+ * @param string $version API method version
29
+ * @param boolean $do_check
30
+ *
31
+ * @return mixed|string|array('error' => STRING)
32
+ */
33
+ static public function method__get_2s_blacklists_db($api_key, $out = null, $version = '1_0', $do_check = true)
34
+ {
35
+ $request = array(
36
+ 'method_name' => '2s_blacklists_db',
37
+ 'auth_key' => $api_key,
38
+ 'out' => $out,
39
+ 'version' => $version,
40
+ );
41
+
42
+ $result = static::send_request($request);
43
+ $result = $do_check ? static::check_response($result, '2s_blacklists_db') : $result;
44
+
45
+ return $result;
46
+ }
47
+
48
+ /**
49
+ * Wrapper for get_api_key API method.
50
+ * Gets access key automatically.
51
+ *
52
+ * @param string $product_name Type of product
53
+ * @param string $email Website admin email
54
+ * @param string $website Website host
55
+ * @param string $platform Website platform
56
+ * @param string|null $timezone
57
+ * @param string|null $language
58
+ * @param string|null $user_ip
59
+ * @param bool $wpms
60
+ * @param bool $white_label
61
+ * @param string $hoster_api_key
62
+ * @param bool $do_check
63
+ *
64
+ * @return array|bool|mixed
65
+ */
66
+ static public function method__get_api_key($product_name, $email, $website, $platform, $timezone = null, $language = null, $user_ip = null, $wpms = false, $white_label = false, $hoster_api_key = '', $do_check = true)
67
+ {
68
+ $request = array(
69
+ 'method_name' => 'get_api_key',
70
+ 'product_name' => $product_name,
71
+ 'email' => $email,
72
+ 'website' => $website,
73
+ 'platform' => $platform,
74
+ 'timezone' => $timezone,
75
+ 'http_accept_language' => $language,
76
+ 'user_ip' => $user_ip,
77
+ 'wpms_setup' => $wpms,
78
+ 'hoster_whitelabel' => $white_label,
79
+ 'hoster_api_key' => $hoster_api_key,
80
+ );
81
+
82
+ $result = static::send_request($request);
83
+ $result = $do_check ? static::check_response($result, 'get_api_key') : $result;
84
+
85
+ return $result;
86
+ }
87
+
88
+ /**
89
+ * Wrapper for get_antispam_report API method.
90
+ * Gets spam report.
91
+ *
92
+ * @param string $host website host
93
+ * @param integer $period report days
94
+ * @param boolean $do_check
95
+ *
96
+ * @return array|bool|mixed
97
+ */
98
+ static public function method__get_antispam_report($host, $period = 1, $do_check = true)
99
+ {
100
+ $request = Array(
101
+ 'method_name' => 'get_antispam_report',
102
+ 'hostname' => $host,
103
+ 'period' => $period
104
+ );
105
+
106
+ $result = static::send_request($request);
107
+ $result = $do_check ? static::check_response($result, 'get_antispam_report') : $result;
108
+
109
+ return $result;
110
+ }
111
+
112
+ /**
113
+ * Wrapper for get_antispam_report_breif API method.
114
+ * Ggets spam statistics.
115
+ *
116
+ * @param string $api_key
117
+ * @param bool $do_check
118
+ *
119
+ * @return array|bool|mixed
120
+ */
121
+ static public function method__get_antispam_report_breif($api_key, $do_check = true)
122
+ {
123
+ $request = array(
124
+ 'method_name' => 'get_antispam_report_breif',
125
+ 'auth_key' => $api_key,
126
+ );
127
+
128
+ $result = static::send_request($request);
129
+ $result = $do_check ? static::check_response($result, 'get_antispam_report_breif') : $result;
130
+
131
+ return $result;
132
+ }
133
+
134
+ /**
135
+ * Wrapper for notice_paid_till API method.
136
+ * Gets information about renew notice.
137
+ *
138
+ * @param string $api_key API key
139
+ * @param string $path_to_cms Website URL
140
+ * @param string $product_name
141
+ * @param bool $do_check
142
+ *
143
+ * @return array|bool|mixed
144
+ */
145
+ static public function method__notice_paid_till($api_key, $path_to_cms, $product_name = 'antispam', $do_check = true)
146
+ {
147
+ $request = array(
148
+ 'method_name' => 'notice_paid_till',
149
+ 'path_to_cms' => $path_to_cms,
150
+ 'auth_key' => $api_key,
151
+ );
152
+
153
+ $product_id = null;
154
+ $product_id = $product_name == 'antispam' ? 1 : $product_id;
155
+ $product_id = $product_name == 'anti-spam-hosting' ? 3 : $product_id;
156
+ $product_id = $product_name == 'security' ? 4 : $product_id;
157
+ if($product_id)
158
+ $request['product_id'] = $product_id;
159
+
160
+ $result = static::send_request($request);
161
+ $result = $do_check ? static::check_response($result, 'notice_paid_till') : $result;
162
+
163
+ return $result;
164
+ }
165
+
166
+ /**
167
+ * Wrapper for ip_info API method.
168
+ * Gets IP country.
169
+ *
170
+ * @param string $data
171
+ * @param bool $do_check
172
+ *
173
+ * @return array|bool|mixed
174
+ */
175
+ static public function method__ip_info($data, $do_check = true)
176
+ {
177
+ $request = array(
178
+ 'method_name' => 'ip_info',
179
+ 'data' => $data
180
+ );
181
+
182
+ $result = static::send_request($request);
183
+ $result = $do_check ? static::check_response($result, 'ip_info') : $result;
184
+ return $result;
185
+ }
186
+
187
+ /**
188
+ * Wrapper for spam_check_cms API method.
189
+ * Checks IP|email via CleanTalk's database.
190
+ *
191
+ * @param string $api_key
192
+ * @param array $data
193
+ * @param null|string $date
194
+ * @param bool $do_check
195
+ *
196
+ * @return array|bool|mixed
197
+ */
198
+ static public function method__spam_check_cms($api_key, $data, $date = null, $do_check = true)
199
+ {
200
+ $request = Array(
201
+ 'method_name' => 'spam_check_cms',
202
+ 'auth_key' => $api_key,
203
+ 'data' => is_array($data) ? implode(',', $data) : $data,
204
+ );
205
+
206
+ if($date) $request['date'] = $date;
207
+
208
+ $result = static::send_request($request, self::URL, 20);
209
+ $result = $do_check ? static::check_response($result, 'spam_check_cms') : $result;
210
+
211
+ return $result;
212
+ }
213
+
214
+ /**
215
+ * Wrapper for spam_check API method.
216
+ * Checks IP|email via CleanTalk's database.
217
+ *
218
+ * @param string $api_key
219
+ * @param array $data
220
+ * @param null|string $date
221
+ * @param bool $do_check
222
+ *
223
+ * @return array|bool|mixed
224
+ */
225
+ static public function method__spam_check($api_key, $data, $date = null, $do_check = true)
226
+ {
227
+ $request = Array(
228
+ 'method_name' => 'spam_check',
229
+ 'auth_key' => $api_key,
230
+ 'data' => is_array($data) ? implode(',', $data) : $data,
231
+ );
232
+
233
+ if($date) $request['date'] = $date;
234
+
235
+ $result = static::send_request($request, self::URL, 10);
236
+ $result = $do_check ? static::check_response($result, 'spam_check') : $result;
237
+
238
+ return $result;
239
+ }
240
+
241
+ /**
242
+ * Wrapper for sfw_logs API method.
243
+ * Sends SpamFireWall logs to the cloud.
244
+ *
245
+ * @param string $api_key
246
+ * @param array $data
247
+ * @param bool $do_check
248
+ *
249
+ * @return array|bool|mixed
250
+ */
251
+ static public function method__sfw_logs($api_key, $data, $do_check = true)
252
+ {
253
+
254
+ $request = array(
255
+ 'auth_key' => $api_key,
256
+ 'method_name' => 'sfw_logs',
257
+ 'data' => json_encode($data),
258
+ 'rows' => count($data),
259
+ 'timestamp' => time()
260
+ );
261
+
262
+ $result = static::send_request($request);
263
+ $result = $do_check ? static::check_response($result, 'sfw_logs') : $result;
264
+
265
+ return $result;
266
+ }
267
+
268
+ /**
269
+ * Wrapper for security_logs API method.
270
+ * Sends security logs to the cloud.
271
+ *
272
+ * @param string $api_key
273
+ * @param array $data
274
+ * @param bool $do_check
275
+ *
276
+ * @return array|bool|mixed
277
+ */
278
+ static public function method__security_logs($api_key, $data, $do_check = true)
279
+ {
280
+ $request = array(
281
+ 'auth_key' => $api_key,
282
+ 'method_name' => 'security_logs',
283
+ 'timestamp' => current_time('timestamp'),
284
+ 'data' => json_encode($data),
285
+ 'rows' => count($data),
286
+ );
287
+
288
+ $result = static::send_request($request);
289
+ $result = $do_check ? static::check_response($result, 'security_logs') : $result;
290
+
291
+ return $result;
292
+ }
293
+
294
+ /**
295
+ * Wrapper for security_logs API method.
296
+ * Sends Securitty Firewall logs to the cloud.
297
+ *
298
+ * @param string $api_key
299
+ * @param array $data
300
+ * @param bool $do_check
301
+ *
302
+ * @return array|bool|mixed
303
+ */
304
+ static public function method__security_logs__sendFWData($api_key, $data, $do_check = true)
305
+ {
306
+
307
+ $request = array(
308
+ 'auth_key' => $api_key,
309
+ 'method_name' => 'security_logs',
310
+ 'timestamp' => current_time('timestamp'),
311
+ 'data_fw' => json_encode($data),
312
+ 'rows_fw' => count($data),
313
+ );
314
+
315
+ $result = static::send_request($request);
316
+ $result = $do_check ? static::check_response($result, 'security_logs') : $result;
317
+
318
+ return $result;
319
+ }
320
+
321
+ /**
322
+ * Wrapper for security_logs API method.
323
+ * Sends empty data to the cloud to syncronize version.
324
+ *
325
+ * @param string $api_key
326
+ * @param bool $do_check
327
+ *
328
+ * @return array|bool|mixed
329
+ */
330
+ static public function method__security_logs__feedback($api_key, $do_check = true)
331
+ {
332
+ $request = array(
333
+ 'auth_key' => $api_key,
334
+ 'method_name' => 'security_logs',
335
+ 'data' => '0',
336
+ );
337
+
338
+ $result = static::send_request($request);
339
+ $result = $do_check ? static::check_response($result, 'security_logs') : $result;
340
+
341
+ return $result;
342
+ }
343
+
344
+ /**
345
+ * Wrapper for security_firewall_data API method.
346
+ * Gets Securitty Firewall data to write to the local database.
347
+ *
348
+ * @param string $api_key
349
+ * @param bool $do_check
350
+ *
351
+ * @return array|bool|mixed
352
+ */
353
+ static public function method__security_firewall_data($api_key, $do_check = true)
354
+ {
355
+
356
+ $request = array(
357
+ 'auth_key' => $api_key,
358
+ 'method_name' => 'security_firewall_data',
359
+ );
360
+
361
+ $result = static::send_request($request);
362
+ $result = $do_check ? static::check_response($result, 'security_firewall_data') : $result;
363
+
364
+ return $result;
365
+ }
366
+
367
+ /**
368
+ * Wrapper for security_firewall_data_file API method.
369
+ * Gets URI with security firewall data in .csv.gz file to write to the local database.
370
+ *
371
+ * @param string $api_key
372
+ * @param bool $do_check
373
+ *
374
+ * @return array|bool|mixed
375
+ */
376
+ static public function method__security_firewall_data_file($api_key, $do_check = true)
377
+ {
378
+
379
+ $request = array(
380
+ 'auth_key' => $api_key,
381
+ 'method_name' => 'security_firewall_data_file',
382
+ );
383
+
384
+ $result = static::send_request($request);
385
+ $result = $do_check ? static::check_response($result, 'security_firewall_data_file') : $result;
386
+
387
+ return $result;
388
+ }
389
+
390
+ /**
391
+ * Wrapper for security_linksscan_logs API method.
392
+ * Send data to the cloud about scanned links.
393
+ *
394
+ * @param string $api_key
395
+ * @param string $scan_time Datetime of scan
396
+ * @param bool $scan_result
397
+ * @param int $links_total
398
+ * @param array $links_list
399
+ * @param bool $do_check
400
+ *
401
+ * @return array|bool|mixed
402
+ */
403
+ static public function method__security_linksscan_logs($api_key, $scan_time, $scan_result, $links_total, $links_list, $do_check = true)
404
+ {
405
+ $request = array(
406
+ 'auth_key' => $api_key,
407
+ 'method_name' => 'security_linksscan_logs',
408
+ 'started' => $scan_time,
409
+ 'result' => $scan_result,
410
+ 'total_links_found' => $links_total,
411
+ 'links_list' => $links_list,
412
+ );
413
+
414
+ $result = static::send_request($request);
415
+ $result = $do_check ? static::check_response($result, 'security_linksscan_logs') : $result;
416
+
417
+ return $result;
418
+ }
419
+
420
+ /**
421
+ * Wrapper for security_mscan_logs API method.
422
+ * Sends result of file scan to the cloud.
423
+ *
424
+ * @param string $api_key
425
+ * @param int $service_id
426
+ * @param string $scan_time Datetime of scan
427
+ * @param bool $scan_result
428
+ * @param int $scanned_total
429
+ * @param array $modified List of modified files with details
430
+ * @param array $unknown List of modified files with details
431
+ * @param bool $do_check
432
+ *
433
+ * @return array|bool|mixed
434
+ */
435
+ static public function method__security_mscan_logs($api_key, $service_id, $scan_time, $scan_result, $scanned_total, $modified, $unknown, $do_check = true)
436
+ {
437
+ $request = array(
438
+ 'method_name' => 'security_mscan_logs',
439
+ 'auth_key' => $api_key,
440
+ 'service_id' => $service_id,
441
+ 'started' => $scan_time,
442
+ 'result' => $scan_result,
443
+ 'total_core_files' => $scanned_total,
444
+ );
445
+
446
+ if(!empty($modified)){
447
+ $request['failed_files'] = json_encode($modified);
448
+ $request['failed_files_rows'] = count($modified);
449
+ }
450
+ if(!empty($unknown)){
451
+ $request['unknown_files'] = json_encode($unknown);
452
+ $request['unknown_files_rows'] = count($unknown);
453
+ }
454
+
455
+ $result = static::send_request($request);
456
+ $result = $do_check ? static::check_response($result, 'security_mscan_logs') : $result;
457
+
458
+ return $result;
459
+ }
460
+
461
+ /**
462
+ * Wrapper for security_mscan_files API method.
463
+ * Sends file to the cloud for analysis.
464
+ *
465
+ * @param string $api_key
466
+ * @param string $file_path Path to the file
467
+ * @param array $file File itself
468
+ * @param string $file_md5 MD5 hash of file
469
+ * @param array $weak_spots List of weak spots found in file
470
+ * @param bool $do_check
471
+ *
472
+ * @return array|bool|mixed
473
+ */
474
+ static public function method__security_mscan_files($api_key, $file_path, $file, $file_md5, $weak_spots, $do_check = true)
475
+ {
476
+ $request = array(
477
+ 'method_name' => 'security_mscan_files',
478
+ 'auth_key' => $api_key,
479
+ 'path_to_sfile' => $file_path,
480
+ 'attached_sfile' => $file,
481
+ 'md5sum_sfile' => $file_md5,
482
+ 'dangerous_code' => $weak_spots,
483
+ );
484
+
485
+ $result = static::send_request($request);
486
+ $result = $do_check ? static::check_response($result, 'security_mscan_files') : $result;
487
+
488
+ return $result;
489
+ }
490
+
491
+ /**
492
+ * Wrapper for get_antispam_report API method.
493
+ * Function gets spam domains report.
494
+ *
495
+ * @param string $api_key
496
+ * @param array|string|mixed $data
497
+ * @param string $date
498
+ * @param bool $do_check
499
+ *
500
+ * @return array|bool|mixed
501
+ */
502
+ static public function method__backlinks_check_cms($api_key, $data, $date = null, $do_check = true)
503
+ {
504
+ $request = array(
505
+ 'method_name' => 'backlinks_check_cms',
506
+ 'auth_key' => $api_key,
507
+ 'data' => is_array($data) ? implode(',', $data) : $data,
508
+ );
509
+
510
+ if($date) $request['date'] = $date;
511
+
512
+ $result = static::send_request($request);
513
+ $result = $do_check ? static::check_response($result, 'backlinks_check_cms') : $result;
514
+
515
+ return $result;
516
+ }
517
+
518
+ /**
519
+ * Wrapper for get_antispam_report API method.
520
+ * Function gets spam domains report
521
+ *
522
+ * @param string $api_key
523
+ * @param array $logs
524
+ * @param bool $do_check
525
+ *
526
+ * @return array|bool|mixed
527
+ */
528
+ static public function method__security_backend_logs($api_key, $logs, $do_check = true)
529
+ {
530
+ $request = array(
531
+ 'method_name' => 'security_backend_logs',
532
+ 'auth_key' => $api_key,
533
+ 'logs' => json_encode($logs),
534
+ 'total_logs' => count($logs),
535
+ );
536
+
537
+ $result = static::send_request($request);
538
+ $result = $do_check ? static::check_response($result, 'security_backend_logs') : $result;
539
+
540
+ return $result;
541
+ }
542
+
543
+ /**
544
+ * Wrapper for get_antispam_report API method.
545
+ * Sends data about auto repairs
546
+ *
547
+ * @param string $api_key
548
+ * @param bool $repair_result
549
+ * @param string $repair_comment
550
+ * @param $repaired_processed_files
551
+ * @param $repaired_total_files_proccessed
552
+ * @param $backup_id
553
+ * @param bool $do_check
554
+ *
555
+ * @return array|bool|mixed
556
+ */
557
+ static public function method__security_mscan_repairs($api_key, $repair_result, $repair_comment, $repaired_processed_files, $repaired_total_files_proccessed, $backup_id, $do_check = true)
558
+ {
559
+ $request = array(
560
+ 'method_name' => 'security_mscan_repairs',
561
+ 'auth_key' => $api_key,
562
+ 'repair_result' => $repair_result,
563
+ 'repair_comment' => $repair_comment,
564
+ 'repair_processed_files' => json_encode($repaired_processed_files),
565
+ 'repair_total_files_processed' => $repaired_total_files_proccessed,
566
+ 'backup_id' => $backup_id,
567
+ 'mscan_log_id' => 1,
568
+ );
569
+
570
+ $result = static::send_request($request);
571
+ $result = $do_check ? static::check_response($result, 'security_mscan_repairs') : $result;
572
+
573
+ return $result;
574
+ }
575
+
576
+ /**
577
+ * Wrapper for get_antispam_report API method.
578
+ * Force server to update checksums for specific plugin\theme
579
+ *
580
+ * @param string $api_key
581
+ * @param string $plugins_and_themes_to_refresh
582
+ * @param bool $do_check
583
+ *
584
+ * @return array|bool|mixed
585
+ */
586
+ static public function method__request_checksums($api_key, $plugins_and_themes_to_refresh, $do_check = true)
587
+ {
588
+ $request = array(
589
+ 'method_name' => 'request_checksums',
590
+ 'auth_key' => $api_key,
591
+ 'data' => $plugins_and_themes_to_refresh
592
+ );
593
+
594
+ $result = static::send_request($request);
595
+ $result = $do_check ? static::check_response($result, 'request_checksums') : $result;
596
+
597
+ return $result;
598
+ }
599
+
600
+ /**
601
+ * Function sends raw request to API server
602
+ *
603
+ * @param array $data to send
604
+ * @param string $url of API server
605
+ * @param integer $timeout timeout in seconds
606
+ * @param boolean $ssl use ssl on not
607
+ *
608
+ * @return array|bool
609
+ */
610
+ static public function send_request($data, $url = self::URL, $timeout = 10, $ssl = false, $ssl_path = '')
611
+ {
612
+ // Possibility to switch agent vaersion
613
+ $data['agent'] = !empty($data['agent'])
614
+ ? $data['agent']
615
+ : (defined('CLEANTALK_AGENT') ? CLEANTALK_AGENT : self::AGENT);
616
+
617
+ // Make URL string
618
+ $data_string = http_build_query($data);
619
+ $data_string = str_replace("&amp;", "&", $data_string);
620
+
621
+ // For debug purposes
622
+ if(defined('CLEANTALK_DEBUG') && CLEANTALK_DEBUG){
623
+ global $apbct_debug;
624
+ $apbct_debug['sent_data'] = $data;
625
+ $apbct_debug['request_string'] = $data_string;
626
+ }
627
+
628
+ // Possibility to switch API url
629
+ $url = defined('CLEANTALK_API_URL') ? CLEANTALK_API_URL : $url;
630
+
631
+ if(function_exists('curl_init')){
632
+
633
+ $ch = curl_init();
634
+
635
+ // Set diff options
636
+ curl_setopt($ch, CURLOPT_URL, $url);
637
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
638
+ curl_setopt($ch, CURLOPT_POST, true);
639
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
640
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
641
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
642
+
643
+ $ssl_path = $ssl_path
644
+ ? $ssl_path
645
+ : (defined('CLEANTALK_CASERT_PATH') ? CLEANTALK_CASERT_PATH : '');
646
+
647
+ // Switch on/off SSL
648
+ if($ssl && $ssl_path){
649
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
650
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
651
+ curl_setopt($ch, CURLOPT_CAINFO, $ssl_path);
652
+ }else{
653
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
654
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
655
+ }
656
+
657
+ // Make a request
658
+ $result = curl_exec($ch);
659
+ $errors = curl_error($ch);
660
+ curl_close($ch);
661
+
662
+ // Retry with SSL enabled if failed
663
+ if($result === false){
664
+ if($ssl === false){
665
+ return self::send_request($data, $url, $timeout, true, $ssl_path);
666
+ }
667
+ if (function_exists('gethostbynamel')) {
668
+ $server_ips = gethostbynamel('api.cleantalk.org');
669
+ if ($server_ips !== false && is_array($server_ips) && count($server_ips)) {
670
+ foreach ($server_ips as $ip) {
671
+ if( strpos( $url, $ip ) === false ) {
672
+ return self::send_request($data, 'https://'.$ip);
673
+ }
674
+ }
675
+ }
676
+ }
677
+ }
678
+
679
+ }else{
680
+ $errors = 'CURL_NOT_INSTALLED';
681
+ }
682
+
683
+ // Trying to use file_get_contents() to make a API call
684
+ if(!empty($errors)){
685
+ if(ini_get('allow_url_fopen')){
686
+ $opts = array(
687
+ 'http' => array(
688
+ 'method' => "POST",
689
+ 'timeout' => $timeout,
690
+ 'content' => $data_string,
691
+ ),
692
+ );
693
+ $context = stream_context_create($opts);
694
+ $result = @file_get_contents($url, 0, $context);
695
+
696
+ $errors = $result === false
697
+ ? $errors . '_FAILED_TO_USE_FILE_GET_CONTENTS'
698
+ : false;
699
+
700
+ }else{
701
+ $errors .= '_AND_ALLOW_URL_FOPEN_IS_DISABLED';
702
+ }
703
+ }
704
+
705
+ return empty($result) || !empty($errors)
706
+ ? array('error' => $errors)
707
+ : $result;
708
+ }
709
+
710
+ /**
711
+ * Function checks server response
712
+ *
713
+ * @param array|string $result
714
+ * @param string $method_name
715
+ *
716
+ * @return mixed (array || array('error' => true))
717
+ */
718
+ static public function check_response($result, $method_name = null)
719
+ {
720
+ // Errors handling
721
+ // Bad connection
722
+ if(is_array($result) && isset($result['error'])){
723
+ $last = error_get_last();
724
+ $out = ! empty( $result['error'] )
725
+ ? array( 'error' => 'CONNECTION_ERROR : "' . $result['error'] . '"' )
726
+ : array( 'error' => 'CONNECTION_ERROR : "Unknown Error. Last error: ' . $last['message'] );
727
+ return $out;
728
+ }
729
+
730
+ // JSON decode errors
731
+ $result = json_decode($result, true);
732
+ if(empty($result)){
733
+ return array(
734
+ 'error' => 'JSON_DECODE_ERROR',
735
+ );
736
+ }
737
+
738
+ // Server errors
739
+ if( $result && ( isset( $result['error_no'], $result['error_message'] ) ) ){
740
+
741
+ if( $result['error_no'] != 12 ){
742
+ return array(
743
+ 'error' => "SERVER_ERROR NO: {$result['error_no']} MSG: {$result['error_message']}",
744
+ 'error_no' => $result['error_no'],
745
+ 'error_message' => $result['error_message'],
746
+ );
747
+ }
748
+ }
749
+
750
+ // Pathces for different methods
751
+ switch($method_name){
752
+
753
+ // notice_paid_till
754
+ case 'notice_paid_till':
755
+
756
+ $result = isset($result['data']) ? $result['data'] : $result;
757
+
758
+ if((isset($result['error_no']) && $result['error_no'] == 12) ||
759
+ (
760
+ !(isset($result['service_id']) && is_int($result['service_id'])) &&
761
+ empty($result['moderate_ip'])
762
+ )
763
+ )
764
+ $result['valid'] = 0;
765
+ else
766
+ $result['valid'] = 1;
767
+
768
+ return $result;
769
+
770
+ break;
771
+
772
+ // get_antispam_report_breif
773
+ case 'get_antispam_report_breif':
774
+
775
+ $out = isset($result['data']) && is_array($result['data'])
776
+ ? $result['data']
777
+ : array('error' => 'NO_DATA');
778
+
779
+ for($tmp = array(), $i = 0; $i < 7; $i++){
780
+ $tmp[date('Y-m-d', time() - 86400 * 7 + 86400 * $i)] = 0;
781
+ }
782
+ $out['spam_stat'] = (array)array_merge($tmp, isset($out['spam_stat']) ? $out['spam_stat'] : array());
783
+ $out['top5_spam_ip'] = isset($out['top5_spam_ip']) ? $out['top5_spam_ip'] : array();
784
+
785
+ return $out;
786
+
787
+ break;
788
+
789
+ default:
790
+ return isset($result['data']) && is_array($result['data'])
791
+ ? $result['data']
792
+ : array('error' => 'NO_DATA');
793
+ break;
794
+ }
795
+ }
796
  }
lib/Cleantalk/Common/Firewall.php CHANGED
@@ -1,209 +1,221 @@
1
- <?php
2
-
3
- namespace Cleantalk\Common;
4
-
5
- use Cleantalk\Common\Helper as Helper;
6
- use Cleantalk\Variables\Get;
7
-
8
- /**
9
- * CleanTalk SpamFireWall base class.
10
- * Compatible with any CMS.
11
- *
12
- * @depends \Cleantalk\Antispam\Helper class
13
- * @depends \Cleantalk\Antispam\API class
14
- * @depends \Cleantalk\Antispam\DB class
15
- *
16
- * @version 3.3
17
- * @author Cleantalk team (welcome@cleantalk.org)
18
- * @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
19
- * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
20
- * @see https://github.com/CleanTalk/php-antispam
21
- */
22
- class Firewall
23
- {
24
-
25
- public $ip_array = Array();
26
-
27
- // Database
28
- protected $db;
29
-
30
- //Debug
31
- public $debug;
32
- public $debug_data = '';
33
-
34
- private $statuses_priority = array(
35
- // Lowest
36
- 'PASS_SFW',
37
- 'PASS_SFW__BY_COOKIE',
38
- 'PASS_ANTIFLOOD',
39
- 'PASS_ANTICRAWLER',
40
- 'DENY_ANTIFLOOD',
41
- 'DENY_ANTICRAWLER',
42
- 'DENY_SFW',
43
- 'PASS_SFW__BY_WHITELIST',
44
- // Highest
45
- );
46
-
47
- private $fw_modules = array();
48
- private $module_names = array();
49
-
50
- /**
51
- * Creates Database driver instance.
52
- *
53
- * @param $db
54
- */
55
- public function __construct( $db ){
56
- $this->db = $db;
57
- $this->debug = !! Get::get( 'debug' );
58
- $this->ip_array = $this->ip__get( array('real'), true );
59
- }
60
-
61
- /**
62
- * Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
63
- *
64
- * @param array $ips_input type of IP you want to receive
65
- * @param bool $v4_only
66
- *
67
- * @return array|mixed|null
68
- */
69
- public function ip__get( $ips_input = array( 'real', 'remote_addr', 'x_forwarded_for', 'x_real_ip', 'cloud_flare' ), $v4_only = true ){
70
-
71
- $result = Helper::ip__get( $ips_input, $v4_only );
72
-
73
- return ! empty( $result ) ? array( 'real' => $result ) : array();
74
-
75
- }
76
-
77
- /**
78
- * Loads the FireWall module to the array.
79
- * For inner usage only.
80
- * Not returns anything, the result is private storage of the modules.
81
- *
82
- * @param \Cleantalk\Common\Firewall\FirewallModule $module
83
- */
84
- public function load_fw_module( \Cleantalk\Common\Firewall\FirewallModule $module ) {
85
-
86
- if( ! in_array( $module, $this->fw_modules ) ) {
87
- $module->setDb( $this->db );
88
- $module->ip__append_additional( $this->ip_array );
89
- $this->fw_modules[ $module->module_name ] = $module;
90
- $module->setIpArray( $this->ip_array );
91
- }
92
-
93
- }
94
-
95
- /**
96
- * Do main logic of the module.
97
- *
98
- * @return void returns die page or set cookies
99
- */
100
- public function run() {
101
-
102
- $this->module_names = array_keys( $this->fw_modules );
103
-
104
- $results = array();
105
-
106
- // Checking
107
- foreach ( $this->fw_modules as $module ) {
108
-
109
- if( isset( $module->isExcluded ) && $module->isExcluded ) {
110
- continue;
111
- }
112
-
113
- $module_results = $module->check();
114
- if( ! empty( $module_results ) ) {
115
- $results[$module->module_name] = $this->prioritize( $module_results );
116
- }
117
-
118
- if( $this->is_whitelisted( $results ) ) {
119
- // Break protection logic if it whitelisted or trusted network.
120
- break;
121
- }
122
-
123
- }
124
-
125
- // Write Logs
126
- foreach ( $this->fw_modules as $module ) {
127
- if( array_key_exists( $module->module_name, $results ) ){
128
- $module->update_log( $results[$module->module_name]['ip'], $results[$module->module_name]['status'] );
129
- }
130
- }
131
-
132
- // Get the primary result
133
- $result = $this->prioritize( $results );
134
-
135
- // Do finish action - die or set cookies
136
- foreach( $this->module_names as $module_name ){
137
-
138
- if( strpos( $result['status'], $module_name ) ){
139
- // Blocked
140
- if( strpos( $result['status'], 'DENY' ) !== false ){
141
- $this->fw_modules[ $module_name ]->actions_for_denied( $result );
142
- $this->fw_modules[ $module_name ]->_die( $result );
143
-
144
- // Allowed
145
- }else{
146
- $this->fw_modules[ $module_name ]->actions_for_passed( $result );
147
- }
148
- }
149
-
150
- }
151
-
152
- }
153
-
154
- /**
155
- * Sets priorities for firewall results.
156
- * It generates one main result from multi-level results array.
157
- *
158
- * @param array $results
159
- *
160
- * @return array Single element array of result
161
- */
162
- private function prioritize( $results ){
163
-
164
- $current_fw_result_priority = 0;
165
- $result = array( 'status' => 'PASS', 'passed_ip' => '' );
166
-
167
- if( is_array( $results ) ) {
168
- foreach ( $results as $fw_result ) {
169
- $priority = array_search( $fw_result['status'], $this->statuses_priority ) + ( isset($fw_result['is_personal']) && $fw_result['is_personal'] ? count ( $this->statuses_priority ) : 0 );
170
- if( $priority >= $current_fw_result_priority ){
171
- $current_fw_result_priority = $priority;
172
- $result['status'] = $fw_result['status'];
173
- $result['passed_ip'] = isset( $fw_result['ip'] ) ? $fw_result['ip'] : $fw_result['passed_ip'];
174
- $result['blocked_ip'] = isset( $fw_result['ip'] ) ? $fw_result['ip'] : $fw_result['blocked_ip'];
175
- $result['pattern'] = isset( $fw_result['pattern'] ) ? $fw_result['pattern'] : array();
176
- }
177
- }
178
- }
179
-
180
- $result['ip'] = strpos( $result['status'], 'PASS' ) !== false ? $result['passed_ip'] : $result['blocked_ip'];
181
- $result['passed'] = strpos( $result['status'], 'PASS' ) !== false;
182
-
183
- return $result;
184
-
185
- }
186
-
187
- /**
188
- * Check the result if it whitelisted or trusted network
189
- *
190
- * @param array $results
191
- *
192
- * @return bool
193
- */
194
- private function is_whitelisted( $results ) {
195
-
196
- foreach ( $results as $fw_result ) {
197
- if (
198
- strpos( $fw_result['status'], 'PASS_BY_TRUSTED_NETWORK' ) !== false ||
199
- strpos( $fw_result['status'], 'PASS_BY_WHITELIST' ) !== false ||
200
- strpos( $fw_result['status'], 'PASS_SFW__BY_WHITELIST' ) !== false
201
- ) {
202
- return true;
203
- }
204
- }
205
- return false;
206
-
207
- }
208
-
209
- }
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Cleantalk\Common;
4
+
5
+ use Cleantalk\Common\Helper as Helper;
6
+ use Cleantalk\Variables\Get;
7
+
8
+ /**
9
+ * CleanTalk SpamFireWall base class.
10
+ * Compatible with any CMS.
11
+ *
12
+ * @depends \Cleantalk\Antispam\Helper class
13
+ * @depends \Cleantalk\Antispam\API class
14
+ * @depends \Cleantalk\Antispam\DB class
15
+ *
16
+ * @version 3.3
17
+ * @author Cleantalk team (welcome@cleantalk.org)
18
+ * @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
19
+ * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
20
+ * @see https://github.com/CleanTalk/php-antispam
21
+ */
22
+ class Firewall
23
+ {
24
+
25
+ public $ip_array = Array();
26
+
27
+ // Database
28
+ protected $db;
29
+
30
+ //Debug
31
+ public $debug;
32
+ public $debug_data = '';
33
+
34
+ private $statuses_priority = array(
35
+ // Lowest
36
+ 'PASS_SFW',
37
+ 'PASS_SFW__BY_COOKIE',
38
+ 'PASS_ANTIFLOOD',
39
+ 'PASS_ANTICRAWLER_UA',
40
+ 'PASS_ANTICRAWLER',
41
+ 'DENY_ANTIFLOOD',
42
+ 'DENY_ANTICRAWLER_UA',
43
+ 'DENY_ANTICRAWLER',
44
+ 'DENY_SFW',
45
+ 'PASS_SFW__BY_WHITELIST',
46
+ // Highest
47
+ );
48
+
49
+ private $fw_modules = array();
50
+ private $module_names = array();
51
+
52
+ /**
53
+ * Creates Database driver instance.
54
+ *
55
+ * @param $db
56
+ */
57
+ public function __construct( $db ){
58
+ $this->db = $db;
59
+ $this->debug = !! Get::get( 'debug' );
60
+ $this->ip_array = $this->ip__get( array('real'), true );
61
+ }
62
+
63
+ /**
64
+ * Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
65
+ *
66
+ * @param array $ips_input type of IP you want to receive
67
+ * @param bool $v4_only
68
+ *
69
+ * @return array|mixed|null
70
+ */
71
+ public function ip__get( $ips_input = array( 'real', 'remote_addr', 'x_forwarded_for', 'x_real_ip', 'cloud_flare' ), $v4_only = true ){
72
+
73
+ $result = Helper::ip__get( $ips_input, $v4_only );
74
+
75
+ return ! empty( $result ) ? array( 'real' => $result ) : array();
76
+
77
+ }
78
+
79
+ /**
80
+ * Loads the FireWall module to the array.
81
+ * For inner usage only.
82
+ * Not returns anything, the result is private storage of the modules.
83
+ *
84
+ * @param \Cleantalk\Common\Firewall\FirewallModule $module
85
+ */
86
+ public function load_fw_module( \Cleantalk\Common\Firewall\FirewallModule $module ) {
87
+
88
+ if( ! in_array( $module, $this->fw_modules ) ) {
89
+ $module->setDb( $this->db );
90
+ $module->ip__append_additional( $this->ip_array );
91
+ $this->fw_modules[ $module->module_name ] = $module;
92
+ $module->setIpArray( $this->ip_array );
93
+ }
94
+
95
+ }
96
+
97
+ /**
98
+ * Do main logic of the module.
99
+ *
100
+ * @return void returns die page or set cookies
101
+ */
102
+ public function run() {
103
+
104
+ $this->module_names = array_keys( $this->fw_modules );
105
+
106
+ $results = array();
107
+
108
+ // Checking
109
+ foreach ( $this->fw_modules as $module ) {
110
+
111
+ if( isset( $module->isExcluded ) && $module->isExcluded ) {
112
+ continue;
113
+ }
114
+
115
+ $module_results = $module->check();
116
+ if( ! empty( $module_results ) ) {
117
+ $results[$module->module_name] = $module_results;
118
+ }
119
+
120
+ if( $this->is_whitelisted( $results ) ) {
121
+ // Break protection logic if it whitelisted or trusted network.
122
+ break;
123
+ }
124
+
125
+ }
126
+
127
+ // Write Logs
128
+ foreach ( $this->fw_modules as $module ) {
129
+ if( array_key_exists( $module->module_name, $results ) ){
130
+ foreach ( $results[$module->module_name] as $result ) {
131
+ $module->update_log( $result['ip'], $result['status'] );
132
+ }
133
+ }
134
+ }
135
+
136
+ // Get the primary result
137
+ $result = $this->prioritize( $results );
138
+
139
+ // Do finish action - die or set cookies
140
+ foreach( $this->module_names as $module_name ){
141
+
142
+ if( strpos( $result['status'], $module_name ) ){
143
+ // Blocked
144
+ if( strpos( $result['status'], 'DENY' ) !== false ){
145
+ $this->fw_modules[ $module_name ]->actions_for_denied( $result );
146
+ $this->fw_modules[ $module_name ]->_die( $result );
147
+
148
+ // Allowed
149
+ }else{
150
+ $this->fw_modules[ $module_name ]->actions_for_passed( $result );
151
+ }
152
+ }
153
+
154
+ }
155
+
156
+ }
157
+
158
+ /**
159
+ * Sets priorities for firewall results.
160
+ * It generates one main result from multi-level results array.
161
+ *
162
+ * @param array $results
163
+ *
164
+ * @return array Single element array of result
165
+ */
166
+ private function prioritize( $results ){
167
+
168
+ $current_fw_result_priority = 0;
169
+ $result = array( 'status' => 'PASS', 'passed_ip' => '' );
170
+
171
+ if( is_array( $results ) ) {
172
+ foreach ( $this->fw_modules as $module ) {
173
+ if( array_key_exists( $module->module_name, $results ) ) {
174
+ foreach ( $results[$module->module_name] as $fw_result ) {
175
+ $priority = array_search( $fw_result['status'], $this->statuses_priority ) + ( isset($fw_result['is_personal']) && $fw_result['is_personal'] ? count ( $this->statuses_priority ) : 0 );
176
+ if( $priority >= $current_fw_result_priority ){
177
+ $current_fw_result_priority = $priority;
178
+ $result['status'] = $fw_result['status'];
179
+ $result['passed_ip'] = isset( $fw_result['ip'] ) ? $fw_result['ip'] : $fw_result['passed_ip'];
180
+ $result['blocked_ip'] = isset( $fw_result['ip'] ) ? $fw_result['ip'] : $fw_result['blocked_ip'];
181
+ $result['pattern'] = isset( $fw_result['pattern'] ) ? $fw_result['pattern'] : array();
182
+ }
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ $result['ip'] = strpos( $result['status'], 'PASS' ) !== false ? $result['passed_ip'] : $result['blocked_ip'];
189
+ $result['passed'] = strpos( $result['status'], 'PASS' ) !== false;
190
+
191
+ return $result;
192
+
193
+ }
194
+
195
+ /**
196
+ * Check the result if it whitelisted or trusted network
197
+ *
198
+ * @param array $results
199
+ *
200
+ * @return bool
201
+ */
202
+ private function is_whitelisted( $results ) {
203
+
204
+ foreach ( $this->fw_modules as $module ) {
205
+ if( array_key_exists( $module->module_name, $results ) ){
206
+ foreach ( $results[$module->module_name] as $fw_result ) {
207
+ if (
208
+ strpos( $fw_result['status'], 'PASS_BY_TRUSTED_NETWORK' ) !== false ||
209
+ strpos( $fw_result['status'], 'PASS_BY_WHITELIST' ) !== false ||
210
+ strpos( $fw_result['status'], 'PASS_SFW__BY_WHITELIST' ) !== false
211
+ ) {
212
+ return true;
213
+ }
214
+ }
215
+ }
216
+ }
217
+ return false;
218
+
219
+ }
220
+
221
+ }
lib/Cleantalk/Common/Helper.php CHANGED
@@ -828,5 +828,34 @@ class Helper
828
  $line = array_combine( $map, $line );
829
  return $line;
830
  }
831
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
832
  }
828
  $line = array_combine( $map, $line );
829
  return $line;
830
  }
831
+
832
+ /**
833
+ * Escapes MySQL params
834
+ *
835
+ * @param string|int $param
836
+ * @param string $quotes
837
+ *
838
+ * @return int|string
839
+ */
840
+ public static function db__prepare_param($param, $quotes = '\'')
841
+ {
842
+ if(is_array($param)){
843
+ foreach($param as &$par){
844
+ $par = self::db__prepare_param($par);
845
+ }
846
+ }
847
+ switch(true){
848
+ case is_numeric($param):
849
+ $param = intval($param);
850
+ break;
851
+ case is_string($param) && strtolower($param) == 'null':
852
+ $param = 'NULL';
853
+ break;
854
+ case is_string($param):
855
+ global $wpdb;
856
+ $param = $quotes . $wpdb->_real_escape($param) . $quotes;
857
+ break;
858
+ }
859
+ return $param;
860
+ }
861
  }
readme.txt CHANGED
@@ -2,9 +2,9 @@
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.149
8
  License: GPLv2
9
 
10
  Spam protection, anti-spam, firewall, premium plugin. No spam comments & users, no spam contact form & WooCommerce anti-spam.
@@ -59,8 +59,8 @@ Native spam protection for WordPress, JetPack comments and any other comment plu
59
  = Spam bots registrations filter =
60
  Filters spam bots on registration forms of WordPress, BuddyPress, bbPress, S2Member, WooCommerce, Profile builder, Login with AJAX and any other registration plugins.
61
 
62
- = Protection from contact form spam =
63
- The plugin is tested and ready to protect from spam emails via Formidable forms, Contact form 7, JetPack Contact form, Fast Secure Contact form, Ninja forms, Landing Page Builder, Gravity forms, Contact Form by BestWebSoft, Simple Contact Form Plugin - PirateForms, Visual Form Builder, Contact Form by WebDorado, Contact Form Email, MW WP Form, Contact Form by Jeff Bulllins, Contact Us Form, WCP Contact Form, WPForms Lite, Custom Contact, Forms, Caldera Forms, Visual Form Builder, Contact Form Clean and Simple, Divi by Elegant Themes, The7 theme and any other themes or custom contact forms, amoForms, Ultimate Form Builder, Contact Bank - Contact Forms Builder, Forms easily built with Smart Forms, Usernoise contact form, Contact Form by Web-Settler, HubSpot Marketing Free, QuForm.
64
 
65
  = WooCommerce spam filter =
66
  Anti-spam by CleanTalk filters spam registrations and spam reviews for WooCommerce. The plugin is fully compatible with WooCommerce 2.1 and higher.
@@ -580,6 +580,22 @@ If your website has forms that send data to external sources, you can enable opt
580
 
581
  == Changelog ==
582
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
583
  = 5.149 Nov 19 2020 =
584
  * Fix: External forms protection fixed.
585
  * Fix: check for array in spam_stat collect.
2
  Contributors: safronik
3
  Tags: spam, antispam, anti-spam, comments, firewall
4
  Requires at least: 3.0
5
+ Tested up to: 5.6
6
  Requires PHP: 5.4
7
+ Stable tag: 5.150
8
  License: GPLv2
9
 
10
  Spam protection, anti-spam, firewall, premium plugin. No spam comments & users, no spam contact form & WooCommerce anti-spam.
59
  = Spam bots registrations filter =
60
  Filters spam bots on registration forms of WordPress, BuddyPress, bbPress, S2Member, WooCommerce, Profile builder, Login with AJAX and any other registration plugins.
61
 
62
+ = Spam filter for contact forms =
63
+ The plugin is tested and ready to protect from spam emails via Formidable forms, Contact form 7, JetPack Contact form, Fast Secure Contact form, Ninja forms, Landing Page Builder, Gravity forms, Contact Form by BestWebSoft, Simple Contact Form Plugin - PirateForms, Visual Form Builder, Contact Form by WebDorado, Contact Form Email, MW WP Form, Contact Form by Jeff Bulllins, Contact Us Form, WCP Contact Form, WPForms Lite, Custom Contact, Forms, Caldera Forms, Visual Form Builder, Contact Form Clean and Simple, Divi by Elegant Themes, The7 theme and any other themes or custom contact forms, amoForms, Ultimate Form Builder, Contact Bank - Contact Forms Builder, Forms easily built with Smart Forms, Usernoise contact form, Contact Form by Web-Settler, HubSpot Marketing Free, QuForm, Form Maker by 10Web, WP User Frontend, NEX-Forms.
64
 
65
  = WooCommerce spam filter =
66
  Anti-spam by CleanTalk filters spam registrations and spam reviews for WooCommerce. The plugin is fully compatible with WooCommerce 2.1 and higher.
580
 
581
  == Changelog ==
582
 
583
+ = 5.150 Dec 3 2020 =
584
+ * Fix: Prevent skip checking woocommerce registration during checkout.
585
+ * Fix: skip gravity multipage checking.
586
+ * New: AC UA checking implemented.
587
+ * Fix: skip buffer replace for rss feeds.
588
+ * Fix: Easy Registration Forms login form skip.
589
+ * Fix: Quotas in hidden fields.
590
+ * Fix: skip tinkoff payment form fields collection.
591
+ * New: Helper prepare_param added.
592
+ * Fix: erforms internal request skip.
593
+ * Integration: Landing Page Builder integration implemented.
594
+ * Upd: Easy Registration Form block message implemented.
595
+ * Integration: Profile Builder.
596
+ * Fix: Skip connector mysql request.
597
+ * New: AC UA - new option implemented.
598
+
599
  = 5.149 Nov 19 2020 =
600
  * Fix: External forms protection fixed.
601
  * Fix: check for array in spam_stat collect.