Wordfence Security – Firewall & Malware Scan - Version 3.6.9

Version Description

  • Fixed JS error that occurs occasionally when users are viewing activity log in real-time.
  • New Feature: Prevent users registering 'admin' username if it doesn't exist. Recommended if you've deleted 'admin'. Enable on 'options' page.
  • Check if GeoIP library is already declared for all functions. Fixes Fatal error: Cannot redeclare geoip_country_code_by_name.
  • Fixed a compatibility issue with sites and hosts using Varnish front-end cache to ensure legit users don't get blocked. Added two HTTP no-cache and Expires headers.
  • Fixed bug when using Advanced User-Agent blocking with certain patterns this would appear: Warning: preg_match() [function.preg-match]: Unknown modifier
  • Vastly improved speed of Advanced User-Agent blocking. No longer using regex but still support wildcards using fnmatch()
  • We now support usernames with spaces in the list of users to ignore in the live traffic config on 'options' page.
  • Improved language in status messages to avoid confusion. Changed "unrecognized files" to "additional files" to describe non-core/theme/plugin files.
Download this release

Release Info

Developer mmaunder
Plugin Icon 128x128 Wordfence Security – Firewall & Malware Scan
Version 3.6.9
Comparing to
See all releases

Code changes from version 3.6.8 to 3.6.9

js/admin.js CHANGED
@@ -265,6 +265,8 @@ window['wordfenceAdmin'] = {
265
  }
266
  },
267
  addActItem: function(item){
 
 
268
  if(item.msg.indexOf('SUM_') == 0){
269
  this.processSummaryLine(item);
270
  jQuery('#consoleSummary').scrollTop(jQuery('#consoleSummary').prop('scrollHeight'));
265
  }
266
  },
