Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 62 additions & 1 deletion inc/fw-update.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ function spbc_security_firewall_update__init($delay = null)

sleep((int)$delay);

// A direct update lives longer than the cron task lock, so it has to be checked before anything is wiped
if ( spbc_security_firewall_update_direct_lock__is_active() ) {
return true;
}

$spbc->update_logger::clearStorage();
$spbc->update_logger->writeLog('UPDATE INIT START');

Expand Down Expand Up @@ -584,7 +589,8 @@ static function ($hash) {
SPBC_TBL_FIREWALL_DATA . '_temp', // Write to the main table for daughter blogs
SPBC_TBL_FIREWALL_DATA__IPS . '_temp',
SPBC_TBL_FIREWALL_DATA__COUNTRIES . '_temp',
$path
$path,
$current_file_content
);

$single_file_result = empty($result['error'])
Expand Down Expand Up @@ -844,13 +850,67 @@ function spbc_security_firewall_update__checker()
return true;
}

/**
* Heartbeat option name of a running direct Security FireWall update.
*/
if ( ! defined('SPBC_SECFW_DIRECT_UPDATE_LOCK_OPTION') ) {
define('SPBC_SECFW_DIRECT_UPDATE_LOCK_OPTION', 'spbc_secfw_direct_update_lock');
}

/**
* Seconds without a heartbeat after which a direct update is considered dead.
*/
if ( ! defined('SPBC_SECFW_DIRECT_UPDATE_LOCK_TTL') ) {
define('SPBC_SECFW_DIRECT_UPDATE_LOCK_TTL', 120);
}

/**
* @return bool
*/
function spbc_security_firewall_update_direct_lock__is_active()
{
$heartbeat = (int)get_option(SPBC_SECFW_DIRECT_UPDATE_LOCK_OPTION, 0);

return $heartbeat > 0 && time() - $heartbeat < SPBC_SECFW_DIRECT_UPDATE_LOCK_TTL;
}

function spbc_security_firewall_update_direct_lock__touch()
{
update_option(SPBC_SECFW_DIRECT_UPDATE_LOCK_OPTION, time(), false);
}

function spbc_security_firewall_update_direct_lock__release()
{
update_option(SPBC_SECFW_DIRECT_UPDATE_LOCK_OPTION, 0, false);
}

/**
* Update security firewall in single thread
*
* @return bool|string[]|array[]
* @throws Exception
*/
function spbc_security_firewall_update_direct()
{
spbc_security_firewall_update_direct_lock__touch();

try {
$result = spbc_security_firewall_update_direct__run();
} catch ( Exception $e ) {
spbc_security_firewall_update_direct_lock__release();
throw $e;
}

spbc_security_firewall_update_direct_lock__release();

return $result;
}

/**
* @return bool|string[]|array[]
* @throws Exception
*/
function spbc_security_firewall_update_direct__run()
{
global $spbc;

Expand All @@ -873,6 +933,7 @@ function spbc_security_firewall_update_direct()

// process_file
foreach ( $urls as $url ) {
spbc_security_firewall_update_direct_lock__touch();
$result_process_file = spbc_security_firewall_update__process_file($url, true);
if ( ! empty($result_process_file['error']) ) {
$spbc->update_logger->writeLog('DIRECT UPDATE ERROR: processing file: ' . @json_encode($result_process_file['error']));
Expand Down
25 changes: 20 additions & 5 deletions lib/CleantalkSP/SpbctWP/Firewall/FW.php
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ public static function firewallUpdateGetMultifiles($spbc_key)
* @param string $data_table__personal Table name with personal IPs
* @param string $data_table__personal_countries Table name with with personal country list
* @param string $file_url Local or remote URL
* @param string|null $raw_gz_content Already fetched GZ content, saves a repeated download when passed
*
* @return array|bool|int|mixed|string
*/
Expand All @@ -557,10 +558,18 @@ public static function updateWriteToDb(
$data_table__common,
$data_table__personal,
$data_table__personal_countries,
$file_url
$file_url,
$raw_gz_content = null
) {
// Check if the URL is remote address or not, and use a proper function to extract data
$data = HTTP::getDataFromGZ($file_url);
if ( is_string($raw_gz_content) && $raw_gz_content !== '' ) {
$data = function_exists('gzdecode') ? @gzdecode($raw_gz_content) : false;
if ( $data === false ) {
$data = array('error' => 'Can not unpack datafile');
}
} else {
// Check if the URL is remote address or not, and use a proper function to extract data
$data = HTTP::getDataFromGZ($file_url);
}

if ( empty($data['error']) ) {
$inserted = 0;
Expand Down Expand Up @@ -812,11 +821,17 @@ public static function dataTablesCreateTemporaryTablesForTables($db, $table_name
if ( ! $db->execute(
'CREATE TABLE IF NOT EXISTS `' . $table_name__temp . '` LIKE `' . $table_name . '`; '
) ) {
return array('error' => 'CREATE TABLES: COULD NOT CREATE ' . $table_name__temp);
return array(
'error' => 'CREATE TABLES: COULD NOT CREATE ' . $table_name__temp
. ' DB Error: ' . substr($db->getLastError(), 0, 1000),
);
}

if ( ! $db->execute('TRUNCATE `' . $table_name__temp . '`; ') ) {
return array('error' => 'CREATE TABLES: COULD NOT TRUNCATE ' . $table_name__temp);
return array(
'error' => 'CREATE TABLES: COULD NOT TRUNCATE ' . $table_name__temp
. ' DB Error: ' . substr($db->getLastError(), 0, 1000),
);
}
}

Expand Down