Shield Security for WordPress - Version 8.2.2

Version Description

  • Current Release = Released: 14th October, 2019 - Release Notes

  • (v.2) FIXED: Fixes for scans running under Windows/IIS.

  • (v.2) IMPROVED: Adds a check that a site can send an HTTP request to itself before allowing scans to run.

  • (v.2) IMPROVED: Scans clean up after themselves better, if they fail to run.

  • (v.2) IMPROVED: Server's own IP address detection when site migrated to a new host.

  • (v.2) UPDATED: International translations.

  • (v.2) FIXED: PHP notices when data wasn't as expected.

Download this release

Release Info

Developer paultgoodchild
Plugin Icon 128x128 Shield Security for WordPress
Version 8.2.2
Comparing to
See all releases

Code changes from version 8.2.1 to 8.2.2

Files changed (36) hide show
  1. icwp-wpsf.php +1 -1
  2. languages/wp-simple-firewall-de_DE.mo +0 -0
  3. languages/wp-simple-firewall-es_ES.mo +0 -0
  4. languages/wp-simple-firewall-fr_FR.mo +0 -0
  5. languages/wp-simple-firewall-ja.mo +0 -0
  6. languages/wp-simple-firewall-pt_PT.mo +0 -0
  7. languages/wp-simple-firewall-ru_RU.mo +0 -0
  8. plugin-spec.php +3 -3
  9. readme.txt +13 -7
  10. src/config/feature-comments_filter.php +0 -7
  11. src/config/feature-firewall.php +0 -7
  12. src/config/feature-hack_protect.php +0 -35
  13. src/config/feature-ips.php +0 -29
  14. src/config/feature-lockdown.php +0 -14
  15. src/config/feature-login_protect.php +0 -28
  16. src/config/feature-plugin.php +3 -17
  17. src/config/feature-user_management.php +0 -14
  18. src/features/base.php +1 -1
  19. src/features/plugin.php +50 -23
  20. src/lib/src/Modules/HackGuard/Options.php +25 -5
  21. src/lib/src/Modules/HackGuard/Scan/Queue/Controller.php +28 -5
  22. src/lib/src/Modules/License/AjaxHandler.php +1 -1
  23. src/lib/src/Modules/Plugin/Options.php +23 -0
  24. src/lib/vendor/composer/autoload_classmap.php +1 -0
  25. src/lib/vendor/composer/autoload_static.php +1 -0
  26. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php +2 -12
  27. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Fs.php +12 -0
  28. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeVersionsBase.php +64 -0
  29. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Cp/Files.php +4 -4
  30. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Versions.php +5 -33
  31. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Versions.php +5 -33
  32. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Files.php +8 -10
  33. src/processors/hack_protect.php +9 -2
  34. src/processors/hackprotect_scanner.php +30 -9
  35. src/processors/usermanagement_passwords.php +1 -1
  36. templates/twig/wpadmin_pages/insights/scans/scan_areas.twig +10 -2
icwp-wpsf.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Shield Security
4
  * Plugin URI: https://icwp.io/2f
5
  * Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
6
- * Version: 8.2.1
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: One Dollar Plugin
3
  * Plugin Name: Shield Security
4
  * Plugin URI: https://icwp.io/2f
5
  * Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