267
  addActItem: function(item){
268
+ if(! item){ return; }
269
+ if(! item.msg){ return; }
270
  if(item.msg.indexOf('SUM_') == 0){
271
  this.processSummaryLine(item);
272
  jQuery('#consoleSummary').scrollTop(jQuery('#consoleSummary').prop('scrollHeight'));
lib/GeoIP.dat CHANGED
Binary file
lib/menu_options.php CHANGED
@@ -217,6 +217,7 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
217
  </td></tr>
218
  <tr><th>Immediately lock out invalid usernames</th><td><input type="checkbox" id="loginSec_lockInvalidUsers" class="wfConfigElem" name="loginSec_lockInvalidUsers" <?php $w->cb('loginSec_lockInvalidUsers'); ?> /></td></tr>
219
  <tr><th>Don't let WordPress reveal valid users in login errors</th><td><input type="checkbox" id="loginSec_maskLoginErrors" class="wfConfigElem" name="loginSec_maskLoginErrors" <?php $w->cb('loginSec_maskLoginErrors'); ?> /></td></tr>
 
220
  <tr><td colspan="2">
221
  <div class="wfMarker" id="wfMarkerOtherOptions"></div>
222
  <h3 class="wfConfigHeading">Other Options</h3>
217
  </td></tr>
218
  <tr><th>Immediately lock out invalid usernames</th><td><input type="checkbox" id="loginSec_lockInvalidUsers" class="wfConfigElem" name="loginSec_lockInvalidUsers" <?php $w->cb('loginSec_lockInvalidUsers'); ?> /></td></tr>
219
  <tr><th>Don't let WordPress reveal valid users in login errors</th><td><input type="checkbox" id="loginSec_maskLoginErrors" class="wfConfigElem" name="loginSec_maskLoginErrors" <?php $w->cb('loginSec_maskLoginErrors'); ?> /></td></tr>
220
+ <tr><th>Prevent users registering 'admin' username if it doesn't exist</th><td><input type="checkbox" id="loginSec_blockAdminReg" class="wfConfigElem" name="loginSec_blockAdminReg" <?php $w->cb('loginSec_blockAdminReg'); ?> /></td></tr>
221
  <tr><td colspan="2">
222
  <div class="wfMarker" id="wfMarkerOtherOptions"></div>
223
  <h3 class="wfConfigHeading">Other Options</h3>
lib/wfConfig.php CHANGED
@@ -38,6 +38,7 @@ class wfConfig {
38
  "loginSecurityEnabled" => false,
39
  "loginSec_lockInvalidUsers" => false,
40
  "loginSec_maskLoginErrors" => false,
 
41
  "other_hideWPVersion" => false,
42
  "other_noAnonMemberComments" => false,
43
  "other_scanComments" => false,
@@ -102,6 +103,7 @@ class wfConfig {
102
  "loginSecurityEnabled" => true,
103
  "loginSec_lockInvalidUsers" => false,
104
  "loginSec_maskLoginErrors" => true,
 
105
  "other_hideWPVersion" => true,
106
  "other_noAnonMemberComments" => true,
107
  "other_scanComments" => true,
@@ -166,6 +168,7 @@ class wfConfig {
166
  "loginSecurityEnabled" => true,
167
  "loginSec_lockInvalidUsers" => false,
168
  "loginSec_maskLoginErrors" => true,
 
169
  "other_hideWPVersion" => true,
170
  "other_noAnonMemberComments" => true,
171
  "other_scanComments" => true,
@@ -230,6 +233,7 @@ class wfConfig {
230
  "loginSecurityEnabled" => true,
231
  "loginSec_lockInvalidUsers" => false,
232
  "loginSec_maskLoginErrors" => true,
 
233
  "other_hideWPVersion" => true,
234
  "other_noAnonMemberComments" => true,
235
  "other_scanComments" => true,
@@ -294,6 +298,7 @@ class wfConfig {
294
  "loginSecurityEnabled" => true,
295
  "loginSec_lockInvalidUsers" => true,
296
  "loginSec_maskLoginErrors" => true,
 
297
  "other_hideWPVersion" => true,
298
  "other_noAnonMemberComments" => true,
299
  "other_scanComments" => true,
38
  "loginSecurityEnabled" => false,
39
  "loginSec_lockInvalidUsers" => false,
40
  "loginSec_maskLoginErrors" => false,
41
+ "loginSec_blockAdminReg" => false,
42
  "other_hideWPVersion" => false,
43
  "other_noAnonMemberComments" => false,
44
  "other_scanComments" => false,
103
  "loginSecurityEnabled" => true,
104
  "loginSec_lockInvalidUsers" => false,
105
  "loginSec_maskLoginErrors" => true,
106
+ "loginSec_blockAdminReg" => true,
107
  "other_hideWPVersion" => true,
108
  "other_noAnonMemberComments" => true,
109
  "other_scanComments" => true,
168
  "loginSecurityEnabled" => true,
169
  "loginSec_lockInvalidUsers" => false,
170
  "loginSec_maskLoginErrors" => true,
171
+ "loginSec_blockAdminReg" => true,
172
  "other_hideWPVersion" => true,
173
  "other_noAnonMemberComments" => true,
174
  "other_scanComments" => true,
233
  "loginSecurityEnabled" => true,
234
  "loginSec_lockInvalidUsers" => false,
235
  "loginSec_maskLoginErrors" => true,
236
+ "loginSec_blockAdminReg" => true,
237
  "other_hideWPVersion" => true,
238
  "other_noAnonMemberComments" => true,
239
  "other_scanComments" => true,
298
  "loginSecurityEnabled" => true,
299
  "loginSec_lockInvalidUsers" => true,
300
  "loginSec_maskLoginErrors" => true,
301
+ "loginSec_blockAdminReg" => true,
302
  "other_hideWPVersion" => true,
303
  "other_noAnonMemberComments" => true,
304
  "other_scanComments" => true,
lib/wfGeoIP.php CHANGED
@@ -237,477 +237,529 @@ class wfGeoIP {
237
  );
238
 
239
  }
240
- function geoip_load_shared_mem ($file) {
241
-
242
- $fp = fopen($file, "rb");
243
- if (!$fp) {
244
- print "error opening $file: $php_errormsg\n";
245
- exit;
246
- }
247
- $s_array = fstat($fp);
248
- $size = $s_array['size'];
249
- if ($shmid = @shmop_open (GEOIP_SHM_KEY, "w", 0, 0)) {
250
- shmop_delete ($shmid);
251
- shmop_close ($shmid);
252
- }
253
- $shmid = shmop_open (GEOIP_SHM_KEY, "c", 0644, $size);
254
- shmop_write ($shmid, fread($fp, $size), 0);
255
- shmop_close ($shmid);
 
 
256
  }
257
 
258
- function _setup_segments($gi){
259
- $gi->databaseType = GEOIP_COUNTRY_EDITION;
260
- $gi->record_length = STANDARD_RECORD_LENGTH;
261
- if ($gi->flags & GEOIP_SHARED_MEMORY) {
262
- $offset = @shmop_size ($gi->shmid) - 3;
263
- for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
264
- $delim = @shmop_read ($gi->shmid, $offset, 3);
265
- $offset += 3;
266
- if ($delim == (chr(255).chr(255).chr(255))) {
267
- $gi->databaseType = ord(@shmop_read ($gi->shmid, $offset, 1));
268
- $offset++;
269
-
270
- if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
271
- $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
272
- } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){
273
- $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
274
- } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)||
275
- ($gi->databaseType == GEOIP_CITY_EDITION_REV1)
276
- || ($gi->databaseType == GEOIP_ORG_EDITION)
277
- || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
278
- || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
279
- || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
280
- || ($gi->databaseType == GEOIP_ISP_EDITION)
281
- || ($gi->databaseType == GEOIP_ISP_EDITION_V6)
282
- || ($gi->databaseType == GEOIP_USERTYPE_EDITION)
283
- || ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6)
284
- || ($gi->databaseType == GEOIP_LOCATIONA_EDITION)
285
- || ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION)
286
- || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
287
- || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
288
- || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1)
289
- || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6)
290
- || ($gi->databaseType == GEOIP_ASNUM_EDITION)
291
- || ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)){
292
- $gi->databaseSegments = 0;
293
- $buf = @shmop_read ($gi->shmid, $offset, SEGMENT_RECORD_LENGTH);
294
- for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){
295
- $gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
296
- }
297
- if (($gi->databaseType == GEOIP_ORG_EDITION)
298
- || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
299
- || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
300
- || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
301
- || ($gi->databaseType == GEOIP_ISP_EDITION)
302
- || ($gi->databaseType == GEOIP_ISP_EDITION_V6)) {
303
- $gi->record_length = ORG_RECORD_LENGTH;
304
- }
305
- }
306
- break;
307
- } else {
308
- $offset -= 4;
309
- }
310
- }
311
- if (($gi->databaseType == GEOIP_COUNTRY_EDITION)||
312
- ($gi->databaseType == GEOIP_COUNTRY_EDITION_V6)||
313
- ($gi->databaseType == GEOIP_PROXY_EDITION)||
314
- ($gi->databaseType == GEOIP_NETSPEED_EDITION)){
315
- $gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
316
- }
317
- } else {
318
- $filepos = ftell($gi->filehandle);
319
- fseek($gi->filehandle, -3, SEEK_END);
320
- for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
321
- $delim = fread($gi->filehandle,3);
322
- if ($delim == (chr(255).chr(255).chr(255))){
323
- $gi->databaseType = ord(fread($gi->filehandle,1));
324
- if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
325
- $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
326
- }
327
- else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){
328
- $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
329
- } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)
330
- || ($gi->databaseType == GEOIP_CITY_EDITION_REV1)
331
- || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
332
- || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
333
- || ($gi->databaseType == GEOIP_ORG_EDITION)
334
- || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
335
- || ($gi->databaseType == GEOIP_ISP_EDITION)
336
- || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
337
- || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
338
- || ($gi->databaseType == GEOIP_ISP_EDITION_V6)
339
- || ($gi->databaseType == GEOIP_LOCATIONA_EDITION)
340
- || ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION)
341
- || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
342
- || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
343
- || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1)
344
- || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6)
345
- || ($gi->databaseType == GEOIP_USERTYPE_EDITION)
346
- || ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6)
347
- || ($gi->databaseType == GEOIP_ASNUM_EDITION)
348
- || ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)){
349
- $gi->databaseSegments = 0;
350
- $buf = fread($gi->filehandle,SEGMENT_RECORD_LENGTH);
351
- for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){
352
- $gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
353
- }
354
- if ( ( $gi->databaseType == GEOIP_ORG_EDITION )
355
- || ( $gi->databaseType == GEOIP_DOMAIN_EDITION )
356
- || ( $gi->databaseType == GEOIP_ISP_EDITION )
357
- || ( $gi->databaseType == GEOIP_ORG_EDITION_V6 )
358
- || ( $gi->databaseType == GEOIP_DOMAIN_EDITION_V6 )
359
- || ( $gi->databaseType == GEOIP_ISP_EDITION_V6 )) {
360
- $gi->record_length = ORG_RECORD_LENGTH;
361
- }
362
- }
363
- break;
364
- } else {
365
- fseek($gi->filehandle, -4, SEEK_CUR);
366
- }
367
- }
368
- if (($gi->databaseType == GEOIP_COUNTRY_EDITION)||
369
- ($gi->databaseType == GEOIP_COUNTRY_EDITION_V6)||
370
- ($gi->databaseType == GEOIP_PROXY_EDITION)||
371
- ($gi->databaseType == GEOIP_NETSPEED_EDITION)){
372
- $gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
373
- }
374
- fseek($gi->filehandle,$filepos,SEEK_SET);
375
- }
376
- return $gi;
 
 
377
  }
378
 
379
- function geoip_open($filename, $flags) {
380
- $gi = new wfGeoIP;
381
- $gi->flags = $flags;
382
- if ($gi->flags & GEOIP_SHARED_MEMORY) {
383
- $gi->shmid = @shmop_open (GEOIP_SHM_KEY, "a", 0, 0);
384
- } else {
385
- $gi->filehandle = fopen($filename,"rb") or die( "Can not open $filename\n" );
386
- if ($gi->flags & GEOIP_MEMORY_CACHE) {
387
- $s_array = fstat($gi->filehandle);
388
- $gi->memory_buffer = fread($gi->filehandle, $s_array['size']);
389
- }
390
- }
391
-
392
- $gi = _setup_segments($gi);
393
- return $gi;
 
 
394
  }
