View source
<?php
namespace Cleantalk\Common\Firewall;
use Cleantalk\Common\API;
use Cleantalk\Common\DB;
use Cleantalk\Common\Helper;
use Cleantalk\Common\Variables\Get;
use Cleantalk\Common\Variables\Server;
class Firewall {
private $ip_array;
private $db;
private $debug;
private $statuses_priority = array(
'PASS_SFW',
'PASS_SFW__BY_COOKIE',
'PASS_ANTIFLOOD_UA',
'PASS_ANTIFLOOD',
'PASS_ANTICRAWLER_UA',
'PASS_ANTICRAWLER',
'DENY_ANTIFLOOD_UA',
'DENY_ANTIFLOOD',
'DENY_ANTICRAWLER_UA',
'DENY_ANTICRAWLER',
'DENY_SFW',
'PASS_SFW__BY_WHITELIST',
);
private $fw_modules = array();
private $module_names = array();
private $api_key;
private $log_table_name;
private $helper;
private $api;
public function __construct($api_key, DB $db, $log_table_name) {
$this->api_key = $api_key;
$this->db = $db;
$this->log_table_name = $db->prefix . $log_table_name;
$this->debug = (bool) Get::get('debug');
$this->ip_array = $this
->ipGet('real', true);
$this->helper = new Helper();
$this->api = new API();
}
public function setSpecificHelper(Helper $helper) {
$this->helper = $helper;
}
public function setSpecificApi(API $api) {
$this->api = $api;
}
public function loadFwModule(FirewallModule $module) {
if (!in_array($module, $this->fw_modules)) {
$module
->setApiKey($this->api_key);
$module
->setDb($this->db);
$module
->setLogTableName($this->log_table_name);
$module
->setHelper($this->helper);
$module
->setIpArray($this->ip_array);
$module
->setIsDebug($this->debug);
$module
->ipAppendAdditional($this->ip_array);
$this->fw_modules[$module->module_name] = $module;
}
}
public function run() {
$this->module_names = array_keys($this->fw_modules);
$results = array();
foreach ($this->fw_modules as $module) {
if (isset($module->isExcluded) && $module->isExcluded) {
continue;
}
$module_results = $module
->check();
if (!empty($module_results)) {
$results[$module->module_name] = $module_results;
}
if ($this
->isWhitelisted($results)) {
break;
}
}
foreach ($this->fw_modules as $module) {
if (array_key_exists($module->module_name, $results)) {
foreach ($results[$module->module_name] as $result) {
if (in_array($result['status'], array(
'PASS_SFW__BY_WHITELIST',
'PASS_SFW',
'PASS_ANTIFLOOD',
'PASS_ANTICRAWLER',
'PASS_ANTICRAWLER_UA',
'PASS_ANTIFLOOD_UA',
))) {
continue;
}
$module
->update_log($result['ip'], $result['status'], !empty($result['network']) ? $result['network'] : null, !empty($result['is_personal']) ? $result['is_personal'] : null);
}
}
}
$result = $this
->prioritize($results);
foreach ($this->module_names as $module_name) {
if (strpos($result['status'], $module_name)) {
if (strpos($result['status'], 'DENY') !== false) {
$this->fw_modules[$module_name]
->actionsForDenied($result);
$this->fw_modules[$module_name]
->_die($result);
}
else {
$this->fw_modules[$module_name]
->actionsForPassed($result);
}
}
}
}
private function prioritize($results) {
$current_fw_result_priority = 0;
$result = array(
'status' => 'PASS',
'passed_ip' => '',
);
if (is_array($results)) {
foreach ($this->fw_modules as $module) {
if (array_key_exists($module->module_name, $results)) {
foreach ($results[$module->module_name] as $fw_result) {
$priority = array_search($fw_result['status'], $this->statuses_priority) + (isset($fw_result['is_personal']) && $fw_result['is_personal'] ? count($this->statuses_priority) : 0);
if ($priority >= $current_fw_result_priority) {
$current_fw_result_priority = $priority;
$result['status'] = $fw_result['status'];
$result['passed_ip'] = isset($fw_result['ip']) ? $fw_result['ip'] : $fw_result['passed_ip'];
$result['blocked_ip'] = isset($fw_result['ip']) ? $fw_result['ip'] : $fw_result['blocked_ip'];
$result['pattern'] = isset($fw_result['pattern']) ? $fw_result['pattern'] : array();
}
}
}
}
}
$result['ip'] = strpos($result['status'], 'PASS') !== false ? $result['passed_ip'] : $result['blocked_ip'];
$result['passed'] = strpos($result['status'], 'PASS') !== false;
return $result;
}
private function isWhitelisted($results) {
global $apbct;
foreach ($this->fw_modules as $module) {
if (array_key_exists($module->module_name, $results)) {
foreach ($results[$module->module_name] as $fw_result) {
if (strpos($fw_result['status'], 'PASS_BY_TRUSTED_NETWORK') !== false || strpos($fw_result['status'], 'PASS_BY_WHITELIST') !== false || strpos($fw_result['status'], 'PASS_SFW__BY_WHITELIST') !== false) {
return true;
}
}
}
}
return false;
}
private function ipGet($ips_input, $v4_only = true) {
$result = Helper::ip__get($ips_input, $v4_only);
return !empty($result) ? array(
'real' => $result,
) : array();
}
public function sendLogs() {
$query = "SELECT * FROM " . $this->log_table_name . ";";
$this->db
->fetch_all($query);
if (count($this->db->result)) {
$data = array();
foreach ($this->db->result as $key => $value) {
$value['status'] = $value['status'] === 'DENY_ANTICRAWLER' ? 'BOT_PROTECTION' : $value['status'];
$value['status'] = $value['status'] === 'PASS_ANTICRAWLER' ? 'BOT_PROTECTION' : $value['status'];
$value['status'] = $value['status'] === 'DENY_ANTICRAWLER_UA' ? 'BOT_PROTECTION' : $value['status'];
$value['status'] = $value['status'] === 'PASS_ANTICRAWLER_UA' ? 'BOT_PROTECTION' : $value['status'];
$value['status'] = $value['status'] === 'DENY_ANTIFLOOD' ? 'FLOOD_PROTECTION' : $value['status'];
$value['status'] = $value['status'] === 'PASS_ANTIFLOOD' ? 'FLOOD_PROTECTION' : $value['status'];
$value['status'] = $value['status'] === 'PASS_SFW__BY_COOKIE' ? null : $value['status'];
$value['status'] = $value['status'] === 'PASS_SFW' ? null : $value['status'];
$value['status'] = $value['status'] === 'DENY_SFW' ? null : $value['status'];
$data[] = array(
trim($value['ip']),
$value['blocked_entries'],
$value['all_entries'] - $value['blocked_entries'],
$value['entries_timestamp'],
$value['status'],
$value['ua_name'],
$value['ua_id'],
);
}
unset($key, $value);
$api = $this->api;
$result = $api::method__sfw_logs($this->api_key, $data);
if (empty($result['error'])) {
if ($result['rows'] == count($data)) {
$this->db
->execute("TRUNCATE TABLE " . $this->log_table_name . ";");
return $result;
}
return array(
'error' => 'SENT_AND_RECEIVED_LOGS_COUNT_DOESNT_MACH',
);
}
return $result;
}
return array(
'rows' => 0,
);
}
public function getUpdater($data_table_name) {
$fw_updater = new FirewallUpdater($this->api_key, $this->db, $data_table_name);
$fw_updater
->setSpecificHelper($this->helper);
$fw_updater
->setSpecificApi($this->api);
return $fw_updater;
}
}