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;
 }
Example #2
0
 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;
 }
Example #3
0
 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;
 }
Example #4
0
 /**
  * @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);
     }
 }
Example #5
0
 /**
  * @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;
 }
Example #6
0
 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);
 }