395
 
396
- function geoip_close($gi) {
397
- if ($gi->flags & GEOIP_SHARED_MEMORY) {
398
- return true;
399
- }
 
400
 
401
- return fclose($gi->filehandle);
 
402
  }
403
 
404
- function geoip_country_id_by_name_v6($gi, $name) {
405
- $rec = dns_get_record($name, DNS_AAAA);
406
- if ( !$rec ) {
407
- return false;
408
- }
409
- $addr = $rec[0]["ipv6"];
410
- if (!$addr || $addr == $name) {
411
- return false;
412
- }
413
- return geoip_country_id_by_addr_v6($gi, $addr);
 
 
414
  }
415
 
416
- function geoip_country_id_by_name($gi, $name) {
417
- $addr = gethostbyname($name);
418
- if (!$addr || $addr == $name) {
419
- return false;
420
- }
421
- return geoip_country_id_by_addr($gi, $addr);
 
 
422
  }
423
 
424
- function geoip_country_code_by_name_v6($gi, $name) {
425
- $country_id = geoip_country_id_by_name_v6($gi,$name);
426
- if ($country_id !== false) {
427
- return $gi->GEOIP_COUNTRY_CODES[$country_id];
428
- }
429
- return false;
 
 
430
  }
431
 
432
- function geoip_country_code_by_name($gi, $name) {
433
- $country_id = geoip_country_id_by_name($gi,$name);
434
- if ($country_id !== false) {
435
- return $gi->GEOIP_COUNTRY_CODES[$country_id];
436
- }
437
- return false;
 
 
438
  }
439
 
440
- function geoip_country_name_by_name_v6($gi, $name) {
441
- $country_id = geoip_country_id_by_name_v6($gi,$name);
442
- if ($country_id !== false) {
443
- return $gi->GEOIP_COUNTRY_NAMES[$country_id];
444
- }
445
- return false;
 
 
446
  }
447
 
448
- function geoip_country_name_by_name($gi, $name) {
449
- $country_id = geoip_country_id_by_name($gi,$name);
450
- if ($country_id !== false) {
451
- return $gi->GEOIP_COUNTRY_NAMES[$country_id];
452
- }
453
- return false;
 
 
454
  }
455
 
456
- function geoip_country_id_by_addr_v6($gi, $addr) {
457
- $ipnum = inet_pton($addr);
458
- return _geoip_seek_country_v6($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
 
 
459
  }
460
 
461
- function geoip_country_id_by_addr($gi, $addr) {
462
- $ipnum = ip2long($addr);
463
- return _geoip_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
 
 
464
  }
465
 
466
- function geoip_country_code_by_addr_v6($gi, $addr) {
467
- $country_id = geoip_country_id_by_addr_v6($gi,$addr);
468
- if ($country_id !== false) {
469
- return $gi->GEOIP_COUNTRY_CODES[$country_id];
470
- }
471
- return false;
 
 
472
  }
473
 
474
- function geoip_country_code_by_addr($gi, $addr) {
475
- if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
476
- $record = geoip_record_by_addr($gi,$addr);
477
- if ( $record !== false ) {
478
- return $record->country_code;
479
- }
480
- } else {
481
- $country_id = geoip_country_id_by_addr($gi,$addr);
482
- if ($country_id !== false) {
483
- return $gi->GEOIP_COUNTRY_CODES[$country_id];
484
- }
485
- }
486
- return false;
 
 
487
  }
488
 
489
- function geoip_country_name_by_addr_v6($gi, $addr) {
490
- $country_id = geoip_country_id_by_addr_v6($gi,$addr);
491
- if ($country_id !== false) {
492
- return $gi->GEOIP_COUNTRY_NAMES[$country_id];
493
- }
494
- return false;
 
 
495
  }
496
 
497
- function geoip_country_name_by_addr($gi, $addr) {
498
- if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
499
- $record = geoip_record_by_addr($gi,$addr);
500
- return $record->country_name;
501
- } else {
502
- $country_id = geoip_country_id_by_addr($gi,$addr);
503
- if ($country_id !== false) {
504
- return $gi->GEOIP_COUNTRY_NAMES[$country_id];
505
- }
506
- }
507
- return false;
 
 
508
  }
509
 
510
- function _geoip_seek_country_v6($gi, $ipnum) {
511
-
512
- # arrays from unpack start with offset 1
513
- # yet another php mystery. array_merge work around
514
- # this broken behaviour
515
- $v6vec = array_merge(unpack( "C16", $ipnum));
516
-
517
- $offset = 0;
518
- for ($depth = 127; $depth >= 0; --$depth) {
519
- if ($gi->flags & GEOIP_MEMORY_CACHE) {
520
- // workaround php's broken substr, strpos, etc handling with
521
- // mbstring.func_overload and mbstring.internal_encoding
522
- $enc = mb_internal_encoding();
523
- mb_internal_encoding('ISO-8859-1');
524
-
525
- $buf = substr($gi->memory_buffer,
526
- 2 * $gi->record_length * $offset,
527
- 2 * $gi->record_length);
528
-
529
- mb_internal_encoding($enc);
530
- } elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
531
- $buf = @shmop_read ($gi->shmid,
532
- 2 * $gi->record_length * $offset,
533
- 2 * $gi->record_length );
534
- } else {
535
- fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
536
- or die("fseek failed");
537
- $buf = fread($gi->filehandle, 2 * $gi->record_length);
538
- }
539
- $x = array(0,0);
540
- for ($i = 0; $i < 2; ++$i) {
541
- for ($j = 0; $j < $gi->record_length; ++$j) {
542
- $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
543
- }
544
- }
545
-
546
- $bnum = 127 - $depth;
547
- $idx = $bnum >> 3;
548
- $b_mask = 1 << ( $bnum & 7 ^ 7 );
549
- if (($v6vec[$idx] & $b_mask) > 0) {
550
- if ($x[1] >= $gi->databaseSegments) {
551
- return $x[1];
552
- }
553
- $offset = $x[1];
554
- } else {
555
- if ($x[0] >= $gi->databaseSegments) {
556
- return $x[0];
557
- }
558
- $offset = $x[0];
559
- }
560
- }
561
- trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
562
- return false;
 
 
563
  }
564
 
