Skip to content
Merged
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
95 changes: 83 additions & 12 deletions inc/spbc-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -680,32 +680,103 @@ function spbc_field_options_overview_traffic_light()
return $groups;
}

/**
* Get personal (allow/ban) statuses for the given list of IP addresses.
* Mirrors the network/mask matching logic used for the Firewall log (View::getFirewallRows())
* but works from raw IP addresses instead of the pre-computed network/mask log columns.
*
* @param array $ips IP addresses (IPv6 addresses expected to be already normalized)
* @return array IP address => status (1 - allowed, 0/negative - banned, null - no personal record)
*/
function spbc_field_security_logs__get_personal_statuses($ips)
{
global $wpdb;

$statuses = array();
$ipv6_rows = null;

foreach (array_unique($ips) as $ip) {
if (IP::validate($ip) === 'v6') {
if ($ipv6_rows === null) {
// @psalm-suppress WpdbUnsafeMethodsIssue
$ipv6_rows = $wpdb->get_results(
'SELECT network1, network2, network3, network4, mask1, mask2, mask3, mask4, status FROM '
. SPBC_TBL_FIREWALL_DATA__IPS_V6,
ARRAY_A
);
$ipv6_rows = $ipv6_rows ?: array();
}

$extended_ip = IP::extendIPv6(IP::normalizeIPv6($ip) ?: $ip);
$max_status = null;
foreach ($ipv6_rows as $row) {
$hex_network = str_pad(dechex($row['network1']), 8, '0', STR_PAD_LEFT)
. str_pad(dechex($row['network2']), 8, '0', STR_PAD_LEFT)
. str_pad(dechex($row['network3']), 8, '0', STR_PAD_LEFT)
. str_pad(dechex($row['network4']), 8, '0', STR_PAD_LEFT);
$network = implode(':', str_split($hex_network, 4));
if (IP::validate($network) !== 'v6') {
continue;
}
$mask = IP::convertLongIntMaskToDec($row['mask1'])
+ IP::convertLongIntMaskToDec($row['mask2'])
+ IP::convertLongIntMaskToDec($row['mask3'])
+ IP::convertLongIntMaskToDec($row['mask4']);
if (IP::isIpv6AddrInIpv6Network($extended_ip, $network, $mask) === 1) {
$status = (int)$row['status'];
if ($max_status === null || $status > $max_status) {
$max_status = $status;
}
}
}
$statuses[$ip] = $max_status;
} elseif (IP::validate($ip) === 'v4') {
$ip_uint = sprintf('%u', ip2long($ip));
// @psalm-suppress WpdbUnsafeMethodsIssue
$status = $wpdb->get_var(
'SELECT MAX(status) FROM ' . SPBC_TBL_FIREWALL_DATA__IPS_V4 . ' WHERE network = (' . $ip_uint . ' & mask)'
);
$statuses[$ip] = $status !== null ? (int)$status : null;
} else {
$statuses[$ip] = null;
}
}

return $statuses;
}

function spbc_field_security_logs__prepare_data(&$table)
{
if ($table->items_count) {
$personal_status_ips = array();
foreach ($table->rows as $row) {
$ips_c[] = $row->auth_ip;
$personal_status_ips[] = $row->auth_ip;
}
unset($row);
$ips_c = spbc_get_countries_by_ips(implode(',', $ips_c));
$personal_statuses = spbc_field_security_logs__get_personal_statuses($personal_status_ips);

$time_offset = current_time('timestamp') - time();

foreach ($table->rows as $row) {
// we need to use normalized IPv6 address for allow/ban actions
$ip = IP::validate($row->auth_ip) === 'v6'
? (IP::normalizeIPv6($row->auth_ip) ?: $row->auth_ip)
: $row->auth_ip;
$ip = $row->auth_ip;
$ip_attr = Escape::escAttr($ip);
$ip_js = Escape::escJs($ip);
$allow_layout = '<a href="#" onclick="return spbcSecLogsAllowIp(\''
. $ip_js
. '\')" class="spbcGreen tbl-row_action--allow" data-ip="' . $ip_attr . '">'
. esc_html__('Allow', 'security-malware-firewall') . '</a>';
$ban_layout = '<a href="#" onclick="return spbcSecLogsBanIp(\''
. $ip_js
. '\')" class="spbc---red tbl-row_action--ban" data-ip="' . $ip_attr . '">'
. esc_html__('Ban', 'security-malware-firewall') . '</a>';
$personal_status = isset($personal_statuses[$ip]) ? $personal_statuses[$ip] : null;

$allow_layout = ($personal_status !== null && $personal_status > 0)
? '<span class="spbcGray">' . esc_html__('Allowed', 'security-malware-firewall') . '</span>'
: '<a href="#" onclick="return spbcSecLogsAllowIp(\''
. $ip_js
. '\')" class="spbcGreen tbl-row_action--allow" data-ip="' . $ip_attr . '">'
. esc_html__('Allow', 'security-malware-firewall') . '</a>';
$ban_layout = ($personal_status !== null && $personal_status <= 0)
? '<span class="spbcGray">' . esc_html__('Banned', 'security-malware-firewall') . '</span>'
: '<a href="#" onclick="return spbcSecLogsBanIp(\''
. $ip_js
. '\')" class="spbc---red tbl-row_action--ban" data-ip="' . $ip_attr . '">'
. esc_html__('Ban', 'security-malware-firewall') . '</a>';

$user_part = $row->user_login;
$user = get_user_by('login', $row->user_login);
Expand Down
Loading