6
+ * Version: 8.2.2
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: One Dollar Plugin
languages/wp-simple-firewall-de_DE.mo CHANGED
Binary file
languages/wp-simple-firewall-es_ES.mo CHANGED
Binary file
languages/wp-simple-firewall-fr_FR.mo CHANGED
Binary file
languages/wp-simple-firewall-ja.mo CHANGED
Binary file
languages/wp-simple-firewall-pt_PT.mo CHANGED
Binary file
languages/wp-simple-firewall-ru_RU.mo CHANGED
Binary file
plugin-spec.php CHANGED
@@ -1,8 +1,8 @@
1
  {
2
  "properties": {
3
- "version": "8.2.1",
4
- "release_timestamp": 1570444789,
5
- "build": "201910.0701",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "human_name": "Shield",
1
  {
2
  "properties": {
3
+ "version": "8.2.2",
4
+ "release_timestamp": 1570808000,
5
+ "build": "201910.1102",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "human_name": "Shield",
readme.txt CHANGED
@@ -8,7 +8,7 @@ Requires at least: 3.5.2
8
  Requires PHP: 5.4.0
9
  Recommended PHP: 7.0
10
  Tested up to: 5.3
11
- Stable tag: 8.2.1
12
 
13
  Security protection from hackers through smarter automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
14
 
@@ -370,17 +370,23 @@ You will always be able to use Shield Security and its free features in-full.
370
 
371
  [Go Pro for just $1/month](https://icwp.io/aa).
372
 
373
- = 8.2.1 - Current Release =
374
- *Released: 7th October, 2019* - [Release Notes](https://icwp.io/g0)
375
 
376
- * **(v.1)** IMPROVED: Further reduce Malware false positives by also using SVN trunk data when verifying files for plugins and themes.
377
- * **(v.1)** ADDED: Initial support for repairing Themes that have been installed from WordPress.org.
378
- * **(v.1)** ADDED: Support for using [WP Hashes.com](https://wphashes.com) for WordPress.org themes (already done for plugins).
379
- * **(v.1)** FIXED: PHP notices in the logs.
 
 
380
 
381
  = 8.2 - Series =
382
  *Released: 1st October, 2019* - [Release Notes](https://icwp.io/g0)
383
 
 
 
 
 
384
  * **(v.0)** IMPROVED: [**PRO**] Malware scanner now uses network intelligence to the gather information on malware results.
385
  * **(v.0)** NEW: Traffic Watcher feature is now free for all users (no longer Pro-only).
386
  * **(v.0)** IMPROVED: Scanning cron is improved and more efficient.
8
  Requires PHP: 5.4.0
9
  Recommended PHP: 7.0
10
  Tested up to: 5.3
11
+ Stable tag: 8.2.2
12
 
13
  Security protection from hackers through smarter automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
14
 
370
 
371
  [Go Pro for just $1/month](https://icwp.io/aa).
372
 
373
+ = 8.2.2 - Current Release =
374
+ *Released: 14th October, 2019* - [Release Notes](https://icwp.io/g0)
375
 
376
+ * **(v.2)** FIXED: Fixes for scans running under Windows/IIS.
377
+ * **(v.2)** IMPROVED: Adds a check that a site can send an HTTP request to itself before allowing scans to run.
378
+ * **(v.2)** IMPROVED: Scans clean up after themselves better, if they fail to run.
379
+ * **(v.2)** IMPROVED: Server's own IP address detection when site migrated to a new host.
380
+ * **(v.2)** UPDATED: International translations.
381
+ * **(v.2)** FIXED: PHP notices when data wasn't as expected.
382
 
383
  = 8.2 - Series =
384
  *Released: 1st October, 2019* - [Release Notes](https://icwp.io/g0)
385
 
386
+ * **(v.1)** IMPROVED: Further reduce Malware false positives by also using SVN trunk data when verifying files for plugins and themes.
387
+ * **(v.1)** ADDED: Initial support for repairing Themes that have been installed from WordPress.org.
388
+ * **(v.1)** ADDED: Support for using [WP Hashes.com](https://wphashes.com) for WordPress.org themes (already done for plugins).
389
+ * **(v.1)** FIXED: PHP notices in the logs.
390
  * **(v.0)** IMPROVED: [**PRO**] Malware scanner now uses network intelligence to the gather information on malware results.
391
  * **(v.0)** NEW: Traffic Watcher feature is now free for all users (no longer Pro-only).
392
  * **(v.0)** IMPROVED: Scanning cron is improved and more efficient.
src/config/feature-comments_filter.php CHANGED
@@ -362,13 +362,6 @@
362
  "name": "Custom Reload Message",
363
  "summary": "If you want a custom message when the comment token has expired, please provide this here.",
364
  "description": "This message is displayed on the submit-button when the comment token is expired."
365
- },
366
- {
367
- "key": "insights_last_comment_block_at",
368
- "section": "section_non_ui",
369
- "transferable": false,
370
- "type": "integer",
371
- "default": 0
372
  }
373
  ],
374
  "definitions": {
362
  "name": "Custom Reload Message",
363
  "summary": "If you want a custom message when the comment token has expired, please provide this here.",
364
  "description": "This message is displayed on the submit-button when the comment token is expired."
 
 
 
 
 
 
 
365
  }
366
  ],
367
  "definitions": {
src/config/feature-firewall.php CHANGED
@@ -253,13 +253,6 @@
253
  "name": "Firewall Block Message",
254
  "summary": "Message Displayed To Visitor When A Firewall Block Is Triggered",
255
  "description": "When you select the option to display a message to the visitor, this is the message that is displayed."
256
- },
257
- {
258
- "key": "insights_last_firewall_block_at",
259
- "section": "section_non_ui",
260
- "transferable": false,
261
- "type": "integer",
262
- "default": 0
263
  }
264
  ],
265
  "definitions": {
253
  "name": "Firewall Block Message",
254
  "summary": "Message Displayed To Visitor When A Firewall Block Is Triggered",
255
  "description": "When you select the option to display a message to the visitor, this is the message that is displayed."
 
 
 
 
 
 
 
256
  }
257
  ],
258
  "definitions": {
src/config/feature-hack_protect.php CHANGED
@@ -606,41 +606,6 @@
606
  "type": "array",
607
  "default": []
608
  },
609
- {
610
- "key": "insights_last_scan_ufc_at",
611
- "section": "section_non_ui",
612
- "transferable": false,
613
- "type": "integer",
614
- "default": 0
615
- },
616
- {
617
- "key": "insights_last_scan_apc_at",
618
- "section": "section_non_ui",
619
- "transferable": false,
620
- "type": "integer",
621
- "default": 0
622
- },
623
- {
624
- "key": "insights_last_scan_wcf_at",
625
- "section": "section_non_ui",
626
- "transferable": false,
627
- "type": "integer",
628
- "default": 0
629
- },
630
- {
631
- "key": "insights_last_scan_ptg_at",
632
- "section": "section_non_ui",
633
- "transferable": false,
634
- "type": "integer",
635
- "default": 0
636
- },
637
- {
638
- "key": "insights_last_scan_wpv_at",
639
- "section": "section_non_ui",
640
- "transferable": false,
641
- "type": "integer",
642
- "default": 0
643
- },
644
  {
645
  "key": "rebuild_self",
646
  "section": "section_non_ui",
606
  "type": "array",
607
  "default": []
608
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
609
  {
610
  "key": "rebuild_self",
611
  "section": "section_non_ui",
src/config/feature-ips.php CHANGED
@@ -447,35 +447,6 @@
447
  "summary": "Visitor Triggers The IP Offenses System Through A Firewall Block",
448
  "description": "This message is displayed if the visitor triggered the IP Offenses system and reports how many offenses remain before being blocked."
449
  },
450
- {
451
- "key": "this_server_ip",
452
- "section": "section_non_ui",
453
- "transferable": false,
454
- "sensitive": true,
455
- "type": "text",
456
- "default": ""
457
- },
458
- {
459
- "key": "this_server_ip_last_check_at",
460
- "section": "section_non_ui",
461
- "transferable": false,
462
- "type": "integer",
463
- "default": 0
464
- },
465
- {
466
- "key": "insights_last_transgression_at",
467
- "section": "section_non_ui",
468
- "transferable": false,
469
- "type": "integer",
470
- "default": 0
471
- },
472
- {
473
- "key": "insights_last_ip_block_at",
474
- "section": "section_non_ui",
475
- "transferable": false,
476
- "type": "integer",
477
- "default": 0
478
- },
479
  {
480
  "key": "autounblock_ips",
481
  "section": "section_non_ui",
447
  "summary": "Visitor Triggers The IP Offenses System Through A Firewall Block",
448
  "description": "This message is displayed if the visitor triggered the IP Offenses system and reports how many offenses remain before being blocked."
449
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
450
  {
451
  "key": "autounblock_ips",
452
  "section": "section_non_ui",
src/config/feature-lockdown.php CHANGED
@@ -161,20 +161,6 @@
161
  "name": "Block Username Fishing",
162
  "summary": "Block the ability to discover WordPress usernames based on author IDs",
163
  "description": "When enabled, any URL requests containing 'author=' will be killed. Warning: Enabling this option may interfere with expected operations of your site."
164
- },
165
- {
166
- "key": "insights_xml_block_at",
167
- "section": "section_non_ui",
168
- "transferable": false,
169
- "type": "integer",
170
- "default": 0
171
- },
172
- {
173
- "key": "insights_restapi_block_at",
174
- "section": "section_non_ui",
175
- "transferable": false,
176
- "type": "integer",
177
- "default": 0
178
  }
179
  ],
180
  "definitions": {
161
  "name": "Block Username Fishing",
162
  "summary": "Block the ability to discover WordPress usernames based on author IDs",
163
  "description": "When enabled, any URL requests containing 'author=' will be killed. Warning: Enabling this option may interfere with expected operations of your site."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  }
165
  ],
166
  "definitions": {
src/config/feature-login_protect.php CHANGED
@@ -459,34 +459,6 @@
459
  "transferable": false,
460
  "type": "boolean",
461
  "value": true
462
- },
463
- {
464
- "key": "insights_last_2fa_login_at",
465
- "section": "section_non_ui",
466
- "transferable": false,
467
- "type": "integer",
468
- "default": 0
469
- },
470
- {
471
- "key": "insights_last_login_block_at",
472
- "section": "section_non_ui",
473
- "transferable": false,
474
- "type": "integer",
475
- "default": 0
476
- },
477
- {
478
- "key": "insights_last_register_block_at",
479
- "section": "section_non_ui",
480
- "transferable": false,
481
- "type": "integer",
482
- "default": 0
483
- },
484
- {
485
- "key": "insights_last_reset-password_block_at",
486
- "transferable": false,
487
- "section": "section_non_ui",
488
- "type": "integer",
489
- "default": 0
490
  }
491
  ],
492
  "definitions": {
459
  "transferable": false,
460
  "type": "boolean",
461
  "value": true
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
462
  }
463
  ],
464
  "definitions": {
src/config/feature-plugin.php CHANGED
@@ -391,26 +391,12 @@
391
  "default": ""
392
  },
393
  {
394
- "key": "this_server_ip",
395
  "section": "section_non_ui",
396
  "transferable": false,
397
  "sensitive": true,
398
- "type": "text",
399
- "default": ""
400
- },
401
- {
402
- "key": "this_server_ip_last_check_at",
403
- "section": "section_non_ui",
404
- "transferable": false,
405
- "type": "integer",
406
- "default": 0
407
- },
408
- {
409
- "key": "insights_test_cron_last_run_at",
410
- "transferable": false,
411
- "section": "section_non_ui",
412
- "type": "integer",
413
- "default": 0
414
  },
415
  {
416
  "key": "last_ip_detect_source",
391
  "default": ""
392
  },
393
  {
394
+ "key": "this_server_ip_details",
395
  "section": "section_non_ui",
396
  "transferable": false,
397
  "sensitive": true,
398
+ "type": "array",
399
+ "default": []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
  },
401
  {
402
  "key": "last_ip_detect_source",
src/config/feature-user_management.php CHANGED
@@ -306,20 +306,6 @@
306
  "type": "integer",
307
  "default": 0
308
  },
309
- {
310
- "key": "insights_last_idle_logout_at",
311
- "section": "section_non_ui",
312
- "transferable": false,
313
- "type": "integer",
314
- "default": 0
315
- },
316
- {
317
- "key": "insights_last_password_block_at",
318
- "section": "section_non_ui",
319
- "transferable": false,
320
- "type": "integer",
321
- "default": 0
322
- },
323
  {
324
  "key": "hard_suspended_userids",
325
  "section": "section_non_ui",
306
  "type": "integer",
307
  "default": 0
308
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
  {
310
  "key": "hard_suspended_userids",
311
  "section": "section_non_ui",
src/features/base.php CHANGED
@@ -887,7 +887,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
887
  if ( $sValue == 'default' ) {
888
  $sValue = $this->getTextOptDefault( $sOptKey );
889
  }
890
- return $sValue;
891
  }
892
 
893
  /**
887
  if ( $sValue == 'default' ) {
888
  $sValue = $this->getTextOptDefault( $sOptKey );
889
  }
890
+ return __( $sValue, 'wp-simple-firewall' );
891
  }
892
 
893
  /**
src/features/plugin.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
  use FernleafSystems\Wordpress\Plugin\Shield;
 
4
  use FernleafSystems\Wordpress\Services\Services;
5
 
6
  class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf {
@@ -48,34 +49,54 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
48
  * @return bool
49
  */
50
  public function getLastCheckServerIpAtHasExpired() {
51
- return ( Services::Request()->ts() - $this->getLastCheckServerIpAt() > DAY_IN_SECONDS );
52
- }
53
-
54
- /**
55
- * @return int
56
- */
57
- public function getLastCheckServerIpAt() {
58
- return $this->getOpt( 'this_server_ip_last_check_at', 0 );
59
  }
60
 
61
  /**
62
  * @return string
63
  */
64
  public function getMyServerIp() {
 
65
  $oOpts = $this->getOptions();
66
 
67
- $sThisServerIp = $oOpts->getOpt( 'this_server_ip', '' );
68
- if ( $this->getLastCheckServerIpAtHasExpired() ) {
 
69
  $sThisServerIp = Services::IP()->whatIsMyIp();
70
  if ( !empty( $sThisServerIp ) ) {
71
- $oOpts->setOpt( 'this_server_ip', $sThisServerIp );
 
 
 
 
72
  }
73
- // we always update so we don't forever check on every single page load
74
- $oOpts->setOptAt( 'this_server_ip_last_check_at' );
75
  }
76
  return $sThisServerIp;
77
  }
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  /**
80
  * @return bool
81
  */
@@ -188,16 +209,6 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
188
  );
189
  }
190
 
191
- /**
192
- * @param bool $bOnOrOff
193
- * @return $this
194
- * @deprecated 8.2
195
- */
196
- public function setPluginTrackingPermission( $bOnOrOff = true ) {
197
- return $this->setOpt( 'enable_tracking', $bOnOrOff ? 'Y' : 'N' )
198
- ->setOpt( 'tracking_permission_set_at', Services::Request()->ts() );
199
- }
200
-
201
  /**
202
  * @return array
203
  */
@@ -221,6 +232,14 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
221
  return $bGloballyDisabled || !$this->isOpt( 'global_enable_plugin_features', 'Y' );
222
  }
223
 
 
 
 
 
 
 
 
 
224
  /**
225
  * @return array
226
  */
@@ -772,6 +791,14 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
772
  return $this->getDbH( 'notes' );
773
  }
774
 
 
 
 
 
 
 
 
 
775
  /**
776
  * @return string
777
  */
1
  <?php
2
 
3
  use FernleafSystems\Wordpress\Plugin\Shield;
4
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
5
  use FernleafSystems\Wordpress\Services\Services;
6
 
7
  class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf {
49
  * @return bool
50
  */
51
  public function getLastCheckServerIpAtHasExpired() {
52
+ /** @var Plugin\Options $oOpts */
53
+ $oOpts = $this->getOptions();
54
+ $aDetails = $oOpts->getServerIpDetails();
55
+ $nAge = Services::Request()->ts() - $aDetails[ 'check_ts' ];
56
+ return ( $nAge > HOUR_IN_SECONDS )
57
+ && ( $this->getServerHash() != $aDetails[ 'hash' ] || $nAge > WEEK_IN_SECONDS );
 
 
58
  }
59
 
60
  /**
61
  * @return string
62
  */
63
  public function getMyServerIp() {
64
+ /** @var Plugin\Options $oOpts */
65
  $oOpts = $this->getOptions();
66
 
67
+ $sThisServerIp = $oOpts->getServerIpDetails()[ 'ip' ];
68
+ if ( empty( $sThisServerIp ) || $this->getLastCheckServerIpAtHasExpired() ) {
69
+
70
  $sThisServerIp = Services::IP()->whatIsMyIp();
71
  if ( !empty( $sThisServerIp ) ) {
72
+ $oOpts->updateServerIpDetails( [
73
+ 'ip' => $sThisServerIp,
74
+ 'hash' => $this->getServerHash(),
75
+ 'check_ts' => Services::Request()->ts(),
76
+ ] );
77
  }
 
 
78
  }
79
  return $sThisServerIp;
80
  }
81
 
82
+ /**
83
+ * @return string
84
+ */
85
+ private function getServerHash() {
86
+ return md5( serialize(
87
+ array_values( array_intersect_key(
88
+ $_SERVER,
89
+ array_flip( [
90
+ 'SERVER_SOFTWARE',
91
+ 'SERVER_SIGNATURE',
92
+ 'PATH',
93
+ 'DOCUMENT_ROOT',
94
+ 'SERVER_ADDR',
95
+ ] )
96
+ ) )
97
+ ) );
98
+ }
99
+
100
  /**
101
  * @return bool
102
  */
209
  );
210
  }
211
 
 
 
 
 
 
 
 
 
 
 
212
  /**
213
  * @return array
214
  */
232
  return $bGloballyDisabled || !$this->isOpt( 'global_enable_plugin_features', 'Y' );
233
  }
