public function downgrade_license() { $api = new wfAPI('', wfUtils::getWPVersion()); $return = array(); try { $keyData = $api->call('get_anon_api_key'); if ($keyData['ok'] && $keyData['apiKey']) { wfConfig::set('apiKey', $keyData['apiKey']); wfConfig::set('isPaid', 0); $return['apiKey'] = $keyData['apiKey']; $return['isPaid'] = 0; //When downgrading we must disable all two factor authentication because it can lock an admin out if we don't. wfConfig::set_ser('twoFactorUsers', array()); } else { throw new Exception('Could not understand the response we received from the Wordfence servers when applying for a free API key.'); } } catch (Exception $e) { $return['errorMsg'] = 'Could not fetch free API key from Wordfence: ' . htmlentities($e->getMessage()); return $return; } $return['ok'] = 1; return $return; }
public static function getIPsGeo($IPs) { //works with int or dotted. Outputs same format it receives. $IPs = array_unique($IPs); $toResolve = array(); $db = new wfDB(); global $wpdb; $locsTable = $wpdb->base_prefix . 'wfLocs'; $IPLocs = array(); foreach ($IPs as $IP) { $isBinaryIP = !self::isValidIP($IP); if ($isBinaryIP) { $ip_printable = wfUtils::inet_ntop($IP); $ip_bin = $IP; } else { $ip_printable = $IP; $ip_bin = wfUtils::inet_pton($IP); } $row = $db->querySingleRec("select IP, ctime, failed, city, region, countryName, countryCode, lat, lon, unix_timestamp() - ctime as age from " . $locsTable . " where IP=%s", $ip_bin); if ($row) { if ($row['age'] > WORDFENCE_MAX_IPLOC_AGE) { $db->queryWrite("delete from " . $locsTable . " where IP=%s", $row['IP']); } else { if ($row['failed'] == 1) { $IPLocs[$ip_printable] = false; } else { $row['IP'] = self::inet_ntop($row['IP']); $IPLocs[$ip_printable] = $row; } } } if (!isset($IPLocs[$ip_printable])) { $toResolve[] = $ip_printable; } } if (sizeof($toResolve) > 0) { $api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion()); try { $freshIPs = $api->call('resolve_ips', array(), array('ips' => implode(',', $toResolve))); if (is_array($freshIPs)) { foreach ($freshIPs as $IP => $value) { $IP_bin = wfUtils::inet_pton($IP); if ($value == 'failed') { $db->queryWrite("insert IGNORE into " . $locsTable . " (IP, ctime, failed) values (%s, unix_timestamp(), 1)", $IP_bin); $IPLocs[$IP] = false; } else { if (is_array($value)) { for ($i = 0; $i <= 5; $i++) { //Prevent warnings in debug mode about uninitialized values if (!isset($value[$i])) { $value[$i] = ''; } } $db->queryWrite("insert IGNORE into " . $locsTable . " (IP, ctime, failed, city, region, countryName, countryCode, lat, lon) values (%s, unix_timestamp(), 0, '%s', '%s', '%s', '%s', %s, %s)", $IP_bin, $value[3], $value[2], $value[1], $value[0], $value[4], $value[5]); $IPLocs[$IP] = array('IP' => $IP, 'city' => $value[3], 'region' => $value[2], 'countryName' => $value[1], 'countryCode' => $value[0], 'lat' => $value[4], 'lon' => $value[5]); } } } } } catch (Exception $e) { wordfence::status(2, 'error', "Call to Wordfence API to resolve IPs failed: " . $e->getMessage()); return array(); } } return $IPLocs; }
public static function preCommentApprovedFilter($approved, $cData) { if ($approved == 1 && !is_user_logged_in() && wfConfig::get('other_noAnonMemberComments')) { $user = get_user_by('email', trim($cData['comment_author_email'])); if ($user) { wfConfig::inc('totalSpamStopped'); return 0; //hold for moderation if the user is not signed in but used a members email } } if (($approved == 1 || $approved == 0) && wfConfig::get('other_scanComments')) { $wf = new wfScanEngine(); try { if ($wf->isBadComment($cData['comment_author'], $cData['comment_author_email'], $cData['comment_author_url'], $cData['comment_author_IP'], $cData['comment_content'])) { wfConfig::inc('totalSpamStopped'); return 'spam'; } } catch (Exception $e) { //This will most likely be an API exception because we can't contact the API, so we ignore it and let the normal comment mechanisms run. } } if (wfConfig::get('isPaid') && ($approved == 1 || $approved == 0) && wfConfig::get('advancedCommentScanning')) { self::$commentSpamItems = array(); preg_replace_callback('/(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})/', 'wordfence::pushCommentSpamIP', $cData['comment_content']); $IPs = self::$commentSpamItems; self::$commentSpamItems = array(); preg_replace_callback('/https?:\\/\\/([a-zA-Z0-9\\-]+\\.[a-zA-Z0-9\\-\\.]+[a-zA-Z0-9])/i', 'wordfence::pushCommentSpamHost', $cData['comment_content']); $hosts = self::$commentSpamItems; self::$commentSpamItems = array(); try { $api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion()); $res = $api->call('advanced_comment_scan', array(), array('author' => $cData['comment_author'], 'email' => $cData['comment_author_email'], 'URL' => $cData['comment_author_url'], 'commentIP' => $cData['comment_author_IP'], 'wfIP' => wfUtils::getIP(), 'hosts' => sizeof($hosts) > 0 ? implode(',', $hosts) : '', 'IPs' => sizeof($IPs) > 0 ? implode(',', $IPs) : '')); if (is_array($res) && isset($res['spam']) && $res['spam'] == 1) { wfConfig::inc('totalSpamStopped'); return 'spam'; } } catch (Exception $e) { //API server is probably down } } wfConfig::inc('totalCommentsFiltered'); return $approved; }
/** * @throws wfScanKnownFilesException */ public function fetchKnownFiles() { try { $dataArr = $this->api->binCall('get_known_files', json_encode(array('plugins' => $this->plugins, 'themes' => $this->themes))); if ($dataArr['code'] != 200) { throw new wfScanKnownFilesException("Got error response from Wordfence servers: " . $dataArr['code'], $dataArr['code']); } $this->knownFiles = @json_decode($dataArr['data'], true); if (!is_array($this->knownFiles)) { throw new wfScanKnownFilesException("Invalid response from Wordfence servers."); } } catch (Exception $e) { throw new wfScanKnownFilesException($e->getMessage(), $e->getCode(), $e); } }
/** * @param string|null $ip * @return bool */ public static function verifyGooglebotViaNOC1($ip = null) { global $wpdb; $table = $wpdb->base_prefix . 'wfCrawlers'; if ($ip === null) { $ip = wfUtils::getIP(); } $db = new wfDB(); $IPn = wfUtils::inet_pton($ip); $patternSig = 'googlenoc1'; $status = $db->querySingle("select status from {$table}\n\t\t\t\twhere IP=%s\n\t\t\t\tand patternSig=UNHEX(MD5('%s'))\n\t\t\t\tand lastUpdate > unix_timestamp() - %d", $IPn, $patternSig, WORDFENCE_CRAWLER_VERIFY_CACHE_TIME); if ($status === 'verified') { return true; } else { if ($status === 'fakeBot') { return false; } } $api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion()); try { $data = $api->call('verify_googlebot', array('ip' => $ip)); if (is_array($data) && !empty($data['verified'])) { // Cache results $db->queryWrite("insert into {$table} (IP, patternSig, status, lastUpdate)\nvalues (%s, UNHEX(MD5('%s')), '%s', unix_timestamp())\nON DUPLICATE KEY UPDATE status='%3\$s', lastUpdate=unix_timestamp()", $IPn, $patternSig, 'verified'); return true; } else { $db->queryWrite("insert into {$table} (IP, patternSig, status, lastUpdate)\nvalues (%s, UNHEX(MD5('%s')), '%s', unix_timestamp())\nON DUPLICATE KEY UPDATE status='%3\$s', lastUpdate=unix_timestamp()", $IPn, $patternSig, 'fakeBot'); } } catch (Exception $e) { // Do nothing, bail } return false; }
public static function ajax_saveConfig_callback() { $reload = ''; $opts = wfConfig::parseOptions(); $emails = array(); foreach (explode(',', preg_replace('/[\\r\\n\\s\\t]+/', '', $opts['alertEmails'])) as $email) { if (strlen($email) > 0) { array_push($emails, $email); } } if (sizeof($emails) > 0) { $badEmails = array(); foreach ($emails as $email) { if (!preg_match('/^[^@]+@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,8})$/i', $email)) { array_push($badEmails, $email); } } if (sizeof($badEmails) > 0) { return array('errorMsg' => "The following emails are invalid: " . htmlentities(implode(', ', $badEmails))); } $opts['alertEmails'] = implode(',', $emails); } else { $opts['alertEmails'] = ''; } $whiteIPs = array(); foreach (explode(',', preg_replace('/[\\r\\n\\s\\t]+/', '', $opts['whitelisted'])) as $whiteIP) { if (strlen($whiteIP) > 0) { array_push($whiteIPs, $whiteIP); } } if (sizeof($whiteIPs) > 0) { $badWhiteIPs = array(); foreach ($whiteIPs as $whiteIP) { if (!preg_match('/^[\\[\\]\\-\\d]+\\.[\\[\\]\\-\\d]+\\.[\\[\\]\\-\\d]+\\.[\\[\\]\\-\\d]+$/', $whiteIP)) { array_push($badWhiteIPs, $whiteIP); } } if (sizeof($badWhiteIPs) > 0) { return array('errorMsg' => "Please make sure you separate your IP addresses with commas. The following whitelisted IP addresses are invalid: " . htmlentities(implode(', ', $badWhiteIPs))); } $opts['whitelisted'] = implode(',', $whiteIPs); } else { $opts['whitelisted'] = ''; } $validUsers = array(); $invalidUsers = array(); foreach (explode(',', $opts['liveTraf_ignoreUsers']) as $val) { $val = trim($val); if (strlen($val) > 0) { if (get_user_by('login', $val)) { array_push($validUsers, $val); } else { array_push($invalidUsers, $val); } } } $opts['apiKey'] = trim($opts['apiKey']); if ($opts['apiKey'] && !preg_match('/^[a-fA-F0-9]+$/', $opts['apiKey'])) { //User entered something but it's garbage. return array('errorMsg' => "You entered an API key but it is not in a valid format. It must consist only of characters A to F and 0 to 9."); } if (sizeof($invalidUsers) > 0) { return array('errorMsg' => "The following users you selected to ignore in live traffic reports are not valid on this system: " . htmlentities(implode(', ', $invalidUsers))); } if (sizeof($validUsers) > 0) { $opts['liveTraf_ignoreUsers'] = implode(',', $validUsers); } else { $opts['liveTraf_ignoreUsers'] = ''; } $validIPs = array(); $invalidIPs = array(); foreach (explode(',', preg_replace('/[\\r\\n\\s\\t]+/', '', $opts['liveTraf_ignoreIPs'])) as $val) { if (strlen($val) > 0) { if (preg_match('/^\\d+\\.\\d+\\.\\d+\\.\\d+$/', $val)) { array_push($validIPs, $val); } else { array_push($invalidIPs, $val); } } } if (sizeof($invalidIPs) > 0) { return array('errorMsg' => "The following IPs you selected to ignore in live traffic reports are not valid: " . htmlentities(implode(', ', $invalidIPs))); } if (sizeof($validIPs) > 0) { $opts['liveTraf_ignoreIPs'] = implode(',', $validIPs); } if (preg_match('/[a-zA-Z0-9\\d]+/', $opts['liveTraf_ignoreUA'])) { $opts['liveTraf_ignoreUA'] = trim($opts['liveTraf_ignoreUA']); } else { $opts['liveTraf_ignoreUA'] = ''; } if (!$opts['other_WFNet']) { $wfdb = new wfDB(); global $wpdb; $p = $wpdb->base_prefix; $wfdb->queryWrite("delete from {$p}" . "wfBlocks where wfsn=1 and permanent=0"); } if ($opts['howGetIPs'] != wfConfig::get('howGetIPs', '')) { $reload = 'reload'; } foreach ($opts as $key => $val) { if ($key != 'apiKey') { //Don't save API key yet wfConfig::set($key, $val); } } $paidKeyMsg = false; if (!$opts['apiKey']) { //Empty API key (after trim above), then try to get one. $api = new wfAPI('', wfUtils::getWPVersion()); try { $keyData = $api->call('get_anon_api_key'); if ($keyData['ok'] && $keyData['apiKey']) { wfConfig::set('apiKey', $keyData['apiKey']); wfConfig::set('isPaid', 0); $reload = 'reload'; } else { throw new Exception("We could not understand the Wordfence server's response because it did not contain an 'ok' and 'apiKey' element."); } } catch (Exception $e) { return array('errorMsg' => "Your options have been saved, but we encountered a problem. You left your API key blank, so we tried to get you a free API key from the Wordfence servers. However we encountered a problem fetching the free key: " . htmlentities($e->getMessage())); } } else { if ($opts['apiKey'] != wfConfig::get('apiKey')) { $api = new wfAPI($opts['apiKey'], wfUtils::getWPVersion()); try { $res = $api->call('check_api_key', array(), array()); if ($res['ok'] && isset($res['isPaid'])) { wfConfig::set('apiKey', $opts['apiKey']); $reload = 'reload'; wfConfig::set('isPaid', $res['isPaid']); //res['isPaid'] is boolean coming back as JSON and turned back into PHP struct. Assuming JSON to PHP handles bools. if ($res['isPaid']) { $paidKeyMsg = true; } } else { throw new Exception("We could not understand the Wordfence API server reply when updating your API key."); } } catch (Exception $e) { return array('errorMsg' => "Your options have been saved. However we noticed you changed your API key and we tried to verify it with the Wordfence servers and received an error: " . htmlentities($e->getMessage())); } } } return array('ok' => 1, 'reload' => $reload, 'paidKeyMsg' => $paidKeyMsg); }