/** * @param $startIP * @param $endIP * @return array */ public static function rangeToCIDRs($startIP, $endIP) { $start_ip_printable = wfUtils::inet_ntop($startIP); if (filter_var($start_ip_printable, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { return self::rangeToCIDRsIPv4(current(unpack('N', substr($startIP, 12, 4))), current(unpack('N', substr($endIP, 12, 4)))); } $startIPBin = str_pad(wfHelperBin::bin2str($startIP), 128, '0', STR_PAD_LEFT); $endIPBin = str_pad(wfHelperBin::bin2str($endIP), 128, '0', STR_PAD_LEFT); $IPIncBin = $startIPBin; $CIDRs = array(); while (strcmp($IPIncBin, $endIPBin) <= 0) { $longNetwork = 128; $IPNetBin = $IPIncBin; while ($IPIncBin[$longNetwork - 1] == '0' && strcmp(substr_replace($IPNetBin, '1', $longNetwork - 1, 1), $endIPBin) <= 0) { $IPNetBin[$longNetwork - 1] = '1'; $longNetwork--; } $CIDRs[] = self::inet_ntop(str_pad(wfHelperBin::str2bin($IPIncBin), 16, "", STR_PAD_LEFT)) . ($longNetwork < 128 ? '/' . $longNetwork : ''); $IPIncBin = str_pad(wfHelperBin::bin2str(wfHelperBin::addbin2bin(chr(1), wfHelperBin::str2bin($IPNetBin))), 128, '0', STR_PAD_LEFT); } return $CIDRs; }
} $headers['User-Agent'] = $hit->UA; $headers['Referer'] = $hit->referer; $request->setHeaders($headers); preg_match('/request\\.([a-z]+)(?:\\[(.*?)\\](.*?))?/i', $hitData->paramKey, $matches); if ($matches) { switch ($matches[1]) { case 'body': $request->setMethod('POST'); parse_str("{$matches['2']}{$matches['3']}", $body); $request->setBody($body); break; } } } $request->setIP(wfUtils::inet_ntop($hit->IP)); $request->setTimestamp($hit->ctime); $waf = wfWAF::getInstance(); $waf->setRequest($request); $result = '<strong class="ok">Passed</strong>'; $failedRules = array(); try { $waf->runRules(); } catch (wfWAFAllowException $e) { $result = '<strong class="ok">Whitelisted</strong>'; } catch (wfWAFBlockException $e) { $result = '<strong class="error">Blocked</strong>'; $failedRules = $waf->getFailedRules(); } catch (wfWAFBlockSQLiException $e) { $result = '<strong class="error">Blocked For SQLi</strong>'; $failedRules = $waf->getFailedRules();
/** * */ public static function processAttackData() { global $wpdb; $waf = wfWAF::getInstance(); if ($waf->getStorageEngine()->getConfig('attackDataKey', false) === false) { $waf->getStorageEngine()->setConfig('attackDataKey', mt_rand(0, 0xfff)); } $limit = 500; $lastSendTime = wfConfig::get('lastAttackDataSendTime'); $attackData = $wpdb->get_results($wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS * FROM {$wpdb->base_prefix}wfHits\nWHERE action in ('blocked:waf', 'learned:waf')\nAND attackLogTime > %.6f\nLIMIT %d", $lastSendTime, $limit)); $totalRows = $wpdb->get_var('SELECT FOUND_ROWS()'); if ($attackData) { $response = wp_remote_get(sprintf(WFWAF_API_URL_SEC . "waf-rules/%d.txt", $waf->getStorageEngine()->getConfig('attackDataKey'))); if (!is_wp_error($response)) { $okToSendBody = wp_remote_retrieve_body($response); if ($okToSendBody === 'ok') { // Build JSON to send $dataToSend = array(); $attackDataToUpdate = array(); foreach ($attackData as $attackDataRow) { $actionData = (array) wfRequestModel::unserializeActionData($attackDataRow->actionData); $dataToSend[] = array($attackDataRow->attackLogTime, $attackDataRow->ctime, wfUtils::inet_ntop($attackDataRow->IP), array_key_exists('learningMode', $actionData) ? $actionData['learningMode'] : 0, array_key_exists('paramKey', $actionData) ? base64_encode($actionData['paramKey']) : false, array_key_exists('paramValue', $actionData) ? base64_encode($actionData['paramValue']) : false, array_key_exists('failedRules', $actionData) ? $actionData['failedRules'] : '', strpos($attackDataRow->URL, 'https') === 0 ? 1 : 0, array_key_exists('fullRequest', $actionData) ? $actionData['fullRequest'] : ''); if (array_key_exists('fullRequest', $actionData)) { unset($actionData['fullRequest']); $attackDataToUpdate[$attackDataRow->id] = array('actionData' => wfRequestModel::serializeActionData($actionData)); } if ($attackDataRow->attackLogTime > $lastSendTime) { $lastSendTime = $attackDataRow->attackLogTime; } } $response = wp_remote_post(WFWAF_API_URL_SEC . "?" . http_build_query(array('action' => 'send_waf_attack_data', 'k' => $waf->getStorageEngine()->getConfig('apiKey'), 's' => $waf->getStorageEngine()->getConfig('siteURL') ? $waf->getStorageEngine()->getConfig('siteURL') : sprintf('%s://%s/', $waf->getRequest()->getProtocol(), rawurlencode($waf->getRequest()->getHost())))), array('body' => json_encode($dataToSend), 'headers' => array('Content-Type' => 'application/json'), 'timeout' => 30)); if (!is_wp_error($response) && ($body = wp_remote_retrieve_body($response))) { $jsonData = json_decode($body, true); if (is_array($jsonData) && array_key_exists('success', $jsonData)) { // Successfully sent data, remove the full request from the table to reduce storage size foreach ($attackDataToUpdate as $hitID => $dataToUpdate) { $wpdb->update($wpdb->base_prefix . 'wfHits', $dataToUpdate, array('id' => $hitID)); } wfConfig::set('lastAttackDataSendTime', $lastSendTime); if ($totalRows > $limit) { self::scheduleSendAttackData(); } } } } else { if (is_string($okToSendBody) && preg_match('/next check in: ([0-9]+)/', $okToSendBody, $matches)) { self::scheduleSendAttackData(time() + $matches[1]); } } // Could be that the server is down, so hold off on sending data for a little while. } else { self::scheduleSendAttackData(time() + 7200); } } self::trimWfHits(); }
/** * @param mixed $ip_address * @param int|null $unixday */ public static function logBlockedIP($ip_address, $unixday = null) { /** @var wpdb $wpdb */ global $wpdb; if (wfUtils::isValidIP($ip_address)) { $ip_bin = wfUtils::inet_pton($ip_address); } else { $ip_bin = $ip_address; $ip_address = wfUtils::inet_ntop($ip_bin); } $blocked_table = "{$wpdb->base_prefix}wfBlockedIPLog"; $unixday_insert = 'FLOOR(UNIX_TIMESTAMP() / 86400)'; if (is_int($unixday)) { $unixday_insert = absint($unixday); } $country = wfUtils::IP2Country($ip_address); $wpdb->query($wpdb->prepare(<<<SQL INSERT INTO {$blocked_table} (IP, countryCode, blockCount, unixday) VALUES (%s, %s, 1, {$unixday_insert}) ON DUPLICATE KEY UPDATE blockCount = blockCount + 1 SQL , $ip_bin, $country)); }
public function displayIP($binaryIP) { $readableIP = wfUtils::inet_ntop($binaryIP); $country = wfUtils::countryCode2Name(wfUtils::IP2Country($readableIP)); return "{$readableIP} (" . ($country ? $country : 'Unknown') . ")"; }
public function resolveIPs(&$results) { if (sizeof($results) < 1) { return; } $IPs = array(); foreach ($results as &$res) { if ($res['IP']) { //Can also be zero in case of non IP events $IPs[] = $res['IP']; } } $IPLocs = wfUtils::getIPsGeo($IPs); //Creates an array with IP as key and data as value foreach ($results as &$res) { $ip_printable = wfUtils::inet_ntop($res['IP']); if (isset($IPLocs[$ip_printable])) { $res['loc'] = $IPLocs[$ip_printable]; } else { $res['loc'] = false; } } }
/** * */ public static function processAttackData() { global $wpdb; $waf = wfWAF::getInstance(); if ($waf->getStorageEngine()->getConfig('attackDataKey', false) === false) { $waf->getStorageEngine()->setConfig('attackDataKey', mt_rand(0, 0xfff)); } //Send alert email if needed if (wfConfig::get('wafAlertOnAttacks')) { $alertInterval = wfConfig::get('wafAlertInterval', 0); $cutoffTime = max(time() - $alertInterval, wfConfig::get('wafAlertLastSendTime')); $wafAlertWhitelist = wfConfig::get('wafAlertWhitelist', ''); $wafAlertWhitelist = preg_split("/[,\r\n]+/", $wafAlertWhitelist); foreach ($wafAlertWhitelist as $index => &$entry) { $entry = trim($entry); if (!preg_match('/^(?:\\d{1,3}(?:\\.|$)){4}/', $entry) && !preg_match('/^((?:[\\da-f]{1,4}(?::|)){0,8})(::)?((?:[\\da-f]{1,4}(?::|)){0,8})$/i', $entry)) { unset($wafAlertWhitelist[$index]); continue; } $packed = @wfUtils::inet_pton($entry); if ($packed === false) { unset($wafAlertWhitelist[$index]); continue; } $entry = bin2hex($packed); } $wafAlertWhitelist = array_filter($wafAlertWhitelist); $attackData = $wpdb->get_results($wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS * FROM {$wpdb->base_prefix}wfHits\n\tWHERE action = 'blocked:waf' " . (count($wafAlertWhitelist) ? "AND HEX(IP) NOT IN (" . implode(", ", array_fill(0, count($wafAlertWhitelist), '%s')) . ")" : "") . "AND attackLogTime > %.6f\n\tORDER BY attackLogTime DESC\n\tLIMIT 10", array_merge($wafAlertWhitelist, array($cutoffTime)))); $attackCount = $wpdb->get_var('SELECT FOUND_ROWS()'); if ($attackCount >= wfConfig::get('wafAlertThreshold')) { $durationMessage = wfUtils::makeDuration($alertInterval); $message = <<<ALERTMSG The Wordfence Web Application Firewall has blocked {$attackCount} attacks over the last {$durationMessage}. Below is a sample of these recent attacks: ALERTMSG; $attackTable = array(); $dateMax = $ipMax = $countryMax = 0; foreach ($attackData as $row) { $row->longDescription = "Blocked for " . $row->actionDescription; $actionData = json_decode($row->actionData, true); if (!is_array($actionData) || !isset($actionData['paramKey']) || !isset($actionData['paramValue'])) { continue; } $paramKey = base64_decode($actionData['paramKey']); $paramValue = base64_decode($actionData['paramValue']); if (strlen($paramValue) > 100) { $paramValue = substr($paramValue, 0, 100) . chr(2026); } if (preg_match('/([a-z0-9_]+\\.[a-z0-9_]+)(?:\\[(.+?)\\](.*))?/i', $paramKey, $matches)) { switch ($matches[1]) { case 'request.queryString': $row->longDescription = "Blocked for " . $row->actionDescription . ' in query string: ' . $matches[2] . '=' . $paramValue; break; case 'request.body': $row->longDescription = "Blocked for " . $row->actionDescription . ' in POST body: ' . $matches[2] . '=' . $paramValue; break; case 'request.cookie': $row->longDescription = "Blocked for " . $row->actionDescription . ' in cookie: ' . $matches[2] . '=' . $paramValue; break; case 'request.fileNames': $row->longDescription = "Blocked for a " . $row->actionDescription . ' in file: ' . $matches[2] . '=' . $paramValue; break; } } $date = date_i18n('F j, Y g:ia', floor($row->attackLogTime)); $dateMax = max(strlen($date), $dateMax); $ip = wfUtils::inet_ntop($row->IP); $ipMax = max(strlen($ip), $ipMax); $country = wfUtils::countryCode2Name(wfUtils::IP2Country($ip)); $country = empty($country) ? 'Unknown' : $country; $countryMax = max(strlen($country), $countryMax); $attackTable[] = array('date' => $date, 'IP' => $ip, 'country' => $country, 'message' => $row->longDescription); } foreach ($attackTable as $row) { $date = str_pad($row['date'], $dateMax + 2); $ip = str_pad($row['IP'] . " ({$row['country']})", $ipMax + $countryMax + 8); $attackMessage = $row['message']; $message .= $date . $ip . $attackMessage . "\n"; } self::alert('Increased Attack Rate', $message, false); wfConfig::set('wafAlertLastSendTime', time()); } } //Send attack data $limit = 500; $lastSendTime = wfConfig::get('lastAttackDataSendTime'); $attackData = $wpdb->get_results($wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS * FROM {$wpdb->base_prefix}wfHits\nWHERE action in ('blocked:waf', 'learned:waf', 'logged:waf', 'blocked:waf-always')\nAND attackLogTime > %.6f\nLIMIT %d", $lastSendTime, $limit)); $totalRows = $wpdb->get_var('SELECT FOUND_ROWS()'); if ($attackData && wfConfig::get('other_WFNet', true)) { $response = wp_remote_get(sprintf(WFWAF_API_URL_SEC . "waf-rules/%d.txt", $waf->getStorageEngine()->getConfig('attackDataKey'))); if (!is_wp_error($response)) { $okToSendBody = wp_remote_retrieve_body($response); if ($okToSendBody === 'ok') { // Build JSON to send $dataToSend = array(); $attackDataToUpdate = array(); foreach ($attackData as $attackDataRow) { $actionData = (array) wfRequestModel::unserializeActionData($attackDataRow->actionData); $dataToSend[] = array($attackDataRow->attackLogTime, $attackDataRow->ctime, wfUtils::inet_ntop($attackDataRow->IP), array_key_exists('learningMode', $actionData) ? $actionData['learningMode'] : 0, array_key_exists('paramKey', $actionData) ? base64_encode($actionData['paramKey']) : false, array_key_exists('paramValue', $actionData) ? base64_encode($actionData['paramValue']) : false, array_key_exists('failedRules', $actionData) ? $actionData['failedRules'] : '', strpos($attackDataRow->URL, 'https') === 0 ? 1 : 0, array_key_exists('fullRequest', $actionData) ? $actionData['fullRequest'] : ''); if (array_key_exists('fullRequest', $actionData)) { unset($actionData['fullRequest']); $attackDataToUpdate[$attackDataRow->id] = array('actionData' => wfRequestModel::serializeActionData($actionData)); } if ($attackDataRow->attackLogTime > $lastSendTime) { $lastSendTime = $attackDataRow->attackLogTime; } } $response = wp_remote_post(WFWAF_API_URL_SEC . "?" . http_build_query(array('action' => 'send_waf_attack_data', 'k' => $waf->getStorageEngine()->getConfig('apiKey'), 's' => $waf->getStorageEngine()->getConfig('siteURL') ? $waf->getStorageEngine()->getConfig('siteURL') : sprintf('%s://%s/', $waf->getRequest()->getProtocol(), rawurlencode($waf->getRequest()->getHost())), 't' => microtime(true)), null, '&'), array('body' => json_encode($dataToSend), 'headers' => array('Content-Type' => 'application/json'), 'timeout' => 30)); if (!is_wp_error($response) && ($body = wp_remote_retrieve_body($response))) { $jsonData = json_decode($body, true); if (is_array($jsonData) && array_key_exists('success', $jsonData)) { // Successfully sent data, remove the full request from the table to reduce storage size foreach ($attackDataToUpdate as $hitID => $dataToUpdate) { $wpdb->update($wpdb->base_prefix . 'wfHits', $dataToUpdate, array('id' => $hitID)); } wfConfig::set('lastAttackDataSendTime', $lastSendTime); if ($totalRows > $limit) { self::scheduleSendAttackData(); } if (array_key_exists('data', $jsonData) && array_key_exists('watchedIPList', $jsonData['data'])) { $waf->getStorageEngine()->setConfig('watchedIPs', $jsonData['data']['watchedIPList']); } } } } else { if (is_string($okToSendBody) && preg_match('/next check in: ([0-9]+)/', $okToSendBody, $matches)) { self::scheduleSendAttackData(time() + $matches[1]); } } // Could be that the server is down, so hold off on sending data for a little while. } else { self::scheduleSendAttackData(time() + 7200); } } else { if (!wfConfig::get('other_WFNet', true)) { wfConfig::set('lastAttackDataSendTime', time()); } } self::trimWfHits(); }
<th>Block Count</th> </tr> </thead> <tbody> <?php if ($top_ips_blocked) { ?> <?php foreach ($top_ips_blocked as $row) { ?> <tr class="<?php echo wfHelperString::cycle('odd', 'even'); ?> "> <td><code><?php echo wfUtils::inet_ntop($row->IP); ?> </code></td> <td> <?php if ($row->countryCode) { ?> <img src="//www.wordfence.com/images/flags/<?php echo esc_attr(strtolower($row->countryCode)); ?> .png" class="wfFlag" height="11" width="16" alt="<?php echo esc_attr($row->countryName); ?> " title="<?php echo esc_attr($row->countryName); ?>
/** * @param $action * @return bool|string|void */ public static function updateBlockedIPs($action) { //'add' or 'remove' if (wfConfig::get('cacheType') != 'falcon') { return; } $htaccessPath = self::getHtaccessPath(); if (!$htaccessPath) { return "Wordfence could not find your .htaccess file."; } if ($action == 'remove') { $fh = @fopen($htaccessPath, 'r+'); if (!$fh) { $err = error_get_last(); return $err['message']; } flock($fh, LOCK_EX); fseek($fh, 0, SEEK_SET); //start of file clearstatcache(); $contents = @fread($fh, filesize($htaccessPath)); if (!$contents) { fclose($fh); return "Could not read from {$htaccessPath}"; } $contents = preg_replace('/#WFIPBLOCKS.*WFIPBLOCKS[r\\s\\n\\t]*/s', '', $contents); ftruncate($fh, 0); fseek($fh, 0, SEEK_SET); @fwrite($fh, $contents); flock($fh, LOCK_UN); fclose($fh); return false; } else { if ($action == 'add') { $fh = @fopen($htaccessPath, 'r+'); if (!$fh) { $err = error_get_last(); return $err['message']; } $lines = array(); $wfLog = new wfLog(wfConfig::get('apiKey'), wfUtils::getWPVersion()); $IPs = $wfLog->getBlockedIPsAddrOnly(); if (sizeof($IPs) > 0) { foreach ($IPs as $IP) { $lines[] = "Deny from {$IP}\n"; } } $ranges = $wfLog->getRangesBasic(); $browserAdded = false; $browserLines = array(); if ($ranges) { foreach ($ranges as $r) { $arr = explode('|', $r); $range = isset($arr[0]) ? $arr[0] : false; $browser = isset($arr[1]) ? $arr[1] : false; $referer = isset($arr[2]) ? $arr[2] : false; if ($range) { if ($browser || $referer) { continue; } //We don't allow combos in falcon list($start_range, $end_range) = explode('-', $range); if (preg_match('/[\\.:]/', $start_range)) { $start_range = wfUtils::inet_pton($start_range); $end_range = wfUtils::inet_pton($end_range); } else { $start_range = wfUtils::inet_pton(long2ip($start_range)); $end_range = wfUtils::inet_pton(long2ip($end_range)); } $cidrs = wfUtils::rangeToCIDRs($start_range, $end_range); $hIPs = wfUtils::inet_ntop($start_range) . ' - ' . wfUtils::inet_ntop($end_range); if (sizeof($cidrs) > 0) { $lines[] = '#Start of blocking code for IP range: ' . $hIPs . "\n"; foreach ($cidrs as $c) { $lines[] = "Deny from {$c}\n"; } $lines[] = '#End of blocking code for IP range: ' . $hIPs . "\n"; } } else { if ($browser) { if ($range || $referer) { continue; } $browserLines[] = "\t#Blocking code for browser pattern: {$browser}\n"; $browser = preg_replace('/([\\-\\_\\.\\+\\!\\@\\#\\$\\%\\^\\&\\(\\)\\[\\]\\{\\}\\/])/', "\\\\\$1", $browser); $browser = preg_replace('/\\*/', '.*', $browser); $browserLines[] = "\tSetEnvIf User-Agent " . $browser . " WordfenceBadBrowser=1\n"; $browserAdded = true; } else { if ($referer) { if ($browser || $range) { continue; } $browserLines[] = "\t#Blocking code for referer pattern: {$referer}\n"; $referer = preg_replace('/([\\-\\_\\.\\+\\!\\@\\#\\$\\%\\^\\&\\(\\)\\[\\]\\{\\}\\/])/', "\\\\\$1", $referer); $referer = preg_replace('/\\*/', '.*', $referer); $browserLines[] = "\tSetEnvIf Referer " . $referer . " WordfenceBadBrowser=1\n"; $browserAdded = true; } } } } } if ($browserAdded) { $lines[] = "<IfModule mod_setenvif.c>\n"; foreach ($browserLines as $l) { $lines[] = $l; } $lines[] = "\tDeny from env=WordfenceBadBrowser\n"; $lines[] = "</IfModule>\n"; } } } $blockCode = "#WFIPBLOCKS - Do not remove this line. Disable Web Caching in Wordfence to remove this data.\nOrder Deny,Allow\n"; $blockCode .= implode('', $lines); $blockCode .= "#Do not remove this line. Disable Web Caching in Wordfence to remove this data - WFIPBLOCKS\n"; //Minimize time between lock/unlock flock($fh, LOCK_EX); fseek($fh, 0, SEEK_SET); //start of file clearstatcache(); //Or we get the wrong size from a cached entry and corrupt the file $contents = @fread($fh, filesize($htaccessPath)); if (!$contents) { fclose($fh); return "Could not read from {$htaccessPath}"; } $contents = preg_replace('/#WFIPBLOCKS.*WFIPBLOCKS[r\\s\\n\\t]*/s', '', $contents); $contents = $blockCode . $contents; ftruncate($fh, 0); fseek($fh, 0, SEEK_SET); @fwrite($fh, $contents); flock($fh, LOCK_UN); fclose($fh); return false; }
/** * @return array */ public static function ajax_blockIPUARange_callback() { $ipRange = trim($_POST['ipRange']); $uaRange = trim($_POST['uaRange']); $referer = trim($_POST['referer']); $reason = trim($_POST['reason']); if (preg_match('/\\|+/', $ipRange . $uaRange . $referer)) { return array('err' => 1, 'errorMsg' => "You are not allowed to include a pipe character \"|\" in your IP range, browser pattern or referer"); } if (!$ipRange && wfUtils::isUABlocked($uaRange)) { return array('err' => 1, 'errorMsg' => "The browser pattern you specified will block you from your own website. We have not accepted this pattern to protect you from being blocked."); } if (fnmatch($referer, site_url(), FNM_CASEFOLD)) { return array('err' => 1, 'errorMsg' => "The referer pattern you specified matches your own website and will block visitors as they surf from one page to another on your site. You can't enter this pattern."); } if ($ipRange) { list($start_range, $end_range) = explode('-', $ipRange); if (!wfUtils::isValidIP($start_range) || !wfUtils::isValidIP($end_range)) { return array('err' => 1, 'errorMsg' => "The IP range you specified is not valid. Please specify an IP range like the following example: \"1.2.3.4 - 1.2.3.8\" without quotes."); } $ip1 = wfUtils::inet_pton($start_range); $ip2 = wfUtils::inet_pton($end_range); if (strcmp($ip1, $ip2) >= 0) { return array('err' => 1, 'errorMsg' => "The first IP address in your range must be less than the second IP address in your range."); } $clientIP = wfUtils::inet_pton(wfUtils::getIP()); if (strcmp($ip1, $clientIP) <= 0 && strcmp($ip2, $clientIP) >= 0) { return array('err' => 1, 'errorMsg' => "You are trying to block yourself. Your IP address is " . wp_kses(wfUtils::getIP(), array()) . " which falls into the range " . wp_kses($ipRange, array()) . ". This blocking action has been cancelled so that you don't block yourself from your website."); } $ipRange = wfUtils::inet_ntop($ip1) . '-' . wfUtils::inet_ntop($ip2); } $range = $ipRange . '|' . $uaRange . '|' . $referer; self::getLog()->blockRange('IU', $range, $reason); return array('ok' => 1); }
/** * Permanently blocks all temporarily locked out IPs. */ public static function ajax_permanentlyBlockAllIPs_callback() { /** @var wpdb $wpdb */ global $wpdb; $IPs = array(); $type = !empty($_REQUEST['type']) ? $_REQUEST['type'] : null; $reason = !empty($_REQUEST['reason']) ? $_REQUEST['reason'] : 'Manual block by administrator'; switch ($type) { case 'throttled': $IPs = $wpdb->get_col('SELECT DISTINCT IP FROM ' . $wpdb->base_prefix . 'wfThrottleLog'); break; case 'lockedOut': $lockoutSecs = wfConfig::get('loginSec_lockoutMins') * 60; $IPs = $wpdb->get_col($wpdb->prepare('SELECT DISTINCT IP FROM ' . $wpdb->base_prefix . 'wfLockedOut WHERE blockedTime + %d > UNIX_TIMESTAMP()', $lockoutSecs)); break; case 'blocked': $blockedTime = wfConfig::get('blockedTime'); $IPs = $wpdb->get_col($wpdb->prepare('SELECT DISTINCT IP FROM ' . $wpdb->base_prefix . 'wfBlocks WHERE wfsn = 0 AND permanent = 0 AND blockedTime + %d > UNIX_TIMESTAMP()', $blockedTime)); break; } if ($IPs && is_array($IPs)) { foreach ($IPs as $IP) { self::getLog()->blockIP(wfUtils::inet_ntop($IP), $reason, false, true); } } switch ($type) { case 'lockedOut': if ($IPs) { foreach ($IPs as &$IP) { $IP = $wpdb->prepare('%s', $IP); } $wpdb->query('DELETE FROM ' . $wpdb->base_prefix . 'wfLockedOut WHERE IP IN (' . join(', ', $IPs) . ')'); } break; } return array('ok' => 1); }