565
- function _geoip_seek_country($gi, $ipnum) {
566
- $offset = 0;
567
- for ($depth = 31; $depth >= 0; --$depth) {
568
- if ($gi->flags & GEOIP_MEMORY_CACHE) {
569
- // workaround php's broken substr, strpos, etc handling with
570
- // mbstring.func_overload and mbstring.internal_encoding
571
- $enc = mb_internal_encoding();
572
- mb_internal_encoding('ISO-8859-1');
573
-
574
- $buf = substr($gi->memory_buffer,
575
- 2 * $gi->record_length * $offset,
576
- 2 * $gi->record_length);
577
-
578
- mb_internal_encoding($enc);
579
- } elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
580
- $buf = @shmop_read ($gi->shmid,
581
- 2 * $gi->record_length * $offset,
582
- 2 * $gi->record_length );
583
- } else {
584
- fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
585
- or die("fseek failed");
586
- $buf = fread($gi->filehandle, 2 * $gi->record_length);
587
- }
588
- $x = array(0,0);
589
- for ($i = 0; $i < 2; ++$i) {
590
- for ($j = 0; $j < $gi->record_length; ++$j) {
591
- $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
592
- }
593
- }
594
- if ($ipnum & (1 << $depth)) {
595
- if ($x[1] >= $gi->databaseSegments) {
596
- return $x[1];
597
- }
598
- $offset = $x[1];
599
- } else {
600
- if ($x[0] >= $gi->databaseSegments) {
601
- return $x[0];
602
- }
603
- $offset = $x[0];
604
- }
605
- }
606
- trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
607
- return false;
 
 
608
  }
609
 
610
- function _common_get_org($gi, $seek_org){
611
- $record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments;
612
- if ($gi->flags & GEOIP_SHARED_MEMORY) {
613
- $org_buf = @shmop_read ($gi->shmid, $record_pointer, MAX_ORG_RECORD_LENGTH);
614
- } else {
615
- fseek($gi->filehandle, $record_pointer, SEEK_SET);
616
- $org_buf = fread($gi->filehandle,MAX_ORG_RECORD_LENGTH);
617
- }
618
- // workaround php's broken substr, strpos, etc handling with
619
- // mbstring.func_overload and mbstring.internal_encoding
620
- $enc = mb_internal_encoding();
621
- mb_internal_encoding('ISO-8859-1');
622
- $org_buf = substr($org_buf, 0, strpos($org_buf, "\0"));
623
- mb_internal_encoding($enc);
624
- return $org_buf;
 
 
625
  }
626
 
627
- function _get_org_v6($gi,$ipnum){
628
- $seek_org = _geoip_seek_country_v6($gi,$ipnum);
629
- if ($seek_org == $gi->databaseSegments) {
630
- return NULL;
631
- }
632
- return _common_get_org($gi, $seek_org);
 
 
633
  }
634
 
635
- function _get_org($gi,$ipnum){
636
- $seek_org = _geoip_seek_country($gi,$ipnum);
637
- if ($seek_org == $gi->databaseSegments) {
638
- return NULL;
639
- }
640
- return _common_get_org($gi, $seek_org);
 
 
641
  }
642
 
643
-
644
-
645
- function geoip_name_by_addr_v6 ($gi,$addr) {
646
- if ($addr == NULL) {
647
- return 0;
648
- }
649
- $ipnum = inet_pton($addr);
650
- return _get_org_v6($gi, $ipnum);
651
  }
652
 
653
- function geoip_name_by_addr ($gi,$addr) {
654
- if ($addr == NULL) {
655
- return 0;
656
- }
657
- $ipnum = ip2long($addr);
658
- return _get_org($gi, $ipnum);
 
 
659
  }
660
 
661
- function geoip_org_by_addr ($gi,$addr) {
662
- return geoip_name_by_addr($gi, $addr);
 
 
663
  }
664
 
665
- function _get_region($gi,$ipnum){
666
- if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
667
- $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV0;
668
- if ($seek_region >= 1000){
669
- $country_code = "US";
670
- $region = chr(($seek_region - 1000)/26 + 65) . chr(($seek_region - 1000)%26 + 65);
671
- } else {
672
- $country_code = $gi->GEOIP_COUNTRY_CODES[$seek_region];
673
- $region = "";
674
- }
675
- return array ($country_code,$region);
676
- } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1) {
677
- $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV1;
678
- //print $seek_region;
679
- if ($seek_region < US_OFFSET){
680
- $country_code = "";
681
- $region = "";
682
- } else if ($seek_region < CANADA_OFFSET) {
683
- $country_code = "US";
684
- $region = chr(($seek_region - US_OFFSET)/26 + 65) . chr(($seek_region - US_OFFSET)%26 + 65);
685
- } else if ($seek_region < WORLD_OFFSET) {
686
- $country_code = "CA";
687
- $region = chr(($seek_region - CANADA_OFFSET)/26 + 65) . chr(($seek_region - CANADA_OFFSET)%26 + 65);
688
- } else {
689
- $country_code = $gi->GEOIP_COUNTRY_CODES[($seek_region - WORLD_OFFSET) / FIPS_RANGE];
690
- $region = "";
691
- }
692
- return array ($country_code,$region);
693
- }
 
 
694
  }
695
 
696
- function geoip_region_by_addr ($gi,$addr) {
697
- if ($addr == NULL) {
698
- return 0;
699
- }
700
- $ipnum = ip2long($addr);
701
- return _get_region($gi, $ipnum);
 
 
702
  }
703
 
704
- function getdnsattributes ($l,$ip){
705
- $r = new Net_DNS_Resolver();
706
- $r->nameservers = array("ws1.maxmind.com");
707
- $p = $r->search($l."." . $ip .".s.maxmind.com","TXT","IN");
708
- $str = is_object($p->answer[0])?$p->answer[0]->string():'';
709
- $str = substr( $str, 1, -1 );
710
- return $str;
 
 
711
  }
712
  }
713
  ?>
237
  );
238
 
239
  }
240
+ if(! function_exists('geoip_load_shared_mem')){
241
+ function geoip_load_shared_mem ($file) {
242
+
243
+ $fp = fopen($file, "rb");
244
+ if (!$fp) {
245
+ print "error opening $file: $php_errormsg\n";
246
+ exit;
247
+ }
248
+ $s_array = fstat($fp);
249
+ $size = $s_array['size'];
250
+ if ($shmid = @shmop_open (GEOIP_SHM_KEY, "w", 0, 0)) {
251
+ shmop_delete ($shmid);
252
+ shmop_close ($shmid);
253
+ }
254
+ $shmid = shmop_open (GEOIP_SHM_KEY, "c", 0644, $size);
255
+ shmop_write ($shmid, fread($fp, $size), 0);
256
+ shmop_close ($shmid);
257
+ }
258
  }
259
 
