/** * Ajax callback function * * @link http://codex.wordpress.org/AJAX_in_Plugins * @link http://codex.wordpress.org/Function_Reference/check_ajax_referer * @link http://core.trac.wordpress.org/browser/trunk/wp-admin/admin-ajax.php */ public function admin_ajax_callback() { // Check request origin, nonce, capability. if (!check_admin_referer($this->get_ajax_action(), 'nonce') || !current_user_can('manage_options') || empty($_POST)) { // @since 2.0 status_header(403); // Forbidden @since 2.0.0 } $which = isset($_POST['which']) ? $_POST['which'] : NULL; switch (isset($_POST['cmd']) ? $_POST['cmd'] : NULL) { case 'download': $res = IP_Geo_Block::download_database(); break; case 'search': require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-apis.php'; // check format if (filter_var($ip = $_POST['ip'], FILTER_VALIDATE_IP)) { // get option settings and compose request headers $options = IP_Geo_Block::get_option('settings'); $args = IP_Geo_Block::get_request_headers($options); // create object for provider and get location if ($geo = IP_Geo_Block_API::get_instance($which, $options)) { $res = $geo->get_location($ip, $args); } else { $res = array('errorMessage' => 'Unknown service.'); } } else { $res = array('errorMessage' => 'Invalid IP address.'); } break; case 'scan-code': require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-apis.php'; // scan all the country code using selected APIs $ip = IP_Geo_Block::get_ip_address(); $options = IP_Geo_Block::get_option('settings'); $args = IP_Geo_Block::get_request_headers($options); $type = IP_Geo_Block_Provider::get_providers('type', FALSE, FALSE); $providers = IP_Geo_Block_Provider::get_valid_providers($options['providers'], FALSE, FALSE); $res['IP address'] = esc_html($ip); foreach ($providers as $provider) { if ($geo = IP_Geo_Block_API::get_instance($provider, $options)) { $ret = $geo->get_location($ip, $args); $res[$provider] = array('type' => $type[$provider], 'code' => esc_html(FALSE === $ret ? __('n/a', IP_Geo_Block::TEXT_DOMAIN) : (!empty($ret['errorMessage']) ? $ret['errorMessage'] : (!empty($ret['countryCode']) ? $ret['countryCode'] : __('UNKNOWN', IP_Geo_Block::TEXT_DOMAIN))))); } } break; case 'clear-statistics': // set default values update_option($this->option_name['statistics'], IP_Geo_Block::get_default('statistics')); $res = array('page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_SLUG, 'tab' => 'tab=1'); break; case 'clear-cache': // delete cache of IP address delete_transient(IP_Geo_Block::CACHE_KEY); // @since 2.8 $res = array('page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_SLUG, 'tab' => 'tab=1'); break; case 'clear-logs': require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php'; $hook = array('comment', 'login', 'admin', 'xmlrpc'); $which = in_array($which, $hook) ? $which : NULL; IP_Geo_Block_Logs::clean_log($which); $res = array('page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_SLUG, 'tab' => 'tab=4'); break; case 'restore': require_once IP_GEO_BLOCK_PATH . 'includes/localdate.php'; require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php'; // if js is slow then limit the number of rows $limit = IP_Geo_Block_Logs::limit_rows(@$_POST['time']); // compose html with sanitization $which = IP_Geo_Block_Logs::restore_log($which); foreach ($which as $hook => $rows) { $html = ''; $n = 0; foreach ($rows as $logs) { $log = (int) array_shift($logs); $html .= "<tr><td data-value={$log}>"; $html .= ip_geo_block_localdate($log, 'Y-m-d H:i:s') . "</td>"; foreach ($logs as $log) { $log = esc_html($log); $html .= "<td>{$log}</td>"; } $html .= "</tr>"; if (++$n >= $limit) { break; } } $res[$hook] = $html; } break; case 'create_table': case 'delete_table': require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php'; if ('create_table' === $_POST['cmd']) { IP_Geo_Block_Logs::create_log(); } else { IP_Geo_Block_Logs::delete_log(); } $res = array('page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_SLUG); } if (isset($res)) { // wp_send_json_{success,error}() @since 3.5.0 wp_send_json($res); } // @since 3.5.0 die; // End of ajax }
/** * Validate ip address. * * @param string $hook a name to identify action hook applied in this call. * @param array $settings option settings * @param boolean $die send http response and die if validation fails */ private function validate_ip($hook, $settings, $block = TRUE, $die = TRUE) { // set IP address to be validated $ips = array(self::get_ip_address()); // pick up all the IPs in HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP and etc. foreach (explode(',', $settings['validation']['proxy']) as $var) { if (isset($_SERVER[$var])) { foreach (explode(',', $_SERVER[$var]) as $ip) { if (!in_array($ip = trim($ip), $ips) && filter_var($ip, FILTER_VALIDATE_IP)) { array_unshift($ips, $ip); } } } } // register auxiliary validation functions $var = self::PLUGIN_SLUG . "-{$hook}"; add_filter($var, array($this, 'check_auth'), 9, 2); add_filter($var, array($this, 'check_fail'), 8, 2); $settings['extra_ips'] = apply_filters(self::PLUGIN_SLUG . '-extra-ips', $settings['extra_ips'], $hook); $settings['extra_ips']['white_list'] && add_filter($var, array($this, 'check_ips_white'), 7, 2); $settings['extra_ips']['black_list'] && add_filter($var, array($this, 'check_ips_black'), 7, 2); // make valid provider name list require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-apis.php'; $providers = IP_Geo_Block_Provider::get_valid_providers($settings['providers']); // apply custom filter for validation // @usage add_filter( "ip-geo-block-$hook", 'my_validation' ); // @param $validate = array( // 'ip' => $ip, /* validated ip address */ // 'auth' => $auth, /* authenticated or not */ // 'code' => $code, /* country code or reason of rejection */ // 'result' => $result, /* 'passed', 'blocked' */ // ); foreach ($ips as $this->remote_addr) { $validate = self::_get_geolocation($this->remote_addr, $settings, $providers); $validate = apply_filters($var, $validate, $settings); // if no 'result' then validate ip address by country if (empty($validate['result'])) { $validate = self::validate_country($validate, $settings, $block); } // if one of IPs is blocked then stop if ($result = 'passed' !== $validate['result']) { break; } } // update cache IP_Geo_Block_API_Cache::update_cache($hook, $validate, $settings); if ($die) { // record log (0:no, 1:blocked, 2:passed, 3:unauth, 4:auth, 5:all) $var = (int) $settings['validation']['reclogs']; if (1 === $var && $result || 2 === $var && !$result || 3 === $var && !$validate['auth'] || 4 === $var && $validate['auth'] || 5 === $var) { // all require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php'; IP_Geo_Block_Logs::record_log($hook, $validate, $settings); } if ($result) { // update statistics if ($settings['save_statistics']) { $this->update_statistics($hook, $validate); } // send response code to refuse $this->send_response($hook, $settings['response_code']); } } return $validate; }