234
 
235
+ /**
236
+ * @return bool
237
+ */
238
+ public function getCanSiteCallToItself() {
239
+ $oHttp = Services::HttpRequest();
240
+ return $oHttp->get( Services::WpGeneral()->getHomeUrl() ) && $oHttp->lastResponse->getCode() < 400;
241
+ }
242
+
243
  /**
244
  * @return array
245
  */
791
  return $this->getDbH( 'notes' );
792
  }
793
 
794
+ /**
795
+ * @return int
796
+ * @deprecated 8.2.2
797
+ */
798
+ public function getLastCheckServerIpAt() {
799
+ return $this->getOpt( 'this_server_ip_last_check_at', 0 );
800
+ }
801
+
802
  /**
803
  * @return string
804
  */
src/lib/src/Modules/HackGuard/Options.php CHANGED
@@ -66,6 +66,13 @@ class Options extends Base\ShieldOptions {
66
  return 300; // TODO: Def
67
  }
68
 
 
 
 
 
 
 
 
69
  /**
70
  * @return string[]
71
  */
@@ -202,7 +209,7 @@ class Options extends Base\ShieldOptions {
202
  public function addRemoveScanToBuild( $sScan, $bAdd = true ) {
203
  $aS = $this->getScansToBuild();
204
  if ( $bAdd ) {
205
- $aS[ $sScan ] = $sScan;
206
  }
207
  else if ( isset( $aS[ $sScan ] ) ) {
208
  unset( $aS[ $sScan ] );
@@ -211,11 +218,24 @@ class Options extends Base\ShieldOptions {
211
  }
212
 
213
  /**
214
- * @return array
215
  */
216
  public function getScansToBuild() {
217
- $aS = $this->getOpt( 'scans_to_build' );
218
- return is_array( $aS ) ? $aS : [];
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  }
220
 
221
  /**
@@ -223,7 +243,7 @@ class Options extends Base\ShieldOptions {
223
  * @return Options
224
  */
225
  public function setScansToBuild( $aScans ) {
226
- return $this->setOpt( 'scans_to_build', array_intersect( $aScans, $this->getScanSlugs() ) );
227
  }
228
 
229
  /**
66
  return 300; // TODO: Def
67
  }
68
 
69
+ /**
70
+ * @return int
71
+ */
72
+ public function getMalQueueExpirationInterval() {
73
+ return MINUTE_IN_SECONDS*10;
74
+ }
75
+
76
  /**
77
  * @return string[]
78
  */
209
  public function addRemoveScanToBuild( $sScan, $bAdd = true ) {
210
  $aS = $this->getScansToBuild();
211
  if ( $bAdd ) {
212
+ $aS[ $sScan ] = Services::Request()->ts();
213
  }
214
  else if ( isset( $aS[ $sScan ] ) ) {
215
  unset( $aS[ $sScan ] );
218
  }
219
 
220
  /**
221
+ * @return int[] - keys are scan slugs
222
  */
223
  public function getScansToBuild() {
224
+ $aS = $this->getOpt( 'scans_to_build', [] );
225
+ if ( !is_array( $aS ) ) {
226
+ $aS = [];
227
+ }
228
+ if ( !empty( $aS ) ) {
229
+ // We keep scans "to build" for no longer than a minute to prevent indefinite halting with failed Async HTTP.
230
+ $aS = array_filter( $aS,
231
+ function ( $nToBuildAt ) {
232
+ return is_int( $nToBuildAt )
233
+ && Services::Request()->carbon()->subMinute()->timestamp < $nToBuildAt;
234
+ }
235
+ );
236
+ $this->setScansToBuild( $aS );
237
+ }
238
+ return $aS;
239
  }
240
 
241
  /**
243
  * @return Options
244
  */
245
  public function setScansToBuild( $aScans ) {
246
+ return $this->setOpt( 'scans_to_build', array_intersect_key( $aScans, array_flip( $this->getScanSlugs() ) ) );
247
  }
248
 
249
  /**
src/lib/src/Modules/HackGuard/Scan/Queue/Controller.php CHANGED
@@ -2,9 +2,10 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Queue;
4
 
5
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\ScanQueue\Select;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
 
8
 
9
  /**
10
  * Class Controller
@@ -40,10 +41,13 @@ class Controller {
40
  /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
41
  $oMod = $this->getMod();
42
  /** @var HackGuard\Options $oOpts */
43
- $oOpts = $oMod->getOptions();
44
- /** @var Select $oSel */
45
  $oSel = $oMod->getDbHandler_ScanQueue()->getQuerySelector();
46
 
 
 
 
47
  $aScans = array_fill_keys( $oOpts->getScanSlugs(), false );
48
  foreach ( $oSel->getInitiatedScans() as $sInitScan ) {
49
  $aScans[ $sInitScan ] = true;
@@ -51,6 +55,23 @@ class Controller {
51
  return $aScans;
52
  }
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  /**
55
  * @return string[]
56
  */
@@ -65,7 +86,7 @@ class Controller {
65
  /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
66
  $oMod = $this->getMod();
67
  $oDbH = $oMod->getDbHandler_ScanQueue();
68
- /** @var Select $oSel */
69
  $oSel = $oDbH->getQuerySelector();
70
 
71
  $aUnfinished = $oSel->getUnfinishedScans();
@@ -125,9 +146,11 @@ class Controller {
125
  */
126
  public function getQueueProcessor() {
127
  if ( empty( $this->oQueueProcessor ) ) {
 
 
128
  $this->oQueueProcessor = ( new QueueProcessor( 'shield_scanq' ) )
129
  ->setMod( $this->getMod() )
130
- ->setExpirationInterval( MINUTE_IN_SECONDS*10 );
131
  }
132
  return $this->oQueueProcessor;
133
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Queue;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Databases\ScanQueue;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
+ use FernleafSystems\Wordpress\Services\Services;
9
 
10
  /**
11
  * Class Controller
41
  /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
42
  $oMod = $this->getMod();
43
  /** @var HackGuard\Options $oOpts */
44
+ $oOpts = $this->getOptions();
45
+ /** @var ScanQueue\Select $oSel */
46
  $oSel = $oMod->getDbHandler_ScanQueue()->getQuerySelector();
47
 
48
+ // First clean the queue:
49
+ $this->cleanExpiredFromQueue();
50
+
51
  $aScans = array_fill_keys( $oOpts->getScanSlugs(), false );
52
  foreach ( $oSel->getInitiatedScans() as $sInitScan ) {
53
  $aScans[ $sInitScan ] = true;
55
  return $aScans;
56
  }
57
 
58
+ /**
59
+ * @return bool
60
+ */
61
+ protected function cleanExpiredFromQueue() {
62
+ /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
63
+ $oMod = $this->getMod();
64
+ /** @var HackGuard\Options $oOpts */
65
+ $oOpts = $this->getOptions();
66
+ $nExpiredBoundary = Services::Request()
67
+ ->carbon()
68
+ ->subSeconds( $oOpts->getMalQueueExpirationInterval() )->timestamp;
69
+ /** @var ScanQueue\Delete $oDel */
70
+ $oDel = $oMod->getDbHandler_ScanQueue()->getQueryDeleter();
71
+ return $oDel->addWhereOlderThan( $nExpiredBoundary )
72
+ ->query();
73
+ }
74
+
75
  /**
76
  * @return string[]
77
  */
86
  /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
87
  $oMod = $this->getMod();
88
  $oDbH = $oMod->getDbHandler_ScanQueue();
89
+ /** @var ScanQueue\Select $oSel */
90
  $oSel = $oDbH->getQuerySelector();
91
 
92
  $aUnfinished = $oSel->getUnfinishedScans();
146
  */
147
  public function getQueueProcessor() {
148
  if ( empty( $this->oQueueProcessor ) ) {
149
+ /** @var HackGuard\Options $oOpts */
150
+ $oOpts = $this->getOptions();
151
  $this->oQueueProcessor = ( new QueueProcessor( 'shield_scanq' ) )
152
  ->setMod( $this->getMod() )
153
+ ->setExpirationInterval( $oOpts->getMalQueueExpirationInterval() );
154
  }
155
  return $this->oQueueProcessor;
156
  }
src/lib/src/Modules/License/AjaxHandler.php CHANGED
@@ -55,7 +55,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
55
  $sResult = 'Successful - no problems detected communicating with license server.';
56
  }
57
  else {
58
- $sResult = 'Unknown failure due to unexpected response.';
59
  }
60
  }
61
  else {
55
  $sResult = 'Successful - no problems detected communicating with license server.';
56
  }
57
  else {
58
+ $sResult = 'Unknown failure due to unexpected response: '.$oHttpReq->lastResponse->body;
59
  }
60
  }
61
  else {
src/lib/src/Modules/Plugin/Options.php CHANGED
@@ -51,6 +51,29 @@ class Options extends Base\ShieldOptions {
51
  return $aConfig;
52
  }
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  /**
55
  * @return bool
56
  */
51
  return $aConfig;
52
  }
53
 
54
+ /**
55
+ * @return array
56
+ */
57
+ public function getServerIpDetails() {
58
+ $aDetails = $this->getOpt( 'this_server_ip_details', [] );
59
+ if ( empty( $aDetails ) ) {
60
+ $aDetails = [
61
+ 'ip' => '',
62
+ 'hash' => '',
63
+ 'check_ts' => Services::Request()->carbon()->subYear()->timestamp,
64
+ ];
65
+ }
66
+ return $aDetails;
67
+ }
68
+
69
+ /**
70
+ * @param array $aDetails
71
+ * @return $this
72
+ */
73
+ public function updateServerIpDetails( $aDetails ) {
74
+ return $this->setOpt( 'this_server_ip_details', array_merge( $this->getServerIpDetails(), $aDetails ) );
75
+ }
76
+
77
  /**
78
  * @return bool
79
  */
src/lib/vendor/composer/autoload_classmap.php CHANGED
@@ -462,6 +462,7 @@ return array(
462
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
463
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Ssl' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Ssl.php',
464
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\PluginThemeFilesBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeFilesBase.php',
 
465
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\RepoBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/RepoBase.php',
466
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\VersionsBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/VersionsBase.php',
467
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Core' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Core.php',
462
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
463
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Ssl' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Ssl.php',
464
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\PluginThemeFilesBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeFilesBase.php',
465
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\PluginThemeVersionsBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeVersionsBase.php',
466
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\RepoBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/RepoBase.php',
467
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\VersionsBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/VersionsBase.php',
468
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Core' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Core.php',
src/lib/vendor/composer/autoload_static.php CHANGED
@@ -611,6 +611,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
611
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
612
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Ssl' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Ssl.php',
613
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\PluginThemeFilesBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeFilesBase.php',
 
614
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\RepoBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/RepoBase.php',
615
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\VersionsBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/VersionsBase.php',
616
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Core' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Core.php',
611
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
612
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Ssl' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Ssl.php',
613
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\PluginThemeFilesBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeFilesBase.php',
614
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\PluginThemeVersionsBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeVersionsBase.php',
615
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\RepoBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/RepoBase.php',
616
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\VersionsBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/VersionsBase.php',
617
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Core' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Core.php',
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php CHANGED
@@ -40,8 +40,7 @@ class CoreFileHashes {
40
  * @return string
41
  */
42
  public function getFileFragment( $sFile ) {
43
- $sNorm = wp_normalize_path( $sFile );
44
- return path_is_absolute( $sFile ) ? str_replace( wp_normalize_path( ABSPATH ), '', $sNorm ) : $sNorm;
45
  }
46
 
47
  /**
@@ -49,16 +48,7 @@ class CoreFileHashes {
49
  * @return string
50
  */
51
  public function getAbsolutePathFromFragment( $sFile ) {
52
- $sNorm = wp_normalize_path( $sFile );
53
- if ( !path_is_absolute( $sNorm ) ) {
54
- if ( strpos( $sNorm, 'wp-content/' ) === 0 ) {
55
- $sNorm = path_join( WP_CONTENT_DIR, str_replace( 'wp-content/', '', $sNorm ) );
56
- }
57
- else {
58
- $sNorm = path_join( ABSPATH, $sNorm );
59
- }
60
- }
61
- return $sNorm;
62
  }
63
 
64
  /**
40
  * @return string
41
  */
42
  public function getFileFragment( $sFile ) {
43
+ return Services::WpFs()->getPathRelativeToAbsPath( $sFile );
 
44
  }
45
 
46
  /**
48
  * @return string
49
  */
50
  public function getAbsolutePathFromFragment( $sFile ) {
51
+ return wp_normalize_path( path_join( ABSPATH, $this->getFileFragment( $sFile ) ) );
 
 
 
 
 
 
 
 
 
52
  }
53
 
54
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Fs.php CHANGED
@@ -180,6 +180,18 @@ class Fs {
180
  return false;
181
  }
182
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  /**
184
  * @param string $sFilePath
185
  * @return int|null
180
  return false;
181
  }
182
 
183
+ /**
184
+ * @param $sPath
185
+ * @return string
186
+ */
187
+ public function getPathRelativeToAbsPath( $sPath ) {
188
+ return preg_replace(
189
+ sprintf( '#^%s#i', preg_quote( wp_normalize_path( ABSPATH ), '#' ) ),
190
+ '',
191
+ wp_normalize_path( $sPath )
192
+ );
193
+ }
194
+
195
  /**
196
  * @param string $sFilePath
197
  * @return int|null
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeVersionsBase.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Base;
4
+
5
+ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
6
+ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
7
+
8
+ abstract class PluginThemeVersionsBase {
9
+
10
+ /**
11
+ * @return string[]
12
+ */
13
+ public function all() {
14
+ $aVersions = array_filter( array_keys( $this->allVersionsUrls() ) );
15
+ usort( $aVersions, 'version_compare' );
16
+ return $aVersions;
17
+ }
18
+
19
+ /**
20
+ * @return string[]
21
+ */
22
+ public function allVersionsUrls() {
23
+ $aVersions = [];
24
+ $sSlug = $this->getWorkingSlug();
25
+ if ( !empty( $sSlug ) ) {
26
+ try {
27
+ $oInfo = $this->getApi()
28
+ ->setWorkingSlug( $sSlug )
29
+ ->getInfo();
30
+ $aVersions = isset( $oInfo->versions ) ? $oInfo->versions : [];
31
+ }
32
+ catch ( \Exception $oE ) {
33
+ }
34
+ }
35
+ return is_array( $aVersions ) ? $aVersions : [];
36
+ }
37
+
38
+ /**
39
+ * @return Plugin\Api|Theme\Api
40
+ */
41
+ abstract protected function getApi();
42
+
43
+ /**
44
+ * @return string
45
+ */
46
+ abstract protected function getWorkingSlug();
47
+
48
+ /**
49
+ * @return string
50
+ * @throws \Exception
51
+ */
52
+ public function latest() {
53
+ return $this->getApi()
54
+ ->setWorkingSlug( $this->getWorkingSlug() )
55
+ ->getInfo()->version;
56
+ }
57
+
58
+ /**
59
+ * @param string $sVersion
60
+ * @param bool $bVerifyUrl
61
+ * @return bool
62
+ */
63
+ abstract public function exists( $sVersion, $bVerifyUrl = false );
64
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Cp/Files.php CHANGED
@@ -16,11 +16,11 @@ class Files extends Services\Utilities\WpOrg\Wp\Files {
16
  * @throws \InvalidArgumentException
17
  */
18
  public function getOriginalFileFromVcs( $sFilePath ) {
19
- $sTmpFile = null;
20
- $oHashes = Services\Services::CoreFileHashes();
21
- if ( !$oHashes->isCoreFile( $sFilePath ) ) {
22
  throw new \InvalidArgumentException( 'File provided is not actually a core file.' );
23
  }
24
- return ( new Repo() )->downloadFromVcs( $oHashes->getFileFragment( $sFilePath ) );
 
 
25
  }
26
  }
16
  * @throws \InvalidArgumentException
17
  */
18
  public function getOriginalFileFromVcs( $sFilePath ) {
19
+ if ( !Services\Services::CoreFileHashes()->isCoreFile( $sFilePath ) ) {
 
 
20
  throw new \InvalidArgumentException( 'File provided is not actually a core file.' );
21
  }
22
+ return ( new Repo() )->downloadFromVcs(
23
+ Services\Services::WpFs()->getPathRelativeToAbsPath( $sFilePath )
24
+ );
25
  }
26
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Versions.php CHANGED
@@ -3,45 +3,17 @@
3
  namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
4
 
5
  use FernleafSystems\Wordpress\Services\Utilities\HttpUtil;
 
6
 
7
- class Versions {
8
 
9
  use Base;
10
 
11
  /**
12
- * @return string[]
13
  */
14
- public function all() {
15
- $aVersions = array_filter( array_keys( $this->allVersionsUrls() ) );
16
- usort( $aVersions, 'version_compare' );
17
- return $aVersions;
18
- }
19
-
20
- /**
21
- * @return string[]
22
- */
23
- public function allVersionsUrls() {
24
- try {
25
- $aVersions = ( new Api() )
26
- ->setWorkingSlug( $this->getWorkingSlug() )
27
- ->getInfo()
28
- ->versions;
29
- }
30
- catch ( \Exception $oE ) {
31
- $aVersions = [];
32
- }
33
- return $aVersions;
34
- }
35
-
36
- /**
37
- * @return string
38
- * @throws \Exception
39
- */
40
- public function latest() {
41
- return ( new Api() )
42
- ->setWorkingSlug( $this->getWorkingSlug() )
43
- ->getInfo()
44
- ->version;
45
  }
46
 
47
  /**
3
  namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
4
 
5
  use FernleafSystems\Wordpress\Services\Utilities\HttpUtil;
6
+ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Base\PluginThemeVersionsBase;
7
 
8
+ class Versions extends PluginThemeVersionsBase {
9
 
10
  use Base;
11
 
12
  /**
13
+ * @return Api
14
  */
15
+ protected function getApi() {
16
+ return new Api();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Versions.php CHANGED
@@ -3,45 +3,17 @@
3
  namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
4
 
5
  use FernleafSystems\Wordpress\Services\Utilities\HttpUtil;
 
6
 
7
- class Versions {
8
 
9
  use Base;
10
 
11
  /**
12
- * @return string[]
13
  */
14
- public function all() {
15
- $aVersions = array_filter( array_keys( $this->allVersionsUrls() ) );
16
- usort( $aVersions, 'version_compare' );
17
- return $aVersions;
18
- }
19
-
20
- /**
21
- * @return string[]
22
- */
23
- public function allVersionsUrls() {
24
- try {
25
- $aVersions = ( new Api() )
26
- ->setWorkingSlug( $this->getWorkingSlug() )
27
- ->getInfo()
28
- ->versions;
29
- }
30
- catch ( \Exception $oE ) {
31
- $aVersions = [];
32
- }
33
- return $aVersions;
34
- }
35
-
36
- /**
37
- * @return string
38
- * @throws \Exception
39
- */
40
- public function latest() {
41
- return ( new Api() )
42
- ->setWorkingSlug( $this->getWorkingSlug() )
43
- ->getInfo()
44
- ->version;
45
  }
46
 
47
  /**
3
  namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
4
 
5
  use FernleafSystems\Wordpress\Services\Utilities\HttpUtil;
6
+ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Base\PluginThemeVersionsBase;
7
 
8
+ class Versions extends PluginThemeVersionsBase {
9
 
10
  use Base;
11
 
12
  /**
13
+ * @return Api
14
  */
15
+ protected function getApi() {
16
+ return new Api();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Files.php CHANGED
@@ -16,12 +16,12 @@ class Files {
16
  * @throws \InvalidArgumentException
17
  */
18
  public function getOriginalFileFromVcs( $sFilePath ) {
19
- $sTmpFile = null;
20
- $oHashes = Services\Services::CoreFileHashes();
21
- if ( !$oHashes->isCoreFile( $sFilePath ) ) {
22
  throw new \InvalidArgumentException( 'File provided is not actually a core file.' );
23
  }
24
- return ( new Repo() )->downloadFromVcs( $oHashes->getFileFragment( $sFilePath ) );
 
 
25
  }
26
 
27
  /**
@@ -30,13 +30,11 @@ class Files {
30
  * @throws \InvalidArgumentException
31
  */
32
  public function replaceFileFromVcs( $sFilePath ) {
33
- $oHashes = Services\Services::CoreFileHashes();
34
- if ( !$oHashes->isCoreFile( $sFilePath ) ) {
35
- throw new \InvalidArgumentException( 'File provided is not actually a core file.' );
36
- }
37
-
38
  $sTmp = $this->getOriginalFileFromVcs( $sFilePath );
39
  return !empty( $sTmp )
40
- && Services\Services::WpFs()->move( $sTmp, $oHashes->getAbsolutePathFromFragment( $sFilePath ) );
 
 
 
41
  }
42
  }
16
  * @throws \InvalidArgumentException
17
  */
18
  public function getOriginalFileFromVcs( $sFilePath ) {
19
+ if ( !Services\Services::CoreFileHashes()->isCoreFile( $sFilePath ) ) {
 
 
20
  throw new \InvalidArgumentException( 'File provided is not actually a core file.' );
21
  }
22
+ return ( new Repo() )->downloadFromVcs(
23
+ Services\Services::WpFs()->getPathRelativeToAbsPath( $sFilePath )
24
+ );
25
  }
26
 
27
  /**
30
  * @throws \InvalidArgumentException
31
  */
32
  public function replaceFileFromVcs( $sFilePath ) {
 
 
 
 
 
33
  $sTmp = $this->getOriginalFileFromVcs( $sFilePath );
34
  return !empty( $sTmp )
35
+ && Services\Services::WpFs()->move(
36
+ $sTmp,
37
+ Services\Services::CoreFileHashes()->getAbsolutePathFromFragment( $sFilePath )
38
+ );
39
  }
40
  }
src/processors/hack_protect.php CHANGED
@@ -95,6 +95,10 @@ class ICWP_WPSF_Processor_HackProtect extends Modules\BaseShield\ShieldProcessor
95
  $aUiTrack[ 'selected_scans' ] = $oOpts->getScanSlugs();
96
  }
97
 
 
 
 
 
98
  $oScannerMain = $this->getSubProScanner();
99
  $oQueCon = $oMod->getScanController();
100
  $aData = [
@@ -111,7 +115,8 @@ class ICWP_WPSF_Processor_HackProtect extends Modules\BaseShield\ShieldProcessor
111
  'item_repair' => $oMod->getAjaxActionData( 'item_repair', true ),
112
  ],
113
  'flags' => [
114
- 'is_premium' => $oMod->isPremium()
 
115
  ],
116
  'strings' => [
117
  'never' => __( 'Never', 'wp-simple-firewall' ),
@@ -132,9 +137,11 @@ class ICWP_WPSF_Processor_HackProtect extends Modules\BaseShield\ShieldProcessor
132
  'run_scans_now' => __( 'Run Scans Now', 'wp-simple-firewall' ),
133
  'no_entries_to_display' => __( 'No entries to display.', 'wp-simple-firewall' ),
134
  'scan_progress' => __( 'Scan Progress', 'wp-simple-firewall' ),
 
135
  ],
136
  'vars' => [
137
- 'initial_check' => $oQueCon->hasRunningScans()
 
138
  ],
139
  'scans' => [
140
  'apc' => [
95
  $aUiTrack[ 'selected_scans' ] = $oOpts->getScanSlugs();
96
  }
97
 
98
+ // Can Scan Checks:
99
+ $aReasonCantScan = $this->getSubProScanner()
100
+ ->getReasonsScansCantExecute();
101
+
102
  $oScannerMain = $this->getSubProScanner();
103
  $oQueCon = $oMod->getScanController();
104
  $aData = [
115
  'item_repair' => $oMod->getAjaxActionData( 'item_repair', true ),
116
  ],
117
  'flags' => [
118
+ 'is_premium' => $oMod->isPremium(),
119
+ 'can_scan' => count( $aReasonCantScan ) === 0,
120
  ],
121
  'strings' => [
122
  'never' => __( 'Never', 'wp-simple-firewall' ),
137
  'run_scans_now' => __( 'Run Scans Now', 'wp-simple-firewall' ),
138
  'no_entries_to_display' => __( 'No entries to display.', 'wp-simple-firewall' ),
139
  'scan_progress' => __( 'Scan Progress', 'wp-simple-firewall' ),
140
+ 'reason_not_call_self' => __( "This site currently can't make HTTP requests to itself.", 'wp-simple-firewall' ),
141
  ],
142
  'vars' => [
143
+ 'initial_check' => $oQueCon->hasRunningScans(),
144
+ 'cannot_scan_reasons' => $aReasonCantScan
145
  ],
146
  'scans' => [
147
  'apc' => [
src/processors/hackprotect_scanner.php CHANGED
@@ -164,19 +164,40 @@ class ICWP_WPSF_Processor_HackProtect_Scanner extends ShieldProcessor {
164
  /** @var HackGuard\Options $oOpts */
165
  $oOpts = $this->getOptions();
166
 
167
- $aScans = [];
168
- foreach ( $oOpts->getScanSlugs() as $sScanSlug ) {
169
- $oProc = $this->getSubPro( $sScanSlug );
170
- if ( $oProc->isAvailable() && $oProc->isEnabled() ) {
171
- $aScans[] = $sScanSlug;
 
 
172
  }
 
 
 
 
 
 
 
 
 
173
  }
 
174
 
175
- $oOpts->setIsScanCron( true );
176
- $oMod->saveModOptions();
 
 
 
 
 
 
177
 
178
- $oMod->getScanController()
179
- ->startScans( $aScans );
 
 
 
180
  }
181
 
182
  /**
164
  /** @var HackGuard\Options $oOpts */
165
  $oOpts = $this->getOptions();
166
 
167
+ if ( $this->getCanScansExecute() ) {
168
+ $aScans = [];
169
+ foreach ( $oOpts->getScanSlugs() as $sScanSlug ) {
170
+ $oProc = $this->getSubPro( $sScanSlug );
171
+ if ( $oProc->isAvailable() && $oProc->isEnabled() ) {
172
+ $aScans[] = $sScanSlug;
173
+ }
174
  }
175
+
176
+ $oOpts->setIsScanCron( true );
177
+ $oMod->saveModOptions();
178
+
179
+ $oMod->getScanController()
180
+ ->startScans( $aScans );
181
+ }
182
+ else {
183
+ error_log( 'Shield scans cannot execute.' );
184
  }
185
+ }
186
 
187
+ /**
188
+ * @return string[]
189
+ */
190
+ public function getReasonsScansCantExecute() {
191
+ return array_keys( array_filter( [
192
+ 'reason_not_call_self' => !$this->getCon()->getModule_Plugin()->getCanSiteCallToItself()
193
+ ] ) );
194
+ }
195
 
196
+ /**
197
+ * @return bool
198
+ */
199
+ public function getCanScansExecute() {
200
+ return count( $this->getReasonsScansCantExecute() ) === 0;
201
  }
202
 
203
  /**
src/processors/usermanagement_passwords.php CHANGED
@@ -209,7 +209,7 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends Modules\BaseShield\Sh
209
  /**
210
  * TODO: Upon upgrading minimum PHP 5.6, remove the older, and install newer as-is
211
  */
212
- if ( Services::Data()->getPhpVersionIsAtLeast( '5.6' ) ) {
213
  $aResults = ( new \ZxcvbnPhp56\Zxcvbn() )->passwordStrength( $sPassword );
214
  }
215
  else {
209
  /**
210
  * TODO: Upon upgrading minimum PHP 5.6, remove the older, and install newer as-is
211
  */
212
+ if ( Services::Data()->getPhpVersionIsAtLeast( '5.6' ) && extension_loaded( 'mbstring' ) ) {
213
  $aResults = ( new \ZxcvbnPhp56\Zxcvbn() )->passwordStrength( $sPassword );
214
  }
215
  else {
templates/twig/wpadmin_pages/insights/scans/scan_areas.twig CHANGED
@@ -141,12 +141,20 @@
141
  </div>
142
  </div>
143
  <div class="card-footer">
144
- {{ strings.more_items_longer }}
145
  <button class="btn btn-primary float-right"
 
146
  type="submit" id="StartScans">{{ strings.run_scans_now }} &rarr;</button>
 
 
 
 
 
 
 
 
 
147
  </div>
148
  </div>
149
- </button>
150
  {% include '/wpadmin_pages/insights/scans/modal_progress.twig' %}
151
  </form>
152
 
141
  </div>
142
  </div>
143
  <div class="card-footer">
 
144
  <button class="btn btn-primary float-right"
145
+ {% if not flags.can_scan %}disabled="disabled"{% endif %}
146
  type="submit" id="StartScans">{{ strings.run_scans_now }} &rarr;</button>
147
+ {% if flags.can_scan %}
148
+ {{ strings.more_items_longer }}
149
+ {% else %}
150
+ <p>Scans are currently disabled because:
151
+ {% for cannot_scan_reason in vars.cannot_scan_reasons %}
152
+ <br />-<span class="text-danger">{{ strings[cannot_scan_reason] }}</span>
153
+ {% endfor %}
154
+ </p>
155
+ {% endif %}
156
  </div>
157
  </div>
 
158
  {% include '/wpadmin_pages/insights/scans/modal_progress.twig' %}
159
  </form>
160