260
+ if(! function_exists('')){
261
+ function _setup_segments($gi){
262
+ $gi->databaseType = GEOIP_COUNTRY_EDITION;
263
+ $gi->record_length = STANDARD_RECORD_LENGTH;
264
+ if ($gi->flags & GEOIP_SHARED_MEMORY) {
265
+ $offset = @shmop_size ($gi->shmid) - 3;
266
+ for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
267
+ $delim = @shmop_read ($gi->shmid, $offset, 3);
268
+ $offset += 3;
269
+ if ($delim == (chr(255).chr(255).chr(255))) {
270
+ $gi->databaseType = ord(@shmop_read ($gi->shmid, $offset, 1));
271
+ $offset++;
272
+
273
+ if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
274
+ $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
275
+ } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){
276
+ $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
277
+ } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)||
278
+ ($gi->databaseType == GEOIP_CITY_EDITION_REV1)
279
+ || ($gi->databaseType == GEOIP_ORG_EDITION)
280
+ || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
281
+ || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
282
+ || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
283
+ || ($gi->databaseType == GEOIP_ISP_EDITION)
284
+ || ($gi->databaseType == GEOIP_ISP_EDITION_V6)
285
+ || ($gi->databaseType == GEOIP_USERTYPE_EDITION)
286
+ || ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6)
287
+ || ($gi->databaseType == GEOIP_LOCATIONA_EDITION)
288
+ || ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION)
289
+ || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
290
+ || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
291
+ || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1)
292
+ || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6)
293
+ || ($gi->databaseType == GEOIP_ASNUM_EDITION)
294
+ || ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)){
295
+ $gi->databaseSegments = 0;
296
+ $buf = @shmop_read ($gi->shmid, $offset, SEGMENT_RECORD_LENGTH);
297
+ for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){
298
+ $gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
299
+ }
300
+ if (($gi->databaseType == GEOIP_ORG_EDITION)
301
+ || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
302
+ || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
303
+ || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
304
+ || ($gi->databaseType == GEOIP_ISP_EDITION)
305
+ || ($gi->databaseType == GEOIP_ISP_EDITION_V6)) {
306
+ $gi->record_length = ORG_RECORD_LENGTH;
307
+ }
308
+ }
309
+ break;
310
+ } else {
311
+ $offset -= 4;
312
+ }
313
+ }
314
+ if (($gi->databaseType == GEOIP_COUNTRY_EDITION)||
315
+ ($gi->databaseType == GEOIP_COUNTRY_EDITION_V6)||
316
+ ($gi->databaseType == GEOIP_PROXY_EDITION)||
317
+ ($gi->databaseType == GEOIP_NETSPEED_EDITION)){
318
+ $gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
319
+ }
320
+ } else {
321
+ $filepos = ftell($gi->filehandle);
322
+ fseek($gi->filehandle, -3, SEEK_END);
323
+ for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
324
+ $delim = fread($gi->filehandle,3);
325
+ if ($delim == (chr(255).chr(255).chr(255))){
326
+ $gi->databaseType = ord(fread($gi->filehandle,1));
327
+ if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
328
+ $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
329
+ }
330
+ else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){
331
+ $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
332
+ } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)
333
+ || ($gi->databaseType == GEOIP_CITY_EDITION_REV1)
334
+ || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
335
+ || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
336
+ || ($gi->databaseType == GEOIP_ORG_EDITION)
337
+ || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
338
+ || ($gi->databaseType == GEOIP_ISP_EDITION)
339
+ || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
340
+ || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
341
+ || ($gi->databaseType == GEOIP_ISP_EDITION_V6)
342
+ || ($gi->databaseType == GEOIP_LOCATIONA_EDITION)
343
+ || ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION)
344
+ || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
345
+ || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
346
+ || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1)
347
+ || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6)
348
+ || ($gi->databaseType == GEOIP_USERTYPE_EDITION)
349
+ || ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6)
350
+ || ($gi->databaseType == GEOIP_ASNUM_EDITION)
351
+ || ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)){
352
+ $gi->databaseSegments = 0;
353
+ $buf = fread($gi->filehandle,SEGMENT_RECORD_LENGTH);
354
+ for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){
355
+ $gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
356
+ }
357
+ if ( ( $gi->databaseType == GEOIP_ORG_EDITION )
358
+ || ( $gi->databaseType == GEOIP_DOMAIN_EDITION )
359
+ || ( $gi->databaseType == GEOIP_ISP_EDITION )
360
+ || ( $gi->databaseType == GEOIP_ORG_EDITION_V6 )
361
+ || ( $gi->databaseType == GEOIP_DOMAIN_EDITION_V6 )
362
+ || ( $gi->databaseType == GEOIP_ISP_EDITION_V6 )) {
363
+ $gi->record_length = ORG_RECORD_LENGTH;
364
+ }
365
+ }
366
+ break;
367
+ } else {
368
+ fseek($gi->filehandle, -4, SEEK_CUR);
369
+ }
370
+ }
371
+ if (($gi->databaseType == GEOIP_COUNTRY_EDITION)||
372
+ ($gi->databaseType == GEOIP_COUNTRY_EDITION_V6)||
373
+ ($gi->databaseType == GEOIP_PROXY_EDITION)||
374
+ ($gi->databaseType == GEOIP_NETSPEED_EDITION)){
375
+ $gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
376
+ }
377
+ fseek($gi->filehandle,$filepos,SEEK_SET);
378
+ }
379
+ return $gi;
380
+ }
381
  }
382
 
383
+ if(! function_exists('geoip_open')){
384
+ function geoip_open($filename, $flags) {
385
+ $gi = new wfGeoIP;
386
+ $gi->flags = $flags;
387
+ if ($gi->flags & GEOIP_SHARED_MEMORY) {
388
+ $gi->shmid = @shmop_open (GEOIP_SHM_KEY, "a", 0, 0);
389
+ } else {
390
+ $gi->filehandle = fopen($filename,"rb") or die( "Can not open $filename\n" );
391
+ if ($gi->flags & GEOIP_MEMORY_CACHE) {
392
+ $s_array = fstat($gi->filehandle);
393
+ $gi->memory_buffer = fread($gi->filehandle, $s_array['size']);
394
+ }
395
+ }
396
+
397
+ $gi = _setup_segments($gi);
398
+ return $gi;
399
+ }
400
  }
401
 
402
+ if(! function_exists('geoip_close')){
403
+ function geoip_close($gi) {
404
+ if ($gi->flags & GEOIP_SHARED_MEMORY) {
405
+ return true;
406
+ }
407
 
408
+ return fclose($gi->filehandle);
409
+ }
410
  }
411
 
412
+ if(! function_exists('geoip_country_id_by_name_v6')){
413
+ function geoip_country_id_by_name_v6($gi, $name) {
414
+ $rec = dns_get_record($name, DNS_AAAA);
415
+ if ( !$rec ) {
416
+ return false;
417
+ }
418
+ $addr = $rec[0]["ipv6"];
419
+ if (!$addr || $addr == $name) {
420
+ return false;
421
+ }
422
+ return geoip_country_id_by_addr_v6($gi, $addr);
423
+ }
424
  }
425
 
426
+ if(! function_exists('geoip_country_id_by_name')){
427
+ function geoip_country_id_by_name($gi, $name) {
428
+ $addr = gethostbyname($name);
429
+ if (!$addr || $addr == $name) {
430
+ return false;
431
+ }
432
+ return geoip_country_id_by_addr($gi, $addr);
433
+ }
434
  }
435
 
436
+ if(! function_exists('geoip_country_id_by_name')){
437
+ function geoip_country_code_by_name_v6($gi, $name) {
438
+ $country_id = geoip_country_id_by_name_v6($gi,$name);
439
+ if ($country_id !== false) {
440
+ return $gi->GEOIP_COUNTRY_CODES[$country_id];
441
+ }
442
+ return false;
443
+ }
444
  }
445
 
446
+ if(! function_exists('geoip_country_code_by_name')){
447
+ function geoip_country_code_by_name($gi, $name) {
448
+ $country_id = geoip_country_id_by_name($gi,$name);
449
+ if ($country_id !== false) {
450
+ return $gi->GEOIP_COUNTRY_CODES[$country_id];
451
+ }
452
+ return false;
453
+ }
454
  }
