PluginProbe ʕ •ᴥ•ʔ
Wordfence Security – Firewall, Malware Scan, and Login Security / 3.2.4
Wordfence Security – Firewall, Malware Scan, and Login Security v3.2.4
8.2.2 8.2.1 8.2.0 3.7.1 3.7.2 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.8.8 3.8.9 3.9.1 4.0.1 4.0.2 4.0.3 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.0.9 5.1.1 5.1.2 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.2.1 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.1 5.3.10 5.3.11 5.3.12 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.3.8 5.3.9 6.0.1 6.0.10 6.0.11 6.0.12 6.0.14 6.0.15 6.0.16 6.0.17 6.0.18 6.0.19 6.0.2 6.0.20 6.0.21 6.0.22 6.0.23 6.0.24 6.0.25 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.0.8 6.0.9 6.1.1 6.1.10 6.1.11 6.1.12 6.1.14 6.1.15 6.1.16 6.1.17 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6 6.1.7 6.1.8 6.1.9 6.2.0 6.2.1 6.2.10 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.2.8 6.2.9 6.3.0 6.3.1 6.3.10 6.3.11 6.3.12 6.3.14 6.3.15 6.3.16 6.3.17 6.3.18 6.3.19 6.3.2 6.3.20 6.3.21 6.3.22 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.3.8 6.3.9 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1.0 7.1.1 7.1.10 7.1.11 7.1.12 7.1.14 7.1.15 7.1.16 7.1.17 7.1.18 7.1.19 7.1.2 7.1.20 7.1.3 7.1.4 7.1.5 7.1.6 7.1.7 7.1.8 7.1.9 7.10.0 7.10.1 7.10.2 7.10.3 7.10.4 7.10.5 7.10.6 7.10.7 7.11.0 7.11.1 7.11.2 7.11.3 7.11.4 7.11.5 7.11.6 7.11.7 7.2.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3.1 7.3.2 7.3.3 7.3.4 7.3.5 7.3.6 7.4.0 7.4.1 7.4.10 7.4.11 7.4.12 7.4.14 7.4.2 7.4.3 trunk 7.4.4 1.1 7.4.5 1.2 7.4.6 1.3 7.4.7 1.3.1 7.4.8 1.3.2 7.4.9 1.3.3 7.5.0 1.4.2 7.5.1 1.4.3 7.5.10 1.4.4 7.5.11 1.4.5 7.5.2 1.4.6 7.5.3 1.4.7 7.5.4 1.4.8 7.5.5 1.5.1 7.5.6 1.5.2 7.5.7 1.5.3 7.5.8 1.5.4 7.5.9 1.5.5 7.6.0 1.5.6 7.6.1 2.0.1 7.6.2 2.0.2 7.7.0 2.0.3 7.7.1 2.0.5 7.8.0 2.0.6 7.8.1 2.0.7 7.8.2 2.1.0 7.9.0 2.1.1 7.9.1 2.1.2 7.9.2 2.1.3 7.9.3 2.1.4 8.0.0 2.1.5 8.0.1 3.0.2 8.0.2 3.0.3 8.0.3 3.0.4 8.0.4 3.0.5 8.0.5 3.0.6 8.1.0 3.0.7 8.1.1 3.0.8 8.1.2 3.0.9 8.1.3 3.1.0 8.1.4 3.1.1 v1.4.1 3.1.2 3.1.4 3.1.6 3.2.1 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.1 3.4.4 3.4.5 3.5.1 3.5.2 3.6.1 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.6.9
wordfence / lib / wfUtils.php
wordfence / lib Last commit date
Diff 14 years ago .htaccess 14 years ago Diff.php 14 years ago GeoIP.dat 13 years ago IPTraf.php 13 years ago diffResult.php 14 years ago email_genericAlert.php 14 years ago email_newIssues.php 14 years ago email_unlockRequest.php 14 years ago menu_activity.php 13 years ago menu_blockedIPs.php 13 years ago menu_countryBlocking.php 13 years ago menu_options.php 13 years ago menu_scan.php 13 years ago menu_scanSchedule.php 13 years ago schedWeekEntry.php 13 years ago sysinfo.php 14 years ago unknownFiles.php 13 years ago viewFullActivityLog.php 13 years ago wf503.php 13 years ago wfAPI.php 13 years ago wfAction.php 14 years ago wfArray.php 13 years ago wfBrowscap.php 14 years ago wfBrowscapCache.php 14 years ago wfBulkCountries.php 13 years ago wfConfig.php 13 years ago wfCountryMap.php 13 years ago wfCrawl.php 13 years ago wfDB.php 13 years ago wfDict.php 14 years ago wfGeoIP.php 13 years ago wfIssues.php 13 years ago wfLockedOut.php 14 years ago wfLog.php 13 years ago wfModTracker.php 14 years ago wfRate.php 14 years ago wfScanEngine.php 13 years ago wfSchema.php 13 years ago wfUnlockMsg.php 14 years ago wfUtils.php 13 years ago wfViewResult.php 14 years ago wordfenceClass.php 13 years ago wordfenceConstants.php 13 years ago wordfenceHash.php 13 years ago wordfenceScanner.php 13 years ago wordfenceURLHoover.php 13 years ago
wfUtils.php
460 lines
1 <?php
2 require_once('wfConfig.php');
3 require_once('wfCountryMap.php');
4 class wfUtils {
5 private static $isWindows = false;
6 public static $scanLockFH = false;
7 private static $lastErrorReporting = false;
8 private static $lastDisplayErrors = false;
9 public static function makeTimeAgo($secs, $noSeconds = false) {
10 if($secs < 1){
11 return "a moment";
12 }
13 $months = floor($secs / (86400 * 30));
14 $days = floor($secs / 86400);
15 $hours = floor($secs / 3600);
16 $minutes = floor($secs / 60);
17 if($months) {
18 $days -= $months * 30;
19 return self::pluralize($months, 'month', $days, 'day');
20 } else if($days) {
21 $hours -= $days * 24;
22 return self::pluralize($days, 'day', $hours, 'hour');
23 } else if($hours) {
24 $minutes -= $hours * 60;
25 return self::pluralize($hours, 'hour', $minutes, 'min');
26 } else if($minutes) {
27 $secs -= $minutes * 60;
28 return self::pluralize($minutes, 'min');
29 } else {
30 if($noSeconds){
31 return "less than a minute";
32 } else {
33 return floor($secs) . " secs";
34 }
35 }
36 }
37 public static function pluralize($m1, $t1, $m2 = false, $t2 = false) {
38 if($m1 != 1) {
39 $t1 = $t1 . 's';
40 }
41 if($m2 != 1) {
42 $t2 = $t2 . 's';
43 }
44 if($m1 && $m2){
45 return "$m1 $t1 $m2 $t2";
46 } else {
47 return "$m1 $t1";
48 }
49 }
50 public static function formatBytes($bytes, $precision = 2) {
51 $units = array('B', 'KB', 'MB', 'GB', 'TB');
52
53 $bytes = max($bytes, 0);
54 $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
55 $pow = min($pow, count($units) - 1);
56
57 // Uncomment one of the following alternatives
58 $bytes /= pow(1024, $pow);
59 // $bytes /= (1 << (10 * $pow));
60
61 return round($bytes, $precision) . ' ' . $units[$pow];
62 }
63 public static function inet_ntoa($ip){
64 $long = 4294967295 - ($ip - 1);
65 return long2ip(-$long);
66 }
67 public static function inet_aton($ip){
68 return sprintf("%u", ip2long($ip));
69 }
70 public static function getBaseURL(){
71 return plugins_url() . '/wordfence/';
72 }
73 public static function getPluginBaseDir(){
74 return WP_CONTENT_DIR . '/plugins/';
75 //return ABSPATH . 'wp-content/plugins/';
76 }
77 public static function getIP(){
78 $IP = 0;
79 if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
80 $IP = $_SERVER['HTTP_X_FORWARDED_FOR'];
81 if(is_array($IP) && isset($IP[0])){ $IP = $IP[0]; } //It seems that some hosts may modify _SERVER vars into arrays.
82 }
83 if((! preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $IP)) && isset($_SERVER['HTTP_X_REAL_IP'])){
84 $IP = $_SERVER['HTTP_X_REAL_IP'];
85 if(is_array($IP) && isset($IP[0])){ $IP = $IP[0]; } //It seems that some hosts may modify _SERVER vars into arrays.
86 }
87 if((! preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $IP)) && isset($_SERVER['REMOTE_ADDR'])){
88 $IP = $_SERVER['REMOTE_ADDR'];
89 if(is_array($IP) && isset($IP[0])){ $IP = $IP[0]; } //It seems that some hosts may modify _SERVER vars into arrays.
90 }
91 if(preg_match('/,/', $IP)){
92 $parts = explode(',', $IP); //Some users have "unknown,100.100.100.100" for example so we take the first thing that looks like an IP.
93 foreach($parts as $part){
94 if(preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $part)){
95 $IP = trim($part);
96 break;
97 }
98 }
99 }
100 if(preg_match('/:\d+$/', $IP)){
101 $IP = preg_replace('/:\d+$/', '', $IP);
102 }
103 if(self::isValidIP($IP)){
104 return $IP;
105 } else {
106 $msg = "Wordfence can't get the IP of clients and therefore can't operate. We received IP: $IP. X-Forwarded-For was: " . $_SERVER['HTTP_X_FORWARDED_FOR'] . " REMOTE_ADDR was: " . $_SERVER['REMOTE_ADDR'];
107 $possible = array();
108 foreach($_SERVER as $key => $val){
109 if(preg_match('/^\d+\.\d+\.\d+\.\d+/', $val) && strlen($val) < 255){
110 if($val != '127.0.0.1'){
111 $possible[$key] = $val;
112 }
113 }
114 }
115 if(sizeof($possible) > 0){
116 $msg .= " Report the following on the Wordfence forums and they may be able to help. Headers that may contain the client IP: ";
117 foreach($possible as $key => $val){
118 $msg .= "$key => $val ";
119 }
120 }
121 wordfence::status(1, 'error', $msg);
122 error_log($msg);
123 return false;
124 }
125 }
126 public static function isValidIP($IP){
127 if(preg_match('/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/', $IP, $m)){
128 if(
129 $m[0] >= 0 && $m[0] <= 255 &&
130 $m[1] >= 0 && $m[1] <= 255 &&
131 $m[2] >= 0 && $m[2] <= 255 &&
132 $m[3] >= 0 && $m[3] <= 255
133 ){
134 return true;
135 }
136 }
137 return false;
138 }
139 public static function getRequestedURL(){
140 return (@$_SERVER['HTTPS'] ? 'https' : 'http') . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
141 }
142
143 public static function editUserLink($userID){
144 return get_admin_url() . 'user-edit.php?user_id=' . $userID;
145 }
146 public static function tmpl($file, $data){
147 extract($data);
148 ob_start();
149 include $file;
150 return ob_get_contents() . (ob_end_clean() ? "" : "");
151 }
152 public static function bigRandomHex(){
153 return dechex(rand(0, 2147483647)) . dechex(rand(0, 2147483647)) . dechex(rand(0, 2147483647));
154 }
155 public static function encrypt($str){
156 $key = wfConfig::get('encKey');
157 if(! $key){
158 wordfence::status(1, 'error', "Wordfence error: No encryption key found!");
159 return false;
160 }
161 $db = new wfDB();
162 return $db->querySingle("select HEX(AES_ENCRYPT('%s', '%s')) as val", $str, $key);
163 }
164 public static function decrypt($str){
165 $key = wfConfig::get('encKey');
166 if(! $key){
167 wordfence::status(1, 'error', "Wordfence error: No encryption key found!");
168 return false;
169 }
170 $db = new wfDB();
171 return $db->querySingle("select AES_DECRYPT(UNHEX('%s'), '%s') as val", $str, $key);
172 }
173 public static function lcmem(){
174 $trace=debug_backtrace();
175 $caller=array_shift($trace);
176 $c2 = array_shift($trace);
177 $mem = memory_get_usage(true);
178 error_log("$mem at " . $caller['file'] . " line " . $caller['line']);
179 }
180 public static function logCaller(){
181 $trace=debug_backtrace();
182 $caller=array_shift($trace);
183 $c2 = array_shift($trace);
184 error_log("Caller for " . $caller['file'] . " line " . $caller['line'] . " is " . $c2['file'] . ' line ' . $c2['line']);
185 }
186 public static function getWPVersion(){
187 global $wp_version;
188 global $wordfence_wp_version;
189 if(isset($wordfence_wp_version)){
190 return $wordfence_wp_version;
191 } else {
192 return $wp_version;
193 }
194 }
195 public static function isAdminPageMU(){
196 if(preg_match('/^[\/a-zA-Z0-9\-\_\s\+\~\!\^\.]*\/wp-admin\/network\//', $_SERVER['REQUEST_URI'])){
197 return true;
198 }
199 return false;
200 }
201 public static function getSiteBaseURL(){
202 return rtrim(site_url(), '/') . '/';
203 }
204 public static function longestLine($data){
205 $lines = preg_split('/[\r\n]+/', $data);
206 $max = 0;
207 foreach($lines as $line){
208 $len = strlen($line);
209 if($len > $max){
210 $max = $len;
211 }
212 }
213 return $max;
214 }
215 public static function longestNospace($data){
216 $lines = preg_split('/[\r\n\s\t]+/', $data);
217 $max = 0;
218 foreach($lines as $line){
219 $len = strlen($line);
220 if($len > $max){
221 $max = $len;
222 }
223 }
224 return $max;
225 }
226 public static function requestMaxMemory(){
227 if(wfConfig::get('maxMem', false) && (int) wfConfig::get('maxMem') > 0){
228 $maxMem = (int) wfConfig::get('maxMem');
229 } else {
230 $maxMem = 256;
231 }
232 if( function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < $maxMem ) ){
233 @ini_set('memory_limit', $maxMem . 'M');
234 }
235 }
236 public static function isAdmin(){
237 if(is_multisite()){
238 if(current_user_can('manage_network')){
239 return true;
240 }
241 } else {
242 if(current_user_can('manage_options')){
243 return true;
244 }
245 }
246 return false;
247 }
248 public static function isWindows(){
249 if(! self::$isWindows){
250 if(preg_match('/^win/i', PHP_OS)){
251 self::$isWindows = 'yes';
252 } else {
253 self::$isWindows = 'no';
254 }
255 }
256 return self::$isWindows == 'yes' ? true : false;
257 }
258 public static function getScanLock(){
259 //Windows does not support non-blocking flock, so we use time.
260 $scanRunning = wfConfig::get('wf_scanRunning');
261 if($scanRunning && time() - $scanRunning < WORDFENCE_MAX_SCAN_TIME){
262 return false;
263 }
264 wfConfig::set('wf_scanRunning', time());
265 return true;
266 }
267 public static function clearScanLock(){
268 wfConfig::set('wf_scanRunning', '');
269 }
270 public static function isScanRunning(){
271 $scanRunning = wfConfig::get('wf_scanRunning');
272 if($scanRunning && time() - $scanRunning < WORDFENCE_MAX_SCAN_TIME){
273 return true;
274 } else {
275 return false;
276 }
277 }
278 public static function getIPGeo($IP){ //Works with int or dotted
279
280 $locs = self::getIPsGeo(array($IP));
281 if(isset($locs[$IP])){
282 return $locs[$IP];
283 } else {
284 return false;
285 }
286 }
287 public static function getIPsGeo($IPs){ //works with int or dotted. Outputs same format it receives.
288 $IPs = array_unique($IPs);
289 $isInt = false;
290 if(strpos($IPs[0], '.') === false){
291 $isInt = true;
292 }
293 $toResolve = array();
294 $db = new wfDB();
295 global $wp_version;
296 global $wpdb;
297 $locsTable = $wpdb->base_prefix . 'wfLocs';
298 $IPLocs = array();
299 foreach($IPs as $IP){
300 $r1 = $db->query("select IP, ctime, failed, city, region, countryName, countryCode, lat, lon, unix_timestamp() - ctime as age from " . $locsTable . " where IP=%s", ($isInt ? $IP : self::inet_aton($IP)) );
301 if($r1){
302 if($row = mysql_fetch_assoc($r1)){
303 if($row['age'] > WORDFENCE_MAX_IPLOC_AGE){
304 $db->query("delete from " . $locsTable . " where IP=%s", $row['IP']);
305 } else {
306 if($row['failed'] == 1){
307 $IPLocs[$IP] = false;
308 } else {
309 if(! $isInt){
310 $row['IP'] = self::inet_ntoa($row['IP']);
311 }
312 $IPLocs[$IP] = $row;
313 }
314 }
315 }
316 }
317 if(! isset($IPLocs[$IP])){
318 $toResolve[] = $IP;
319 }
320 }
321 if(sizeof($toResolve) > 0){
322 $api = new wfAPI(wfConfig::get('apiKey'), $wp_version);
323 try {
324 $freshIPs = $api->call('resolve_ips', array(), array(
325 'ips' => implode(',', $toResolve)
326 ));
327 if(is_array($freshIPs)){
328 foreach($freshIPs as $IP => $value){
329 if($value == 'failed'){
330 $db->query("insert IGNORE into " . $locsTable . " (IP, ctime, failed) values (%s, unix_timestamp(), 1)", ($isInt ? $IP : self::inet_aton($IP)) );
331 $IPLocs[$IP] = false;
332 } else {
333 $db->query("insert IGNORE into " . $locsTable . " (IP, ctime, failed, city, region, countryName, countryCode, lat, lon) values (%s, unix_timestamp(), 0, '%s', '%s', '%s', '%s', %s, %s)",
334 ($isInt ? $IP : self::inet_aton($IP)),
335 $value[3], //city
336 $value[2], //region
337 $value[1], //countryName
338 $value[0],//countryCode
339 $value[4],//lat
340 $value[5]//lon
341 );
342 $IPLocs[$IP] = array(
343 'IP' => $IP,
344 'city' => $value[3],
345 'region' => $value[2],
346 'countryName' => $value[1],
347 'countryCode' => $value[0],
348 'lat' => $value[4],
349 'lon' => $value[5]
350 );
351 }
352 }
353 }
354 } catch(Exception $e){
355 wordfence::status(2, 'error', "Call to Wordfence API to resolve IPs failed: " . $e->getMessage());
356 return array();
357 }
358 }
359 return $IPLocs;
360 }
361 public function reverseLookup($IP){
362 $db = new wfDB();
363 global $wpdb;
364 $reverseTable = $wpdb->base_prefix . 'wfReverseCache';
365 $IPn = wfUtils::inet_aton($IP);
366 $host = $db->querySingle("select host from " . $reverseTable . " where IP=%s and unix_timestamp() - lastUpdate < %d", $IPn, WORDFENCE_REVERSE_LOOKUP_CACHE_TIME);
367 if(! $host){
368 $ptr = implode(".", array_reverse(explode(".",$IP))) . ".in-addr.arpa";
369 $host = @dns_get_record($ptr, DNS_PTR);
370 if($host == null){
371 $host = 'NONE';
372 } else {
373 $host = $host[0]['target'];
374 }
375 $db->query("insert into " . $reverseTable . " (IP, host, lastUpdate) values (%s, '%s', unix_timestamp()) ON DUPLICATE KEY UPDATE host='%s', lastUpdate=unix_timestamp()", $IPn, $host, $host);
376 }
377 if($host == 'NONE'){
378 return '';
379 } else {
380 return $host;
381 }
382 }
383 public static function errorsOff(){
384 self::$lastErrorReporting = @ini_get('error_reporting');
385 @error_reporting(0);
386 self::$lastDisplayErrors = @ini_get('display_errors');
387 @ini_set('display_errors', 0);
388 if(class_exists('wfScan')){ wfScan::$errorHandlingOn = false; }
389 }
390 public static function errorsOn(){
391 @error_reporting(self::$lastErrorReporting);
392 @ini_set('display_errors', self::$lastDisplayErrors);
393 if(class_exists('wfScan')){ wfScan::$errorHandlingOn = true; }
394 }
395 public static function fileTooBig($file){ //Deals with files > 2 gigs on 32 bit systems which are reported with the wrong size due to integer overflow
396 wfUtils::errorsOff();
397 $fh = @fopen($file, 'r');
398 wfUtils::errorsOn();
399 if(! $fh){ return false; }
400 $offset = WORDFENCE_MAX_FILE_SIZE_TO_PROCESS + 1;
401 $tooBig = false;
402 if(fseek($fh, $offset, SEEK_SET) === 0){
403 if(strlen(fread($fh, 1)) === 1){
404 $tooBig = true;
405 }
406 } //Otherwise we couldn't seek there so it must be smaller
407 fclose($fh);
408 return $tooBig;
409 }
410 public static function fileOver2Gigs($file){
411 $fh = @fopen($file, 'r');
412 if(! $fh){ return false; }
413 $offset = 2147483647;
414 $tooBig = false;
415 if(fseek($fh, $offset, SEEK_SET) === 0){
416 if(strlen(fread($fh, 1)) === 1){
417 $tooBig = true;
418 }
419 } //Otherwise we couldn't seek there so it must be smaller
420 fclose($fh);
421 return $tooBig;
422 }
423 public static function countryCode2Name($code){
424 if(isset(wfCountryMap::$map[$code])){
425 return wfCountryMap::$map[$code];
426 } else {
427 return '';
428 }
429 }
430 public static function extractBareURI($URL){
431 $URL = preg_replace('/^https?:\/\/[^\/]+/i', '', $URL); //strip of method and host
432 $URL = preg_replace('/\#.*$/', '', $URL); //strip off fragment
433 $URL = preg_replace('/\?.*$/', '', $URL); //strip off query string
434 return $URL;
435 }
436 public static function IP2Country($IP){
437 if(! (function_exists('geoip_open') && function_exists('geoip_country_code_by_addr'))){
438 require_once('wfGeoIP.php');
439 }
440 $gi = geoip_open(dirname(__FILE__) . "/GeoIP.dat",GEOIP_STANDARD);
441 $country = geoip_country_code_by_addr($gi, $IP);
442 geoip_close($gi);
443 return $country ? $country : '';
444 }
445 public static function siteURLRelative(){
446 if(is_multisite()){
447 $URL = network_site_url();
448 } else {
449 $URL = site_url();
450 }
451 $URL = preg_replace('/^https?:\/\/[^\/]+/i', '', $URL);
452 $URL = rtrim($URL, '/') . '/';
453 return $URL;
454 }
455
456 }
457
458
459 ?>
460