455
 
456
+ if(! function_exists('geoip_country_name_by_name_v6')){
457
+ function geoip_country_name_by_name_v6($gi, $name) {
458
+ $country_id = geoip_country_id_by_name_v6($gi,$name);
459
+ if ($country_id !== false) {
460
+ return $gi->GEOIP_COUNTRY_NAMES[$country_id];
461
+ }
462
+ return false;
463
+ }
464
  }
465
 
466
+ if(! function_exists('geoip_country_name_by_name')){
467
+ function geoip_country_name_by_name($gi, $name) {
468
+ $country_id = geoip_country_id_by_name($gi,$name);
469
+ if ($country_id !== false) {
470
+ return $gi->GEOIP_COUNTRY_NAMES[$country_id];
471
+ }
472
+ return false;
473
+ }
474
  }
475
 
476
+ if(! function_exists('geoip_country_id_by_addr_v6')){
477
+ function geoip_country_id_by_addr_v6($gi, $addr) {
478
+ $ipnum = inet_pton($addr);
479
+ return _geoip_seek_country_v6($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
480
+ }
481
  }
482
 
483
+ if(! function_exists('geoip_country_id_by_addr')){
484
+ function geoip_country_id_by_addr($gi, $addr) {
485
+ $ipnum = ip2long($addr);
486
+ return _geoip_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
487
+ }
488
  }
489
 
490
+ if(! function_exists('geoip_country_code_by_addr_v6')){
491
+ function geoip_country_code_by_addr_v6($gi, $addr) {
492
+ $country_id = geoip_country_id_by_addr_v6($gi,$addr);
493
+ if ($country_id !== false) {
494
+ return $gi->GEOIP_COUNTRY_CODES[$country_id];
495
+ }
496
+ return false;
497
+ }
498
  }
499
 
500
+ if(! function_exists('geoip_country_code_by_addr')){
501
+ function geoip_country_code_by_addr($gi, $addr) {
502
+ if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
503
+ $record = geoip_record_by_addr($gi,$addr);
504
+ if ( $record !== false ) {
505
+ return $record->country_code;
506
+ }
507
+ } else {
508
+ $country_id = geoip_country_id_by_addr($gi,$addr);
509
+ if ($country_id !== false) {
510
+ return $gi->GEOIP_COUNTRY_CODES[$country_id];
511
+ }
512
+ }
513
+ return false;
514
+ }
515
  }
516
 
517
+ if(! function_exists('geoip_country_name_by_addr_v6')){
518
+ function geoip_country_name_by_addr_v6($gi, $addr) {
519
+ $country_id = geoip_country_id_by_addr_v6($gi,$addr);
520
+ if ($country_id !== false) {
521
+ return $gi->GEOIP_COUNTRY_NAMES[$country_id];
522
+ }
523
+ return false;
524
+ }
525
  }
526
 
527
+ if(! function_exists('geoip_country_name_by_addr')){
528
+ function geoip_country_name_by_addr($gi, $addr) {
529
+ if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
530
+ $record = geoip_record_by_addr($gi,$addr);
531
+ return $record->country_name;
532
+ } else {
533
+ $country_id = geoip_country_id_by_addr($gi,$addr);
534
+ if ($country_id !== false) {
535
+ return $gi->GEOIP_COUNTRY_NAMES[$country_id];
536
+ }
537
+ }
538
+ return false;
539
+ }
540
  }
541
 
542
+ if(! function_exists('_geoip_seek_country_v6')){
543
+ function _geoip_seek_country_v6($gi, $ipnum) {
544
+
545
+ # arrays from unpack start with offset 1
546
+ # yet another php mystery. array_merge work around
547
+ # this broken behaviour
548
+ $v6vec = array_merge(unpack( "C16", $ipnum));
549
+
550
+ $offset = 0;
551
+ for ($depth = 127; $depth >= 0; --$depth) {
552
+ if ($gi->flags & GEOIP_MEMORY_CACHE) {
553
+ // workaround php's broken substr, strpos, etc handling with
554
+ // mbstring.func_overload and mbstring.internal_encoding
555
+ $enc = mb_internal_encoding();
556
+ mb_internal_encoding('ISO-8859-1');
557
+
558
+ $buf = substr($gi->memory_buffer,
559
+ 2 * $gi->record_length * $offset,
560
+ 2 * $gi->record_length);
561
+
562
+ mb_internal_encoding($enc);
563
+ } elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
564
+ $buf = @shmop_read ($gi->shmid,
565
+ 2 * $gi->record_length * $offset,
566
+ 2 * $gi->record_length );
567
+ } else {
568
+ fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
569
+ or die("fseek failed");
570
+ $buf = fread($gi->filehandle, 2 * $gi->record_length);
571
+ }
572
+ $x = array(0,0);
573
+ for ($i = 0; $i < 2; ++$i) {
574
+ for ($j = 0; $j < $gi->record_length; ++$j) {
575
+ $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
576
+ }
577
+ }
578
+
579
+ $bnum = 127 - $depth;
580
+ $idx = $bnum >> 3;
581
+ $b_mask = 1 << ( $bnum & 7 ^ 7 );
582
+ if (($v6vec[$idx] & $b_mask) > 0) {
583
+ if ($x[1] >= $gi->databaseSegments) {
584
+ return $x[1];
585
+ }
586
+ $offset = $x[1];
587
+ } else {
588
+ if ($x[0] >= $gi->databaseSegments) {
589
+ return $x[0];
590
+ }
591
+ $offset = $x[0];
592
+ }
593
+ }
594
+ trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
595
+ return false;
596
+ }
597
  }
598
 
599
+ if(! function_exists('_geoip_seek_country')){
600
+ function _geoip_seek_country($gi, $ipnum) {
601
+ $offset = 0;
602
+ for ($depth = 31; $depth >= 0; --$depth) {
603
+ if ($gi->flags & GEOIP_MEMORY_CACHE) {
604
+ // workaround php's broken substr, strpos, etc handling with
605
+ // mbstring.func_overload and mbstring.internal_encoding
606
+ $enc = mb_internal_encoding();
607
+ mb_internal_encoding('ISO-8859-1');
608
+
609
+ $buf = substr($gi->memory_buffer,
610
+ 2 * $gi->record_length * $offset,
611
+ 2 * $gi->record_length);
612
+
613
+ mb_internal_encoding($enc);
614
+ } elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
615
+ $buf = @shmop_read ($gi->shmid,
616
+ 2 * $gi->record_length * $offset,
617
+ 2 * $gi->record_length );
618
+ } else {
619
+ fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
620
+ or die("fseek failed");
621
+ $buf = fread($gi->filehandle, 2 * $gi->record_length);
622
+ }
623
+ $x = array(0,0);
624
+ for ($i = 0; $i < 2; ++$i) {
625
+ for ($j = 0; $j < $gi->record_length; ++$j) {
626
+ $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
627
+ }
628
+ }
629
+ if ($ipnum & (1 << $depth)) {
630
+ if ($x[1] >= $gi->databaseSegments) {
631
+ return $x[1];
632
+ }
633
+ $offset = $x[1];
634
+ } else {
635
+ if ($x[0] >= $gi->databaseSegments) {
636
+ return $x[0];
637
+ }
638
+ $offset = $x[0];
639
+ }
640
+ }
641
+ trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
642
+ return false;
643
+ }
644
  }
645
 
646
+ if(! function_exists('_common_get_org')){
647
+ function _common_get_org($gi, $seek_org){
648
+ $record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments;
649
+ if ($gi->flags & GEOIP_SHARED_MEMORY) {
650
+ $org_buf = @shmop_read ($gi->shmid, $record_pointer, MAX_ORG_RECORD_LENGTH);
651
+ } else {
652
+ fseek($gi->filehandle, $record_pointer, SEEK_SET);
653
+ $org_buf = fread($gi->filehandle,MAX_ORG_RECORD_LENGTH);
654
+ }
655
+ // workaround php's broken substr, strpos, etc handling with
656
+ // mbstring.func_overload and mbstring.internal_encoding
657
+ $enc = mb_internal_encoding();
658
+ mb_internal_encoding('ISO-8859-1');
659
+ $org_buf = substr($org_buf, 0, strpos($org_buf, "\0"));
660
+ mb_internal_encoding($enc);
661
+ return $org_buf;
662
+ }
663
  }
664
 
665
+ if(! function_exists('_get_org_v6')){
666
+ function _get_org_v6($gi,$ipnum){
667
+ $seek_org = _geoip_seek_country_v6($gi,$ipnum);
668
+ if ($seek_org == $gi->databaseSegments) {
669
+ return NULL;
670
+ }
671
+ return _common_get_org($gi, $seek_org);
672
+ }
673
  }
674
 
675
+ if(! function_exists('_get_org')){
676
+ function _get_org($gi,$ipnum){
677
+ $seek_org = _geoip_seek_country($gi,$ipnum);
678
+ if ($seek_org == $gi->databaseSegments) {
679
+ return NULL;
680
+ }
681
+ return _common_get_org($gi, $seek_org);
682
+ }
683
  }
684
 
685
+ if(! function_exists('geoip_name_by_addr_v6')){
686
+ function geoip_name_by_addr_v6 ($gi,$addr) {
687
+ if ($addr == NULL) {
688
+ return 0;
689
+ }
690
+ $ipnum = inet_pton($addr);
691
+ return _get_org_v6($gi, $ipnum);
692
+ }
693
  }
694
 
695
+ if(! function_exists('geoip_name_by_addr')){
696
+ function geoip_name_by_addr ($gi,$addr) {
697
+ if ($addr == NULL) {
698
+ return 0;
699
+ }
700
+ $ipnum = ip2long($addr);
701
+ return _get_org($gi, $ipnum);
702
+ }
703
  }
704
 
705
+ if(! function_exists('geoip_org_by_addr')){
706
+ function geoip_org_by_addr ($gi,$addr) {
707
+ return geoip_name_by_addr($gi, $addr);
708
+ }
709
  }
710
 
711
+ if(! function_exists('_get_region')){
712
+ function _get_region($gi,$ipnum){
713
+ if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
714
+ $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV0;
715
+ if ($seek_region >= 1000){
716
+ $country_code = "US";
717
+ $region = chr(($seek_region - 1000)/26 + 65) . chr(($seek_region - 1000)%26 + 65);
718
+ } else {
719
+ $country_code = $gi->GEOIP_COUNTRY_CODES[$seek_region];
720
+ $region = "";
721
+ }
722
+ return array ($country_code,$region);
723
+ } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1) {
724
+ $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV1;
725
+ //print $seek_region;
726
+ if ($seek_region < US_OFFSET){
727
+ $country_code = "";
728
+ $region = "";
729
+ } else if ($seek_region < CANADA_OFFSET) {
730
+ $country_code = "US";
731
+ $region = chr(($seek_region - US_OFFSET)/26 + 65) . chr(($seek_region - US_OFFSET)%26 + 65);
732
+ } else if ($seek_region < WORLD_OFFSET) {
733
+ $country_code = "CA";
734
+ $region = chr(($seek_region - CANADA_OFFSET)/26 + 65) . chr(($seek_region - CANADA_OFFSET)%26 + 65);
735
+ } else {
736
+ $country_code = $gi->GEOIP_COUNTRY_CODES[($seek_region - WORLD_OFFSET) / FIPS_RANGE];
737
+ $region = "";
738
+ }
739
+ return array ($country_code,$region);
740
+ }
741
+ }
742
  }
743
 
744
+ if(! function_exists('geoip_region_by_addr')){
745
+ function geoip_region_by_addr ($gi,$addr) {
746
+ if ($addr == NULL) {
747
+ return 0;
748
+ }
749
+ $ipnum = ip2long($addr);
750
+ return _get_region($gi, $ipnum);
751
+ }
752
  }
753
 
754
+ if(! function_exists('getdnsattributes')){
755
+ function getdnsattributes ($l,$ip){
756
+ $r = new Net_DNS_Resolver();
757
+ $r->nameservers = array("ws1.maxmind.com");
758
+ $p = $r->search($l."." . $ip .".s.maxmind.com","TXT","IN");
759
+ $str = is_object($p->answer[0])?$p->answer[0]->string():'';
760
+ $str = substr( $str, 1, -1 );
761
+ return $str;
762
+ }
763
  }
764
  }
765
  ?>
lib/wfUtils.php CHANGED
@@ -503,21 +503,16 @@ class wfUtils {
503
  }
504
  }
505
  public static function doNotCache(){
 
 
506
  define('DONOTCACHEPAGE', true);
507
  define('DONOTCACHEDB', true);
508
  define('DONOTCDN', true);
509
  define('DONOTCACHEOBJECT', true);
 
510
  }
511
  public static function isUABlocked($uaPattern){ // takes a pattern using asterisks as wildcards, turns it into regex and checks it against the visitor UA returning true if blocked
512
- $uaPieces = explode('*', $uaPattern);
513
- for($i = 0; $i < sizeof($uaPieces); $i++){
514
- $uaPieces[$i] = preg_quote($uaPieces[$i]);
515
- }
516
- $uaPatternRegex = '/^' . implode('.*', $uaPieces) . '$/i';
517
- if(preg_match($uaPatternRegex, $_SERVER['HTTP_USER_AGENT'])){
518
- return true;
519
- }
520
- return false;
521
  }
522
  }
523
 
503
  }
504
  }
505
  public static function doNotCache(){
506
+ header("Cache-Control: no-cache, must-revalidate");
507
+ header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); //In the past
508
  define('DONOTCACHEPAGE', true);
509
  define('DONOTCACHEDB', true);
510
  define('DONOTCDN', true);
511
  define('DONOTCACHEOBJECT', true);
512
+
513
  }
514
  public static function isUABlocked($uaPattern){ // takes a pattern using asterisks as wildcards, turns it into regex and checks it against the visitor UA returning true if blocked
515
+ return fnmatch($uaPattern, $_SERVER['HTTP_USER_AGENT'], FNM_CASEFOLD);
 
 
 
 
 
 
 
 
516
  }
517
  }
518
 
lib/wordfenceClass.php CHANGED
@@ -276,6 +276,7 @@ class wordfence {
276
  add_filter('get_the_generator_rdf', 'wordfence::genFilter', 99, 2);
277
  add_filter('get_the_generator_comment', 'wordfence::genFilter', 99, 2);
278
  add_filter('get_the_generator_export', 'wordfence::genFilter', 99, 2);
 
279
  if(is_admin()){
280
  add_action('admin_init', 'wordfence::admin_init');
281
  if(is_multisite()){
@@ -487,6 +488,12 @@ class wordfence {
487
  }
488
  }
489
  }
 
 
 
 
 
 
490
  public static function authenticateFilter($authResult){
491
  $IP = wfUtils::getIP();
492
  if(self::getLog()->isWhitelisted($IP)){
@@ -784,7 +791,8 @@ class wordfence {
784
  }
785
  $validUsers = array();
786
  $invalidUsers = array();
787
- foreach(explode(',', preg_replace('/[\r\n\s\t]+/', '', $opts['liveTraf_ignoreUsers'])) as $val){
 
788
  if(strlen($val) > 0){
789
  if(get_user_by('login', $val)){
790
  array_push($validUsers, $val);
276
  add_filter('get_the_generator_rdf', 'wordfence::genFilter', 99, 2);
277
  add_filter('get_the_generator_comment', 'wordfence::genFilter', 99, 2);
278
  add_filter('get_the_generator_export', 'wordfence::genFilter', 99, 2);
279
+ add_filter('registration_errors', 'wordfence::registrationFilter', 99, 3);
280
  if(is_admin()){
281
  add_action('admin_init', 'wordfence::admin_init');
282
  if(is_multisite()){
488
  }
489
  }
490
  }
491
+ public static function registrationFilter($errors, $santizedLogin, $userEmail){
492
+ if(wfConfig::get('loginSec_blockAdminReg') && $santizedLogin == 'admin'){
493
+ $errors->add('user_login_error', '<strong>ERROR</strong>: You can\'t register using that username');
494
+ }
495
+ return $errors;
496
+ }
497
  public static function authenticateFilter($authResult){
498
  $IP = wfUtils::getIP();
499
  if(self::getLog()->isWhitelisted($IP)){
791
  }
792
  $validUsers = array();
793
  $invalidUsers = array();
794
+ foreach(explode(',', $opts['liveTraf_ignoreUsers']) as $val){
795
+ $val = trim($val);
796
  if(strlen($val) > 0){
797
  if(get_user_by('login', $val)){
798
  array_push($validUsers, $val);
lib/wordfenceScanner.php CHANGED
@@ -252,7 +252,7 @@ class wordfenceScanner {
252
  return $this->results;
253
  }
254
  private function writeScanningStatus(){
255
- wordfence::status(2, 'info', "Scanned contents of " . $this->totalFilesScanned . " unrecognized files at " . sprintf('%.2f', ($this->totalFilesScanned / (microtime(true) - $this->startTime))) . " per second");
256
  }
257
  private function addEncIssue($ignoreP, $ignoreC, $encoding, $file){
258
  $this->addResult(array(
252
  return $this->results;
253
  }
254
  private function writeScanningStatus(){
255
+ wordfence::status(2, 'info', "Scanned contents of " . $this->totalFilesScanned . " additional files at " . sprintf('%.2f', ($this->totalFilesScanned / (microtime(true) - $this->startTime))) . " per second");
256
  }
257
  private function addEncIssue($ignoreP, $ignoreC, $encoding, $file){
258
  $this->addResult(array(
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: mmaunder
3
  Tags: wordpress, security, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure
4
  Requires at least: 3.3.1
5
  Tested up to: 3.5.1
6
- Stable tag: 3.6.8
7
 
8
  Wordfence Security is a free enterprise class security plugin that includes a firewall, virus scanning, real-time traffic with geolocation and more.
9
 
@@ -155,6 +155,16 @@ or a theme, because often these have been updated to fix a security hole.
155
 
156
  == Changelog ==
157
 
 
 
 
 
 
 
 
 
 
 
158
  = 3.6.8 =
159
  * Fixed bug that caused IP range blocking to not block.
160
  * Fixed bug that caused unblocking a permanently blocked IP to work, but not refresh the list.
3
  Tags: wordpress, security, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure
4
  Requires at least: 3.3.1
5
  Tested up to: 3.5.1
6
+ Stable tag: 3.6.9
7
 
8
  Wordfence Security is a free enterprise class security plugin that includes a firewall, virus scanning, real-time traffic with geolocation and more.
9
 
155
 
156
  == Changelog ==
157
 
158
+ = 3.6.9 =
159
+ * Fixed JS error that occurs occasionally when users are viewing activity log in real-time.
160
+ * New Feature: Prevent users registering 'admin' username if it doesn't exist. Recommended if you've deleted 'admin'. Enable on 'options' page.
161
+ * Check if GeoIP library is already declared for all functions. Fixes Fatal error: Cannot redeclare geoip_country_code_by_name.
162
+ * Fixed a compatibility issue with sites and hosts using Varnish front-end cache to ensure legit users don't get blocked. Added two HTTP no-cache and Expires headers.
163
+ * Fixed bug when using Advanced User-Agent blocking with certain patterns this would appear: Warning: preg_match() [function.preg-match]: Unknown modifier
164
+ * Vastly improved speed of Advanced User-Agent blocking. No longer using regex but still support wildcards using fnmatch()
165
+ * We now support usernames with spaces in the list of users to ignore in the live traffic config on 'options' page.
166
+ * Improved language in status messages to avoid confusion. Changed "unrecognized files" to "additional files" to describe non-core/theme/plugin files.
167
+
168
  = 3.6.8 =
169
  * Fixed bug that caused IP range blocking to not block.
170
  * Fixed bug that caused unblocking a permanently blocked IP to work, but not refresh the list.
wordfence.php CHANGED
@@ -4,10 +4,10 @@ Plugin Name: Wordfence Security
4
  Plugin URI: http://www.wordfence.com/
5
  Description: Wordfence Security - Anti-virus and Firewall security plugin for WordPress
6
  Author: Mark Maunder
7
- Version: 3.6.8
8
  Author URI: http://www.wordfence.com/
9
  */
10
- define('WORDFENCE_VERSION', '3.6.8');
11
  if(get_option('wordfenceActivated') != 1){
12
  add_action('activated_plugin','wordfence_save_activation_error'); function wordfence_save_activation_error(){ update_option('wf_plugin_act_error', ob_get_contents()); }
13
  }
4
  Plugin URI: http://www.wordfence.com/
5
  Description: Wordfence Security - Anti-virus and Firewall security plugin for WordPress
6
  Author: Mark Maunder
7
+ Version: 3.6.9
8
  Author URI: http://www.wordfence.com/
9
  */
10
+ define('WORDFENCE_VERSION', '3.6.9');
11
  if(get_option('wordfenceActivated') != 1){
12
  add_action('activated_plugin','wordfence_save_activation_error'); function wordfence_save_activation_error(){ update_option('wf_plugin_act_error', ob_get_contents()); }
13
  }