Version Description
Current Release = Released: 25th February, 2020 - Release Notes
(v.3) IMPROVED: AJAX handling and general plugin requests have been refined to be less prone to errors.
(v.3) IMPROVED: The Traffic Log Viewer will now be displayed even if it's disabled.
(v.3) REMOVED: 2 options from the Automatic Updates module have been removed, that influenced translations and version control.
(v.3) IMPROVED: Some minor improvements and optimisations.
(v.3) IMPROVED: Adjusted how Shield stores temporary WP options to prevent duplicates.
(v.3) FIXED: Login backup-code wasn't always reset after it was used.
(v.3) FIXED: IP address wasn't blocked even after committing an offense in 1 particular scenario.
Download this release
Release Info
Developer | paultgoodchild |
Plugin | Shield Security for WordPress |
Version | 8.6.3 |
Comparing to | |
See all releases |
Code changes from version 8.5.7 to 8.6.3
- icwp-wpsf.php +1 -1
- init.php +11 -1
- plugin-spec.php +3 -3
- readme.txt +20 -43
- src/common/icwp-foundation.php +0 -18
- src/common/icwp-serviceproviders.php +0 -548
- src/common/icwp-wpcron.php +0 -171
- src/config/feature-autoupdates.php +0 -22
- src/config/feature-license.php +27 -19
- src/config/feature-login_protect.php +19 -3
- src/config/feature-plugin.php +0 -7
- src/config/feature-user_management.php +71 -0
- src/features/admin_access_restriction.php +6 -14
- src/features/base.php +23 -61
- src/features/base_wpsf.php +0 -54
- src/features/comments_filter.php +11 -15
- src/features/hack_protect.php +18 -207
- src/features/headers.php +0 -63
- src/features/insights.php +0 -6
- src/features/ips.php +11 -16
- src/features/license.php +174 -380
- src/features/login_protect.php +36 -13
- src/features/plugin.php +3 -134
- src/features/user_management.php +20 -170
- src/lib/src/Controller/Controller.php +36 -24
- src/lib/src/Crons/BaseCron.php +17 -0
- src/lib/src/Crons/DailyCron.php +30 -0
- src/lib/src/Crons/HourlyCron.php +30 -0
- src/lib/src/Databases/AuditTrail/Handler.php +0 -14
- src/lib/src/Databases/Base/BaseQuery.php +0 -14
- src/lib/src/Databases/IPs/EntryVO.php +0 -39
- src/lib/src/Databases/IPs/Select.php +0 -43
- src/lib/src/Deprecated/Foundation.php +0 -24
- src/lib/src/License/EddLicenseVO.php +0 -1
- src/lib/src/Modules/Autoupdates/Strings.php +2 -2
- src/lib/src/Modules/Base/AjaxHandlerBase.php +17 -9
- src/lib/src/Modules/Base/AjaxHandlerShield.php +0 -2
- src/lib/src/Modules/Base/BaseProcessor.php +1 -0
- src/lib/src/Modules/Base/Options.php +3 -1
- src/lib/src/Modules/Base/Strings.php +3 -0
- src/lib/src/Modules/CommentsFilter/Options.php +7 -0
- src/lib/src/Modules/CommentsFilter/Scan/Bot.php +5 -4
- src/lib/src/Modules/CommentsFilter/Token/Create.php +5 -4
- src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BuildAll.php +0 -53
- src/lib/src/Modules/HackGuard/Options.php +0 -16
- src/lib/src/Modules/IPs/AjaxHandler.php +19 -15
- src/lib/src/Modules/IPs/Components/ProcessOffense.php +11 -6
- src/lib/src/Modules/IPs/Components/QueryIpBlock.php +2 -7
- src/lib/src/Modules/IPs/Lib/BlacklistHandler.php +101 -0
- src/lib/src/Modules/IPs/Lib/BlackmarkRequest.php +84 -0
- src/lib/src/Modules/IPs/Lib/BlockRequest.php +144 -0
- src/lib/src/Modules/IPs/Lib/Ops/AddIp.php +41 -5
- src/lib/src/Modules/IPs/Lib/Ops/LookupIpOnList.php +4 -20
- src/lib/src/Modules/License/AdminNotices.php +72 -0
- src/lib/src/Modules/License/AjaxHandler.php +26 -32
- src/lib/src/Modules/License/Lib/LicenseEmails.php +66 -0
- src/lib/src/Modules/License/Lib/LicenseHandler.php +201 -0
- src/lib/src/Modules/License/Lib/LookupRequest.php +56 -0
- src/lib/src/Modules/License/Lib/Verify.php +94 -0
- src/lib/src/Modules/License/Lib/WpHashes/ApiTokenManager.php +145 -0
- src/lib/src/Modules/LoginGuard/AjaxHandler.php +15 -12
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php +155 -0
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php +328 -0
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaControllerConsumer.php +33 -0
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Backup.php +169 -0
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/BaseProvider.php +258 -0
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Email.php +237 -0
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/GoogleAuth.php +260 -0
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Yubikey.php +254 -0
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/UserProfile.php +90 -0
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/ValidateLoginIntentRequest.php +67 -0
- src/lib/src/Modules/LoginGuard/Options.php +114 -3
- src/lib/src/Modules/LoginGuard/Strings.php +6 -0
- src/lib/src/Modules/Plugin/AdminNotices.php +2 -1
- src/lib/src/Modules/Plugin/Lib/WpHashesTokenManager.php +19 -2
- src/lib/src/Modules/Plugin/Options.php +0 -17
- src/lib/src/Modules/Plugin/Strings.php +3 -0
- src/lib/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php +143 -0
- src/lib/src/Modules/UserManagement/Lib/Registration/EmailValidate.php +82 -0
- src/lib/src/Modules/UserManagement/Options.php +16 -0
- src/lib/src/Modules/UserManagement/Strings.php +16 -0
- src/lib/src/Modules/UserManagement/Suspend/Idle.php +4 -6
- src/lib/src/Modules/UserManagement/Suspend/PasswordExpiry.php +4 -3
- src/lib/src/Scans/Mal/Utilities/FalsePositiveQuery.php +10 -4
- src/lib/src/Scans/Mal/Utilities/FalsePositiveReporter.php +14 -4
- src/lib/src/Scans/Mal/Utilities/Patterns.php +5 -2
- src/lib/src/Scans/Ptg/ScannerBase.php +0 -53
- src/lib/src/Scans/Ptg/ScannerPlugins.php +0 -23
- src/lib/src/Scans/Wpv/Scan.php +7 -2
- src/lib/src/Tables/Build/Ip.php +2 -0
- src/lib/src/Tables/Render/IpBlack.php +9 -2
- src/lib/src/Users/ShieldUserMeta.php +17 -0
- src/lib/src/Utilities/AdminNotices/Controller.php +1 -1
- src/lib/vendor/composer/autoload_classmap.php +30 -7
- src/lib/vendor/composer/autoload_static.php +30 -7
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/General.php +18 -7
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/System.php +8 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Data.php +1 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php +25 -4
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ApiInfo.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/AssetHashesBase.php +3 -5
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Base.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/PluginThemeBase.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Base.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Retrieve.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Services/Base.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Services/IPs.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Token/Base.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Token/Solicit.php +16 -13
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Verify/Base.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Verify/Email.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Vulnerabilities/Base.php +2 -2
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Vulnerabilities/BasePluginTheme.php +2 -2
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php +0 -160
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddActions.php +5 -3
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php +6 -4
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Base.php +110 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Lookup.php +59 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Ping.php +26 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/Lookup.php +5 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Options/TestCanUseTransients.php +57 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Options/Transient.php +82 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php +3 -4
- src/lib/vendor/symfony/polyfill-mbstring/Mbstring.php +8 -1
- src/processors/admin_access_restriction.php +3 -17
- src/processors/adminaccess_whitelabel.php +7 -4
- src/processors/autoupdates.php +24 -53
- src/processors/comments_filter.php +2 -16
- src/processors/commentsfilter_botspam.php +6 -3
- src/processors/email.php +16 -63
- src/processors/events.php +0 -8
- src/processors/hackprotect_integrity.php +2 -1
- src/processors/hackprotect_scan_assets_base.php +0 -29
- src/processors/hackprotect_scan_base.php +0 -57
- src/processors/hackprotect_scan_ptg.php +0 -117
- src/processors/hackprotect_scan_ufc.php +3 -3
- src/processors/hackprotect_scan_wcf.php +4 -2
- src/processors/hackprotect_scanner.php +0 -9
- src/processors/headers.php +1 -1
- src/processors/ips.php +5 -413
- src/processors/license.php +20 -15
- src/processors/lockdown.php +1 -1
- src/processors/login_protect.php +18 -17
- src/processors/loginprotect_intent.php +9 -319
- src/processors/loginprotect_intent_tracker.php +4 -0
- src/processors/loginprotect_intentprovider_backup.php +3 -84
- src/processors/loginprotect_intentprovider_base.php +3 -0
- src/processors/loginprotect_intentprovider_email.php +4 -75
- src/processors/loginprotect_intentprovider_ga.php +3 -48
- src/processors/loginprotect_intentprovider_yubikey.php +4 -44
- src/processors/plugin.php +7 -11
- src/processors/plugin_importexport.php +8 -8
- src/processors/sessions.php +0 -9
- src/processors/user_management.php +4 -24
- src/processors/usermanagement_sessions.php +0 -18
- src/wizards/login_protect.php +35 -36
- src/wizards/plugin.php +2 -1
- templates/php/snippets/user_profile_backupcode.php +0 -47
- templates/php/snippets/user_profile_emailauthentication.php +0 -29
- templates/php/snippets/user_profile_googleauthenticator.php +0 -89
- templates/php/snippets/user_profile_yubikey.php +0 -81
- templates/twig/notices/wphashes-token-fail.twig +7 -0
- templates/twig/pages/login_intent/index.twig +1 -127
- templates/twig/snippets/login_intent/form.twig +136 -0
- templates/twig/snippets/user/profile/mfa/mfa_backup.twig +18 -0
- templates/twig/snippets/user/profile/mfa/mfa_container.twig +11 -0
- templates/twig/snippets/user/profile/mfa/mfa_email.twig +13 -0
- templates/twig/snippets/user/profile/mfa/mfa_ga.twig +55 -0
- templates/twig/snippets/user/profile/mfa/mfa_yubikey.twig +36 -0
- templates/twig/wpadmin_pages/insights/license/license.twig +17 -4
- templates/twig/wpadmin_pages/insights/traffic/index.twig +6 -4
icwp-wpsf.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
-
* Version: 8.
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
+
* Version: 8.6.3
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
init.php
CHANGED
@@ -59,4 +59,14 @@ catch ( \Exception $oE ) {
|
|
59 |
error_log( 'Perhaps due to a failed upgrade, the Shield plugin failed to load certain component(s) - you should remove the plugin and reinstall.' );
|
60 |
error_log( $oE->getMessage() );
|
61 |
}
|
62 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
error_log( 'Perhaps due to a failed upgrade, the Shield plugin failed to load certain component(s) - you should remove the plugin and reinstall.' );
|
60 |
error_log( $oE->getMessage() );
|
61 |
}
|
62 |
+
}
|
63 |
+
|
64 |
+
if ( !function_exists( 'shield_security_get_plugin' ) ) {
|
65 |
+
/**
|
66 |
+
* @return ICWP_WPSF_Shield_Security|null
|
67 |
+
*/
|
68 |
+
function shield_security_get_plugin() {
|
69 |
+
global $oICWP_Wpsf;
|
70 |
+
return ( $oICWP_Wpsf instanceof \ICWP_WPSF_Shield_Security ) ? $oICWP_Wpsf : null;
|
71 |
+
}
|
72 |
+
}
|
plugin-spec.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "8.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "202002.
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield",
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "8.6.3",
|
4 |
+
"release_timestamp": 1582635039,
|
5 |
+
"build": "202002.2505",
|
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.
|
12 |
|
13 |
Smarter security protection from hackers through automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
|
14 |
|
@@ -370,47 +370,24 @@ You will always be able to use Shield Security and its free features in-full.
|
|
370 |
|
371 |
[Go Pro for just $1/month](https://shsec.io/aa).
|
372 |
|
373 |
-
= 8.
|
374 |
-
*Released:
|
375 |
-
|
376 |
-
* **(v.
|
377 |
-
* **(v.
|
378 |
-
* **(v.
|
379 |
-
* **(v.
|
380 |
-
|
381 |
-
|
382 |
-
*
|
383 |
-
|
384 |
-
|
385 |
-
*
|
386 |
-
|
387 |
-
* **(v.
|
388 |
-
* **(v.
|
389 |
-
* **(v.
|
390 |
-
* **(v.
|
391 |
-
* **(v.
|
392 |
-
* **(v.2)** IMPROVED: Plugin/Theme Hack Guard Snapshot building is optimised to reduce disruption is some cases.
|
393 |
-
* **(v.2)** IMPROVED: Visitor IP detection processing.
|
394 |
-
* **(v.2)** IMPROVED: Improved cache-prevention of Login Two-Factor Authentication portal.
|
395 |
-
* **(v.2)** FIXED: Firewall email alert was not sent when using certain dedicated email plugins.
|
396 |
-
* **(v.2)** FIXED: Firewall 404 setting was redirecting instead of responding with 404.
|
397 |
-
* **(v.2)** ADDED: Added support for NodePing filtering in the traffic logger.
|
398 |
-
* **(v.1)** FIXED: Fix for page loading issue/slowdown in some cases.
|
399 |
-
* **(v.0)** NEW: Initial support for checksum scanning of premium plugins and themes.
|
400 |
-
* **(v.0)** NEW: Ability to switch-off Security Admin with an email confirmation if key is lost/forgotten.
|
401 |
-
* **(v.0)** NEW: Ability to auto-repair theme files.
|
402 |
-
* **(v.0)** ADDED: Ability to whitelist requests so that they are never blacklisted.
|
403 |
-
* **(v.0)** ADDED: Ability to filter the IP White/Black list tables for a specific IP address.
|
404 |
-
* **(v.0)** ADDED: Support for repeated audit trail entries - so the logs don't get filled with repeated messages.
|
405 |
-
* **(v.0)** ADDED: [**PRO**] Option to provide complete, custom Content Security Policy headers.
|
406 |
-
* **(v.0)** IMPROVED: Protection against a certain type of broken plugin installation if WordPress doesn't properly copy files.
|
407 |
-
* **(v.0)** IMPROVED: Redesigned Table UI for scan results.
|
408 |
-
* **(v.0)** IMPROVED: Redesigned Plugin/Theme File Guard.
|
409 |
-
* **(v.0)** IMPROVED: Completely re-written much of the scanners code.
|
410 |
-
* **(v.0)** IMPROVED: Better detection of the hosting server's IP addresses - i.e. support for IPv6 alongside IPv4.
|
411 |
-
* **(v.0)** FIXED: Two-Factor Authentication (2FA) login screen redirection bug.
|
412 |
-
* **(v.0)** FIXED: It was possible to temporarily by-pass the 2FA screen to gain access to WP Admin after logging-in.
|
413 |
-
* **(v.0)** CLEANED: Code cleaning.
|
414 |
-
* **(v.0)** UPDATED: Twitter Bootstrap library.
|
415 |
|
416 |
#### [Full Shield Security Changelog](https://shsec.io/shieldwporgfullchangelog)
|
8 |
Requires PHP: 5.4.0
|
9 |
Recommended PHP: 7.0
|
10 |
Tested up to: 5.3
|
11 |
+
Stable tag: 8.6.3
|
12 |
|
13 |
Smarter security protection from hackers through automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
|
14 |
|
370 |
|
371 |
[Go Pro for just $1/month](https://shsec.io/aa).
|
372 |
|
373 |
+
= 8.6.3 - Current Release =
|
374 |
+
*Released: 25th February, 2020* - [Release Notes](https://shsec.io/gl)
|
375 |
+
|
376 |
+
* **(v.3)** IMPROVED: AJAX handling and general plugin requests have been refined to be less prone to errors.
|
377 |
+
* **(v.3)** IMPROVED: The Traffic Log Viewer will now be displayed even if it's disabled.
|
378 |
+
* **(v.3)** REMOVED: 2 options from the Automatic Updates module have been removed, that influenced translations and version control.
|
379 |
+
* **(v.3)** IMPROVED: Some minor improvements and optimisations.
|
380 |
+
* **(v.3)** IMPROVED: Adjusted how Shield stores temporary WP options to prevent duplicates.
|
381 |
+
* **(v.3)** FIXED: Login backup-code wasn't always reset after it was used.
|
382 |
+
* **(v.3)** FIXED: IP address wasn't blocked even after committing an offense in 1 particular scenario.
|
383 |
+
|
384 |
+
= 8.6 - Series =
|
385 |
+
*Released: 19th February, 2020* - [Release Notes](https://shsec.io/gl)
|
386 |
+
|
387 |
+
* **(v.1)** NEW: [**PRO**] Deep scanning for valid email addresses when user registers with site.
|
388 |
+
* **(v.1)** ADDED: [**PRO**] New option allows users to turn on email-based two-factor authentication from their profile.
|
389 |
+
* **(v.1)** ADDED: Support for manually blocking IP Ranges (not just single IPs).
|
390 |
+
* **(v.1)** IMPROVED: Two-Factor Authentication system has been rewritten and improved.
|
391 |
+
* **(v.1)** IMPROVED: Table ordering and descriptions for the IP Black List.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
392 |
|
393 |
#### [Full Shield Security Changelog](https://shsec.io/shieldwporgfullchangelog)
|
src/common/icwp-foundation.php
DELETED
@@ -1,18 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class ICWP_WPSF_Foundation
|
5 |
-
* @deprecated 8.4
|
6 |
-
*/
|
7 |
-
class ICWP_WPSF_Foundation {
|
8 |
-
|
9 |
-
const DEFAULT_SERVICE_PREFIX = 'icwp_wpsf_';
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @param string $sSuffix
|
13 |
-
* @return string
|
14 |
-
*/
|
15 |
-
protected function prefix( $sSuffix ) {
|
16 |
-
return self::DEFAULT_SERVICE_PREFIX.$sSuffix;
|
17 |
-
}
|
18 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-serviceproviders.php
DELETED
@@ -1,548 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Services\Services;
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Class ICWP_WPSF_ServiceProviders
|
7 |
-
*/
|
8 |
-
class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
9 |
-
|
10 |
-
const URL_STATUS_CAKE_IPS = 'https://app.statuscake.com/Workfloor/Locations.php?format=json';
|
11 |
-
const URL_ICONTROLWP_IPS = 'https://serviceips.icontrolwp.com/';
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var ICWP_WPSF_ServiceProviders
|
15 |
-
*/
|
16 |
-
protected static $oInstance = null;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* @return ICWP_WPSF_ServiceProviders
|
20 |
-
*/
|
21 |
-
public static function GetInstance() {
|
22 |
-
if ( is_null( self::$oInstance ) ) {
|
23 |
-
self::$oInstance = new self();
|
24 |
-
}
|
25 |
-
return self::$oInstance;
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @return string[][]
|
30 |
-
*/
|
31 |
-
public function getIps_CloudFlare() {
|
32 |
-
$oWp = Services::WpGeneral();
|
33 |
-
|
34 |
-
$sStoreKey = $this->prefix( 'serviceips_cloudflare' );
|
35 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
36 |
-
if ( empty( $aIps ) ) {
|
37 |
-
$aIps = [
|
38 |
-
4 => $this->downloadServiceIps_Cloudflare( 4 ),
|
39 |
-
6 => $this->downloadServiceIps_Cloudflare( 6 )
|
40 |
-
];
|
41 |
-
$oWp->setTransient( $sStoreKey, $aIps, $this->getLookupExpiration() );
|
42 |
-
}
|
43 |
-
return $aIps;
|
44 |
-
}
|
45 |
-
|
46 |
-
/**
|
47 |
-
* @return string[]
|
48 |
-
*/
|
49 |
-
public function getIps_CloudFlareV4() {
|
50 |
-
$aIps = $this->getIps_CloudFlare();
|
51 |
-
return $aIps[ 4 ];
|
52 |
-
}
|
53 |
-
|
54 |
-
/**
|
55 |
-
* @return string[]
|
56 |
-
*/
|
57 |
-
public function getIps_CloudFlareV6() {
|
58 |
-
$aIps = $this->getIps_CloudFlare();
|
59 |
-
return $aIps[ 6 ];
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* @return string[]
|
64 |
-
*/
|
65 |
-
public function getIps_DuckDuckGo() {
|
66 |
-
return [ '107.20.237.51', '23.21.226.191', '107.21.1.8', '54.208.102.37' ];
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* @param bool $bFlat
|
71 |
-
* @return array[]|string[]
|
72 |
-
*/
|
73 |
-
public function getIps_iControlWP( $bFlat = false ) {
|
74 |
-
$oWp = Services::WpGeneral();
|
75 |
-
|
76 |
-
$sStoreKey = $this->prefix( 'serviceips_icontrolwp' );
|
77 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
78 |
-
if ( empty( $aIps ) ) {
|
79 |
-
$aIps = $this->downloadServiceIps_iControlWP();
|
80 |
-
$oWp->setTransient( $sStoreKey, $aIps, $this->getLookupExpiration() );
|
81 |
-
}
|
82 |
-
|
83 |
-
return $bFlat ? array_merge( $aIps[ 4 ], $aIps[ 6 ] ) : $aIps;
|
84 |
-
}
|
85 |
-
|
86 |
-
/**
|
87 |
-
* @return array[]
|
88 |
-
*/
|
89 |
-
public function getIps_ManageWp() {
|
90 |
-
$oWp = Services::WpGeneral();
|
91 |
-
|
92 |
-
$sStoreKey = $this->prefix( 'serviceips_managewp' );
|
93 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
94 |
-
if ( empty( $aIps ) ) {
|
95 |
-
$aIps = $this->downloadServiceIps_ManageWp();
|
96 |
-
$oWp->setTransient( $sStoreKey, $aIps, $this->getLookupExpiration() );
|
97 |
-
}
|
98 |
-
return $aIps;
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* @return string[][]
|
103 |
-
*/
|
104 |
-
public function getIps_Pingdom() {
|
105 |
-
$oWp = Services::WpGeneral();
|
106 |
-
|
107 |
-
$sStoreKey = $this->prefix( 'serviceips_pingdom' );
|
108 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
109 |
-
if ( empty( $aIps ) ) {
|
110 |
-
$aIps = [
|
111 |
-
4 => $this->downloadServiceIps_Pingdom( 4 ),
|
112 |
-
6 => $this->downloadServiceIps_Pingdom( 6 )
|
113 |
-
];
|
114 |
-
$oWp->setTransient( $sStoreKey, $aIps, $this->getLookupExpiration() );
|
115 |
-
}
|
116 |
-
return $aIps;
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* @return string[]
|
121 |
-
*/
|
122 |
-
public function getIps_Statuscake() {
|
123 |
-
$oWp = Services::WpGeneral();
|
124 |
-
|
125 |
-
$sStoreKey = $this->prefix( 'serviceips_statuscake' );
|
126 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
127 |
-
if ( empty( $aIps ) || !is_array( $aIps ) ) {
|
128 |
-
$aIps = $this->downloadServiceIps_StatusCake();
|
129 |
-
$oWp->setTransient( $sStoreKey, $aIps, $this->getLookupExpiration() );
|
130 |
-
}
|
131 |
-
return $aIps;
|
132 |
-
}
|
133 |
-
|
134 |
-
/**
|
135 |
-
* @return array[]
|
136 |
-
*/
|
137 |
-
public function getIps_UptimeRobot() {
|
138 |
-
$oWp = Services::WpGeneral();
|
139 |
-
|
140 |
-
$sStoreKey = $this->prefix( 'serviceips_uptimerobot' );
|
141 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
142 |
-
if ( empty( $aIps ) ) {
|
143 |
-
$aIps = [
|
144 |
-
4 => $this->downloadServiceIps_UptimeRobot( 4 ),
|
145 |
-
6 => $this->downloadServiceIps_UptimeRobot( 6 )
|
146 |
-
];
|
147 |
-
$oWp->setTransient( $sStoreKey, $aIps, $this->getLookupExpiration() );
|
148 |
-
}
|
149 |
-
return $aIps;
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* @param string $sIp
|
154 |
-
* @param string $sUserAgent
|
155 |
-
* @return bool
|
156 |
-
*/
|
157 |
-
public function isIp_AppleBot( $sIp, $sUserAgent ) {
|
158 |
-
$oWp = Services::WpGeneral();
|
159 |
-
|
160 |
-
$sStoreKey = $this->prefix( 'serviceips_applebot' );
|
161 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
162 |
-
if ( !is_array( $aIps ) ) {
|
163 |
-
$aIps = [];
|
164 |
-
}
|
165 |
-
|
166 |
-
if ( !in_array( $sIp, $aIps ) && $this->verifyIp_AppleBot( $sIp, $sUserAgent ) ) {
|
167 |
-
$aIps[] = $sIp;
|
168 |
-
$oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
|
169 |
-
}
|
170 |
-
|
171 |
-
return in_array( $sIp, $aIps );
|
172 |
-
}
|
173 |
-
|
174 |
-
/**
|
175 |
-
* @param string $sIp
|
176 |
-
* @param string $sUserAgent
|
177 |
-
* @return bool
|
178 |
-
*/
|
179 |
-
public function isIp_BaiduBot( $sIp, $sUserAgent ) {
|
180 |
-
$oWp = Services::WpGeneral();
|
181 |
-
|
182 |
-
$sStoreKey = $this->prefix( 'serviceips_baidubot' );
|
183 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
184 |
-
if ( !is_array( $aIps ) ) {
|
185 |
-
$aIps = [];
|
186 |
-
}
|
187 |
-
|
188 |
-
if ( !in_array( $sIp, $aIps ) && $this->verifyIp_BaiduBot( $sIp, $sUserAgent ) ) {
|
189 |
-
$aIps[] = $sIp;
|
190 |
-
$oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
|
191 |
-
}
|
192 |
-
|
193 |
-
return in_array( $sIp, $aIps );
|
194 |
-
}
|
195 |
-
|
196 |
-
/**
|
197 |
-
* @param string $sIp
|
198 |
-
* @param string $sUserAgent
|
199 |
-
* @return bool
|
200 |
-
*/
|
201 |
-
public function isIp_BingBot( $sIp, $sUserAgent ) {
|
202 |
-
$oWp = Services::WpGeneral();
|
203 |
-
|
204 |
-
$sStoreKey = $this->prefix( 'serviceips_bingbot' );
|
205 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
206 |
-
if ( !is_array( $aIps ) ) {
|
207 |
-
$aIps = [];
|
208 |
-
}
|
209 |
-
|
210 |
-
if ( !in_array( $sIp, $aIps ) && $this->verifyIp_BingBot( $sIp, $sUserAgent ) ) {
|
211 |
-
$aIps[] = $sIp;
|
212 |
-
$oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
|
213 |
-
}
|
214 |
-
|
215 |
-
return in_array( $sIp, $aIps );
|
216 |
-
}
|
217 |
-
|
218 |
-
/**
|
219 |
-
* @param string $sIp
|
220 |
-
* @return bool
|
221 |
-
*/
|
222 |
-
public function isIp_Cloudflare( $sIp ) {
|
223 |
-
$bIs = false;
|
224 |
-
try {
|
225 |
-
$oIp = Services::IP();
|
226 |
-
if ( $oIp->getIpVersion( $sIp ) == 4 ) {
|
227 |
-
$bIs = $oIp->checkIp( $sIp, $this->getIps_CloudFlareV4() );
|
228 |
-
}
|
229 |
-
else {
|
230 |
-
$bIs = $oIp->checkIp( $sIp, $this->getIps_CloudFlareV6() );
|
231 |
-
}
|
232 |
-
}
|
233 |
-
catch ( Exception $oE ) {
|
234 |
-
}
|
235 |
-
return $bIs;
|
236 |
-
}
|
237 |
-
|
238 |
-
/**
|
239 |
-
* https://duckduckgo.com/duckduckbot
|
240 |
-
* @param string $sIp
|
241 |
-
* @param string $sUserAgent
|
242 |
-
* @return bool
|
243 |
-
*/
|
244 |
-
public function isIp_DuckDuckGoBot( $sIp, $sUserAgent ) {
|
245 |
-
$bIsBot = false;
|
246 |
-
// We check the useragent if available
|
247 |
-
if ( is_null( $sUserAgent ) || stripos( $sUserAgent, 'DuckDuckBot' ) !== false ) {
|
248 |
-
$bIsBot = in_array( $sIp, $this->getIps_DuckDuckGo() );
|
249 |
-
}
|
250 |
-
return $bIsBot;
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* @param string $sIp
|
255 |
-
* @param string $sAgent
|
256 |
-
* @return bool
|
257 |
-
*/
|
258 |
-
public function isIp_iControlWP( $sIp, $sAgent = null ) { //TODO: Agent
|
259 |
-
$bIsBot = false;
|
260 |
-
if ( is_null( $sAgent ) || stripos( $sAgent, 'iControlWPApp' ) !== false ) {
|
261 |
-
$bIsBot = in_array( $sIp, $this->getIps_iControlWP( true ) );
|
262 |
-
}
|
263 |
-
return $bIsBot;
|
264 |
-
}
|
265 |
-
|
266 |
-
/**
|
267 |
-
* https://support.google.com/webmasters/answer/80553?hl=en
|
268 |
-
* @param string $sIp
|
269 |
-
* @param string $sUserAgent
|
270 |
-
* @return bool
|
271 |
-
*/
|
272 |
-
public function isIp_GoogleBot( $sIp, $sUserAgent ) {
|
273 |
-
$oWp = Services::WpGeneral();
|
274 |
-
|
275 |
-
$sStoreKey = $this->prefix( 'serviceips_googlebot' );
|
276 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
277 |
-
if ( !is_array( $aIps ) ) {
|
278 |
-
$aIps = [];
|
279 |
-
}
|
280 |
-
|
281 |
-
if ( !in_array( $sIp, $aIps ) && $this->verifyIp_GoogleBot( $sIp, $sUserAgent ) ) {
|
282 |
-
$aIps[] = $sIp;
|
283 |
-
$oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
|
284 |
-
}
|
285 |
-
|
286 |
-
return in_array( $sIp, $aIps );
|
287 |
-
}
|
288 |
-
|
289 |
-
/**
|
290 |
-
* @param string $sIp
|
291 |
-
* @param string $sAgent
|
292 |
-
* @return bool
|
293 |
-
*/
|
294 |
-
public function isIp_Statuscake( $sIp, $sAgent ) {
|
295 |
-
$bIsIp = false;
|
296 |
-
if ( stripos( $sAgent, 'StatusCake' ) !== false ) {
|
297 |
-
$aIps = $this->getIps_Statuscake();
|
298 |
-
$bIsIp = in_array( $sIp, $aIps );
|
299 |
-
}
|
300 |
-
return $bIsIp;
|
301 |
-
}
|
302 |
-
|
303 |
-
/**
|
304 |
-
* @param string $sIp
|
305 |
-
* @param string $sAgent
|
306 |
-
* @return bool
|
307 |
-
*/
|
308 |
-
public function isIp_Pingdom( $sIp, $sAgent ) {
|
309 |
-
$bIsIp = false;
|
310 |
-
if ( stripos( $sAgent, 'pingdom.com' ) !== false ) {
|
311 |
-
$aIps = $this->getIps_Pingdom();
|
312 |
-
$bIsIp = in_array( $sIp, $aIps[ Services::IP()->getIpVersion( $sIp ) ] );
|
313 |
-
}
|
314 |
-
return $bIsIp;
|
315 |
-
}
|
316 |
-
|
317 |
-
/**
|
318 |
-
* @param string $sIp
|
319 |
-
* @param string $sAgent
|
320 |
-
* @return bool
|
321 |
-
*/
|
322 |
-
public function isIp_UptimeRobot( $sIp, $sAgent ) {
|
323 |
-
$bIsIp = false;
|
324 |
-
if ( stripos( $sAgent, 'UptimeRobot' ) !== false ) {
|
325 |
-
$aIps = $this->getIps_UptimeRobot();
|
326 |
-
$bIsIp = in_array( $sIp, $aIps[ Services::IP()->getIpVersion( $sIp ) ] );
|
327 |
-
}
|
328 |
-
return $bIsIp;
|
329 |
-
}
|
330 |
-
|
331 |
-
/**
|
332 |
-
* https://yandex.com/support/webmaster/robot-workings/check-yandex-robots.html
|
333 |
-
* @param string $sIp
|
334 |
-
* @param string $sUserAgent
|
335 |
-
* @return bool
|
336 |
-
*/
|
337 |
-
public function isIp_YandexBot( $sIp, $sUserAgent ) {
|
338 |
-
$oWp = Services::WpGeneral();
|
339 |
-
|
340 |
-
$sStoreKey = $this->prefix( 'serviceips_yandexbot' );
|
341 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
342 |
-
if ( !is_array( $aIps ) ) {
|
343 |
-
$aIps = [];
|
344 |
-
}
|
345 |
-
|
346 |
-
if ( !in_array( $sIp, $aIps ) && $this->verifyIp_YandexBot( $sIp, $sUserAgent ) ) {
|
347 |
-
$aIps[] = $sIp;
|
348 |
-
$oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
|
349 |
-
}
|
350 |
-
|
351 |
-
return in_array( $sIp, $aIps );
|
352 |
-
}
|
353 |
-
|
354 |
-
/**
|
355 |
-
* https://yandex.com/support/webmaster/robot-workings/check-yandex-robots.html
|
356 |
-
* @param string $sIp
|
357 |
-
* @param string $sUserAgent
|
358 |
-
* @return bool
|
359 |
-
*/
|
360 |
-
public function isIp_YahooBot( $sIp, $sUserAgent ) {
|
361 |
-
$oWp = Services::WpGeneral();
|
362 |
-
|
363 |
-
$sStoreKey = $this->prefix( 'serviceips_yahoobot' );
|
364 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
365 |
-
if ( !is_array( $aIps ) ) {
|
366 |
-
$aIps = [];
|
367 |
-
}
|
368 |
-
|
369 |
-
if ( !in_array( $sIp, $aIps ) && $this->verifyIp_YahooBot( $sIp, $sUserAgent ) ) {
|
370 |
-
$aIps[] = $sIp;
|
371 |
-
$oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
|
372 |
-
}
|
373 |
-
|
374 |
-
return in_array( $sIp, $aIps );
|
375 |
-
}
|
376 |
-
|
377 |
-
/**
|
378 |
-
* https://support.apple.com/en-gb/HT204683
|
379 |
-
* https://discussions.apple.com/thread/7090135
|
380 |
-
* Apple IPs start with '17.'
|
381 |
-
* @param string $sIp
|
382 |
-
* @param string $sUserAgent
|
383 |
-
* @return bool
|
384 |
-
*/
|
385 |
-
private function verifyIp_AppleBot( $sIp, $sUserAgent = '' ) {
|
386 |
-
return ( Services::IP()->getIpVersion( $sIp ) != 4 || strpos( $sIp, '17.' ) === 0 )
|
387 |
-
&& $this->isIpOfBot( [ 'Applebot/' ], '#.*\.applebot.apple.com\.?$#i', $sIp, $sUserAgent );
|
388 |
-
}
|
389 |
-
|
390 |
-
/**
|
391 |
-
* @param string $sIp
|
392 |
-
* @param string $sUserAgent
|
393 |
-
* @return bool
|
394 |
-
*/
|
395 |
-
private function verifyIp_BaiduBot( $sIp, $sUserAgent = '' ) {
|
396 |
-
return $this->isIpOfBot( [ 'baidu' ], '#.*\.crawl\.baidu\.(com|jp)\.?$#i', $sIp, $sUserAgent );
|
397 |
-
}
|
398 |
-
|
399 |
-
/**
|
400 |
-
* @param string $sIp
|
401 |
-
* @param string $sUserAgent
|
402 |
-
* @return bool
|
403 |
-
*/
|
404 |
-
private function verifyIp_BingBot( $sIp, $sUserAgent = '' ) {
|
405 |
-
return $this->isIpOfBot( [ 'bingbot' ], '#.*\.search\.msn\.com\.?$#i', $sIp, $sUserAgent );
|
406 |
-
}
|
407 |
-
|
408 |
-
/**
|
409 |
-
* @param string $sIp
|
410 |
-
* @param string $sUserAgent
|
411 |
-
* @return bool
|
412 |
-
*/
|
413 |
-
private function verifyIp_GoogleBot( $sIp, $sUserAgent = '' ) {
|
414 |
-
return $this->isIpOfBot(
|
415 |
-
[ 'Googlebot', 'APIs-Google', 'AdsBot-Google', 'Mediapartners-Google' ],
|
416 |
-
'#.*\.google(bot)?\.com\.?$#i', $sIp, $sUserAgent
|
417 |
-
);
|
418 |
-
}
|
419 |
-
|
420 |
-
/**
|
421 |
-
* @param string $sIp
|
422 |
-
* @param string $sUserAgent
|
423 |
-
* @return bool
|
424 |
-
*/
|
425 |
-
private function verifyIp_YandexBot( $sIp, $sUserAgent = '' ) {
|
426 |
-
return $this->isIpOfBot( [ 'yandex.com/bots' ], '#.*\.yandex?\.(com|ru|net)\.?$#i', $sIp, $sUserAgent );
|
427 |
-
}
|
428 |
-
|
429 |
-
/**
|
430 |
-
* @param string $sIp
|
431 |
-
* @param string $sUserAgent
|
432 |
-
* @return bool
|
433 |
-
*/
|
434 |
-
private function verifyIp_YahooBot( $sIp, $sUserAgent = '' ) {
|
435 |
-
return $this->isIpOfBot( [ 'yahoo!' ], '#.*\.crawl\.yahoo\.net\.?$#i', $sIp, $sUserAgent );
|
436 |
-
}
|
437 |
-
|
438 |
-
/**
|
439 |
-
* Will test useragent, then attempt to resolve to hostname and back again
|
440 |
-
* https://www.elephate.com/detect-verify-crawlers/
|
441 |
-
* @param array $aBotUserAgents
|
442 |
-
* @param string $sBotHostPattern
|
443 |
-
* @param string $sReqIp
|
444 |
-
* @param string $sReqUserAgent
|
445 |
-
* @return bool
|
446 |
-
*/
|
447 |
-
private function isIpOfBot( $aBotUserAgents, $sBotHostPattern, $sReqIp, $sReqUserAgent = '' ) {
|
448 |
-
$bIsBot = false;
|
449 |
-
|
450 |
-
$bCheckIpHost = is_null( $sReqUserAgent );
|
451 |
-
if ( !$bCheckIpHost ) {
|
452 |
-
$aBotUserAgents = array_map(
|
453 |
-
function ( $sAgent ) {
|
454 |
-
return preg_quote( $sAgent, '#' );
|
455 |
-
},
|
456 |
-
$aBotUserAgents
|
457 |
-
);
|
458 |
-
$bCheckIpHost = (bool)preg_match( sprintf( '#%s#i', implode( '|', $aBotUserAgents ) ), $sReqUserAgent );
|
459 |
-
}
|
460 |
-
|
461 |
-
if ( $bCheckIpHost ) {
|
462 |
-
$sHost = @gethostbyaddr( $sReqIp ); // returns the ip on failure
|
463 |
-
$bIsBot = !empty( $sHost ) && ( $sHost != $sReqIp )
|
464 |
-
&& preg_match( $sBotHostPattern, $sHost )
|
465 |
-
&& gethostbyname( $sHost ) === $sReqIp;
|
466 |
-
}
|
467 |
-
return $bIsBot;
|
468 |
-
}
|
469 |
-
|
470 |
-
/**
|
471 |
-
* @param int $sIpVersion
|
472 |
-
* @return string[]
|
473 |
-
*/
|
474 |
-
private function downloadServiceIps_Cloudflare( $sIpVersion = 4 ) {
|
475 |
-
return $this->downloadServiceIps_Standard( 'https://www.cloudflare.com/ips-v%s', $sIpVersion );
|
476 |
-
}
|
477 |
-
|
478 |
-
/**
|
479 |
-
* @return string[]
|
480 |
-
*/
|
481 |
-
private function downloadServiceIps_ManageWp() {
|
482 |
-
return $this->downloadServiceIps_Standard( 'https://managewp.com/wp-content/uploads/2016/11/managewp-ips.txt' );
|
483 |
-
}
|
484 |
-
|
485 |
-
/**
|
486 |
-
* @return array[]
|
487 |
-
*/
|
488 |
-
private function downloadServiceIps_iControlWP() {
|
489 |
-
$aIps = @json_decode( Services::HttpRequest()->getContent( self::URL_ICONTROLWP_IPS ), true );
|
490 |
-
return is_array( $aIps ) ? $aIps : [ 4 => [], 6 => [] ];
|
491 |
-
}
|
492 |
-
|
493 |
-
/**
|
494 |
-
* @param int $sIpVersion
|
495 |
-
* @return string[]
|
496 |
-
*/
|
497 |
-
private function downloadServiceIps_Pingdom( $sIpVersion = 4 ) {
|
498 |
-
return $this->downloadServiceIps_Standard( 'https://my.pingdom.com/probes/ipv%s', $sIpVersion );
|
499 |
-
}
|
500 |
-
|
501 |
-
/**
|
502 |
-
* @return string[]
|
503 |
-
*/
|
504 |
-
private function downloadServiceIps_StatusCake() {
|
505 |
-
$aIps = [];
|
506 |
-
$aData = @json_decode( Services::HttpRequest()->getContent( self::URL_STATUS_CAKE_IPS ), true );
|
507 |
-
if ( is_array( $aData ) ) {
|
508 |
-
foreach ( $aData as $aItem ) {
|
509 |
-
if ( !empty( $aItem[ 'ip' ] ) ) {
|
510 |
-
$aIps[] = $aItem[ 'ip' ];
|
511 |
-
}
|
512 |
-
}
|
513 |
-
}
|
514 |
-
return $aIps;
|
515 |
-
}
|
516 |
-
|
517 |
-
/**
|
518 |
-
* @param int $sIpVersion
|
519 |
-
* @return string[]
|
520 |
-
*/
|
521 |
-
private function downloadServiceIps_UptimeRobot( $sIpVersion = 4 ) {
|
522 |
-
return $this->downloadServiceIps_Standard( 'https://uptimerobot.com/inc/files/ips/IPv%s.txt', $sIpVersion );
|
523 |
-
}
|
524 |
-
|
525 |
-
/**
|
526 |
-
* @param string $sSourceUrl must have an sprintf %s placeholder
|
527 |
-
* @param int $sIpVersion
|
528 |
-
* @return string[]
|
529 |
-
*/
|
530 |
-
private function downloadServiceIps_Standard( $sSourceUrl, $sIpVersion = null ) {
|
531 |
-
if ( !is_null( $sIpVersion ) ) {
|
532 |
-
if ( !in_array( (int)$sIpVersion, [ 4, 6 ] ) ) {
|
533 |
-
$sIpVersion = 4;
|
534 |
-
}
|
535 |
-
$sSourceUrl = Services::HttpRequest()->getContent( sprintf( $sSourceUrl, $sIpVersion ) );
|
536 |
-
}
|
537 |
-
$sRaw = Services::HttpRequest()->getContent( $sSourceUrl );
|
538 |
-
$aIps = empty( $sRaw ) ? [] : explode( "\n", $sRaw );
|
539 |
-
return array_filter( array_map( 'trim', $aIps ) );
|
540 |
-
}
|
541 |
-
|
542 |
-
/**
|
543 |
-
* @return int
|
544 |
-
*/
|
545 |
-
private function getLookupExpiration() {
|
546 |
-
return WEEK_IN_SECONDS*2;
|
547 |
-
}
|
548 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-wpcron.php
DELETED
@@ -1,171 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class ICWP_WPSF_WpCron {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var ICWP_WPSF_WpCron
|
7 |
-
*/
|
8 |
-
protected static $oInstance = null;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var int
|
12 |
-
*/
|
13 |
-
protected $nNextRun;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
protected $sRecurrence;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @var array
|
22 |
-
*/
|
23 |
-
protected $aSchedules;
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @return ICWP_WPSF_WpCron
|
27 |
-
*/
|
28 |
-
public static function GetInstance() {
|
29 |
-
if ( is_null( self::$oInstance ) ) {
|
30 |
-
self::$oInstance = new self();
|
31 |
-
}
|
32 |
-
return self::$oInstance;
|
33 |
-
}
|
34 |
-
|
35 |
-
private function __construct() {
|
36 |
-
add_filter( 'cron_schedules', [ $this, 'addSchedules' ] );
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* @param array $aSchedules
|
41 |
-
* @return array
|
42 |
-
*/
|
43 |
-
public function addSchedules( $aSchedules ) {
|
44 |
-
return array_merge( $aSchedules, $this->getSchedules() );
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* @param string $sSlug
|
49 |
-
* @param array $aNewSchedule
|
50 |
-
* @return $this
|
51 |
-
*/
|
52 |
-
public function addNewSchedule( $sSlug, $aNewSchedule ) {
|
53 |
-
if ( !empty( $aNewSchedule ) && is_array( $aNewSchedule ) ) {
|
54 |
-
$aSchedules = $this->getSchedules();
|
55 |
-
$aSchedules[ $sSlug ] = $aNewSchedule;
|
56 |
-
$this->aSchedules = $aSchedules;
|
57 |
-
}
|
58 |
-
return $this;
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* @return array
|
63 |
-
* @deprecated uses undocumented private WP function
|
64 |
-
*/
|
65 |
-
public function getCrons() {
|
66 |
-
return function_exists( '_get_cron_array' ) && is_array( _get_cron_array() ) ? _get_cron_array() : [];
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* @return array
|
71 |
-
*/
|
72 |
-
protected function getSchedules() {
|
73 |
-
if ( !is_array( $this->aSchedules ) ) {
|
74 |
-
$this->aSchedules = [];
|
75 |
-
}
|
76 |
-
return $this->aSchedules;
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* @param string $sCronName
|
81 |
-
* @return bool
|
82 |
-
*/
|
83 |
-
public function getIfCronExists( $sCronName ) {
|
84 |
-
return (bool)wp_next_scheduled( $sCronName );
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* @return int
|
89 |
-
*/
|
90 |
-
public function getNextRun() {
|
91 |
-
if ( is_null( $this->nNextRun ) ) {
|
92 |
-
return strtotime( 'tomorrow 4am' ) - get_option( 'gmt_offset' )*HOUR_IN_SECONDS;
|
93 |
-
}
|
94 |
-
return $this->nNextRun;
|
95 |
-
}
|
96 |
-
|
97 |
-
/**
|
98 |
-
* @return string
|
99 |
-
*/
|
100 |
-
public function getRecurrence() {
|
101 |
-
if ( empty( $this->sRecurrence ) ) {
|
102 |
-
return 'daily';
|
103 |
-
}
|
104 |
-
return $this->sRecurrence;
|
105 |
-
}
|
106 |
-
|
107 |
-
/**
|
108 |
-
* @param int $nNextRun
|
109 |
-
* @return $this
|
110 |
-
*/
|
111 |
-
public function setNextRun( $nNextRun ) {
|
112 |
-
$this->nNextRun = $nNextRun;
|
113 |
-
return $this;
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* @param string $sRecurrence
|
118 |
-
* @return $this
|
119 |
-
*/
|
120 |
-
public function setRecurrence( $sRecurrence ) {
|
121 |
-
$this->sRecurrence = $sRecurrence;
|
122 |
-
return $this;
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* @return $this
|
127 |
-
*/
|
128 |
-
public function reset() {
|
129 |
-
return $this
|
130 |
-
->setNextRun( null )
|
131 |
-
->setRecurrence( null );
|
132 |
-
}
|
133 |
-
|
134 |
-
/**
|
135 |
-
* @param string $sUniqueCronName
|
136 |
-
* @param callable $cCallback
|
137 |
-
* @return $this
|
138 |
-
* @throws Exception
|
139 |
-
*/
|
140 |
-
public function createCronJob( $sUniqueCronName, $cCallback ) {
|
141 |
-
if ( !is_callable( $cCallback ) ) {
|
142 |
-
throw new Exception( sprintf( 'Tried to schedule a new cron but the Callback function is not callable: %s', print_r( $cCallback, true ) ) );
|
143 |
-
}
|
144 |
-
add_action( $sUniqueCronName, $cCallback );
|
145 |
-
return $this->setCronSchedule( $sUniqueCronName );
|
146 |
-
}
|
147 |
-
|
148 |
-
/**
|
149 |
-
* @param string $sUniqueCronName
|
150 |
-
* @return $this
|
151 |
-
*/
|
152 |
-
public function deleteCronJob( $sUniqueCronName ) {
|
153 |
-
if ( function_exists( 'wp_unschedule_hook' ) ) {
|
154 |
-
wp_unschedule_hook( $sUniqueCronName );
|
155 |
-
}
|
156 |
-
wp_clear_scheduled_hook( $sUniqueCronName );
|
157 |
-
return $this;
|
158 |
-
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* @param string $sUniqueCronActionName
|
162 |
-
* @return $this
|
163 |
-
*/
|
164 |
-
protected function setCronSchedule( $sUniqueCronActionName ) {
|
165 |
-
if ( !wp_next_scheduled( $sUniqueCronActionName ) && !defined( 'WP_INSTALLING' ) ) {
|
166 |
-
wp_schedule_event( $this->getNextRun(), $this->getRecurrence(), $sUniqueCronActionName );
|
167 |
-
$this->reset();
|
168 |
-
}
|
169 |
-
return $this;
|
170 |
-
}
|
171 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/config/feature-autoupdates.php
CHANGED
@@ -128,28 +128,6 @@
|
|
128 |
"summary": "Automatically Update Themes",
|
129 |
"description": "Note: Automatic updates for themes are disabled on WordPress by default."
|
130 |
},
|
131 |
-
{
|
132 |
-
"key": "enable_autoupdate_translations",
|
133 |
-
"section": "section_automatic_updates_for_wordpress_components",
|
134 |
-
"default": "Y",
|
135 |
-
"type": "checkbox",
|
136 |
-
"link_info": "",
|
137 |
-
"link_blog": "",
|
138 |
-
"name": "Translations",
|
139 |
-
"summary": "Automatically Update Translations",
|
140 |
-
"description": "Note: Automatic updates for translations are enabled on WordPress by default."
|
141 |
-
},
|
142 |
-
{
|
143 |
-
"key": "enable_autoupdate_ignore_vcs",
|
144 |
-
"section": "section_automatic_updates_for_wordpress_components",
|
145 |
-
"default": "N",
|
146 |
-
"type": "checkbox",
|
147 |
-
"link_info": "",
|
148 |
-
"link_blog": "",
|
149 |
-
"name": "Ignore Version Control",
|
150 |
-
"summary": "Ignore Version Control Systems Such As GIT and SVN",
|
151 |
-
"description": "If you use SVN or GIT and WordPress detects it, automatic updates are disabled by default. Check this box to ignore version control systems and allow automatic updates."
|
152 |
-
},
|
153 |
{
|
154 |
"key": "update_delay",
|
155 |
"section": "section_options",
|
128 |
"summary": "Automatically Update Themes",
|
129 |
"description": "Note: Automatic updates for themes are disabled on WordPress by default."
|
130 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
{
|
132 |
"key": "update_delay",
|
133 |
"section": "section_options",
|
src/config/feature-license.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
{
|
2 |
-
"slug":
|
3 |
-
"properties":
|
4 |
"slug": "license",
|
5 |
"name": "Pro Security",
|
6 |
"menu_title": "Go Pro!",
|
@@ -16,13 +16,23 @@
|
|
16 |
"run_if_verified_bot": true,
|
17 |
"run_if_wpcli": true
|
18 |
},
|
19 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
{
|
21 |
"slug": "section_non_ui",
|
22 |
"hidden": true
|
23 |
}
|
24 |
],
|
25 |
-
"options":
|
26 |
{
|
27 |
"key": "license_key",
|
28 |
"section": "section_non_ui",
|
@@ -52,13 +62,6 @@
|
|
52 |
"type": "integer",
|
53 |
"default": 0
|
54 |
},
|
55 |
-
{
|
56 |
-
"key": "license_deactivated_reason",
|
57 |
-
"section": "section_non_ui",
|
58 |
-
"transferable": false,
|
59 |
-
"type": "text",
|
60 |
-
"default": ""
|
61 |
-
},
|
62 |
{
|
63 |
"key": "last_warning_email_sent_at",
|
64 |
"section": "section_non_ui",
|
@@ -89,7 +92,7 @@
|
|
89 |
"default": 0
|
90 |
},
|
91 |
{
|
92 |
-
"key": "
|
93 |
"section": "section_non_ui",
|
94 |
"sensitive": true,
|
95 |
"transferable": false,
|
@@ -97,7 +100,7 @@
|
|
97 |
"default": ""
|
98 |
},
|
99 |
{
|
100 |
-
"key": "
|
101 |
"section": "section_non_ui",
|
102 |
"sensitive": true,
|
103 |
"transferable": false,
|
@@ -111,30 +114,35 @@
|
|
111 |
"transferable": false,
|
112 |
"type": "array",
|
113 |
"default": []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
115 |
],
|
116 |
-
"definitions":
|
117 |
"license_store_url": "https://onedollarplugin.com/edd-sl/",
|
|
|
118 |
"keyless_cp": "https://shsec.io/c5",
|
119 |
"license_item_name": "Shield Security Pro",
|
120 |
"license_item_id": "6047",
|
121 |
"license_item_name_sc": "Shield Security Pro (via Shield Central)",
|
122 |
-
"license_item_id_sc": "968",
|
123 |
"lic_verify_expire_days": 7,
|
124 |
"lic_verify_expire_grace_days": 3,
|
125 |
-
"license_key_length": 32,
|
126 |
-
"license_key_type": "alphanumeric",
|
127 |
"keyless": true,
|
128 |
"keyless_handshake_expire": 90,
|
129 |
"events": {
|
130 |
-
"lic_check_success":
|
131 |
"stat": false
|
132 |
},
|
133 |
"lic_fail_email": {
|
134 |
"stat": false
|
135 |
},
|
136 |
"lic_fail_deactivate": {
|
137 |
-
"cat":
|
138 |
"stat": false
|
139 |
}
|
140 |
}
|
1 |
{
|
2 |
+
"slug": "license",
|
3 |
+
"properties": {
|
4 |
"slug": "license",
|
5 |
"name": "Pro Security",
|
6 |
"menu_title": "Go Pro!",
|
16 |
"run_if_verified_bot": true,
|
17 |
"run_if_wpcli": true
|
18 |
},
|
19 |
+
"admin_notices": {
|
20 |
+
"wphashes-token-fail": {
|
21 |
+
"id": "wphashes-token-fail",
|
22 |
+
"schedule": "conditions",
|
23 |
+
"valid_admin": true,
|
24 |
+
"plugin_page_only": true,
|
25 |
+
"can_dismiss": false,
|
26 |
+
"type": "error"
|
27 |
+
}
|
28 |
+
},
|
29 |
+
"sections": [
|
30 |
{
|
31 |
"slug": "section_non_ui",
|
32 |
"hidden": true
|
33 |
}
|
34 |
],
|
35 |
+
"options": [
|
36 |
{
|
37 |
"key": "license_key",
|
38 |
"section": "section_non_ui",
|
62 |
"type": "integer",
|
63 |
"default": 0
|
64 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
{
|
66 |
"key": "last_warning_email_sent_at",
|
67 |
"section": "section_non_ui",
|
92 |
"default": 0
|
93 |
},
|
94 |
{
|
95 |
+
"key": "keyless_handshake_hash",
|
96 |
"section": "section_non_ui",
|
97 |
"sensitive": true,
|
98 |
"transferable": false,
|
100 |
"default": ""
|
101 |
},
|
102 |
{
|
103 |
+
"key": "keyless_handshake_until",
|
104 |
"section": "section_non_ui",
|
105 |
"sensitive": true,
|
106 |
"transferable": false,
|
114 |
"transferable": false,
|
115 |
"type": "array",
|
116 |
"default": []
|
117 |
+
},
|
118 |
+
{
|
119 |
+
"key": "wphashes_api_token",
|
120 |
+
"transferable": false,
|
121 |
+
"section": "section_non_ui",
|
122 |
+
"type": "array",
|
123 |
+
"default": []
|
124 |
}
|
125 |
],
|
126 |
+
"definitions": {
|
127 |
"license_store_url": "https://onedollarplugin.com/edd-sl/",
|
128 |
+
"license_store_url_api": "https://onedollarplugin.com/wp-json/odp-eddkeyless/v1",
|
129 |
"keyless_cp": "https://shsec.io/c5",
|
130 |
"license_item_name": "Shield Security Pro",
|
131 |
"license_item_id": "6047",
|
132 |
"license_item_name_sc": "Shield Security Pro (via Shield Central)",
|
|
|
133 |
"lic_verify_expire_days": 7,
|
134 |
"lic_verify_expire_grace_days": 3,
|
|
|
|
|
135 |
"keyless": true,
|
136 |
"keyless_handshake_expire": 90,
|
137 |
"events": {
|
138 |
+
"lic_check_success": {
|
139 |
"stat": false
|
140 |
},
|
141 |
"lic_fail_email": {
|
142 |
"stat": false
|
143 |
},
|
144 |
"lic_fail_deactivate": {
|
145 |
+
"cat": 2,
|
146 |
"stat": false
|
147 |
}
|
148 |
}
|
src/config/feature-login_protect.php
CHANGED
@@ -18,9 +18,12 @@
|
|
18 |
"admin_notices": {
|
19 |
"email-verification-sent": {
|
20 |
"id": "email-verification-sent",
|
21 |
-
"
|
|
|
|
|
22 |
"type": "warning",
|
23 |
-
"plugin_admin": "yes"
|
|
|
24 |
}
|
25 |
},
|
26 |
"sections": [
|
@@ -256,6 +259,18 @@
|
|
256 |
"summary": "All User Roles Subject To Email Authentication",
|
257 |
"description": "Enforces email-based authentication on all users with the selected roles. Note: This setting only applies to email authentication."
|
258 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
{
|
260 |
"key": "bot_protection_locations",
|
261 |
"section": "section_brute_force_login_protection",
|
@@ -435,7 +450,8 @@
|
|
435 |
"section": "section_non_ui",
|
436 |
"transferable": false,
|
437 |
"type": "integer",
|
438 |
-
"default":
|
|
|
439 |
},
|
440 |
{
|
441 |
"key": "gasp_key",
|
18 |
"admin_notices": {
|
19 |
"email-verification-sent": {
|
20 |
"id": "email-verification-sent",
|
21 |
+
"schedule": "conditions",
|
22 |
+
"plugin_page_only": true,
|
23 |
+
"can_dismiss": false,
|
24 |
"type": "warning",
|
25 |
+
"plugin_admin": "yes",
|
26 |
+
"valid_admin": true
|
27 |
}
|
28 |
},
|
29 |
"sections": [
|
259 |
"summary": "All User Roles Subject To Email Authentication",
|
260 |
"description": "Enforces email-based authentication on all users with the selected roles. Note: This setting only applies to email authentication."
|
261 |
},
|
262 |
+
{
|
263 |
+
"key": "email_any_user_set",
|
264 |
+
"section": "section_2fa_email",
|
265 |
+
"premium": true,
|
266 |
+
"default": "N",
|
267 |
+
"type": "checkbox",
|
268 |
+
"link_info": "https://shsec.io/gj",
|
269 |
+
"link_blog": "",
|
270 |
+
"name": "Allow Any User",
|
271 |
+
"summary": "Allow Any User To Turn-On Two-Factor Authentication By Email",
|
272 |
+
"description": "Allow Any User To Turn-On Two-Factor Authentication By Email."
|
273 |
+
},
|
274 |
{
|
275 |
"key": "bot_protection_locations",
|
276 |
"section": "section_brute_force_login_protection",
|
450 |
"section": "section_non_ui",
|
451 |
"transferable": false,
|
452 |
"type": "integer",
|
453 |
+
"default": 0,
|
454 |
+
"min": 0
|
455 |
},
|
456 |
{
|
457 |
"key": "gasp_key",
|
src/config/feature-plugin.php
CHANGED
@@ -421,13 +421,6 @@
|
|
421 |
"section": "section_non_ui",
|
422 |
"type": "text",
|
423 |
"default": ""
|
424 |
-
},
|
425 |
-
{
|
426 |
-
"key": "wphashes_api_token",
|
427 |
-
"transferable": false,
|
428 |
-
"section": "section_non_ui",
|
429 |
-
"type": "array",
|
430 |
-
"default": []
|
431 |
}
|
432 |
],
|
433 |
"definitions": {
|
421 |
"section": "section_non_ui",
|
422 |
"type": "text",
|
423 |
"default": ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
424 |
}
|
425 |
],
|
426 |
"definitions": {
|
src/config/feature-user_management.php
CHANGED
@@ -25,6 +25,15 @@
|
|
25 |
"Recommendation - Use of this feature is highly recommend."
|
26 |
]
|
27 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
{
|
29 |
"slug": "section_passwords",
|
30 |
"reqs": {
|
@@ -153,6 +162,65 @@
|
|
153 |
"summary": "Limit Simultaneous Sessions For The Same Username",
|
154 |
"description": "The number provided here is the maximum number of simultaneous, distinct, sessions allowed for any given username. Use '0' for no limits."
|
155 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
{
|
157 |
"key": "enable_password_policies",
|
158 |
"section": "section_passwords",
|
@@ -342,6 +410,9 @@
|
|
342 |
"recent": true
|
343 |
},
|
344 |
"user_hard_unsuspended": {
|
|
|
|
|
|
|
345 |
}
|
346 |
}
|
347 |
}
|
25 |
"Recommendation - Use of this feature is highly recommend."
|
26 |
]
|
27 |
},
|
28 |
+
{
|
29 |
+
"slug": "section_user_reg",
|
30 |
+
"title": "User Registration",
|
31 |
+
"title_short": "User Registration",
|
32 |
+
"summary": [
|
33 |
+
"Purpose - Control user registration and prevent SPAM.",
|
34 |
+
"Recommendation - Use of this feature is highly recommend."
|
35 |
+
]
|
36 |
+
},
|
37 |
{
|
38 |
"slug": "section_passwords",
|
39 |
"reqs": {
|
162 |
"summary": "Limit Simultaneous Sessions For The Same Username",
|
163 |
"description": "The number provided here is the maximum number of simultaneous, distinct, sessions allowed for any given username. Use '0' for no limits."
|
164 |
},
|
165 |
+
{
|
166 |
+
"key": "reg_email_validate",
|
167 |
+
"section": "section_user_reg",
|
168 |
+
"premium": true,
|
169 |
+
"type": "select",
|
170 |
+
"default": "log",
|
171 |
+
"value_options": [
|
172 |
+
{
|
173 |
+
"value_key": "disabled",
|
174 |
+
"text": "Disabled"
|
175 |
+
},
|
176 |
+
{
|
177 |
+
"value_key": "log",
|
178 |
+
"text": "Log Only"
|
179 |
+
},
|
180 |
+
{
|
181 |
+
"value_key": "offense",
|
182 |
+
"text": "Increment Offense Counter"
|
183 |
+
},
|
184 |
+
{
|
185 |
+
"value_key": "block",
|
186 |
+
"text": "Immediate Block and Kill"
|
187 |
+
}
|
188 |
+
],
|
189 |
+
"link_info": "https://shsec.io/gk",
|
190 |
+
"link_blog": "",
|
191 |
+
"name": "Validate Email Addresses",
|
192 |
+
"summary": "Validate Email Addresses When User Attempts To Register",
|
193 |
+
"description": "Validate Email Addresses When User Attempts To Register."
|
194 |
+
},
|
195 |
+
{
|
196 |
+
"key": "email_checks",
|
197 |
+
"section": "section_user_reg",
|
198 |
+
"type": "multiple_select",
|
199 |
+
"default": [ "syntax", "domain" ],
|
200 |
+
"value_options": [
|
201 |
+
{
|
202 |
+
"value_key": "syntax",
|
203 |
+
"text": "Email Address Syntax"
|
204 |
+
},
|
205 |
+
{
|
206 |
+
"value_key": "domain",
|
207 |
+
"text": "Domain Name Resolves"
|
208 |
+
},
|
209 |
+
{
|
210 |
+
"value_key": "mx",
|
211 |
+
"text": "Domain MX"
|
212 |
+
},
|
213 |
+
{
|
214 |
+
"value_key": "nondisposable",
|
215 |
+
"text": "Disposable Email Service"
|
216 |
+
}
|
217 |
+
],
|
218 |
+
"link_info": "",
|
219 |
+
"link_blog": "",
|
220 |
+
"name": "Email Checks",
|
221 |
+
"summary": "The Email Address Properties That Will Be Tested",
|
222 |
+
"description": "Select which ."
|
223 |
+
},
|
224 |
{
|
225 |
"key": "enable_password_policies",
|
226 |
"section": "section_passwords",
|
410 |
"recent": true
|
411 |
},
|
412 |
"user_hard_unsuspended": {
|
413 |
+
},
|
414 |
+
"reg_email_invalid": {
|
415 |
+
"offense": true
|
416 |
}
|
417 |
}
|
418 |
}
|
src/features/admin_access_restriction.php
CHANGED
@@ -86,7 +86,7 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
86 |
private function verifySecAdminUsers( $aSecUsers ) {
|
87 |
$oDP = Services::Data();
|
88 |
$oWpUsers = Services::WpUsers();
|
89 |
-
/** @var
|
90 |
$oOpts = $this->getOptions();
|
91 |
|
92 |
$aFiltered = [];
|
@@ -144,10 +144,10 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
144 |
}
|
145 |
|
146 |
/**
|
|
|
147 |
*/
|
148 |
-
|
149 |
-
$
|
150 |
-
switch ( $oReq->query( 'exec' ) ) {
|
151 |
case 'remove_secadmin_confirm':
|
152 |
( new SecurityAdmin\Lib\Actions\RemoveSecAdmin() )
|
153 |
->setMod( $this )
|
@@ -169,7 +169,7 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
169 |
* @return bool
|
170 |
*/
|
171 |
public function isEnabledSecurityAdmin() {
|
172 |
-
/** @var
|
173 |
$oOpts = $this->getOptions();
|
174 |
return $this->isModOptEnabled() &&
|
175 |
( $this->hasSecAdminUsers() ||
|
@@ -204,7 +204,7 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
204 |
$bValid = false;
|
205 |
$sReqKey = Services::Request()->post( 'sec_admin_key' );
|
206 |
if ( !empty( $sReqKey ) ) {
|
207 |
-
/** @var
|
208 |
$oOpts = $this->getOptions();
|
209 |
$bValid = hash_equals( $oOpts->getAccessKeyHash(), md5( $sReqKey ) );
|
210 |
if ( !$bValid ) {
|
@@ -326,17 +326,9 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
326 |
return $this->saveModOptions();
|
327 |
}
|
328 |
|
329 |
-
/**
|
330 |
-
* @return $this
|
331 |
-
*/
|
332 |
-
protected function clearAdminAccessKey() {
|
333 |
-
return $this->setOpt( 'admin_access_key', '' );
|
334 |
-
}
|
335 |
-
|
336 |
public function insertCustomJsVars_Admin() {
|
337 |
parent::insertCustomJsVars_Admin();
|
338 |
|
339 |
-
$aInsertData = [];
|
340 |
if ( $this->getSecAdminTimeLeft() > 0 ) {
|
341 |
$aInsertData = [
|
342 |
'ajax' => [
|
86 |
private function verifySecAdminUsers( $aSecUsers ) {
|
87 |
$oDP = Services::Data();
|
88 |
$oWpUsers = Services::WpUsers();
|
89 |
+
/** @var SecurityAdmin\Options $oOpts */
|
90 |
$oOpts = $this->getOptions();
|
91 |
|
92 |
$aFiltered = [];
|
144 |
}
|
145 |
|
146 |
/**
|
147 |
+
* @inheritDoc
|
148 |
*/
|
149 |
+
protected function handleModAction( $sAction ) {
|
150 |
+
switch ( $sAction ) {
|
|
|
151 |
case 'remove_secadmin_confirm':
|
152 |
( new SecurityAdmin\Lib\Actions\RemoveSecAdmin() )
|
153 |
->setMod( $this )
|
169 |
* @return bool
|
170 |
*/
|
171 |
public function isEnabledSecurityAdmin() {
|
172 |
+
/** @var SecurityAdmin\Options $oOpts */
|
173 |
$oOpts = $this->getOptions();
|
174 |
return $this->isModOptEnabled() &&
|
175 |
( $this->hasSecAdminUsers() ||
|
204 |
$bValid = false;
|
205 |
$sReqKey = Services::Request()->post( 'sec_admin_key' );
|
206 |
if ( !empty( $sReqKey ) ) {
|
207 |
+
/** @var SecurityAdmin\Options $oOpts */
|
208 |
$oOpts = $this->getOptions();
|
209 |
$bValid = hash_equals( $oOpts->getAccessKeyHash(), md5( $sReqKey ) );
|
210 |
if ( !$bValid ) {
|
326 |
return $this->saveModOptions();
|
327 |
}
|
328 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
329 |
public function insertCustomJsVars_Admin() {
|
330 |
parent::insertCustomJsVars_Admin();
|
331 |
|
|
|
332 |
if ( $this->getSecAdminTimeLeft() > 0 ) {
|
333 |
$aInsertData = [
|
334 |
'ajax' => [
|
src/features/base.php
CHANGED
@@ -83,26 +83,11 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
83 |
* @param array $aModProps
|
84 |
*/
|
85 |
protected function setupHooks( $aModProps ) {
|
86 |
-
$oReq = Services::Request();
|
87 |
-
|
88 |
$nRunPriority = isset( $aModProps[ 'load_priority' ] ) ? $aModProps[ 'load_priority' ] : 100;
|
89 |
add_action( $this->prefix( 'run_processors' ), [ $this, 'onRunProcessors' ], $nRunPriority );
|
90 |
add_action( 'init', [ $this, 'onWpInit' ], 1 );
|
91 |
add_action( $this->prefix( 'import_options' ), [ $this, 'processImportOptions' ] );
|
92 |
|
93 |
-
if ( $this->isModuleRequest() ) {
|
94 |
-
|
95 |
-
if ( Services::WpGeneral()->isAjax() ) {
|
96 |
-
$this->loadAjaxHandler();
|
97 |
-
}
|
98 |
-
|
99 |
-
if ( $oReq->request( 'action' ) == $this->prefix()
|
100 |
-
&& check_admin_referer( $oReq->request( 'exec' ), 'exec_nonce' )
|
101 |
-
) {
|
102 |
-
add_action( $this->prefix( 'mod_request' ), [ $this, 'handleModRequest' ] );
|
103 |
-
}
|
104 |
-
}
|
105 |
-
|
106 |
$nMenuPri = isset( $aModProps[ 'menu_priority' ] ) ? $aModProps[ 'menu_priority' ] : 100;
|
107 |
add_filter( $this->prefix( 'submenu_items' ), [ $this, 'supplySubMenuItem' ], $nMenuPri );
|
108 |
add_filter( $this->prefix( 'collect_mod_summary' ), [ $this, 'addModuleSummaryData' ], $nMenuPri );
|
@@ -348,7 +333,19 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
348 |
* A action added to WordPress 'init' hook
|
349 |
*/
|
350 |
public function onWpInit() {
|
351 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
|
353 |
$this->runWizards();
|
354 |
|
@@ -791,7 +788,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
791 |
* @param string $sGlue
|
792 |
* @return string|array
|
793 |
*/
|
794 |
-
public function getLastErrors( $bAsString =
|
795 |
$aErrors = $this->getOpt( 'last_errors' );
|
796 |
if ( !is_array( $aErrors ) ) {
|
797 |
$aErrors = [];
|
@@ -895,7 +892,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
895 |
/**
|
896 |
* @param string $sAction
|
897 |
* @param bool $bAsJsonEncodedObject
|
898 |
-
* @return array
|
899 |
*/
|
900 |
public function getAjaxActionData( $sAction = '', $bAsJsonEncodedObject = false ) {
|
901 |
$aData = $this->getNonceActionData( $sAction );
|
@@ -1183,8 +1180,15 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
1183 |
}
|
1184 |
|
1185 |
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1186 |
*/
|
1187 |
-
|
1188 |
}
|
1189 |
|
1190 |
/**
|
@@ -1964,46 +1968,4 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
1964 |
public function savePluginOptions() {
|
1965 |
$this->saveModOptions();
|
1966 |
}
|
1967 |
-
|
1968 |
-
/**
|
1969 |
-
* @return array[]
|
1970 |
-
* @deprecated 8.5
|
1971 |
-
*/
|
1972 |
-
public function getStatEvents_Recent() {
|
1973 |
-
return [];
|
1974 |
-
}
|
1975 |
-
|
1976 |
-
/**
|
1977 |
-
* @param string $sKey
|
1978 |
-
* @return array|null
|
1979 |
-
* @deprecated 8.5
|
1980 |
-
*/
|
1981 |
-
public function getEventDef( $sKey ) {
|
1982 |
-
return null;
|
1983 |
-
}
|
1984 |
-
|
1985 |
-
/**
|
1986 |
-
* @param string $sKey
|
1987 |
-
* @return bool
|
1988 |
-
* @deprecated 8.5
|
1989 |
-
*/
|
1990 |
-
public function isSupportedEvent( $sKey ) {
|
1991 |
-
return false;
|
1992 |
-
}
|
1993 |
-
|
1994 |
-
/**
|
1995 |
-
* @return array[]
|
1996 |
-
* @deprecated 8.5
|
1997 |
-
*/
|
1998 |
-
protected function getSupportedEvents() {
|
1999 |
-
return [];
|
2000 |
-
}
|
2001 |
-
|
2002 |
-
/**
|
2003 |
-
* @return array[]
|
2004 |
-
* @deprecated 8.5
|
2005 |
-
*/
|
2006 |
-
public function getEvents() {
|
2007 |
-
return $this->getDef( 'events' );
|
2008 |
-
}
|
2009 |
}
|
83 |
* @param array $aModProps
|
84 |
*/
|
85 |
protected function setupHooks( $aModProps ) {
|
|
|
|
|
86 |
$nRunPriority = isset( $aModProps[ 'load_priority' ] ) ? $aModProps[ 'load_priority' ] : 100;
|
87 |
add_action( $this->prefix( 'run_processors' ), [ $this, 'onRunProcessors' ], $nRunPriority );
|
88 |
add_action( 'init', [ $this, 'onWpInit' ], 1 );
|
89 |
add_action( $this->prefix( 'import_options' ), [ $this, 'processImportOptions' ] );
|
90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
$nMenuPri = isset( $aModProps[ 'menu_priority' ] ) ? $aModProps[ 'menu_priority' ] : 100;
|
92 |
add_filter( $this->prefix( 'submenu_items' ), [ $this, 'supplySubMenuItem' ], $nMenuPri );
|
93 |
add_filter( $this->prefix( 'collect_mod_summary' ), [ $this, 'addModuleSummaryData' ], $nMenuPri );
|
333 |
* A action added to WordPress 'init' hook
|
334 |
*/
|
335 |
public function onWpInit() {
|
336 |
+
$oReq = Services::Request();
|
337 |
+
if ( $this->isModuleRequest() ) {
|
338 |
+
|
339 |
+
if ( Services::WpGeneral()->isAjax() ) {
|
340 |
+
$this->loadAjaxHandler();
|
341 |
+
}
|
342 |
+
|
343 |
+
if ( $oReq->request( 'action' ) == $this->prefix()
|
344 |
+
&& check_admin_referer( $oReq->request( 'exec' ), 'exec_nonce' )
|
345 |
+
&& $this->getCon()->getMeetsBasePermissions() ) {
|
346 |
+
$this->handleModAction( $oReq->request( 'exec' ) );
|
347 |
+
}
|
348 |
+
}
|
349 |
|
350 |
$this->runWizards();
|
351 |
|
788 |
* @param string $sGlue
|
789 |
* @return string|array
|
790 |
*/
|
791 |
+
public function getLastErrors( $bAsString = false, $sGlue = " " ) {
|
792 |
$aErrors = $this->getOpt( 'last_errors' );
|
793 |
if ( !is_array( $aErrors ) ) {
|
794 |
$aErrors = [];
|
892 |
/**
|
893 |
* @param string $sAction
|
894 |
* @param bool $bAsJsonEncodedObject
|
895 |
+
* @return array|string
|
896 |
*/
|
897 |
public function getAjaxActionData( $sAction = '', $bAsJsonEncodedObject = false ) {
|
898 |
$aData = $this->getNonceActionData( $sAction );
|
1180 |
}
|
1181 |
|
1182 |
/**
|
1183 |
+
* @param string $sAction
|
1184 |
+
*/
|
1185 |
+
protected function handleModAction( $sAction ) {
|
1186 |
+
}
|
1187 |
+
|
1188 |
+
/**
|
1189 |
+
* @deprecated 8.6.2
|
1190 |
*/
|
1191 |
+
protected function handleModRequest() {
|
1192 |
}
|
1193 |
|
1194 |
/**
|
1968 |
public function savePluginOptions() {
|
1969 |
$this->saveModOptions();
|
1970 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1971 |
}
|
src/features/base_wpsf.php
CHANGED
@@ -379,58 +379,4 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
|
|
379 |
public function getIpOffenceCount() {
|
380 |
return isset( self::$nIpOffenceCount ) ? self::$nIpOffenceCount : 0;
|
381 |
}
|
382 |
-
|
383 |
-
/**
|
384 |
-
* @param string $sEvent
|
385 |
-
* @param array $aMeta
|
386 |
-
* @return $this
|
387 |
-
* @deprecated 8.5
|
388 |
-
*/
|
389 |
-
public function eventAudit( $sEvent = '', $aMeta = [] ) {
|
390 |
-
return $this;
|
391 |
-
}
|
392 |
-
|
393 |
-
/**
|
394 |
-
* @param string $sEvent
|
395 |
-
* @param array $aMeta
|
396 |
-
* @deprecated 8.5
|
397 |
-
*/
|
398 |
-
public function eventOffense( $sEvent, $aMeta = [] ) {
|
399 |
-
}
|
400 |
-
|
401 |
-
/**
|
402 |
-
* @param string $sEvent
|
403 |
-
* @param array $aMeta
|
404 |
-
* @deprecated 8.5
|
405 |
-
*/
|
406 |
-
public function eventStat( $sEvent, $aMeta = [] ) {
|
407 |
-
}
|
408 |
-
|
409 |
-
/**
|
410 |
-
* @param string $sEvent
|
411 |
-
* @param array $aMeta
|
412 |
-
* @return $this
|
413 |
-
* @deprecated 8.5
|
414 |
-
*/
|
415 |
-
protected function addStatEvent( $sEvent, $aMeta = [] ) {
|
416 |
-
return $this;
|
417 |
-
}
|
418 |
-
|
419 |
-
/**
|
420 |
-
* @param bool $bFlush
|
421 |
-
* @return Shield\Databases\AuditTrail\EntryVO[]
|
422 |
-
* @deprecated 8.5
|
423 |
-
*/
|
424 |
-
public function getRegisteredAuditLogs( $bFlush = false ) {
|
425 |
-
return [];
|
426 |
-
}
|
427 |
-
|
428 |
-
/**
|
429 |
-
* @param bool $bFlush
|
430 |
-
* @return string[]
|
431 |
-
* @deprecated 8.5
|
432 |
-
*/
|
433 |
-
public function getRegisteredEvents( $bFlush = false ) {
|
434 |
-
return [];
|
435 |
-
}
|
436 |
}
|
379 |
public function getIpOffenceCount() {
|
380 |
return isset( self::$nIpOffenceCount ) ? self::$nIpOffenceCount : 0;
|
381 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
382 |
}
|
src/features/comments_filter.php
CHANGED
@@ -5,20 +5,6 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
5 |
|
6 |
class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
7 |
|
8 |
-
/**
|
9 |
-
* @return int
|
10 |
-
*/
|
11 |
-
public function getTokenCooldown() {
|
12 |
-
return (int)$this->getOpt( 'comments_cooldown_interval' );
|
13 |
-
}
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @return int
|
17 |
-
*/
|
18 |
-
public function getTokenExpireInterval() {
|
19 |
-
return (int)$this->getOpt( 'comments_token_expire_interval' );
|
20 |
-
}
|
21 |
-
|
22 |
/**
|
23 |
* @return string
|
24 |
*/
|
@@ -76,7 +62,9 @@ class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_B
|
|
76 |
}
|
77 |
|
78 |
protected function doExtraSubmitProcessing() {
|
79 |
-
|
|
|
|
|
80 |
$this->getOptions()->resetOptToDefault( 'comments_cooldown_interval' );
|
81 |
$this->getOptions()->resetOptToDefault( 'comments_token_expire_interval' );
|
82 |
}
|
@@ -219,4 +207,12 @@ class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_B
|
|
219 |
public function getSpamBlacklistFile() {
|
220 |
return $this->getCon()->getPluginCachePath( 'spamblacklist.txt' );
|
221 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
}
|
5 |
|
6 |
class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
/**
|
9 |
* @return string
|
10 |
*/
|
62 |
}
|
63 |
|
64 |
protected function doExtraSubmitProcessing() {
|
65 |
+
/** @var Shield\Modules\CommentsFilter\Options $oOpts */
|
66 |
+
$oOpts = $this->getOptions();
|
67 |
+
if ( $oOpts->getTokenExpireInterval() != 0 && $oOpts->getTokenCooldown() > $oOpts->getTokenExpireInterval() ) {
|
68 |
$this->getOptions()->resetOptToDefault( 'comments_cooldown_interval' );
|
69 |
$this->getOptions()->resetOptToDefault( 'comments_token_expire_interval' );
|
70 |
}
|
207 |
public function getSpamBlacklistFile() {
|
208 |
return $this->getCon()->getPluginCachePath( 'spamblacklist.txt' );
|
209 |
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* @return int
|
213 |
+
* @deprecated 8.6.0
|
214 |
+
*/
|
215 |
+
public function getTokenCooldown() {
|
216 |
+
return (int)$this->getOpt( 'comments_cooldown_interval' );
|
217 |
+
}
|
218 |
}
|
src/features/hack_protect.php
CHANGED
@@ -63,19 +63,17 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
(
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
break;
|
78 |
-
}
|
79 |
}
|
80 |
}
|
81 |
|
@@ -795,11 +793,11 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
795 |
'weight' => 2,
|
796 |
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_wcf' ),
|
797 |
];
|
798 |
-
if ( $bCore && !$
|
799 |
$aThis[ 'key_opts' ][ 'wcf_repair' ] = [
|
800 |
'name' => __( 'WP Core File Repair', 'wp-simple-firewall' ),
|
801 |
-
'enabled' => $
|
802 |
-
'summary' => $
|
803 |
__( 'Core files are automatically repaired', 'wp-simple-firewall' )
|
804 |
: __( "Core files aren't automatically repaired!", 'wp-simple-firewall' ),
|
805 |
'weight' => 1,
|
@@ -807,7 +805,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
807 |
];
|
808 |
}
|
809 |
|
810 |
-
$bUcf = $
|
811 |
$aThis[ 'key_opts' ][ 'ufc' ] = [
|
812 |
'name' => __( 'Unrecognised Files', 'wp-simple-firewall' ),
|
813 |
'enabled' => $bUcf,
|
@@ -817,11 +815,11 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
817 |
'weight' => 2,
|
818 |
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_ufc' ),
|
819 |
];
|
820 |
-
if ( $bUcf && !$
|
821 |
$aThis[ 'key_opts' ][ 'ufc_repair' ] = [
|
822 |
'name' => __( 'Unrecognised Files Removal', 'wp-simple-firewall' ),
|
823 |
-
'enabled' => $
|
824 |
-
'summary' => $
|
825 |
__( 'Unrecognised files are automatically removed', 'wp-simple-firewall' )
|
826 |
: __( "Unrecognised files aren't automatically removed!", 'wp-simple-firewall' ),
|
827 |
'weight' => 1,
|
@@ -935,191 +933,4 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
935 |
protected function getNamespaceBase() {
|
936 |
return 'HackGuard';
|
937 |
}
|
938 |
-
|
939 |
-
/**
|
940 |
-
* @return bool
|
941 |
-
* @deprecated 8.5
|
942 |
-
*/
|
943 |
-
public function isPtgReadyToScan() {
|
944 |
-
return false;
|
945 |
-
}
|
946 |
-
|
947 |
-
/**
|
948 |
-
* @param int $nTime
|
949 |
-
* @return $this
|
950 |
-
* @deprecated 8.5
|
951 |
-
*/
|
952 |
-
public function setPtgLastBuildAt( $nTime = null ) {
|
953 |
-
return $this;
|
954 |
-
}
|
955 |
-
|
956 |
-
/**
|
957 |
-
* @return int
|
958 |
-
* @deprecated 8.5
|
959 |
-
*/
|
960 |
-
public function getPtgLastBuildAt() {
|
961 |
-
return $this->getOpt( 'ptg_last_build_at' );
|
962 |
-
}
|
963 |
-
|
964 |
-
/**
|
965 |
-
* @return bool
|
966 |
-
* @deprecated 8.5
|
967 |
-
*/
|
968 |
-
public function isPtgRebuildSelfRequired() {
|
969 |
-
return $this->isOpt( 'rebuild_self', true );
|
970 |
-
}
|
971 |
-
|
972 |
-
/**
|
973 |
-
* @param bool $bIsRequired
|
974 |
-
* @return $this
|
975 |
-
* @deprecated 8.5
|
976 |
-
*/
|
977 |
-
public function setPtgRebuildSelfRequired( $bIsRequired ) {
|
978 |
-
return $this->setOpt( 'rebuild_self', (bool)$bIsRequired );
|
979 |
-
}
|
980 |
-
|
981 |
-
/**
|
982 |
-
* @return bool
|
983 |
-
* @deprecated 8.5
|
984 |
-
*/
|
985 |
-
public function isPtgBuildRequired() {
|
986 |
-
return false;
|
987 |
-
}
|
988 |
-
|
989 |
-
/**
|
990 |
-
* @param bool $bIsRequired
|
991 |
-
* @return $this
|
992 |
-
* @deprecated 8.5
|
993 |
-
*/
|
994 |
-
public function setPtgUpdateStoreFormat( $bIsRequired ) {
|
995 |
-
return $this->setOpt( 'ptg_update_store_format', (bool)$bIsRequired );
|
996 |
-
}
|
997 |
-
|
998 |
-
/**
|
999 |
-
* @return bool
|
1000 |
-
* @deprecated 8.5
|
1001 |
-
*/
|
1002 |
-
public function getPtgDepth() {
|
1003 |
-
return 0;
|
1004 |
-
}
|
1005 |
-
|
1006 |
-
/**
|
1007 |
-
* @return bool
|
1008 |
-
* @deprecated 8.5
|
1009 |
-
*/
|
1010 |
-
public function isPtgUpdateStoreFormat() {
|
1011 |
-
return $this->isOpt( 'ptg_update_store_format', true );
|
1012 |
-
}
|
1013 |
-
|
1014 |
-
/**
|
1015 |
-
* @return string[]
|
1016 |
-
* @deprecated 8.5
|
1017 |
-
*/
|
1018 |
-
public function getPtgFileExtensions() {
|
1019 |
-
return $this->getOpt( 'ptg_extensions' );
|
1020 |
-
}
|
1021 |
-
|
1022 |
-
/**
|
1023 |
-
* @return bool
|
1024 |
-
* @deprecated 8.5
|
1025 |
-
*/
|
1026 |
-
public function isPtgReinstallLinks() {
|
1027 |
-
return $this->isOpt( 'ptg_reinstall_links', 'Y' );
|
1028 |
-
}
|
1029 |
-
|
1030 |
-
/**
|
1031 |
-
* @return string
|
1032 |
-
* @deprecated 8.5
|
1033 |
-
*/
|
1034 |
-
public function isUfcDeleteFiles() {
|
1035 |
-
/** @var HackGuard\Options $oOpts */
|
1036 |
-
$oOpts = $this->getOptions();
|
1037 |
-
return $oOpts->isUfcDeleteFiles();
|
1038 |
-
}
|
1039 |
-
|
1040 |
-
/**
|
1041 |
-
* @return bool
|
1042 |
-
* @deprecated 8.5
|
1043 |
-
*/
|
1044 |
-
public function isUfcEnabled() {
|
1045 |
-
/** @var HackGuard\Options $oOpts */
|
1046 |
-
$oOpts = $this->getOptions();
|
1047 |
-
return $oOpts->isUfcEnabled();
|
1048 |
-
}
|
1049 |
-
|
1050 |
-
/**
|
1051 |
-
* @return string
|
1052 |
-
* @deprecated 8.5
|
1053 |
-
*/
|
1054 |
-
public function isUfcSendReport() {
|
1055 |
-
/** @var HackGuard\Options $oOpts */
|
1056 |
-
$oOpts = $this->getOptions();
|
1057 |
-
return $oOpts->isUfcSendReport();
|
1058 |
-
}
|
1059 |
-
|
1060 |
-
/**
|
1061 |
-
* @return bool
|
1062 |
-
* @deprecated 8.5
|
1063 |
-
*/
|
1064 |
-
public function isApcEnabled() {
|
1065 |
-
/** @var HackGuard\Options $oOpts */
|
1066 |
-
$oOpts = $this->getOptions();
|
1067 |
-
return $oOpts->isApcEnabled();
|
1068 |
-
}
|
1069 |
-
|
1070 |
-
/**
|
1071 |
-
* @return bool
|
1072 |
-
* @deprecated 8.5
|
1073 |
-
*/
|
1074 |
-
public function isWcfScanEnabled() {
|
1075 |
-
/** @var HackGuard\Options $oOpts */
|
1076 |
-
$oOpts = $this->getOptions();
|
1077 |
-
return $oOpts->isWcfScanEnabled();
|
1078 |
-
}
|
1079 |
-
|
1080 |
-
/**
|
1081 |
-
* @return bool
|
1082 |
-
* @deprecated 8.5
|
1083 |
-
*/
|
1084 |
-
public function isWpvulnEnabled() {
|
1085 |
-
/** @var HackGuard\Options $oOpts */
|
1086 |
-
$oOpts = $this->getOptions();
|
1087 |
-
return $oOpts->isWpvulnEnabled();
|
1088 |
-
}
|
1089 |
-
|
1090 |
-
/**
|
1091 |
-
* @return bool
|
1092 |
-
* @deprecated 8.5
|
1093 |
-
*/
|
1094 |
-
public function isWpvulnSendEmail() {
|
1095 |
-
return $this->isWpvulnEnabled() && $this->isOpt( 'enable_wpvuln_scan', 'enabled_email' );
|
1096 |
-
}
|
1097 |
-
|
1098 |
-
/**
|
1099 |
-
* @return bool
|
1100 |
-
* @deprecated 8.5
|
1101 |
-
*/
|
1102 |
-
public function isWpvulnAutoupdatesEnabled() {
|
1103 |
-
/** @var HackGuard\Options $oOpts */
|
1104 |
-
$oOpts = $this->getOptions();
|
1105 |
-
return $oOpts->isWpvulnAutoupdatesEnabled();
|
1106 |
-
}
|
1107 |
-
|
1108 |
-
/**
|
1109 |
-
* @return string
|
1110 |
-
* @deprecated 8.5
|
1111 |
-
*/
|
1112 |
-
public function getUnrecognisedFileScannerOption() {
|
1113 |
-
return $this->getOpt( 'enable_unrecognised_file_cleaner_scan', 'disabled' );
|
1114 |
-
}
|
1115 |
-
|
1116 |
-
/**
|
1117 |
-
* @return bool
|
1118 |
-
* @deprecated 8.5
|
1119 |
-
*/
|
1120 |
-
public function isWcfScanAutoRepair() {
|
1121 |
-
/** @var HackGuard\Options $oOpts */
|
1122 |
-
$oOpts = $this->getOptions();
|
1123 |
-
return $oOpts->isWcfScanAutoRepair();
|
1124 |
-
}
|
1125 |
}
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
+
* @inheritDoc
|
67 |
+
*/
|
68 |
+
protected function handleModAction( $sAction ) {
|
69 |
+
switch ( $sAction ) {
|
70 |
+
case 'scan_file_download':
|
71 |
+
( new HackGuard\Lib\Utility\FileDownloadHandler() )
|
72 |
+
->setDbHandler( $this->getDbHandler_ScanResults() )
|
73 |
+
->downloadByItemId( (int)Services::Request()->query( 'rid', 0 ) );
|
74 |
+
break;
|
75 |
+
default:
|
76 |
+
break;
|
|
|
|
|
77 |
}
|
78 |
}
|
79 |
|
793 |
'weight' => 2,
|
794 |
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_wcf' ),
|
795 |
];
|
796 |
+
if ( $bCore && !$oOpts->isWcfScanAutoRepair() ) {
|
797 |
$aThis[ 'key_opts' ][ 'wcf_repair' ] = [
|
798 |
'name' => __( 'WP Core File Repair', 'wp-simple-firewall' ),
|
799 |
+
'enabled' => $oOpts->isWcfScanAutoRepair(),
|
800 |
+
'summary' => $oOpts->isWcfScanAutoRepair() ?
|
801 |
__( 'Core files are automatically repaired', 'wp-simple-firewall' )
|
802 |
: __( "Core files aren't automatically repaired!", 'wp-simple-firewall' ),
|
803 |
'weight' => 1,
|
805 |
];
|
806 |
}
|
807 |
|
808 |
+
$bUcf = $oOpts->isUfcEnabled();
|
809 |
$aThis[ 'key_opts' ][ 'ufc' ] = [
|
810 |
'name' => __( 'Unrecognised Files', 'wp-simple-firewall' ),
|
811 |
'enabled' => $bUcf,
|
815 |
'weight' => 2,
|
816 |
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_ufc' ),
|
817 |
];
|
818 |
+
if ( $bUcf && !$oOpts->isUfcDeleteFiles() ) {
|
819 |
$aThis[ 'key_opts' ][ 'ufc_repair' ] = [
|
820 |
'name' => __( 'Unrecognised Files Removal', 'wp-simple-firewall' ),
|
821 |
+
'enabled' => $oOpts->isUfcDeleteFiles(),
|
822 |
+
'summary' => $oOpts->isUfcDeleteFiles() ?
|
823 |
__( 'Unrecognised files are automatically removed', 'wp-simple-firewall' )
|
824 |
: __( "Unrecognised files aren't automatically removed!", 'wp-simple-firewall' ),
|
825 |
'weight' => 1,
|
933 |
protected function getNamespaceBase() {
|
934 |
return 'HackGuard';
|
935 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
936 |
}
|
src/features/headers.php
CHANGED
@@ -140,67 +140,4 @@ class ICWP_WPSF_FeatureHandler_Headers extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
140 |
protected function getNamespaceBase() {
|
141 |
return 'Headers';
|
142 |
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* @return bool
|
146 |
-
* @deprecated 8.5
|
147 |
-
*/
|
148 |
-
public function isContentSecurityPolicyEnabled() {
|
149 |
-
return $this->isOpt( 'enable_x_content_security_policy', 'Y' );
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* @return bool
|
154 |
-
* @deprecated 8.5
|
155 |
-
*/
|
156 |
-
public function isReferrerPolicyEnabled() {
|
157 |
-
return !$this->isOpt( 'x_referrer_policy', 'disabled' );
|
158 |
-
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* @return bool
|
162 |
-
* @deprecated 8.5
|
163 |
-
*/
|
164 |
-
public function isEnabledXFrame() {
|
165 |
-
return in_array( $this->getOpt( 'x_frame' ), [ 'on_sameorigin', 'on_deny' ] );
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* @return bool
|
170 |
-
* @deprecated 8.5
|
171 |
-
*/
|
172 |
-
public function isEnabledXssProtection() {
|
173 |
-
return $this->isOpt( 'x_xss_protect', 'Y' );
|
174 |
-
}
|
175 |
-
|
176 |
-
/**
|
177 |
-
* @return bool
|
178 |
-
* @deprecated 8.5
|
179 |
-
*/
|
180 |
-
public function isEnabledContentTypeHeader() {
|
181 |
-
return $this->isOpt( 'x_content_type', 'Y' );
|
182 |
-
}
|
183 |
-
|
184 |
-
/**
|
185 |
-
* Using this function without first checking isReferrerPolicyEnabled() will result in empty
|
186 |
-
* referrer policy header in the case of "disabled"
|
187 |
-
* @return string
|
188 |
-
* @deprecated 8.5
|
189 |
-
*/
|
190 |
-
public function getReferrerPolicyValue() {
|
191 |
-
$sValue = $this->getOpt( 'x_referrer_policy' );
|
192 |
-
return in_array( $sValue, [ 'empty', 'disabled' ] ) ? '' : $sValue;
|
193 |
-
}
|
194 |
-
|
195 |
-
/**
|
196 |
-
* @return array
|
197 |
-
* @deprecated 8.5
|
198 |
-
*/
|
199 |
-
public function getCspHosts() {
|
200 |
-
$aHosts = $this->getOpt( 'xcsp_hosts', [] );
|
201 |
-
if ( empty( $aHosts ) || !is_array( $aHosts ) ) {
|
202 |
-
$aHosts = [];
|
203 |
-
}
|
204 |
-
return $aHosts;
|
205 |
-
}
|
206 |
}
|
140 |
protected function getNamespaceBase() {
|
141 |
return 'Headers';
|
142 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
}
|
src/features/insights.php
CHANGED
@@ -266,12 +266,6 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
266 |
'insight_notices_count' => $nNoticesCount,
|
267 |
'insight_stats' => $this->getStats(),
|
268 |
],
|
269 |
-
'inputs' => [
|
270 |
-
'license_key' => [
|
271 |
-
'name' => $oCon->prefixOption( 'license_key' ),
|
272 |
-
'maxlength' => $this->getDef( 'license_key_length' ),
|
273 |
-
]
|
274 |
-
],
|
275 |
'ajax' => [
|
276 |
'render_chart_post' => $oEvtsMod->getAjaxActionData( 'render_chart_post', true ),
|
277 |
],
|
266 |
'insight_notices_count' => $nNoticesCount,
|
267 |
'insight_stats' => $this->getStats(),
|
268 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
'ajax' => [
|
270 |
'render_chart_post' => $oEvtsMod->getAjaxActionData( 'render_chart_post', true ),
|
271 |
],
|
src/features/ips.php
CHANGED
@@ -35,7 +35,7 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
|
35 |
}
|
36 |
|
37 |
protected function doExtraSubmitProcessing() {
|
38 |
-
/** @var
|
39 |
$oOpts = $this->getOptions();
|
40 |
if ( !defined( strtoupper( $oOpts->getOpt( 'auto_expire' ).'_IN_SECONDS' ) ) ) {
|
41 |
$oOpts->resetOptToDefault( 'auto_expire' );
|
@@ -118,7 +118,7 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
|
118 |
protected function getSectionWarnings( $sSection ) {
|
119 |
$aWarnings = [];
|
120 |
|
121 |
-
/** @var
|
122 |
$oOpts = $this->getOptions();
|
123 |
|
124 |
switch ( $sSection ) {
|
@@ -206,15 +206,19 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
|
206 |
$aIps = apply_filters( 'icwp_simple_firewall_whitelist_ips', $aIps );
|
207 |
|
208 |
if ( !empty( $aIps ) && is_array( $aIps ) ) {
|
209 |
-
$aWhiteIps = ( new
|
210 |
->setDbHandler( $this->getDbHandler_IPs() )
|
211 |
->white();
|
212 |
foreach ( $aIps as $sIP => $sLabel ) {
|
213 |
if ( !in_array( $sIP, $aWhiteIps ) ) {
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
|
|
|
|
|
|
|
|
218 |
}
|
219 |
}
|
220 |
}
|
@@ -226,13 +230,4 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
|
226 |
protected function getNamespaceBase() {
|
227 |
return 'IPs';
|
228 |
}
|
229 |
-
|
230 |
-
/**
|
231 |
-
* IP addresses that should never be put on the black list.
|
232 |
-
* @return string[]
|
233 |
-
* @deprecated 8.5.1
|
234 |
-
*/
|
235 |
-
public function getReservedIps() {
|
236 |
-
return Services::IP()->getServerPublicIPs();
|
237 |
-
}
|
238 |
}
|
35 |
}
|
36 |
|
37 |
protected function doExtraSubmitProcessing() {
|
38 |
+
/** @var IPs\Options $oOpts */
|
39 |
$oOpts = $this->getOptions();
|
40 |
if ( !defined( strtoupper( $oOpts->getOpt( 'auto_expire' ).'_IN_SECONDS' ) ) ) {
|
41 |
$oOpts->resetOptToDefault( 'auto_expire' );
|
118 |
protected function getSectionWarnings( $sSection ) {
|
119 |
$aWarnings = [];
|
120 |
|
121 |
+
/** @var IPs\Options $oOpts */
|
122 |
$oOpts = $this->getOptions();
|
123 |
|
124 |
switch ( $sSection ) {
|
206 |
$aIps = apply_filters( 'icwp_simple_firewall_whitelist_ips', $aIps );
|
207 |
|
208 |
if ( !empty( $aIps ) && is_array( $aIps ) ) {
|
209 |
+
$aWhiteIps = ( new IPs\Lib\Ops\RetrieveIpsForLists() )
|
210 |
->setDbHandler( $this->getDbHandler_IPs() )
|
211 |
->white();
|
212 |
foreach ( $aIps as $sIP => $sLabel ) {
|
213 |
if ( !in_array( $sIP, $aWhiteIps ) ) {
|
214 |
+
try {
|
215 |
+
( new IPs\Lib\Ops\AddIp() )
|
216 |
+
->setMod( $this )
|
217 |
+
->setIP( $sIP )
|
218 |
+
->toManualWhitelist( $sLabel );
|
219 |
+
}
|
220 |
+
catch ( Exception $oE ) {
|
221 |
+
}
|
222 |
}
|
223 |
}
|
224 |
}
|
230 |
protected function getNamespaceBase() {
|
231 |
return 'IPs';
|
232 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
}
|
src/features/license.php
CHANGED
@@ -1,11 +1,121 @@
|
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
use FernleafSystems\Wordpress\Services\Utilities;
|
6 |
|
7 |
class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
protected function redirectToInsightsSubPage() {
|
10 |
Services::Response()->redirect(
|
11 |
$this->getCon()->getModule_Insights()->getUrl_AdminPage(),
|
@@ -13,9 +123,23 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
13 |
);
|
14 |
}
|
15 |
|
|
|
|
|
|
|
|
|
16 |
protected function setupCustomHooks() {
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
}
|
20 |
|
21 |
/**
|
@@ -26,19 +150,25 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
26 |
}
|
27 |
|
28 |
public function onPluginShutdown() {
|
29 |
-
|
|
|
|
|
|
|
|
|
30 |
parent::onPluginShutdown();
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
* @return Shield\License\EddLicenseVO
|
|
|
35 |
*/
|
36 |
protected function loadLicense() {
|
37 |
-
return
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
* @return array
|
|
|
42 |
*/
|
43 |
protected function getLicenseData() {
|
44 |
$aData = $this->getOpt( 'license_data', [] );
|
@@ -47,6 +177,7 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
47 |
|
48 |
/**
|
49 |
* @return $this
|
|
|
50 |
*/
|
51 |
public function clearLicenseData() {
|
52 |
return $this->setOpt( 'license_data', [] );
|
@@ -55,6 +186,7 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
55 |
/**
|
56 |
* @param Utilities\Licenses\EddLicenseVO $oLic
|
57 |
* @return $this
|
|
|
58 |
*/
|
59 |
protected function setLicenseData( $oLic ) {
|
60 |
return $this->setOpt( 'license_data', $oLic->getRawDataAsArray() );
|
@@ -62,18 +194,9 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
62 |
|
63 |
/**
|
64 |
* @param string $sDeactivatedReason
|
|
|
65 |
*/
|
66 |
public function deactivate( $sDeactivatedReason = '' ) {
|
67 |
-
$oOpts = $this->getOptions();
|
68 |
-
if ( $this->isLicenseActive() ) {
|
69 |
-
$oOpts->setOptAt( 'license_deactivated_at' );
|
70 |
-
}
|
71 |
-
|
72 |
-
if ( !empty( $sDeactivatedReason ) ) {
|
73 |
-
$oOpts->setOpt( 'license_deactivated_reason', $sDeactivatedReason );
|
74 |
-
}
|
75 |
-
// force all options to resave i.e. reset premium to defaults.
|
76 |
-
add_filter( $this->prefix( 'force_options_resave' ), '__return_true' );
|
77 |
}
|
78 |
|
79 |
/**
|
@@ -81,91 +204,44 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
81 |
* for a currently valid license.
|
82 |
* @param bool $bForceCheck
|
83 |
* @return $this
|
|
|
84 |
*/
|
85 |
public function verifyLicense( $bForceCheck = true ) {
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
// 1 check in 20 seconds
|
91 |
-
if ( ( $bForceCheck || $bCheckReq ) && $this->getIsLicenseNotCheckedFor( 20 ) ) {
|
92 |
-
|
93 |
-
$oCurrent = $this->loadLicense();
|
94 |
-
|
95 |
-
$this->touchLicenseCheckFileFlag()
|
96 |
-
->setLicenseLastCheckedAt();
|
97 |
-
$this->saveModOptions();
|
98 |
-
|
99 |
-
$oLookupLicense = $this->lookupOfficialLicense();
|
100 |
-
if ( $oLookupLicense->isValid() ) {
|
101 |
-
$oCurrent = $oLookupLicense;
|
102 |
-
$oCurrent->updateLastVerifiedAt( true );
|
103 |
-
$this->activateLicense()
|
104 |
-
->clearLastErrors();
|
105 |
-
$oCon->fireEvent( 'lic_check_success' );
|
106 |
-
}
|
107 |
-
else {
|
108 |
-
if ( $oCurrent->isValid() ) { // we have something valid previously stored
|
109 |
-
|
110 |
-
if ( !$bForceCheck && $this->isWithinVerifiedGraceExpired() ) {
|
111 |
-
$this->sendLicenseWarningEmail();
|
112 |
-
$oCon->fireEvent( 'lic_fail_email' );
|
113 |
-
}
|
114 |
-
elseif ( $bForceCheck || $oCurrent->isExpired() || $this->isLastVerifiedGraceExpired() ) {
|
115 |
-
$oCurrent = $oLookupLicense;
|
116 |
-
$this->deactivate( __( 'Automatic license verification failed.', 'wp-simple-firewall' ) );
|
117 |
-
$this->sendLicenseDeactivatedEmail();
|
118 |
-
$oCon->fireEvent( 'lic_fail_deactivate' );
|
119 |
-
}
|
120 |
-
}
|
121 |
-
else {
|
122 |
-
// No previously valid license, and the license lookup also failed but the http request was successful.
|
123 |
-
if ( $oLookupLicense->isReady() ) {
|
124 |
-
$this->deactivate();
|
125 |
-
$oCurrent = $oLookupLicense;
|
126 |
-
}
|
127 |
-
}
|
128 |
-
}
|
129 |
-
|
130 |
-
$oCurrent->last_request_at = Services::Request()->ts();
|
131 |
-
$this->setLicenseData( $oCurrent );
|
132 |
-
$this->saveModOptions();
|
133 |
}
|
134 |
-
|
135 |
return $this;
|
136 |
}
|
137 |
|
138 |
/**
|
139 |
* @return bool
|
|
|
140 |
*/
|
141 |
private function isLicenseCheckRequired() {
|
142 |
-
return
|
143 |
-
|| ( $this->isLicenseActive()
|
144 |
-
&& !$this->loadLicense()->isReady() && $this->getIsLicenseNotCheckedFor( HOUR_IN_SECONDS ) )
|
145 |
-
|| ( $this->hasValidWorkingLicense() && $this->isLastVerifiedExpired()
|
146 |
-
&& $this->getIsLicenseNotCheckedFor( HOUR_IN_SECONDS*4 ) );
|
147 |
}
|
148 |
|
149 |
/**
|
150 |
* @return bool
|
|
|
151 |
*/
|
152 |
private function canLicenseCheck() {
|
153 |
-
return
|
154 |
-
&& $this->canLicenseCheck_FileFlag();
|
155 |
}
|
156 |
|
157 |
/**
|
158 |
* @return bool
|
|
|
159 |
*/
|
160 |
private function canLicenseCheck_FileFlag() {
|
161 |
-
|
162 |
-
$sFileFlag = $this->getCon()->getPath_Flags( 'license_check' );
|
163 |
-
$nMtime = $oFs->exists( $sFileFlag ) ? $oFs->getModifiedTime( $sFileFlag ) : 0;
|
164 |
-
return ( Services::Request()->ts() - $nMtime ) > MINUTE_IN_SECONDS;
|
165 |
}
|
166 |
|
167 |
/**
|
168 |
* @return $this
|
|
|
169 |
*/
|
170 |
private function touchLicenseCheckFileFlag() {
|
171 |
Services::WpFs()->touch( $this->getCon()->getPath_Flags( 'license_check' ) );
|
@@ -174,110 +250,35 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
174 |
|
175 |
/**
|
176 |
* @return bool
|
|
|
177 |
*/
|
178 |
protected function isLicenseMaybeExpiring() {
|
179 |
-
return
|
180 |
-
(
|
181 |
-
abs( Services::Request()->ts() - $this->loadLicense()->getExpiresAt() )
|
182 |
-
< ( DAY_IN_SECONDS/2 )
|
183 |
-
);
|
184 |
}
|
185 |
|
186 |
/**
|
187 |
* @return $this
|
|
|
188 |
*/
|
189 |
protected function activateLicense() {
|
190 |
-
if ( !$this->isLicenseActive() ) {
|
191 |
-
$this->getOptions()->setOptAt( 'license_activated_at' );
|
192 |
-
}
|
193 |
return $this;
|
194 |
}
|
195 |
|
196 |
/**
|
|
|
197 |
*/
|
198 |
protected function sendLicenseWarningEmail() {
|
199 |
-
$oOpts = $this->getOptions();
|
200 |
-
|
201 |
-
$bCanSend = Services::Request()
|
202 |
-
->carbon()
|
203 |
-
->subDay( 1 )->timestamp > $oOpts->getOpt( 'last_warning_email_sent_at' );
|
204 |
-
|
205 |
-
if ( $bCanSend ) {
|
206 |
-
$oOpts->setOptAt( 'last_warning_email_sent_at' );
|
207 |
-
$this->saveModOptions();
|
208 |
-
|
209 |
-
$aMessage = [
|
210 |
-
__( 'Attempts to verify Shield Pro license has just failed.', 'wp-simple-firewall' ),
|
211 |
-
sprintf( __( 'Please check your license on-site: %s', 'wp-simple-firewall' ), $this->getUrl_AdminPage() ),
|
212 |
-
sprintf( __( 'If this problem persists, please contact support: %s', 'wp-simple-firewall' ), 'https://support.onedollarplugin.com/' )
|
213 |
-
];
|
214 |
-
$this->getEmailProcessor()
|
215 |
-
->sendEmailWithWrap(
|
216 |
-
$this->getPluginDefaultRecipientAddress(),
|
217 |
-
'Pro License Check Has Failed',
|
218 |
-
$aMessage
|
219 |
-
);
|
220 |
-
}
|
221 |
}
|
222 |
|
223 |
/**
|
|
|
224 |
*/
|
225 |
private function sendLicenseDeactivatedEmail() {
|
226 |
-
$oOpts = $this->getOptions();
|
227 |
-
|
228 |
-
$bCanSend = Services::Request()
|
229 |
-
->carbon()
|
230 |
-
->subDay( 1 )->timestamp > $oOpts->getOpt( 'last_deactivated_email_sent_at' );
|
231 |
-
|
232 |
-
if ( $bCanSend ) {
|
233 |
-
$oOpts->setOptAt( 'last_deactivated_email_sent_at' );
|
234 |
-
$this->saveModOptions();
|
235 |
-
|
236 |
-
$aMessage = [
|
237 |
-
__( 'All attempts to verify Shield Pro license have failed.', 'wp-simple-firewall' ),
|
238 |
-
sprintf( __( 'Please check your license on-site: %s', 'wp-simple-firewall' ), $this->getUrl_AdminPage() ),
|
239 |
-
sprintf( __( 'If this problem persists, please contact support: %s', 'wp-simple-firewall' ), 'https://support.onedollarplugin.com/' )
|
240 |
-
];
|
241 |
-
$this->getEmailProcessor()
|
242 |
-
->sendEmailWithWrap(
|
243 |
-
$this->getPluginDefaultRecipientAddress(),
|
244 |
-
'[Action May Be Required] Pro License Has Been Deactivated',
|
245 |
-
$aMessage
|
246 |
-
);
|
247 |
-
}
|
248 |
-
}
|
249 |
-
|
250 |
-
/**
|
251 |
-
* @return Utilities\Licenses\EddLicenseVO
|
252 |
-
*/
|
253 |
-
private function lookupOfficialLicense() {
|
254 |
-
|
255 |
-
$sPass = wp_generate_password( 16 );
|
256 |
-
|
257 |
-
$this->setKeylessRequestAt()
|
258 |
-
->setKeylessRequestHash( sha1( $sPass.Services::WpGeneral()->getHomeUrl( '', true ) ) );
|
259 |
-
$this->saveModOptions();
|
260 |
-
|
261 |
-
$oLicense = ( new Utilities\Licenses\Lookup() )
|
262 |
-
->setRequestParams(
|
263 |
-
[
|
264 |
-
'installation_id' => $this->getCon()->getSiteInstallationId(),
|
265 |
-
'version_shield' => $this->getCon()->getVersion(),
|
266 |
-
'nonce' => $sPass,
|
267 |
-
]
|
268 |
-
)
|
269 |
-
->activateLicenseKeyless( $this->getLicenseStoreUrl(), $this->getLicenseItemId() );
|
270 |
-
|
271 |
-
// clear the handshake data
|
272 |
-
$this->setKeylessRequestAt( 0 )
|
273 |
-
->setKeylessRequestHash( '' );
|
274 |
-
$this->saveModOptions();
|
275 |
-
|
276 |
-
return $oLicense;
|
277 |
}
|
278 |
|
279 |
/**
|
280 |
* @return int
|
|
|
281 |
*/
|
282 |
protected function getLicenseActivatedAt() {
|
283 |
return $this->getOpt( 'license_activated_at' );
|
@@ -285,6 +286,7 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
285 |
|
286 |
/**
|
287 |
* @return int
|
|
|
288 |
*/
|
289 |
protected function getLicenseDeactivatedAt() {
|
290 |
return $this->getOpt( 'license_deactivated_at' );
|
@@ -292,43 +294,17 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
292 |
|
293 |
/**
|
294 |
* @return string
|
295 |
-
|
296 |
-
public function getLicenseKey() {
|
297 |
-
return $this->getOpt( 'license_key' );
|
298 |
-
}
|
299 |
-
|
300 |
-
/**
|
301 |
-
* @return string
|
302 |
-
*/
|
303 |
-
public function hasLicenseKey() {
|
304 |
-
return $this->isLicenseKeyValidFormat();
|
305 |
-
}
|
306 |
-
|
307 |
-
/**
|
308 |
-
* @return string
|
309 |
-
*/
|
310 |
-
public function getLicenseItemId() {
|
311 |
-
return $this->getDef( 'license_item_id' );
|
312 |
-
}
|
313 |
-
|
314 |
-
/**
|
315 |
-
* @return string
|
316 |
*/
|
317 |
public function getLicenseItemName() {
|
318 |
-
return $this->
|
319 |
$this->getDef( 'license_item_name_sc' ) :
|
320 |
$this->getDef( 'license_item_name' );
|
321 |
}
|
322 |
|
323 |
-
/**
|
324 |
-
* @return string
|
325 |
-
*/
|
326 |
-
public function getLicenseStoreUrl() {
|
327 |
-
return $this->getDef( 'license_store_url' );
|
328 |
-
}
|
329 |
-
|
330 |
/**
|
331 |
* @return int
|
|
|
332 |
*/
|
333 |
protected function getLicenseLastCheckedAt() {
|
334 |
return $this->getOpt( 'license_last_checked_at' );
|
@@ -337,31 +313,26 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
337 |
/**
|
338 |
* @param int $nTimePeriod
|
339 |
* @return bool
|
|
|
340 |
*/
|
341 |
private function getIsLicenseNotCheckedFor( $nTimePeriod ) {
|
342 |
-
return
|
343 |
}
|
344 |
|
345 |
/**
|
346 |
* @return int
|
|
|
347 |
*/
|
348 |
public function getLicenseNotCheckedForInterval() {
|
349 |
-
return
|
350 |
}
|
351 |
|
352 |
/**
|
353 |
* @return bool
|
|
|
354 |
*/
|
355 |
public function isLicenseActive() {
|
356 |
-
return
|
357 |
-
&& ( $this->getLicenseDeactivatedAt() < $this->getLicenseActivatedAt() );
|
358 |
-
}
|
359 |
-
|
360 |
-
/**
|
361 |
-
* @return bool
|
362 |
-
*/
|
363 |
-
public function isLicenseKeyValidFormat() {
|
364 |
-
return !is_null( $this->verifyLicenseKeyFormat( $this->getLicenseKey() ) );
|
365 |
}
|
366 |
|
367 |
/**
|
@@ -373,222 +344,45 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
373 |
* 4) the license hasn't expired
|
374 |
* 5) the time since the last check hasn't expired
|
375 |
* @return bool
|
|
|
376 |
*/
|
377 |
public function hasValidWorkingLicense() {
|
378 |
-
|
379 |
-
return ( $this->isKeyless() || $this->isLicenseKeyValidFormat() )
|
380 |
-
&& $oLic->isValid() && $this->isLicenseActive();
|
381 |
-
}
|
382 |
-
|
383 |
-
/**
|
384 |
-
* @return bool
|
385 |
-
*/
|
386 |
-
protected function isKeyless() {
|
387 |
-
return (bool)$this->getDef( 'keyless' );
|
388 |
}
|
389 |
|
390 |
/**
|
391 |
-
* Expires in 3 days.
|
392 |
* @return bool
|
|
|
393 |
*/
|
394 |
protected function isLastVerifiedExpired() {
|
395 |
-
return
|
396 |
-
> $this->getDef( 'lic_verify_expire_days' )*DAY_IN_SECONDS;
|
397 |
}
|
398 |
|
399 |
/**
|
400 |
* @return bool
|
|
|
401 |
*/
|
402 |
protected function isLastVerifiedGraceExpired() {
|
403 |
-
|
404 |
-
*DAY_IN_SECONDS;
|
405 |
-
return ( Services::Request()->ts() - $this->loadLicense()->last_verified_at ) > $nGracePeriod;
|
406 |
}
|
407 |
|
408 |
/**
|
409 |
* @return bool
|
|
|
410 |
*/
|
411 |
protected function isWithinVerifiedGraceExpired() {
|
412 |
-
return
|
413 |
}
|
414 |
|
415 |
/**
|
416 |
* @param int $nAt
|
417 |
* @return $this
|
|
|
418 |
*/
|
419 |
protected function setLicenseLastCheckedAt( $nAt = null ) {
|
420 |
-
$this->getOptions()->setOptAt( 'license_last_checked_at', $nAt );
|
421 |
return $this;
|
422 |
}
|
423 |
|
424 |
-
/**
|
425 |
-
* @param string $sKey
|
426 |
-
* @return string|null
|
427 |
-
*/
|
428 |
-
public function verifyLicenseKeyFormat( $sKey ) {
|
429 |
-
$sCleanKey = null;
|
430 |
-
|
431 |
-
$sKey = $this->cleanLicenseKey( $sKey );
|
432 |
-
$bValid = !empty( $sKey ) && is_string( $sKey )
|
433 |
-
&& ( strlen( $sKey ) == $this->getDef( 'license_key_length' ) );
|
434 |
-
|
435 |
-
if ( $bValid ) {
|
436 |
-
switch ( $this->getDef( 'license_key_type' ) ) {
|
437 |
-
case 'alphanumeric':
|
438 |
-
default:
|
439 |
-
if ( preg_match( '#[^a-z0-9]#i', $sKey ) === 0 ) {
|
440 |
-
$sCleanKey = $sKey;
|
441 |
-
}
|
442 |
-
break;
|
443 |
-
}
|
444 |
-
}
|
445 |
-
|
446 |
-
return $sCleanKey;
|
447 |
-
}
|
448 |
-
|
449 |
-
protected function cleanLicenseKey( $sKey ) {
|
450 |
-
|
451 |
-
switch ( $this->getDef( 'license_key_type' ) ) {
|
452 |
-
case 'alphanumeric':
|
453 |
-
default:
|
454 |
-
$sKey = preg_replace( '#[^a-z0-9]#i', '', $sKey );
|
455 |
-
break;
|
456 |
-
}
|
457 |
-
|
458 |
-
return $sKey;
|
459 |
-
}
|
460 |
-
|
461 |
-
/**
|
462 |
-
*/
|
463 |
-
protected function doPrePluginOptionsSave() {
|
464 |
-
// clean the key.
|
465 |
-
$sLicKey = $this->getLicenseKey();
|
466 |
-
if ( strlen( $sLicKey ) > 0 ) {
|
467 |
-
switch ( $this->getDef( 'license_key_type' ) ) {
|
468 |
-
case 'alphanumeric':
|
469 |
-
default:
|
470 |
-
$this->setOpt( 'license_key', preg_replace( '#[^a-z0-9]#i', '', $sLicKey ) );
|
471 |
-
break;
|
472 |
-
}
|
473 |
-
}
|
474 |
-
}
|
475 |
-
|
476 |
-
/**
|
477 |
-
* @return int
|
478 |
-
*/
|
479 |
-
public function getKeylessRequestAt() {
|
480 |
-
return (int)$this->getOpt( 'keyless_request_at', 0 );
|
481 |
-
}
|
482 |
-
|
483 |
-
/**
|
484 |
-
* @return string
|
485 |
-
*/
|
486 |
-
public function getKeylessRequestHash() {
|
487 |
-
return (string)$this->getOpt( 'keyless_request_hash', '' );
|
488 |
-
}
|
489 |
-
|
490 |
-
/**
|
491 |
-
* @return bool
|
492 |
-
*/
|
493 |
-
public function isKeylessHandshakeExpired() {
|
494 |
-
return ( Services::Request()->ts() - $this->getKeylessRequestAt() )
|
495 |
-
> $this->getDef( 'keyless_handshake_expire' );
|
496 |
-
}
|
497 |
-
|
498 |
-
/**
|
499 |
-
* @param string $sHash
|
500 |
-
* @return $this
|
501 |
-
*/
|
502 |
-
public function setKeylessRequestHash( $sHash ) {
|
503 |
-
return $this->setOpt( 'keyless_request_hash', $sHash );
|
504 |
-
}
|
505 |
-
|
506 |
-
/**
|
507 |
-
* @param int|null $nTime
|
508 |
-
* @return $this
|
509 |
-
*/
|
510 |
-
public function setKeylessRequestAt( $nTime = null ) {
|
511 |
-
$nTime = is_numeric( $nTime ) ? $nTime : Services::Request()->ts();
|
512 |
-
return $this->setOpt( 'keyless_request_at', $nTime );
|
513 |
-
}
|
514 |
-
|
515 |
-
/**
|
516 |
-
* @return bool
|
517 |
-
*/
|
518 |
-
protected function isEnabledForUiSummary() {
|
519 |
-
return $this->hasValidWorkingLicense();
|
520 |
-
}
|
521 |
-
|
522 |
-
public function buildInsightsVars() {
|
523 |
-
$oWp = Services::WpGeneral();
|
524 |
-
$oCon = $this->getCon();
|
525 |
-
$oCarbon = Services::Request()->carbon();
|
526 |
-
|
527 |
-
$oCurrent = $this->loadLicense();
|
528 |
-
|
529 |
-
$nExpiresAt = $oCurrent->getExpiresAt();
|
530 |
-
if ( $nExpiresAt > 0 && $nExpiresAt != PHP_INT_MAX ) {
|
531 |
-
$sExpiresAt = $oCarbon->setTimestamp( $nExpiresAt )->diffForHumans()
|
532 |
-
.sprintf( '<br/><small>%s</small>', $oWp->getTimeStampForDisplay( $nExpiresAt ) );
|
533 |
-
}
|
534 |
-
else {
|
535 |
-
$sExpiresAt = 'n/a';
|
536 |
-
}
|
537 |
-
|
538 |
-
$nLastReqAt = $oCurrent->last_request_at;
|
539 |
-
if ( empty( $nLastReqAt ) ) {
|
540 |
-
$sChecked = __( 'Never', 'wp-simple-firewall' );
|
541 |
-
}
|
542 |
-
else {
|
543 |
-
$sChecked = $oCarbon->setTimestamp( $nLastReqAt )->diffForHumans()
|
544 |
-
.sprintf( '<br/><small>%s</small>', $oWp->getTimeStampForDisplay( $nLastReqAt ) );
|
545 |
-
}
|
546 |
-
$aLicenseTableVars = [
|
547 |
-
'product_name' => $this->getLicenseItemName(),
|
548 |
-
'license_active' => $this->hasValidWorkingLicense() ? __( 'Yes', 'wp-simple-firewall' ) : __( 'Not Active', 'wp-simple-firewall' ),
|
549 |
-
'license_expires' => $sExpiresAt,
|
550 |
-
'license_email' => $oCurrent->customer_email,
|
551 |
-
'last_checked' => $sChecked,
|
552 |
-
'last_errors' => $this->hasLastErrors() ? $this->getLastErrors() : ''
|
553 |
-
];
|
554 |
-
if ( !$this->isKeyless() ) {
|
555 |
-
$aLicenseTableVars[ 'license_key' ] = $this->hasLicenseKey() ? $this->getLicenseKey() : 'n/a';
|
556 |
-
}
|
557 |
-
return [
|
558 |
-
'vars' => [
|
559 |
-
'license_table' => $aLicenseTableVars,
|
560 |
-
'activation_url' => $oWp->getHomeUrl()
|
561 |
-
],
|
562 |
-
'inputs' => [
|
563 |
-
'license_key' => [
|
564 |
-
'name' => $oCon->prefixOption( 'license_key' ),
|
565 |
-
'maxlength' => $this->getDef( 'license_key_length' ),
|
566 |
-
]
|
567 |
-
],
|
568 |
-
'ajax' => [
|
569 |
-
'license_handling' => $this->getAjaxActionData( 'license_handling' ),
|
570 |
-
'connection_debug' => $this->getAjaxActionData( 'connection_debug' )
|
571 |
-
],
|
572 |
-
'aHrefs' => [
|
573 |
-
'shield_pro_url' => 'https://shsec.io/shieldpro',
|
574 |
-
'shield_pro_more_info_url' => 'https://shsec.io/shld1',
|
575 |
-
'iframe_url' => $this->getDef( 'landing_page_url' ),
|
576 |
-
'keyless_cp' => $this->getDef( 'keyless_cp' ),
|
577 |
-
],
|
578 |
-
'flags' => [
|
579 |
-
'show_key' => !$this->isKeyless(),
|
580 |
-
'has_license_key' => $this->isLicenseKeyValidFormat(),
|
581 |
-
'show_ads' => false,
|
582 |
-
'button_enabled_check' => true,
|
583 |
-
'button_enabled_remove' => $this->isLicenseKeyValidFormat(),
|
584 |
-
'show_standard_options' => false,
|
585 |
-
'show_alt_content' => true,
|
586 |
-
'is_pro' => $this->isPremium()
|
587 |
-
],
|
588 |
-
'strings' => $this->getStrings()->getDisplayStrings(),
|
589 |
-
];
|
590 |
-
}
|
591 |
-
|
592 |
/**
|
593 |
* @return string
|
594 |
*/
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\License;
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
use FernleafSystems\Wordpress\Services\Utilities;
|
7 |
|
8 |
class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
9 |
|
10 |
+
/**
|
11 |
+
* @var License\Lib\LicenseHandler
|
12 |
+
*/
|
13 |
+
private $oLicHandler;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var License\Lib\WpHashes\ApiTokenManager
|
17 |
+
*/
|
18 |
+
private $oWpHashesTokenManager;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @return License\Lib\LicenseHandler
|
22 |
+
*/
|
23 |
+
public function getLicenseHandler() {
|
24 |
+
if ( !isset( $this->oLicHandler ) ) {
|
25 |
+
$this->oLicHandler = ( new Shield\Modules\License\Lib\LicenseHandler() )->setMod( $this );
|
26 |
+
}
|
27 |
+
return $this->oLicHandler;
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @return License\Lib\WpHashes\ApiTokenManager
|
32 |
+
*/
|
33 |
+
public function getWpHashesTokenManager() {
|
34 |
+
if ( !isset( $this->oWpHashesTokenManager ) ) {
|
35 |
+
$this->oWpHashesTokenManager = ( new Shield\Modules\License\Lib\WpHashes\ApiTokenManager() )->setMod( $this );
|
36 |
+
}
|
37 |
+
return $this->oWpHashesTokenManager;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return bool
|
42 |
+
*/
|
43 |
+
protected function isEnabledForUiSummary() {
|
44 |
+
return $this->getLicenseHandler()->hasValidWorkingLicense();
|
45 |
+
}
|
46 |
+
|
47 |
+
public function buildInsightsVars() {
|
48 |
+
$oWp = Services::WpGeneral();
|
49 |
+
$oCon = $this->getCon();
|
50 |
+
$oCarbon = Services::Request()->carbon();
|
51 |
+
|
52 |
+
$oCurrent = $this->getLicenseHandler()->getLicense();
|
53 |
+
|
54 |
+
$nExpiresAt = $oCurrent->getExpiresAt();
|
55 |
+
if ( $nExpiresAt > 0 && $nExpiresAt != PHP_INT_MAX ) {
|
56 |
+
$sExpiresAt = $oCarbon->setTimestamp( $nExpiresAt )->diffForHumans()
|
57 |
+
.sprintf( '<br/><small>%s</small>', $oWp->getTimeStampForDisplay( $nExpiresAt ) );
|
58 |
+
}
|
59 |
+
else {
|
60 |
+
$sExpiresAt = 'n/a';
|
61 |
+
}
|
62 |
+
|
63 |
+
$nLastReqAt = $oCurrent->last_request_at;
|
64 |
+
if ( empty( $nLastReqAt ) ) {
|
65 |
+
$sChecked = __( 'Never', 'wp-simple-firewall' );
|
66 |
+
}
|
67 |
+
else {
|
68 |
+
$sChecked = $oCarbon->setTimestamp( $nLastReqAt )->diffForHumans()
|
69 |
+
.sprintf( '<br/><small>%s</small>', $oWp->getTimeStampForDisplay( $nLastReqAt ) );
|
70 |
+
}
|
71 |
+
$aLicenseTableVars = [
|
72 |
+
'product_name' => $oCurrent->is_central ?
|
73 |
+
$this->getDef( 'license_item_name_sc' ) :
|
74 |
+
$this->getDef( 'license_item_name' ),
|
75 |
+
'license_active' => $this->getLicenseHandler()->hasValidWorkingLicense() ?
|
76 |
+
__( '✔', 'wp-simple-firewall' ) : __( '✖', 'wp-simple-firewall' ),
|
77 |
+
'license_expires' => $sExpiresAt,
|
78 |
+
'license_email' => $oCurrent->customer_email,
|
79 |
+
'last_checked' => $sChecked,
|
80 |
+
'last_errors' => $this->hasLastErrors() ? $this->getLastErrors( true ) : '',
|
81 |
+
'wphashes_token' => $this->getWpHashesTokenManager()->hasToken() ?
|
82 |
+
__( '✔', 'wp-simple-firewall' ) : __( '✖', 'wp-simple-firewall' ),
|
83 |
+
'installation_id' => $oCon->getSiteInstallationId(),
|
84 |
+
];
|
85 |
+
return [
|
86 |
+
'vars' => [
|
87 |
+
'license_table' => $aLicenseTableVars,
|
88 |
+
'activation_url' => $oWp->getHomeUrl(),
|
89 |
+
'error' => $this->getLastErrors( true )
|
90 |
+
],
|
91 |
+
'inputs' => [
|
92 |
+
'license_key' => [
|
93 |
+
'name' => $oCon->prefixOption( 'license_key' ),
|
94 |
+
'maxlength' => $this->getDef( 'license_key_length' ),
|
95 |
+
]
|
96 |
+
],
|
97 |
+
'ajax' => [
|
98 |
+
'license_handling' => $this->getAjaxActionData( 'license_handling' ),
|
99 |
+
'connection_debug' => $this->getAjaxActionData( 'connection_debug' )
|
100 |
+
],
|
101 |
+
'aHrefs' => [
|
102 |
+
'shield_pro_url' => 'https://shsec.io/shieldpro',
|
103 |
+
'shield_pro_more_info_url' => 'https://shsec.io/shld1',
|
104 |
+
'iframe_url' => $this->getDef( 'landing_page_url' ),
|
105 |
+
'keyless_cp' => $this->getDef( 'keyless_cp' ),
|
106 |
+
],
|
107 |
+
'flags' => [
|
108 |
+
'show_ads' => false,
|
109 |
+
'button_enabled_check' => true,
|
110 |
+
'show_standard_options' => false,
|
111 |
+
'show_alt_content' => true,
|
112 |
+
'is_pro' => $this->isPremium(),
|
113 |
+
'has_error' => $this->hasLastErrors()
|
114 |
+
],
|
115 |
+
'strings' => $this->getStrings()->getDisplayStrings(),
|
116 |
+
];
|
117 |
+
}
|
118 |
+
|
119 |
protected function redirectToInsightsSubPage() {
|
120 |
Services::Response()->redirect(
|
121 |
$this->getCon()->getModule_Insights()->getUrl_AdminPage(),
|
123 |
);
|
124 |
}
|
125 |
|
126 |
+
public function runHourlyCron() {
|
127 |
+
$this->getWpHashesTokenManager()->getToken();
|
128 |
+
}
|
129 |
+
|
130 |
protected function setupCustomHooks() {
|
131 |
+
add_action( 'wp_loaded', [ $this, 'onWpLoaded' ] );
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* @deprecated 8.6.2
|
136 |
+
*/
|
137 |
+
protected function updateHandler() {
|
138 |
+
$this->getWpHashesTokenManager()->getToken();
|
139 |
+
}
|
140 |
+
|
141 |
+
public function onWpLoaded() {
|
142 |
+
$this->getWpHashesTokenManager()->run();
|
143 |
}
|
144 |
|
145 |
/**
|
150 |
}
|
151 |
|
152 |
public function onPluginShutdown() {
|
153 |
+
try {
|
154 |
+
$this->getLicenseHandler()->verify( false );
|
155 |
+
}
|
156 |
+
catch ( Exception $oE ) {
|
157 |
+
}
|
158 |
parent::onPluginShutdown();
|
159 |
}
|
160 |
|
161 |
/**
|
162 |
* @return Shield\License\EddLicenseVO
|
163 |
+
* @deprecated 8.6.2
|
164 |
*/
|
165 |
protected function loadLicense() {
|
166 |
+
return $this->getLicenseHandler()->getLicense();
|
167 |
}
|
168 |
|
169 |
/**
|
170 |
* @return array
|
171 |
+
* @deprecated 8.6.2
|
172 |
*/
|
173 |
protected function getLicenseData() {
|
174 |
$aData = $this->getOpt( 'license_data', [] );
|
177 |
|
178 |
/**
|
179 |
* @return $this
|
180 |
+
* @deprecated 8.6.2
|
181 |
*/
|
182 |
public function clearLicenseData() {
|
183 |
return $this->setOpt( 'license_data', [] );
|
186 |
/**
|
187 |
* @param Utilities\Licenses\EddLicenseVO $oLic
|
188 |
* @return $this
|
189 |
+
* @deprecated 8.6.2
|
190 |
*/
|
191 |
protected function setLicenseData( $oLic ) {
|
192 |
return $this->setOpt( 'license_data', $oLic->getRawDataAsArray() );
|
194 |
|
195 |
/**
|
196 |
* @param string $sDeactivatedReason
|
197 |
+
* @deprecated 8.6.2
|
198 |
*/
|
199 |
public function deactivate( $sDeactivatedReason = '' ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
}
|
201 |
|
202 |
/**
|
204 |
* for a currently valid license.
|
205 |
* @param bool $bForceCheck
|
206 |
* @return $this
|
207 |
+
* @deprecated 8.6.2
|
208 |
*/
|
209 |
public function verifyLicense( $bForceCheck = true ) {
|
210 |
+
try {
|
211 |
+
$this->getLicenseHandler()->verify( $bForceCheck );
|
212 |
+
}
|
213 |
+
catch ( Exception $oE ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
}
|
|
|
215 |
return $this;
|
216 |
}
|
217 |
|
218 |
/**
|
219 |
* @return bool
|
220 |
+
* @deprecated 8.6.2
|
221 |
*/
|
222 |
private function isLicenseCheckRequired() {
|
223 |
+
return false;
|
|
|
|
|
|
|
|
|
224 |
}
|
225 |
|
226 |
/**
|
227 |
* @return bool
|
228 |
+
* @deprecated 8.6.2
|
229 |
*/
|
230 |
private function canLicenseCheck() {
|
231 |
+
return false;
|
|
|
232 |
}
|
233 |
|
234 |
/**
|
235 |
* @return bool
|
236 |
+
* @deprecated 8.6.2
|
237 |
*/
|
238 |
private function canLicenseCheck_FileFlag() {
|
239 |
+
return false;
|
|
|
|
|
|
|
240 |
}
|
241 |
|
242 |
/**
|
243 |
* @return $this
|
244 |
+
* @deprecated 8.6.2
|
245 |
*/
|
246 |
private function touchLicenseCheckFileFlag() {
|
247 |
Services::WpFs()->touch( $this->getCon()->getPath_Flags( 'license_check' ) );
|
250 |
|
251 |
/**
|
252 |
* @return bool
|
253 |
+
* @deprecated 8.6.2
|
254 |
*/
|
255 |
protected function isLicenseMaybeExpiring() {
|
256 |
+
return false;
|
|
|
|
|
|
|
|
|
257 |
}
|
258 |
|
259 |
/**
|
260 |
* @return $this
|
261 |
+
* @deprecated 8.6.2
|
262 |
*/
|
263 |
protected function activateLicense() {
|
|
|
|
|
|
|
264 |
return $this;
|
265 |
}
|
266 |
|
267 |
/**
|
268 |
+
* @deprecated 8.6.2
|
269 |
*/
|
270 |
protected function sendLicenseWarningEmail() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
}
|
272 |
|
273 |
/**
|
274 |
+
* @deprecated 8.6.2
|
275 |
*/
|
276 |
private function sendLicenseDeactivatedEmail() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
}
|
278 |
|
279 |
/**
|
280 |
* @return int
|
281 |
+
* @deprecated 8.6.2
|
282 |
*/
|
283 |
protected function getLicenseActivatedAt() {
|
284 |
return $this->getOpt( 'license_activated_at' );
|
286 |
|
287 |
/**
|
288 |
* @return int
|
289 |
+
* @deprecated 8.6.2
|
290 |
*/
|
291 |
protected function getLicenseDeactivatedAt() {
|
292 |
return $this->getOpt( 'license_deactivated_at' );
|
294 |
|
295 |
/**
|
296 |
* @return string
|
297 |
+
* @deprecated 8.6.2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
298 |
*/
|
299 |
public function getLicenseItemName() {
|
300 |
+
return $this->getLicenseHandler()->getLicense()->is_central ?
|
301 |
$this->getDef( 'license_item_name_sc' ) :
|
302 |
$this->getDef( 'license_item_name' );
|
303 |
}
|
304 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
/**
|
306 |
* @return int
|
307 |
+
* @deprecated 8.6.2
|
308 |
*/
|
309 |
protected function getLicenseLastCheckedAt() {
|
310 |
return $this->getOpt( 'license_last_checked_at' );
|
313 |
/**
|
314 |
* @param int $nTimePeriod
|
315 |
* @return bool
|
316 |
+
* @deprecated 8.6.2
|
317 |
*/
|
318 |
private function getIsLicenseNotCheckedFor( $nTimePeriod ) {
|
319 |
+
return false;
|
320 |
}
|
321 |
|
322 |
/**
|
323 |
* @return int
|
324 |
+
* @deprecated 8.6.2
|
325 |
*/
|
326 |
public function getLicenseNotCheckedForInterval() {
|
327 |
+
return 0;
|
328 |
}
|
329 |
|
330 |
/**
|
331 |
* @return bool
|
332 |
+
* @deprecated 8.6.2
|
333 |
*/
|
334 |
public function isLicenseActive() {
|
335 |
+
return $this->getLicenseHandler()->isActive();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
336 |
}
|
337 |
|
338 |
/**
|
344 |
* 4) the license hasn't expired
|
345 |
* 5) the time since the last check hasn't expired
|
346 |
* @return bool
|
347 |
+
* @deprecated 8.6.2
|
348 |
*/
|
349 |
public function hasValidWorkingLicense() {
|
350 |
+
return $this->getLicenseHandler()->hasValidWorkingLicense();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
351 |
}
|
352 |
|
353 |
/**
|
|
|
354 |
* @return bool
|
355 |
+
* @deprecated 8.6.2
|
356 |
*/
|
357 |
protected function isLastVerifiedExpired() {
|
358 |
+
return false;
|
|
|
359 |
}
|
360 |
|
361 |
/**
|
362 |
* @return bool
|
363 |
+
* @deprecated 8.6.2
|
364 |
*/
|
365 |
protected function isLastVerifiedGraceExpired() {
|
366 |
+
return false;
|
|
|
|
|
367 |
}
|
368 |
|
369 |
/**
|
370 |
* @return bool
|
371 |
+
* @deprecated 8.6.2
|
372 |
*/
|
373 |
protected function isWithinVerifiedGraceExpired() {
|
374 |
+
return false;
|
375 |
}
|
376 |
|
377 |
/**
|
378 |
* @param int $nAt
|
379 |
* @return $this
|
380 |
+
* @deprecated 8.6.2
|
381 |
*/
|
382 |
protected function setLicenseLastCheckedAt( $nAt = null ) {
|
|
|
383 |
return $this;
|
384 |
}
|
385 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
386 |
/**
|
387 |
* @return string
|
388 |
*/
|
src/features/login_protect.php
CHANGED
@@ -1,12 +1,19 @@
|
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
7 |
|
|
|
|
|
|
|
|
|
|
|
8 |
/**
|
9 |
* @return bool
|
|
|
10 |
*/
|
11 |
public function getIfUseLoginIntentPage() {
|
12 |
return $this->isOpt( 'use_login_intent_page', true );
|
@@ -41,9 +48,10 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
41 |
}
|
42 |
|
43 |
/**
|
|
|
44 |
*/
|
45 |
-
|
46 |
-
switch (
|
47 |
case 'email_send_verify':
|
48 |
$this->processEmailSendVerify();
|
49 |
break;
|
@@ -161,7 +169,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
161 |
* @param bool $bAsOptDefaults
|
162 |
* @return array
|
163 |
*/
|
164 |
-
|
165 |
$aTwoAuthRoles = [
|
166 |
'type' => 'multiple_select',
|
167 |
0 => __( 'Subscribers', 'wp-simple-firewall' ),
|
@@ -227,7 +235,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
227 |
}
|
228 |
|
229 |
/**
|
230 |
-
* @param WP_User $oUser
|
231 |
* @return bool
|
232 |
*/
|
233 |
public function canUserMfaSkip( $oUser ) {
|
@@ -294,7 +302,9 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
294 |
}
|
295 |
|
296 |
/**
|
297 |
-
*
|
|
|
|
|
298 |
*/
|
299 |
public function getMfaSkip() {
|
300 |
return (int)$this->getOpt( 'mfa_skip', 0 );
|
@@ -314,6 +324,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
314 |
|
315 |
/**
|
316 |
* @return bool
|
|
|
317 |
*/
|
318 |
public function isEmailAuthenticationOptionOn() {
|
319 |
return $this->isOpt( 'enable_email_authentication', 'Y' );
|
@@ -322,6 +333,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
322 |
/**
|
323 |
* Also considers whether email sending ability has been verified
|
324 |
* @return bool
|
|
|
325 |
*/
|
326 |
public function isEmailAuthenticationActive() {
|
327 |
return $this->getIfCanSendEmailVerified() && $this->isEmailAuthenticationOptionOn();
|
@@ -329,6 +341,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
329 |
|
330 |
/**
|
331 |
* @return bool
|
|
|
332 |
*/
|
333 |
public function isEnabledBackupCodes() {
|
334 |
return $this->isPremium() && $this->isOpt( 'allow_backupcodes', 'Y' );
|
@@ -336,6 +349,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
336 |
|
337 |
/**
|
338 |
* @return bool
|
|
|
339 |
*/
|
340 |
public function isEnabledGoogleAuthenticator() {
|
341 |
return $this->isOpt( 'enable_google_authenticator', 'Y' );
|
@@ -350,6 +364,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
350 |
|
351 |
/**
|
352 |
* @return int
|
|
|
353 |
*/
|
354 |
public function getCanSendEmailVerifiedAt() {
|
355 |
return $this->getOpt( 'email_can_send_verified_at' );
|
@@ -357,6 +372,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
357 |
|
358 |
/**
|
359 |
* @return bool
|
|
|
360 |
*/
|
361 |
public function getIfCanSendEmailVerified() {
|
362 |
return $this->getCanSendEmailVerifiedAt() > 0;
|
@@ -382,8 +398,20 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
382 |
return is_array( $aLocs ) ? $aLocs : (array)$this->getOptions()->getOptDefault( 'bot_protection_locations' );
|
383 |
}
|
384 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
385 |
/**
|
386 |
* @return bool
|
|
|
387 |
*/
|
388 |
public function isChainedAuth() {
|
389 |
return $this->isOpt( 'enable_chained_authentication', 'Y' );
|
@@ -402,14 +430,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
402 |
* @return $this
|
403 |
*/
|
404 |
public function setIfCanSendEmail( $bCan ) {
|
405 |
-
$
|
406 |
-
if ( $bCan ) {
|
407 |
-
$nDateAt = ( $nCurrentDateAt <= 0 ) ? Services::Request()->ts() : $nCurrentDateAt;
|
408 |
-
}
|
409 |
-
else {
|
410 |
-
$nDateAt = 0;
|
411 |
-
}
|
412 |
-
return $this->setOpt( 'email_can_send_verified_at', $nDateAt );
|
413 |
}
|
414 |
|
415 |
/**
|
@@ -518,6 +539,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
518 |
|
519 |
/**
|
520 |
* @return bool
|
|
|
521 |
*/
|
522 |
public function isYubikeyActive() {
|
523 |
return $this->isOpt( 'enable_yubikey', 'Y' ) && $this->isYubikeyConfigReady();
|
@@ -525,6 +547,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
525 |
|
526 |
/**
|
527 |
* @return bool
|
|
|
528 |
*/
|
529 |
private function isYubikeyConfigReady() {
|
530 |
$sAppId = $this->getOpt( 'yubikey_app_id' );
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
|
7 |
class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
8 |
|
9 |
+
/**
|
10 |
+
* @var LoginGuard\Lib\TwoFactor\MfaController
|
11 |
+
*/
|
12 |
+
private $oLoginIntentController;
|
13 |
+
|
14 |
/**
|
15 |
* @return bool
|
16 |
+
* @deprecated 8.6.0
|
17 |
*/
|
18 |
public function getIfUseLoginIntentPage() {
|
19 |
return $this->isOpt( 'use_login_intent_page', true );
|
48 |
}
|
49 |
|
50 |
/**
|
51 |
+
* @inheritDoc
|
52 |
*/
|
53 |
+
protected function handleModAction( $sAction ) {
|
54 |
+
switch ( $sAction ) {
|
55 |
case 'email_send_verify':
|
56 |
$this->processEmailSendVerify();
|
57 |
break;
|
169 |
* @param bool $bAsOptDefaults
|
170 |
* @return array
|
171 |
*/
|
172 |
+
public function getOptEmailTwoFactorRolesDefaults( $bAsOptDefaults = true ) {
|
173 |
$aTwoAuthRoles = [
|
174 |
'type' => 'multiple_select',
|
175 |
0 => __( 'Subscribers', 'wp-simple-firewall' ),
|
235 |
}
|
236 |
|
237 |
/**
|
238 |
+
* @param \WP_User $oUser
|
239 |
* @return bool
|
240 |
*/
|
241 |
public function canUserMfaSkip( $oUser ) {
|
302 |
}
|
303 |
|
304 |
/**
|
305 |
+
* NOTE: DO NOT REPLACE WITH OPTIONS USE AS THIS RETURNS DAYS
|
306 |
+
* @return int - days
|
307 |
+
* @deprecated 8.6.0
|
308 |
*/
|
309 |
public function getMfaSkip() {
|
310 |
return (int)$this->getOpt( 'mfa_skip', 0 );
|
324 |
|
325 |
/**
|
326 |
* @return bool
|
327 |
+
* @deprecated 8.6.0
|
328 |
*/
|
329 |
public function isEmailAuthenticationOptionOn() {
|
330 |
return $this->isOpt( 'enable_email_authentication', 'Y' );
|
333 |
/**
|
334 |
* Also considers whether email sending ability has been verified
|
335 |
* @return bool
|
336 |
+
* @deprecated 8.6.0
|
337 |
*/
|
338 |
public function isEmailAuthenticationActive() {
|
339 |
return $this->getIfCanSendEmailVerified() && $this->isEmailAuthenticationOptionOn();
|
341 |
|
342 |
/**
|
343 |
* @return bool
|
344 |
+
* @deprecated 8.6.0
|
345 |
*/
|
346 |
public function isEnabledBackupCodes() {
|
347 |
return $this->isPremium() && $this->isOpt( 'allow_backupcodes', 'Y' );
|
349 |
|
350 |
/**
|
351 |
* @return bool
|
352 |
+
* @deprecated 8.6.0
|
353 |
*/
|
354 |
public function isEnabledGoogleAuthenticator() {
|
355 |
return $this->isOpt( 'enable_google_authenticator', 'Y' );
|
364 |
|
365 |
/**
|
366 |
* @return int
|
367 |
+
* @deprecated 8.6.0
|
368 |
*/
|
369 |
public function getCanSendEmailVerifiedAt() {
|
370 |
return $this->getOpt( 'email_can_send_verified_at' );
|
372 |
|
373 |
/**
|
374 |
* @return bool
|
375 |
+
* @deprecated 8.6.0
|
376 |
*/
|
377 |
public function getIfCanSendEmailVerified() {
|
378 |
return $this->getCanSendEmailVerifiedAt() > 0;
|
398 |
return is_array( $aLocs ) ? $aLocs : (array)$this->getOptions()->getOptDefault( 'bot_protection_locations' );
|
399 |
}
|
400 |
|
401 |
+
/**
|
402 |
+
* @return LoginGuard\Lib\TwoFactor\MfaController
|
403 |
+
*/
|
404 |
+
public function getLoginIntentController() {
|
405 |
+
if ( !isset( $this->oLoginIntentController ) ) {
|
406 |
+
$this->oLoginIntentController = ( new LoginGuard\Lib\TwoFactor\MfaController() )
|
407 |
+
->setMod( $this );
|
408 |
+
}
|
409 |
+
return $this->oLoginIntentController;
|
410 |
+
}
|
411 |
+
|
412 |
/**
|
413 |
* @return bool
|
414 |
+
* @deprecated 8.6.0
|
415 |
*/
|
416 |
public function isChainedAuth() {
|
417 |
return $this->isOpt( 'enable_chained_authentication', 'Y' );
|
430 |
* @return $this
|
431 |
*/
|
432 |
public function setIfCanSendEmail( $bCan ) {
|
433 |
+
return $this->setOpt( 'email_can_send_verified_at', $bCan ? Services::Request()->ts() : 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
434 |
}
|
435 |
|
436 |
/**
|
539 |
|
540 |
/**
|
541 |
* @return bool
|
542 |
+
* @deprecated 8.6.0
|
543 |
*/
|
544 |
public function isYubikeyActive() {
|
545 |
return $this->isOpt( 'enable_yubikey', 'Y' ) && $this->isYubikeyConfigReady();
|
547 |
|
548 |
/**
|
549 |
* @return bool
|
550 |
+
* @deprecated 8.6.0
|
551 |
*/
|
552 |
private function isYubikeyConfigReady() {
|
553 |
$sAppId = $this->getOpt( 'yubikey_app_id' );
|
src/features/plugin.php
CHANGED
@@ -75,12 +75,6 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
75 |
&& ( Services::Request()->cookie( $this->getCookieIdBadgeState() ) != 'closed' );
|
76 |
}
|
77 |
|
78 |
-
public function runHourlyCron() {
|
79 |
-
( new Plugin\Lib\WpHashesTokenManager() )
|
80 |
-
->setMod( $this )
|
81 |
-
->getToken();
|
82 |
-
}
|
83 |
-
|
84 |
/**
|
85 |
* @param bool $bDisplay
|
86 |
* @return $this
|
@@ -118,9 +112,10 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
118 |
}
|
119 |
|
120 |
/**
|
|
|
121 |
*/
|
122 |
-
|
123 |
-
switch (
|
124 |
|
125 |
case 'export_file_download':
|
126 |
header( 'Set-Cookie: fileDownload=true; path=/' );
|
@@ -178,15 +173,6 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
178 |
return $aConfig;
|
179 |
}
|
180 |
|
181 |
-
/**
|
182 |
-
* @param bool $bGloballyDisabled
|
183 |
-
* @return bool
|
184 |
-
* @deprecated 8.5.7
|
185 |
-
*/
|
186 |
-
public function filter_IsPluginGloballyDisabled( $bGloballyDisabled ) {
|
187 |
-
return $bGloballyDisabled || !$this->isOpt( 'global_enable_plugin_features', 'Y' );
|
188 |
-
}
|
189 |
-
|
190 |
/**
|
191 |
* @return bool
|
192 |
*/
|
@@ -704,127 +690,10 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
704 |
return 'Plugin';
|
705 |
}
|
706 |
|
707 |
-
/**
|
708 |
-
* @return string
|
709 |
-
* @deprecated 8.5.2
|
710 |
-
*/
|
711 |
-
public function getVisitorAddressSource() {
|
712 |
-
return $this->getOptions()->getOpt( 'visitor_address_source' );
|
713 |
-
}
|
714 |
-
|
715 |
-
/**
|
716 |
-
* @return string
|
717 |
-
* @deprecated 8.5.2
|
718 |
-
*/
|
719 |
-
public function isVisitorAddressSourceAutoDetect() {
|
720 |
-
return $this->getVisitorAddressSource() == 'AUTO_DETECT_IP';
|
721 |
-
}
|
722 |
-
|
723 |
/**
|
724 |
* @return string
|
725 |
*/
|
726 |
public function getSurveyEmail() {
|
727 |
return base64_decode( $this->getDef( 'survey_email' ) );
|
728 |
}
|
729 |
-
|
730 |
-
/**
|
731 |
-
* @return bool
|
732 |
-
* @deprecated 8.5.2
|
733 |
-
*/
|
734 |
-
public function hasImportExportMasterImportUrl() {
|
735 |
-
/** @var Plugin\Options $oOpts */
|
736 |
-
$oOpts = $this->getOptions();
|
737 |
-
return $oOpts->hasImportExportMasterImportUrl();
|
738 |
-
}
|
739 |
-
|
740 |
-
/**
|
741 |
-
* @return int
|
742 |
-
* @deprecated 8.5.2
|
743 |
-
*/
|
744 |
-
public function getImportExportHandshakeExpiresAt() {
|
745 |
-
return $this->getOpt( 'importexport_handshake_expires_at', Services::Request()->ts() );
|
746 |
-
}
|
747 |
-
|
748 |
-
/**
|
749 |
-
* @return string
|
750 |
-
* @deprecated 8.5.2
|
751 |
-
*/
|
752 |
-
public function getImportExportMasterImportUrl() {
|
753 |
-
return $this->getOpt( 'importexport_masterurl', '' );
|
754 |
-
}
|
755 |
-
|
756 |
-
/**
|
757 |
-
* @return bool
|
758 |
-
* @deprecated 8.5.2
|
759 |
-
*/
|
760 |
-
public function isImportExportPermitted() {
|
761 |
-
return $this->isPremium() && $this->isOpt( 'importexport_enable', 'Y' );
|
762 |
-
}
|
763 |
-
|
764 |
-
/**
|
765 |
-
* @return bool
|
766 |
-
* @deprecated 8.5.2
|
767 |
-
*/
|
768 |
-
public function readyToSendTrackingData() {
|
769 |
-
return Services::Request()
|
770 |
-
->carbon()
|
771 |
-
->subWeek()->timestamp > (int)$this->getOptions()->getOpt( 'tracking_last_sent_at', 0 );
|
772 |
-
}
|
773 |
-
|
774 |
-
/**
|
775 |
-
* @return bool
|
776 |
-
* @deprecated 8.5.2
|
777 |
-
*/
|
778 |
-
public function isTrackingEnabled() {
|
779 |
-
return $this->isOpt( 'enable_tracking', 'Y' );
|
780 |
-
}
|
781 |
-
|
782 |
-
/**
|
783 |
-
* @return bool
|
784 |
-
* @deprecated 8.5.2
|
785 |
-
*/
|
786 |
-
public function isTrackingPermissionSet() {
|
787 |
-
return !$this->isOpt( 'tracking_permission_set_at', 0 );
|
788 |
-
}
|
789 |
-
|
790 |
-
/**
|
791 |
-
* @return $this
|
792 |
-
* @deprecated 8.5.2
|
793 |
-
*/
|
794 |
-
public function setTrackingLastSentAt() {
|
795 |
-
return $this->setOpt( 'tracking_last_sent_at', Services::Request()->ts() );
|
796 |
-
}
|
797 |
-
|
798 |
-
/**
|
799 |
-
* @return int
|
800 |
-
* @deprecated 8.5.2
|
801 |
-
*/
|
802 |
-
public function getTrackingLastSentAt() {
|
803 |
-
return (int)max( 0, $this->getOptions()->getOpt( 'tracking_last_sent_at', 0 ) );
|
804 |
-
}
|
805 |
-
|
806 |
-
/**
|
807 |
-
* @return int
|
808 |
-
* @deprecated 8.5.2
|
809 |
-
*/
|
810 |
-
public function getActivatedAt() {
|
811 |
-
return (int)$this->getOpt( 'activated_at', 0 );
|
812 |
-
}
|
813 |
-
|
814 |
-
/**
|
815 |
-
* @return string[]
|
816 |
-
* @deprecated 8.5.1
|
817 |
-
*/
|
818 |
-
public function getMyServerIPs() {
|
819 |
-
return Services::IP()->getServerPublicIPs();
|
820 |
-
}
|
821 |
-
|
822 |
-
/**
|
823 |
-
* @return string
|
824 |
-
* @deprecated 8.5
|
825 |
-
*/
|
826 |
-
public function getMyServerIp() {
|
827 |
-
$aIPs = $this->getMyServerIPs();
|
828 |
-
return array_shift( $aIPs );
|
829 |
-
}
|
830 |
}
|
75 |
&& ( Services::Request()->cookie( $this->getCookieIdBadgeState() ) != 'closed' );
|
76 |
}
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
/**
|
79 |
* @param bool $bDisplay
|
80 |
* @return $this
|
112 |
}
|
113 |
|
114 |
/**
|
115 |
+
* @inheritDoc
|
116 |
*/
|
117 |
+
protected function handleModAction( $sAction ) {
|
118 |
+
switch ( $sAction ) {
|
119 |
|
120 |
case 'export_file_download':
|
121 |
header( 'Set-Cookie: fileDownload=true; path=/' );
|
173 |
return $aConfig;
|
174 |
}
|
175 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
/**
|
177 |
* @return bool
|
178 |
*/
|
690 |
return 'Plugin';
|
691 |
}
|
692 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
693 |
/**
|
694 |
* @return string
|
695 |
*/
|
696 |
public function getSurveyEmail() {
|
697 |
return base64_decode( $this->getDef( 'survey_email' ) );
|
698 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
699 |
}
|
src/features/user_management.php
CHANGED
@@ -52,6 +52,21 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends \ICWP_WPSF_FeatureHandler_
|
|
52 |
$oOpts->getSuspendAutoIdleUserRoles()
|
53 |
) ) )
|
54 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
}
|
56 |
|
57 |
/**
|
@@ -75,37 +90,6 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends \ICWP_WPSF_FeatureHandler_
|
|
75 |
return $this->isPremium() && $this->isOpt( 'enable_user_login_email_notification', 'Y' );
|
76 |
}
|
77 |
|
78 |
-
/**
|
79 |
-
* @return int days
|
80 |
-
*/
|
81 |
-
public function getPassExpireDays() {
|
82 |
-
return ( $this->isPasswordPoliciesEnabled() && $this->isPremium() ) ? (int)$this->getOpt( 'pass_expire' ) : 0;
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* @return int seconds
|
87 |
-
* @deprecated 8.5.2
|
88 |
-
*/
|
89 |
-
public function getPassExpireTimeout() {
|
90 |
-
return $this->getPassExpireDays()*DAY_IN_SECONDS;
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* @return int
|
95 |
-
* @deprecated 8.5.2
|
96 |
-
*/
|
97 |
-
public function getPassMinLength() {
|
98 |
-
return $this->isPremium() ? (int)$this->getOpt( 'pass_min_length' ) : 0;
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* @return int
|
103 |
-
* @deprecated 8.5.2
|
104 |
-
*/
|
105 |
-
public function getPassMinStrength() {
|
106 |
-
return $this->isPremium() ? (int)$this->getOpt( 'pass_min_strength' ) : 0;
|
107 |
-
}
|
108 |
-
|
109 |
/**
|
110 |
* @param int $nStrength
|
111 |
* @return int
|
@@ -121,94 +105,6 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends \ICWP_WPSF_FeatureHandler_
|
|
121 |
return $aMap[ max( 0, min( 4, $nStrength ) ) ];
|
122 |
}
|
123 |
|
124 |
-
/**
|
125 |
-
* @return bool
|
126 |
-
* @deprecated 8.5.2
|
127 |
-
*/
|
128 |
-
public function isPasswordPoliciesEnabled() {
|
129 |
-
return $this->isOpt( 'enable_password_policies', 'Y' )
|
130 |
-
&& $this->getOptions()->isOptReqsMet( 'enable_password_policies' );
|
131 |
-
}
|
132 |
-
|
133 |
-
/**
|
134 |
-
* @return bool
|
135 |
-
* @deprecated 8.5.2
|
136 |
-
*/
|
137 |
-
public function isPassForceUpdateExisting() {
|
138 |
-
return $this->isOpt( 'pass_force_existing', 'Y' );
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* @return bool
|
143 |
-
* @deprecated 8.5.2
|
144 |
-
*/
|
145 |
-
public function isPassExpirationEnabled() {
|
146 |
-
return $this->isPasswordPoliciesEnabled() && ( $this->getPassExpireTimeout() > 0 );
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* @return bool
|
151 |
-
* @deprecated 8.5.2
|
152 |
-
*/
|
153 |
-
public function isPassPreventPwned() {
|
154 |
-
return $this->isOpt( 'pass_prevent_pwned', 'Y' );
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* @return bool
|
159 |
-
* @deprecated 8.5.2
|
160 |
-
*/
|
161 |
-
public function isSuspendEnabled() {
|
162 |
-
return $this->isPremium() &&
|
163 |
-
( $this->isSuspendManualEnabled()
|
164 |
-
|| $this->isSuspendAutoIdleEnabled()
|
165 |
-
|| $this->isSuspendAutoPasswordEnabled()
|
166 |
-
);
|
167 |
-
}
|
168 |
-
|
169 |
-
/**
|
170 |
-
* @return bool
|
171 |
-
* @deprecated 8.5.2
|
172 |
-
*/
|
173 |
-
public function isSuspendManualEnabled() {
|
174 |
-
return $this->isOpt( 'manual_suspend', 'Y' );
|
175 |
-
}
|
176 |
-
|
177 |
-
/**
|
178 |
-
* @return int
|
179 |
-
* @deprecated 8.5.2
|
180 |
-
*/
|
181 |
-
public function getSuspendAutoIdleTime() {
|
182 |
-
return $this->getOpt( 'auto_idle_days', 0 )*DAY_IN_SECONDS;
|
183 |
-
}
|
184 |
-
|
185 |
-
/**
|
186 |
-
* @return array
|
187 |
-
* @deprecated 8.5.2
|
188 |
-
*/
|
189 |
-
public function getSuspendAutoIdleUserRoles() {
|
190 |
-
$aRoles = $this->getOpt( 'auto_idle_roles', [] );
|
191 |
-
return is_array( $aRoles ) ? $aRoles : [];
|
192 |
-
}
|
193 |
-
|
194 |
-
/**
|
195 |
-
* @return bool
|
196 |
-
* @deprecated 8.5.2
|
197 |
-
*/
|
198 |
-
public function isSuspendAutoIdleEnabled() {
|
199 |
-
return ( $this->getSuspendAutoIdleTime() > 0 )
|
200 |
-
&& ( count( $this->getSuspendAutoIdleUserRoles() ) > 0 );
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* @return bool
|
205 |
-
* @deprecated 8.5.2
|
206 |
-
*/
|
207 |
-
public function isSuspendAutoPasswordEnabled() {
|
208 |
-
return $this->isOpt( 'auto_password', 'Y' )
|
209 |
-
&& $this->isPasswordPoliciesEnabled() && $this->getPassExpireTimeout();
|
210 |
-
}
|
211 |
-
|
212 |
/**
|
213 |
* @param int $nUserId
|
214 |
* @param bool $bAdd - set true to add, false to remove
|
@@ -268,6 +164,8 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends \ICWP_WPSF_FeatureHandler_
|
|
268 |
* @return array
|
269 |
*/
|
270 |
public function addInsightsNoticeData( $aAllNotices ) {
|
|
|
|
|
271 |
|
272 |
$aNotices = [
|
273 |
'title' => __( 'Users', 'wp-simple-firewall' ),
|
@@ -287,7 +185,7 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends \ICWP_WPSF_FeatureHandler_
|
|
287 |
}
|
288 |
|
289 |
{//password policies
|
290 |
-
if ( !$
|
291 |
$aNotices[ 'messages' ][ 'password' ] = [
|
292 |
'title' => __( 'Password Policies', 'wp-simple-firewall' ),
|
293 |
'message' => __( "Strong password policies are not enforced.", 'wp-simple-firewall' ),
|
@@ -347,9 +245,9 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends \ICWP_WPSF_FeatureHandler_
|
|
347 |
'href' => $this->getUrl_DirectLinkToOption( 'session_lock_location' ),
|
348 |
];
|
349 |
|
350 |
-
$bPolicies = $
|
351 |
|
352 |
-
$bPwned = $bPolicies && $
|
353 |
$aThis[ 'key_opts' ][ 'pwned' ] = [
|
354 |
'name' => __( 'Pwned Passwords', 'wp-simple-firewall' ),
|
355 |
'enabled' => $bPwned,
|
@@ -382,52 +280,4 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends \ICWP_WPSF_FeatureHandler_
|
|
382 |
protected function getNamespaceBase() {
|
383 |
return 'UserManagement';
|
384 |
}
|
385 |
-
|
386 |
-
/**
|
387 |
-
* @return int
|
388 |
-
* @deprecated 8.5
|
389 |
-
*/
|
390 |
-
public function getMaxSessionTime() {
|
391 |
-
/** @var UserManagement\Options $oOpts */
|
392 |
-
$oOpts = $this->getOptions();
|
393 |
-
return $oOpts->getMaxSessionTime();
|
394 |
-
}
|
395 |
-
|
396 |
-
/**
|
397 |
-
* @return int
|
398 |
-
* @deprecated 8.5
|
399 |
-
*/
|
400 |
-
public function getIdleTimeoutInterval() {
|
401 |
-
return $this->getOpt( 'session_idle_timeout_interval' )*HOUR_IN_SECONDS;
|
402 |
-
}
|
403 |
-
|
404 |
-
/**
|
405 |
-
* @return bool
|
406 |
-
* @deprecated 8.5
|
407 |
-
*/
|
408 |
-
public function hasMaxSessionTimeout() {
|
409 |
-
/** @var UserManagement\Options $oOpts */
|
410 |
-
$oOpts = $this->getOptions();
|
411 |
-
return $oOpts->hasMaxSessionTimeout();
|
412 |
-
}
|
413 |
-
|
414 |
-
/**
|
415 |
-
* @return bool
|
416 |
-
* @deprecated 8.5
|
417 |
-
*/
|
418 |
-
public function hasSessionIdleTimeout() {
|
419 |
-
/** @var UserManagement\Options $oOpts */
|
420 |
-
$oOpts = $this->getOptions();
|
421 |
-
return $oOpts->hasSessionIdleTimeout();
|
422 |
-
}
|
423 |
-
|
424 |
-
/**
|
425 |
-
* @return bool
|
426 |
-
* @deprecated 8.5
|
427 |
-
*/
|
428 |
-
public function isLockToIp() {
|
429 |
-
/** @var UserManagement\Options $oOpts */
|
430 |
-
$oOpts = $this->getOptions();
|
431 |
-
return $oOpts->isLockToIp();
|
432 |
-
}
|
433 |
}
|
52 |
$oOpts->getSuspendAutoIdleUserRoles()
|
53 |
) ) )
|
54 |
);
|
55 |
+
|
56 |
+
{
|
57 |
+
$aChecks = $oOpts->getEmailValidationChecks();
|
58 |
+
if ( !in_array( 'syntax', $aChecks ) ) {
|
59 |
+
$aChecks[] = 'syntax';
|
60 |
+
}
|
61 |
+
// fill in dependencies
|
62 |
+
if ( in_array( 'nondisposable', $aChecks ) && !in_array( 'mx', $aChecks ) ) {
|
63 |
+
$aChecks[] = 'mx';
|
64 |
+
}
|
65 |
+
if ( in_array( 'mx', $aChecks ) && !in_array( 'domain', $aChecks ) ) {
|
66 |
+
$aChecks[] = 'domain';
|
67 |
+
}
|
68 |
+
$oOpts->setOpt( 'email_checks', $aChecks );
|
69 |
+
}
|
70 |
}
|
71 |
|
72 |
/**
|
90 |
return $this->isPremium() && $this->isOpt( 'enable_user_login_email_notification', 'Y' );
|
91 |
}
|
92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
/**
|
94 |
* @param int $nStrength
|
95 |
* @return int
|
105 |
return $aMap[ max( 0, min( 4, $nStrength ) ) ];
|
106 |
}
|
107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
/**
|
109 |
* @param int $nUserId
|
110 |
* @param bool $bAdd - set true to add, false to remove
|
164 |
* @return array
|
165 |
*/
|
166 |
public function addInsightsNoticeData( $aAllNotices ) {
|
167 |
+
/** @var UserManagement\Options $oOpts */
|
168 |
+
$oOpts = $this->getOptions();
|
169 |
|
170 |
$aNotices = [
|
171 |
'title' => __( 'Users', 'wp-simple-firewall' ),
|
185 |
}
|
186 |
|
187 |
{//password policies
|
188 |
+
if ( !$oOpts->isPasswordPoliciesEnabled() ) {
|
189 |
$aNotices[ 'messages' ][ 'password' ] = [
|
190 |
'title' => __( 'Password Policies', 'wp-simple-firewall' ),
|
191 |
'message' => __( "Strong password policies are not enforced.", 'wp-simple-firewall' ),
|
245 |
'href' => $this->getUrl_DirectLinkToOption( 'session_lock_location' ),
|
246 |
];
|
247 |
|
248 |
+
$bPolicies = $oOpts->isPasswordPoliciesEnabled();
|
249 |
|
250 |
+
$bPwned = $bPolicies && $oOpts->isPassPreventPwned();
|
251 |
$aThis[ 'key_opts' ][ 'pwned' ] = [
|
252 |
'name' => __( 'Pwned Passwords', 'wp-simple-firewall' ),
|
253 |
'enabled' => $bPwned,
|
280 |
protected function getNamespaceBase() {
|
281 |
return 'UserManagement';
|
282 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
}
|
src/lib/src/Controller/Controller.php
CHANGED
@@ -410,9 +410,7 @@ class Controller extends Shield\Deprecated\Foundation {
|
|
410 |
/**
|
411 |
*/
|
412 |
public function onWpAdminInit() {
|
413 |
-
|
414 |
-
add_action( 'wp_dashboard_setup', [ $this, 'onWpDashboardSetup' ] );
|
415 |
-
}
|
416 |
add_action( 'admin_enqueue_scripts', [ $this, 'onWpEnqueueAdminCss' ], 100 );
|
417 |
add_action( 'admin_enqueue_scripts', [ $this, 'onWpEnqueueAdminJs' ], 5 );
|
418 |
|
@@ -452,18 +450,35 @@ class Controller extends Shield\Deprecated\Foundation {
|
|
452 |
}
|
453 |
|
454 |
/**
|
|
|
|
|
|
|
455 |
* @return string - the unique, never-changing site install ID.
|
456 |
*/
|
457 |
-
public function getSiteInstallationId() {
|
458 |
$sOptKey = $this->prefixOption( 'install_id' );
|
459 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
460 |
|
461 |
-
|
462 |
-
|
463 |
-
$
|
464 |
-
|
|
|
465 |
}
|
466 |
-
|
|
|
467 |
}
|
468 |
|
469 |
/**
|
@@ -483,7 +498,10 @@ class Controller extends Shield\Deprecated\Foundation {
|
|
483 |
/**
|
484 |
*/
|
485 |
public function onWpDashboardSetup() {
|
486 |
-
|
|
|
|
|
|
|
487 |
wp_add_dashboard_widget(
|
488 |
$this->prefix( 'dashboard_widget' ),
|
489 |
apply_filters( $this->prefix( 'dashboard_widget_title' ), $this->getHumanName() ),
|
@@ -494,12 +512,6 @@ class Controller extends Shield\Deprecated\Foundation {
|
|
494 |
}
|
495 |
}
|
496 |
|
497 |
-
/**
|
498 |
-
* @deprecated 8.5.7
|
499 |
-
*/
|
500 |
-
public function displayDashboardWidget() {
|
501 |
-
}
|
502 |
-
|
503 |
/**
|
504 |
* @return Shield\Utilities\AdminNotices\Controller
|
505 |
*/
|
@@ -526,12 +538,11 @@ class Controller extends Shield\Deprecated\Foundation {
|
|
526 |
$sNonceAction = Services::Request()->request( 'exec' );
|
527 |
check_ajax_referer( $sNonceAction, 'exec_nonce' );
|
528 |
|
529 |
-
$sAction = Services::WpUsers()->isUserLoggedIn() ? 'ajaxAuthAction' : 'ajaxNonAuthAction';
|
530 |
ob_start();
|
531 |
-
$aResponseData = apply_filters(
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
$sNoise = ob_get_clean();
|
536 |
|
537 |
if ( is_array( $aResponseData ) && isset( $aResponseData[ 'success' ] ) ) {
|
@@ -963,7 +974,7 @@ class Controller extends Shield\Deprecated\Foundation {
|
|
963 |
* Hooked to 'shutdown'
|
964 |
*/
|
965 |
public function onWpShutdown() {
|
966 |
-
$this->getSiteInstallationId();
|
967 |
do_action( $this->prefix( 'pre_plugin_shutdown' ) );
|
968 |
do_action( $this->prefix( 'plugin_shutdown' ) );
|
969 |
$this->saveCurrentPluginControllerOptions();
|
@@ -1632,11 +1643,12 @@ class Controller extends Shield\Deprecated\Foundation {
|
|
1632 |
* @return bool
|
1633 |
*/
|
1634 |
public function isPremiumActive() {
|
1635 |
-
return
|
1636 |
}
|
1637 |
|
1638 |
/**
|
1639 |
* @return string
|
|
|
1640 |
*/
|
1641 |
public function getPremiumLicenseFilterName() {
|
1642 |
return $this->prefix( 'license_is_valid'.$this->getUniqueRequestId( false ) );
|
410 |
/**
|
411 |
*/
|
412 |
public function onWpAdminInit() {
|
413 |
+
add_action( 'wp_dashboard_setup', [ $this, 'onWpDashboardSetup' ] );
|
|
|
|
|
414 |
add_action( 'admin_enqueue_scripts', [ $this, 'onWpEnqueueAdminCss' ], 100 );
|
415 |
add_action( 'admin_enqueue_scripts', [ $this, 'onWpEnqueueAdminJs' ], 5 );
|
416 |
|
450 |
}
|
451 |
|
452 |
/**
|
453 |
+
* Only set to rebuild as required if you're doing so at the same point in the WordPress load each time.
|
454 |
+
* Certain plugins can modify the ID at different points in the load.
|
455 |
+
* @param bool $bRebuildIfRequired
|
456 |
* @return string - the unique, never-changing site install ID.
|
457 |
*/
|
458 |
+
public function getSiteInstallationId( $bRebuildIfRequired = false ) {
|
459 |
$sOptKey = $this->prefixOption( 'install_id' );
|
460 |
+
$aID = Services::WpGeneral()->getOption( $sOptKey );
|
461 |
+
|
462 |
+
$aPossibleUniqs = [
|
463 |
+
'url' => Services::Data()->urlStripSchema( Services::WpGeneral()->getHomeUrl( '', true ) ),
|
464 |
+
'server' => Services::Data()->getServerHash(),
|
465 |
+
];
|
466 |
+
|
467 |
+
if ( !is_array( $aID ) ) {
|
468 |
+
$aID = [
|
469 |
+
'uniqs' => $aPossibleUniqs,
|
470 |
+
'id' => ( is_string( $aID ) && strpos( $aID, ':' ) ) ? explode( ':', $aID, 2 )[ 1 ] : ''
|
471 |
+
];
|
472 |
+
}
|
473 |
|
474 |
+
if ( empty( $aID[ 'id' ] ) || empty( $aID[ 'uniqs' ] ) ||
|
475 |
+
( $bRebuildIfRequired && count( array_intersect( $aPossibleUniqs, $aID[ 'uniqs' ] ) ) === 0 ) ) {
|
476 |
+
$aID[ 'id' ] = sha1( uniqid( Services::WpGeneral()->getHomeUrl( '', true ), true ) );
|
477 |
+
$aID[ 'uniqs' ] = $aPossibleUniqs;
|
478 |
+
Services::WpGeneral()->updateOption( $sOptKey, $aID );
|
479 |
}
|
480 |
+
|
481 |
+
return $aID[ 'id' ];
|
482 |
}
|
483 |
|
484 |
/**
|
498 |
/**
|
499 |
*/
|
500 |
public function onWpDashboardSetup() {
|
501 |
+
$bShow = apply_filters( $this->prefix( 'show_dashboard_widget' ),
|
502 |
+
$this->isValidAdminArea() && (bool)$this->getPluginSpec_Property( 'show_dashboard_widget' )
|
503 |
+
);
|
504 |
+
if ( $bShow ) {
|
505 |
wp_add_dashboard_widget(
|
506 |
$this->prefix( 'dashboard_widget' ),
|
507 |
apply_filters( $this->prefix( 'dashboard_widget_title' ), $this->getHumanName() ),
|
512 |
}
|
513 |
}
|
514 |
|
|
|
|
|
|
|
|
|
|
|
|
|
515 |
/**
|
516 |
* @return Shield\Utilities\AdminNotices\Controller
|
517 |
*/
|
538 |
$sNonceAction = Services::Request()->request( 'exec' );
|
539 |
check_ajax_referer( $sNonceAction, 'exec_nonce' );
|
540 |
|
|
|
541 |
ob_start();
|
542 |
+
$aResponseData = apply_filters(
|
543 |
+
$this->prefix( Services::WpUsers()->isUserLoggedIn() ? 'ajaxAuthAction' : 'ajaxNonAuthAction' ),
|
544 |
+
[], $sNonceAction
|
545 |
+
);
|
546 |
$sNoise = ob_get_clean();
|
547 |
|
548 |
if ( is_array( $aResponseData ) && isset( $aResponseData[ 'success' ] ) ) {
|
974 |
* Hooked to 'shutdown'
|
975 |
*/
|
976 |
public function onWpShutdown() {
|
977 |
+
$this->getSiteInstallationId( true );
|
978 |
do_action( $this->prefix( 'pre_plugin_shutdown' ) );
|
979 |
do_action( $this->prefix( 'plugin_shutdown' ) );
|
980 |
$this->saveCurrentPluginControllerOptions();
|
1643 |
* @return bool
|
1644 |
*/
|
1645 |
public function isPremiumActive() {
|
1646 |
+
return $this->getModule_License()->getLicenseHandler()->hasValidWorkingLicense();
|
1647 |
}
|
1648 |
|
1649 |
/**
|
1650 |
* @return string
|
1651 |
+
* @deprecated 8.6.2
|
1652 |
*/
|
1653 |
public function getPremiumLicenseFilterName() {
|
1654 |
return $this->prefix( 'license_is_valid'.$this->getUniqueRequestId( false ) );
|
src/lib/src/Crons/BaseCron.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Crons;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
|
7 |
+
abstract class BaseCron {
|
8 |
+
|
9 |
+
use Shield\Crons\StandardCron;
|
10 |
+
use Shield\Modules\ModConsumer;
|
11 |
+
|
12 |
+
/**
|
13 |
+
*/
|
14 |
+
public function run() {
|
15 |
+
$this->setupCron();
|
16 |
+
}
|
17 |
+
}
|
src/lib/src/Crons/DailyCron.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Crons;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
|
7 |
+
class DailyCron extends BaseCron {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return string
|
11 |
+
*/
|
12 |
+
protected function getCronFrequency() {
|
13 |
+
return 'daily';
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return string
|
18 |
+
* @throws \Exception
|
19 |
+
*/
|
20 |
+
protected function getCronName() {
|
21 |
+
return $this->getCon()->prefix( 'daily' );
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Use the included action to hook into the plugin's daily cron
|
26 |
+
*/
|
27 |
+
public function runCron() {
|
28 |
+
do_action( $this->getCon()->prefix( 'daily_cron' ) );
|
29 |
+
}
|
30 |
+
}
|
src/lib/src/Crons/HourlyCron.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Crons;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
|
7 |
+
class HourlyCron extends BaseCron {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return string
|
11 |
+
*/
|
12 |
+
protected function getCronFrequency() {
|
13 |
+
return 'hourly';
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return string
|
18 |
+
* @throws \Exception
|
19 |
+
*/
|
20 |
+
protected function getCronName() {
|
21 |
+
return $this->getCon()->prefix( 'hourly' );
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Use the included action to hook into the plugin's daily cron
|
26 |
+
*/
|
27 |
+
public function runCron() {
|
28 |
+
do_action( $this->getCon()->prefix( 'hourly_cron' ) );
|
29 |
+
}
|
30 |
+
}
|
src/lib/src/Databases/AuditTrail/Handler.php
CHANGED
@@ -54,18 +54,4 @@ class Handler extends Base\Handler {
|
|
54 |
PRIMARY KEY (id)
|
55 |
) %s;";
|
56 |
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* @param EntryVO[] $aEvents - array of events: key event slug, value created_at timestamp
|
60 |
-
* @deprecated 8.5
|
61 |
-
*/
|
62 |
-
public function commitAudits( $aEvents ) {
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* @param EntryVO $oEntry
|
67 |
-
* @deprecated 8.5
|
68 |
-
*/
|
69 |
-
public function commitAudit( $oEntry ) {
|
70 |
-
}
|
71 |
}
|
54 |
PRIMARY KEY (id)
|
55 |
) %s;";
|
56 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
src/lib/src/Databases/Base/BaseQuery.php
CHANGED
@@ -32,12 +32,6 @@ abstract class BaseQuery {
|
|
32 |
*/
|
33 |
protected $nPage;
|
34 |
|
35 |
-
/**
|
36 |
-
* @var string
|
37 |
-
* @deprecated 8.5
|
38 |
-
*/
|
39 |
-
protected $sOrderBy;
|
40 |
-
|
41 |
/**
|
42 |
* @var array
|
43 |
*/
|
@@ -480,12 +474,4 @@ abstract class BaseQuery {
|
|
480 |
[ '=', '<', '>', '!=', '<>', '<=', '>=', '<=>', 'IN', 'LIKE', 'NOT LIKE' ]
|
481 |
);
|
482 |
}
|
483 |
-
|
484 |
-
/**
|
485 |
-
* @return string
|
486 |
-
* @deprecated 8.5
|
487 |
-
*/
|
488 |
-
public function getOrderBy() {
|
489 |
-
return '';
|
490 |
-
}
|
491 |
}
|
32 |
*/
|
33 |
protected $nPage;
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
/**
|
36 |
* @var array
|
37 |
*/
|
474 |
[ '=', '<', '>', '!=', '<>', '<=', '>=', '<=>', 'IN', 'LIKE', 'NOT LIKE' ]
|
475 |
);
|
476 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
477 |
}
|
src/lib/src/Databases/IPs/EntryVO.php
CHANGED
@@ -16,43 +16,4 @@ use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
|
|
16 |
*/
|
17 |
class EntryVO extends Base\EntryVO {
|
18 |
|
19 |
-
/**
|
20 |
-
* @return string
|
21 |
-
* @deprecated 8.5
|
22 |
-
*/
|
23 |
-
public function getLabel() {
|
24 |
-
return (string)$this->label;
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @return int
|
29 |
-
* @deprecated 8.5
|
30 |
-
*/
|
31 |
-
public function getLastAccessAt() {
|
32 |
-
return (int)$this->last_access_at;
|
33 |
-
}
|
34 |
-
|
35 |
-
/**
|
36 |
-
* @return string
|
37 |
-
* @deprecated 8.5
|
38 |
-
*/
|
39 |
-
public function getList() {
|
40 |
-
return (string)$this->list;
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* @return int
|
45 |
-
* @deprecated 8.5
|
46 |
-
*/
|
47 |
-
public function getTransgressions() {
|
48 |
-
return (int)$this->transgressions;
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* @return bool
|
53 |
-
* @deprecated 8.5
|
54 |
-
*/
|
55 |
-
public function hasTransgressions() {
|
56 |
-
return (int)$this->transgressions > 0;
|
57 |
-
}
|
58 |
}
|
16 |
*/
|
17 |
class EntryVO extends Base\EntryVO {
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
}
|
src/lib/src/Databases/IPs/Select.php
CHANGED
@@ -7,47 +7,4 @@ use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
|
|
7 |
class Select extends Base\Select {
|
8 |
|
9 |
use CommonFilters;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @param string $sIp
|
13 |
-
* @return bool
|
14 |
-
* @deprecated 8.5
|
15 |
-
*/
|
16 |
-
public function getIpOnBlackLists( $sIp ) {
|
17 |
-
return $this->reset()
|
18 |
-
->filterByIp( $sIp )
|
19 |
-
->filterByBlacklist()
|
20 |
-
->first();
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @return EntryVO[]
|
25 |
-
*/
|
26 |
-
public function getAllBlocked() {
|
27 |
-
/** @var EntryVO[] $aRes */
|
28 |
-
return $this->reset()
|
29 |
-
->filterByBlocked( true )
|
30 |
-
->filterByBlacklist()
|
31 |
-
->query();
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @param string $sList
|
36 |
-
* @return EntryVO[]
|
37 |
-
* @deprecated 8.5
|
38 |
-
*/
|
39 |
-
public function allFromList( $sList ) {
|
40 |
-
/** @var EntryVO[] $aRes */
|
41 |
-
return $this->reset()
|
42 |
-
->filterByList( $sList )
|
43 |
-
->query();
|
44 |
-
}
|
45 |
-
|
46 |
-
/**
|
47 |
-
* @return string[]
|
48 |
-
* @deprecated 8.5
|
49 |
-
*/
|
50 |
-
public function getDistinctIps() {
|
51 |
-
return $this->getDistinct_FilterAndSort( 'ip' );
|
52 |
-
}
|
53 |
}
|
7 |
class Select extends Base\Select {
|
8 |
|
9 |
use CommonFilters;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
}
|
src/lib/src/Deprecated/Foundation.php
CHANGED
@@ -19,30 +19,6 @@ class Foundation {
|
|
19 |
return self::DEFAULT_SERVICE_PREFIX.$sSuffix;
|
20 |
}
|
21 |
|
22 |
-
/**
|
23 |
-
* @return \ICWP_WPSF_WpCron
|
24 |
-
* @deprecated 8.5
|
25 |
-
*/
|
26 |
-
public static function loadWpCronProcessor() {
|
27 |
-
$sKey = 'icwp-wpcron';
|
28 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
29 |
-
self::setService( $sKey, \ICWP_WPSF_WpCron::GetInstance() );
|
30 |
-
}
|
31 |
-
return self::getService( $sKey );
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @return \ICWP_WPSF_ServiceProviders
|
36 |
-
* @deprecated 8.5.2
|
37 |
-
*/
|
38 |
-
public function loadServiceProviders() {
|
39 |
-
$sKey = 'icwp-serviceproviders';
|
40 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
41 |
-
self::setService( $sKey, \ICWP_WPSF_ServiceProviders::GetInstance() );
|
42 |
-
}
|
43 |
-
return self::getService( $sKey );
|
44 |
-
}
|
45 |
-
|
46 |
/**
|
47 |
* @return array
|
48 |
*/
|
19 |
return self::DEFAULT_SERVICE_PREFIX.$sSuffix;
|
20 |
}
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
/**
|
23 |
* @return array
|
24 |
*/
|
src/lib/src/License/EddLicenseVO.php
CHANGED
@@ -9,5 +9,4 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\License;
|
|
9 |
*/
|
10 |
class EddLicenseVO extends \FernleafSystems\Wordpress\Services\Utilities\Licenses\EddLicenseVO {
|
11 |
|
12 |
-
use \FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
|
13 |
}
|
9 |
*/
|
10 |
class EddLicenseVO extends \FernleafSystems\Wordpress\Services\Utilities\Licenses\EddLicenseVO {
|
11 |
|
|
|
12 |
}
|
src/lib/src/Modules/Autoupdates/Strings.php
CHANGED
@@ -113,7 +113,7 @@ class Strings extends Base\Strings {
|
|
113 |
$sDescription = __( 'At least automatically upgrading minor versions is recommended (and is the WordPress default).', 'wp-simple-firewall' );
|
114 |
break;
|
115 |
|
116 |
-
case 'enable_autoupdate_translations' :
|
117 |
$sName = __( 'Translations', 'wp-simple-firewall' );
|
118 |
$sSummary = __( 'Automatically Update Translations', 'wp-simple-firewall' );
|
119 |
$sDescription = __( 'Note: Automatic updates for translations are enabled on WordPress by default.', 'wp-simple-firewall' );
|
@@ -137,7 +137,7 @@ class Strings extends Base\Strings {
|
|
137 |
$sDescription = __( 'Note: Automatic updates for themes are disabled on WordPress by default.', 'wp-simple-firewall' );
|
138 |
break;
|
139 |
|
140 |
-
case 'enable_autoupdate_ignore_vcs' :
|
141 |
$sName = __( 'Ignore Version Control', 'wp-simple-firewall' );
|
142 |
$sSummary = __( 'Ignore Version Control Systems Such As GIT and SVN', 'wp-simple-firewall' );
|
143 |
$sDescription = __( 'If you use SVN or GIT and WordPress detects it, automatic updates are disabled by default. Check this box to ignore version control systems and allow automatic updates.', 'wp-simple-firewall' );
|
113 |
$sDescription = __( 'At least automatically upgrading minor versions is recommended (and is the WordPress default).', 'wp-simple-firewall' );
|
114 |
break;
|
115 |
|
116 |
+
case 'enable_autoupdate_translations' : // REMOVED 8.6.2
|
117 |
$sName = __( 'Translations', 'wp-simple-firewall' );
|
118 |
$sSummary = __( 'Automatically Update Translations', 'wp-simple-firewall' );
|
119 |
$sDescription = __( 'Note: Automatic updates for translations are enabled on WordPress by default.', 'wp-simple-firewall' );
|
137 |
$sDescription = __( 'Note: Automatic updates for themes are disabled on WordPress by default.', 'wp-simple-firewall' );
|
138 |
break;
|
139 |
|
140 |
+
case 'enable_autoupdate_ignore_vcs' : // REMOVED 8.6.2
|
141 |
$sName = __( 'Ignore Version Control', 'wp-simple-firewall' );
|
142 |
$sSummary = __( 'Ignore Version Control Systems Such As GIT and SVN', 'wp-simple-firewall' );
|
143 |
$sDescription = __( 'If you use SVN or GIT and WordPress detects it, automatic updates are disabled by default. Check this box to ignore version control systems and allow automatic updates.', 'wp-simple-firewall' );
|
src/lib/src/Modules/Base/AjaxHandlerBase.php
CHANGED
@@ -16,20 +16,28 @@ class AjaxHandlerBase {
|
|
16 |
/**
|
17 |
*/
|
18 |
public function init() {
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
}
|
|
|
25 |
}
|
26 |
|
27 |
/**
|
28 |
-
* @param array
|
|
|
29 |
* @return array
|
30 |
*/
|
31 |
-
public function
|
32 |
-
$sAjaxAction = Services::Request()->request( 'exec' );
|
33 |
if ( !empty( $sAjaxAction ) && ( empty( $aAjaxResponse ) || !is_array( $aAjaxResponse ) ) ) {
|
34 |
$aAjaxResponse = $this->normaliseAjaxResponse( $this->processAjaxAction( $sAjaxAction ) );
|
35 |
}
|
@@ -40,7 +48,7 @@ class AjaxHandlerBase {
|
|
40 |
* @param string $sEncoding
|
41 |
* @return array
|
42 |
*/
|
43 |
-
|
44 |
$oReq = Services::Request();
|
45 |
$aFormParams = [];
|
46 |
$sRaw = $oReq->post( 'form_params', '' );
|
16 |
/**
|
17 |
*/
|
18 |
public function init() {
|
19 |
+
add_filter( $this->getCon()->prefix( 'ajaxAuthAction' ), [ $this, 'handleAjaxAuth' ], 10, 2 );
|
20 |
+
add_filter( $this->getCon()->prefix( 'ajaxNonAuthAction' ), [ $this, 'handleAjaxNonAuth' ], 10, 2 );
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @param array $aAjaxResponse
|
25 |
+
* @param string $sAjaxAction
|
26 |
+
* @return array
|
27 |
+
*/
|
28 |
+
public function handleAjaxAuth( $aAjaxResponse, $sAjaxAction ) {
|
29 |
+
if ( !empty( $sAjaxAction ) && ( empty( $aAjaxResponse ) || !is_array( $aAjaxResponse ) ) ) {
|
30 |
+
$aAjaxResponse = $this->normaliseAjaxResponse( $this->processAjaxAction( $sAjaxAction ) );
|
31 |
}
|
32 |
+
return $aAjaxResponse;
|
33 |
}
|
34 |
|
35 |
/**
|
36 |
+
* @param array $aAjaxResponse
|
37 |
+
* @param string $sAjaxAction
|
38 |
* @return array
|
39 |
*/
|
40 |
+
public function handleAjaxNonAuth( $aAjaxResponse, $sAjaxAction ) {
|
|
|
41 |
if ( !empty( $sAjaxAction ) && ( empty( $aAjaxResponse ) || !is_array( $aAjaxResponse ) ) ) {
|
42 |
$aAjaxResponse = $this->normaliseAjaxResponse( $this->processAjaxAction( $sAjaxAction ) );
|
43 |
}
|
48 |
* @param string $sEncoding
|
49 |
* @return array
|
50 |
*/
|
51 |
+
protected function getAjaxFormParams( $sEncoding = 'none' ) {
|
52 |
$oReq = Services::Request();
|
53 |
$aFormParams = [];
|
54 |
$sRaw = $oReq->post( 'form_params', '' );
|
src/lib/src/Modules/Base/AjaxHandlerShield.php
CHANGED
@@ -2,8 +2,6 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Services\Services;
|
6 |
-
|
7 |
class AjaxHandlerShield extends AjaxHandlerBase {
|
8 |
|
9 |
/**
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
4 |
|
|
|
|
|
5 |
class AjaxHandlerShield extends AjaxHandlerBase {
|
6 |
|
7 |
/**
|
src/lib/src/Modules/Base/BaseProcessor.php
CHANGED
@@ -141,6 +141,7 @@ class BaseProcessor extends Deprecated\Foundation {
|
|
141 |
* @param $sOptionKey
|
142 |
* @param mixed $mDefault
|
143 |
* @return mixed
|
|
|
144 |
*/
|
145 |
public function getOption( $sOptionKey, $mDefault = false ) {
|
146 |
return $this->getMod()->getOpt( $sOptionKey, $mDefault );
|
141 |
* @param $sOptionKey
|
142 |
* @param mixed $mDefault
|
143 |
* @return mixed
|
144 |
+
* @deprecated 8.6.2 - leave for a while JIC.
|
145 |
*/
|
146 |
public function getOption( $sOptionKey, $mDefault = false ) {
|
147 |
return $this->getMod()->getOpt( $sOptionKey, $mDefault );
|
src/lib/src/Modules/Base/Options.php
CHANGED
@@ -1015,7 +1015,9 @@ class Options {
|
|
1015 |
* @return string
|
1016 |
*/
|
1017 |
private function getConfigStorageKey() {
|
1018 |
-
return 'shield_mod_config_'.md5(
|
|
|
|
|
1019 |
}
|
1020 |
|
1021 |
/**
|
1015 |
* @return string
|
1016 |
*/
|
1017 |
private function getConfigStorageKey() {
|
1018 |
+
return 'shield_mod_config_'.md5(
|
1019 |
+
str_replace( wp_normalize_path( ABSPATH ), '', wp_normalize_path( $this->getPathToConfig() ) )
|
1020 |
+
);
|
1021 |
}
|
1022 |
|
1023 |
/**
|
src/lib/src/Modules/Base/Strings.php
CHANGED
@@ -56,6 +56,7 @@ class Strings {
|
|
56 |
'actions_summary' => __( 'Perform actions for this module', 'wp-simple-firewall' ),
|
57 |
'help_title' => __( 'Help', 'wp-simple-firewall' ),
|
58 |
'help_summary' => __( 'Learn More', 'wp-simple-firewall' ),
|
|
|
59 |
'ip_address' => __( 'IP Address', 'wp-simple-firewall' ),
|
60 |
'select' => __( 'Select' ),
|
61 |
'filters_clear' => __( 'Clear Filters', 'wp-simple-firewall' ),
|
@@ -96,6 +97,8 @@ class Strings {
|
|
96 |
'get_pro_protection' => __( 'Upgrade To Pro Protection', 'wp-simple-firewall' ),
|
97 |
|
98 |
'page_title' => 'Twig Page',
|
|
|
|
|
99 |
],
|
100 |
$this->getAdditionalDisplayStrings()
|
101 |
);
|
56 |
'actions_summary' => __( 'Perform actions for this module', 'wp-simple-firewall' ),
|
57 |
'help_title' => __( 'Help', 'wp-simple-firewall' ),
|
58 |
'help_summary' => __( 'Learn More', 'wp-simple-firewall' ),
|
59 |
+
'installation_id' => __( 'Installation ID', 'wp-simple-firewall' ),
|
60 |
'ip_address' => __( 'IP Address', 'wp-simple-firewall' ),
|
61 |
'select' => __( 'Select' ),
|
62 |
'filters_clear' => __( 'Clear Filters', 'wp-simple-firewall' ),
|
97 |
'get_pro_protection' => __( 'Upgrade To Pro Protection', 'wp-simple-firewall' ),
|
98 |
|
99 |
'page_title' => 'Twig Page',
|
100 |
+
|
101 |
+
'wphashes_token' => 'WPHashes.com API Token',
|
102 |
],
|
103 |
$this->getAdditionalDisplayStrings()
|
104 |
);
|
src/lib/src/Modules/CommentsFilter/Options.php
CHANGED
@@ -20,6 +20,13 @@ class Options extends Base\ShieldOptions {
|
|
20 |
return $this->getCon()->prefixOption( $this->getDef( 'spambot_comments_filter_table_name' ) );
|
21 |
}
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
/**
|
24 |
* @return int
|
25 |
*/
|
20 |
return $this->getCon()->prefixOption( $this->getDef( 'spambot_comments_filter_table_name' ) );
|
21 |
}
|
22 |
|
23 |
+
/**
|
24 |
+
* @return int
|
25 |
+
*/
|
26 |
+
public function getTokenCooldown() {
|
27 |
+
return (int)$this->getOpt( 'comments_cooldown_interval' );
|
28 |
+
}
|
29 |
+
|
30 |
/**
|
31 |
* @return int
|
32 |
*/
|
src/lib/src/Modules/CommentsFilter/Scan/Bot.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter\Scan;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
@@ -14,8 +15,8 @@ class Bot {
|
|
14 |
* @return true|\WP_Error
|
15 |
*/
|
16 |
public function scan( $nPostId ) {
|
17 |
-
/** @var \
|
18 |
-
$
|
19 |
|
20 |
$oReq = Services::Request();
|
21 |
$sFieldCheckboxName = $oReq->post( 'cb_nombre' );
|
@@ -23,8 +24,8 @@ class Bot {
|
|
23 |
$nCommentTs = (int)$oReq->post( 'botts' );
|
24 |
$sCommentToken = $oReq->post( 'comment_token' );
|
25 |
|
26 |
-
$nCooldown = $
|
27 |
-
$nExpire = $
|
28 |
|
29 |
$sKey = null;
|
30 |
$sExplanation = null;
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter\Scan;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
15 |
* @return true|\WP_Error
|
16 |
*/
|
17 |
public function scan( $nPostId ) {
|
18 |
+
/** @var CommentsFilter\Options $oOpts */
|
19 |
+
$oOpts = $this->getOptions();
|
20 |
|
21 |
$oReq = Services::Request();
|
22 |
$sFieldCheckboxName = $oReq->post( 'cb_nombre' );
|
24 |
$nCommentTs = (int)$oReq->post( 'botts' );
|
25 |
$sCommentToken = $oReq->post( 'comment_token' );
|
26 |
|
27 |
+
$nCooldown = $oOpts->getTokenCooldown();
|
28 |
+
$nExpire = $oOpts->getTokenExpireInterval();
|
29 |
|
30 |
$sKey = null;
|
31 |
$sExplanation = null;
|
src/lib/src/Modules/CommentsFilter/Token/Create.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter\Token;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
@@ -15,15 +16,15 @@ class Create {
|
|
15 |
* @return string
|
16 |
*/
|
17 |
public function run( $nTs, $nPostId ) {
|
18 |
-
/** @var \
|
19 |
-
$
|
20 |
|
21 |
$sToken = $this->generateNewToken( $nTs, $nPostId );
|
22 |
|
23 |
Services::WpGeneral()->setTransient(
|
24 |
-
$
|
25 |
$sToken,
|
26 |
-
$
|
27 |
);
|
28 |
|
29 |
return $sToken;
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter\Token;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
16 |
* @return string
|
17 |
*/
|
18 |
public function run( $nTs, $nPostId ) {
|
19 |
+
/** @var CommentsFilter\Options $oOpts */
|
20 |
+
$oOpts = $this->getOptions();
|
21 |
|
22 |
$sToken = $this->generateNewToken( $nTs, $nPostId );
|
23 |
|
24 |
Services::WpGeneral()->setTransient(
|
25 |
+
$this->getCon()->prefix( 'comtok-'.md5( sprintf( '%s-%s-%s', $nPostId, $nTs, Services::IP()->getRequestIp() ) ) ),
|
26 |
$sToken,
|
27 |
+
$oOpts->getTokenExpireInterval()
|
28 |
);
|
29 |
|
30 |
return $sToken;
|
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BuildAll.php
DELETED
@@ -1,53 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\FindAssetsToSnap;
|
6 |
-
use FernleafSystems\Wordpress\Services\Core\VOs;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Class BuildAll
|
10 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction
|
11 |
-
* @deprecated 8.5.2
|
12 |
-
*/
|
13 |
-
class BuildAll extends BaseBulk {
|
14 |
-
|
15 |
-
public function build() {
|
16 |
-
foreach ( $this->getAssetsThatNeedBuilt() as $oAsset ) {
|
17 |
-
try {
|
18 |
-
( new Build() )
|
19 |
-
->setMod( $this->getMod() )
|
20 |
-
->setAsset( $oAsset )
|
21 |
-
->run();
|
22 |
-
}
|
23 |
-
catch ( \Exception $oE ) {
|
24 |
-
}
|
25 |
-
}
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Only those that don't have a meta file or the versions are different
|
30 |
-
* @return VOs\WpPluginVo[]|VOs\WpThemeVo[]
|
31 |
-
*/
|
32 |
-
private function getAssetsThatNeedBuilt() {
|
33 |
-
return array_filter(
|
34 |
-
( new FindAssetsToSnap() )
|
35 |
-
->setMod( $this->getMod() )
|
36 |
-
->run(),
|
37 |
-
function ( $oAsset ) {
|
38 |
-
/** @var VOs\WpPluginVo|VOs\WpThemeVo $oAsset */
|
39 |
-
try {
|
40 |
-
$aMeta = ( new Load() )
|
41 |
-
->setMod( $this->getMod() )
|
42 |
-
->setAsset( $oAsset )
|
43 |
-
->run()
|
44 |
-
->getSnapMeta();
|
45 |
-
}
|
46 |
-
catch ( \Exception $oE ) {
|
47 |
-
$aMeta = null;
|
48 |
-
}
|
49 |
-
return ( empty( $aMeta ) || $oAsset->version !== $aMeta[ 'version' ] );
|
50 |
-
}
|
51 |
-
);
|
52 |
-
}
|
53 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Modules/HackGuard/Options.php
CHANGED
@@ -446,20 +446,4 @@ class Options extends Base\ShieldOptions {
|
|
446 |
}
|
447 |
) );
|
448 |
}
|
449 |
-
|
450 |
-
/**
|
451 |
-
* @return int
|
452 |
-
* @deprecated 8.5
|
453 |
-
*/
|
454 |
-
public function getPtgLastBuildAt() {
|
455 |
-
return $this->getOpt( 'ptg_last_build_at' );
|
456 |
-
}
|
457 |
-
|
458 |
-
/**
|
459 |
-
* @return string|false
|
460 |
-
* @deprecated 8.5
|
461 |
-
*/
|
462 |
-
public function getPtgSnapsBaseDir() {
|
463 |
-
return $this->getCon()->getPluginCachePath( 'ptguard/' );
|
464 |
-
}
|
465 |
}
|
446 |
}
|
447 |
) );
|
448 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
449 |
}
|
src/lib/src/Modules/IPs/AjaxHandler.php
CHANGED
@@ -68,10 +68,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
68 |
elseif ( $bIsBlackList && !$oMod->isPremium() ) {
|
69 |
$sMessage = __( "Please upgrade to Pro if you'd like to add IPs to the black list manually.", 'wp-simple-firewall' );
|
70 |
}
|
71 |
-
elseif ( $bIsBlackList && $oIpServ->
|
72 |
-
$sMessage = __( "IP ranges aren't currently supported for blacklisting.", 'wp-simple-firewall' );
|
73 |
-
}
|
74 |
-
elseif ( $bIsBlackList && $oIpServ->checkIp( $sIp, $oIpServ->getRequestIp() ) ) {
|
75 |
$sMessage = __( "Manually black listing your current IP address is not supported.", 'wp-simple-firewall' );
|
76 |
}
|
77 |
elseif ( $bIsBlackList && in_array( $sIp, Services::IP()->getServerPublicIPs() ) ) {
|
@@ -79,28 +76,35 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
79 |
}
|
80 |
else {
|
81 |
$sLabel = isset( $aFormParams[ 'label' ] ) ? $aFormParams[ 'label' ] : '';
|
|
|
82 |
switch ( $sList ) {
|
83 |
-
|
84 |
case $oMod::LIST_MANUAL_WHITE:
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
89 |
break;
|
90 |
|
91 |
case $oMod::LIST_MANUAL_BLACK:
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
96 |
break;
|
97 |
|
98 |
default:
|
99 |
-
$oIp = null;
|
100 |
break;
|
101 |
}
|
102 |
|
103 |
-
if ( !empty( $
|
104 |
$sMessage = __( 'IP address added successfully', 'wp-simple-firewall' );
|
105 |
$bSuccess = true;
|
106 |
}
|
68 |
elseif ( $bIsBlackList && !$oMod->isPremium() ) {
|
69 |
$sMessage = __( "Please upgrade to Pro if you'd like to add IPs to the black list manually.", 'wp-simple-firewall' );
|
70 |
}
|
71 |
+
elseif ( $bIsBlackList && $oIpServ->checkIp( $oIpServ->getRequestIp(), $sIp ) ) {
|
|
|
|
|
|
|
72 |
$sMessage = __( "Manually black listing your current IP address is not supported.", 'wp-simple-firewall' );
|
73 |
}
|
74 |
elseif ( $bIsBlackList && in_array( $sIp, Services::IP()->getServerPublicIPs() ) ) {
|
76 |
}
|
77 |
else {
|
78 |
$sLabel = isset( $aFormParams[ 'label' ] ) ? $aFormParams[ 'label' ] : '';
|
79 |
+
$oIP = null;
|
80 |
switch ( $sList ) {
|
|
|
81 |
case $oMod::LIST_MANUAL_WHITE:
|
82 |
+
try {
|
83 |
+
$oIP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
84 |
+
->setMod( $oMod )
|
85 |
+
->setIP( $sIp )
|
86 |
+
->toManualWhitelist( $sLabel );
|
87 |
+
}
|
88 |
+
catch ( \Exception $oE ) {
|
89 |
+
}
|
90 |
break;
|
91 |
|
92 |
case $oMod::LIST_MANUAL_BLACK:
|
93 |
+
try {
|
94 |
+
$oIP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
95 |
+
->setMod( $oMod )
|
96 |
+
->setIP( $sIp )
|
97 |
+
->toManualBlacklist( $sLabel );
|
98 |
+
}
|
99 |
+
catch ( \Exception $oE ) {
|
100 |
+
}
|
101 |
break;
|
102 |
|
103 |
default:
|
|
|
104 |
break;
|
105 |
}
|
106 |
|
107 |
+
if ( !empty( $oIP ) ) {
|
108 |
$sMessage = __( 'IP address added successfully', 'wp-simple-firewall' );
|
109 |
$bSuccess = true;
|
110 |
}
|
src/lib/src/Modules/IPs/Components/ProcessOffense.php
CHANGED
@@ -25,18 +25,23 @@ class ProcessOffense {
|
|
25 |
/** @var IPs\Options $oOpts */
|
26 |
$oOpts = $oMod->getOptions();
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
if ( $oIP instanceof Databases\IPs\EntryVO ) {
|
34 |
$nCurrent = $oIP->transgressions;
|
35 |
|
36 |
$oTracker = $oMod->loadOffenseTracker();
|
37 |
-
$bToBlock = $oTracker->isBlocked() ||
|
38 |
-
( $oIP->blocked_at == 0 && ( $oOpts->getOffenseLimit() - $nCurrent == 1 ) );
|
39 |
$nNewTotal = $oIP->transgressions + $oTracker->getOffenseCount();
|
|
|
|
|
40 |
|
41 |
/** @var Databases\IPs\Update $oUp */
|
42 |
$oUp = $oMod->getDbHandler_IPs()->getQueryUpdater();
|
25 |
/** @var IPs\Options $oOpts */
|
26 |
$oOpts = $oMod->getOptions();
|
27 |
|
28 |
+
try {
|
29 |
+
$oIP = ( new IPs\Lib\Ops\AddIp() )
|
30 |
+
->setMod( $oMod )
|
31 |
+
->setIP( $this->getIP() )
|
32 |
+
->toAutoBlacklist();
|
33 |
+
}
|
34 |
+
catch ( \Exception $oE ) {
|
35 |
+
$oIP = null;
|
36 |
+
}
|
37 |
|
38 |
if ( $oIP instanceof Databases\IPs\EntryVO ) {
|
39 |
$nCurrent = $oIP->transgressions;
|
40 |
|
41 |
$oTracker = $oMod->loadOffenseTracker();
|
|
|
|
|
42 |
$nNewTotal = $oIP->transgressions + $oTracker->getOffenseCount();
|
43 |
+
$bToBlock = $oTracker->isBlocked() ||
|
44 |
+
( $oIP->blocked_at == 0 && ( $nNewTotal >= $oOpts->getOffenseLimit() ) );
|
45 |
|
46 |
/** @var Databases\IPs\Update $oUp */
|
47 |
$oUp = $oMod->getDbHandler_IPs()->getQueryUpdater();
|
src/lib/src/Modules/IPs/Components/QueryIpBlock.php
CHANGED
@@ -37,11 +37,6 @@ class QueryIpBlock {
|
|
37 |
/** @var Databases\IPs\Update $oUp */
|
38 |
$oUp = $oMod->getDbHandler_IPs()->getQueryUpdater();
|
39 |
$oUp->updateLastAccessAt( $oIP );
|
40 |
-
|
41 |
-
// TODO: 8.6: remove eventually and lose transgressions comparison and query for "blocked" only (see below)
|
42 |
-
if ( $oIP->blocked_at == 0 ) {
|
43 |
-
$oUp->reset()->setBlocked( $oIP );
|
44 |
-
}
|
45 |
}
|
46 |
return $bIpBlocked;
|
47 |
}
|
@@ -58,7 +53,7 @@ class QueryIpBlock {
|
|
58 |
->setDbHandler( $oMod->getDbHandler_IPs() )
|
59 |
->setIP( $this->getIP() )
|
60 |
->setListTypeBlack()
|
61 |
-
|
62 |
->lookup();
|
63 |
|
64 |
if ( $oIP instanceof Databases\IPs\EntryVO ) {
|
@@ -74,7 +69,7 @@ class QueryIpBlock {
|
|
74 |
->setIP( Services::IP()->getRequestIp() )
|
75 |
->fromBlacklist();
|
76 |
}
|
77 |
-
|
78 |
$oBlockIP = $oIP;
|
79 |
}
|
80 |
}
|
37 |
/** @var Databases\IPs\Update $oUp */
|
38 |
$oUp = $oMod->getDbHandler_IPs()->getQueryUpdater();
|
39 |
$oUp->updateLastAccessAt( $oIP );
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
return $bIpBlocked;
|
42 |
}
|
53 |
->setDbHandler( $oMod->getDbHandler_IPs() )
|
54 |
->setIP( $this->getIP() )
|
55 |
->setListTypeBlack()
|
56 |
+
->setIsIpBlocked( true )
|
57 |
->lookup();
|
58 |
|
59 |
if ( $oIP instanceof Databases\IPs\EntryVO ) {
|
69 |
->setIP( Services::IP()->getRequestIp() )
|
70 |
->fromBlacklist();
|
71 |
}
|
72 |
+
else {
|
73 |
$oBlockIP = $oIP;
|
74 |
}
|
75 |
}
|
src/lib/src/Modules/IPs/Lib/BlacklistHandler.php
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class BlacklistHandler {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
public function run() {
|
14 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
15 |
+
$oMod = $this->getMod();
|
16 |
+
/** @var IPs\Options $oOpts */
|
17 |
+
$oOpts = $this->getOptions();
|
18 |
+
if ( $oOpts->isEnabledAutoBlackList() ) {
|
19 |
+
|
20 |
+
( new IPs\Components\UnblockIpByFlag() )
|
21 |
+
->setMod( $oMod )
|
22 |
+
->run();
|
23 |
+
|
24 |
+
add_action( 'init', [ $this, 'loadBotDetectors' ] ); // hook in the bot detection
|
25 |
+
|
26 |
+
if ( !$oMod->isVisitorWhitelisted() && !$this->isRequestWhitelisted() && !$oMod->isVerifiedBot() ) {
|
27 |
+
( new BlockRequest() )
|
28 |
+
->setMod( $oMod )
|
29 |
+
->run();
|
30 |
+
( new BlackmarkRequest() )
|
31 |
+
->setMod( $oMod )
|
32 |
+
->run();
|
33 |
+
}
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
public function loadBotDetectors() {
|
38 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
39 |
+
$oMod = $this->getMod();
|
40 |
+
/** @var IPs\Options $oOpts */
|
41 |
+
$oOpts = $oMod->getOptions();
|
42 |
+
|
43 |
+
if ( !Services::WpUsers()->isUserLoggedIn() ) {
|
44 |
+
|
45 |
+
if ( !$oMod->isVerifiedBot() ) {
|
46 |
+
if ( $oOpts->isEnabledTrackXmlRpc() ) {
|
47 |
+
( new IPs\BotTrack\TrackXmlRpc() )
|
48 |
+
->setMod( $oMod )
|
49 |
+
->run();
|
50 |
+
}
|
51 |
+
if ( $oOpts->isEnabledTrack404() ) {
|
52 |
+
( new IPs\BotTrack\Track404() )
|
53 |
+
->setMod( $oMod )
|
54 |
+
->run();
|
55 |
+
}
|
56 |
+
if ( $oOpts->isEnabledTrackLoginFailed() ) {
|
57 |
+
( new IPs\BotTrack\TrackLoginFailed() )
|
58 |
+
->setMod( $oMod )
|
59 |
+
->run();
|
60 |
+
}
|
61 |
+
if ( $oOpts->isEnabledTrackLoginInvalid() ) {
|
62 |
+
( new IPs\BotTrack\TrackLoginInvalid() )
|
63 |
+
->setMod( $oMod )
|
64 |
+
->run();
|
65 |
+
}
|
66 |
+
if ( $oOpts->isEnabledTrackFakeWebCrawler() ) {
|
67 |
+
( new IPs\BotTrack\TrackFakeWebCrawler() )
|
68 |
+
->setMod( $oMod )
|
69 |
+
->run();
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
/** Always run link cheese regardless of the verified bot or not */
|
74 |
+
if ( $oOpts->isEnabledTrackLinkCheese() ) {
|
75 |
+
( new IPs\BotTrack\TrackLinkCheese() )
|
76 |
+
->setMod( $oMod )
|
77 |
+
->run();
|
78 |
+
}
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @return bool
|
84 |
+
*/
|
85 |
+
private function isRequestWhitelisted() {
|
86 |
+
/** @var IPs\Options $oOpts */
|
87 |
+
$oOpts = $this->getOptions();
|
88 |
+
$bWhitelisted = false;
|
89 |
+
$aWhitelist = $oOpts->getRequestWhitelistAsRegex();
|
90 |
+
if ( !empty( $aWhitelist ) ) {
|
91 |
+
$sPath = strtolower( '/'.ltrim( (string)Services::Request()->getPath(), '/' ) );
|
92 |
+
foreach ( $aWhitelist as $sRule ) {
|
93 |
+
if ( preg_match( $sRule, $sPath ) ) {
|
94 |
+
$bWhitelisted = true;
|
95 |
+
break;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
return $bWhitelisted;
|
100 |
+
}
|
101 |
+
}
|
src/lib/src/Modules/IPs/Lib/BlackmarkRequest.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class BlackmarkRequest {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
public function run() {
|
14 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
15 |
+
$oMod = $this->getMod();
|
16 |
+
|
17 |
+
$oMod->loadOffenseTracker()->setIfCommit( true );
|
18 |
+
|
19 |
+
$oCon = $this->getCon();
|
20 |
+
add_filter( $oCon->prefix( 'firewall_die_message' ), [ $this, 'augmentFirewallDieMessage' ] );
|
21 |
+
add_action( $oCon->prefix( 'pre_plugin_shutdown' ), function () {
|
22 |
+
$this->processOffense();
|
23 |
+
} );
|
24 |
+
add_action( 'shield_security_offense', [ $this, 'processCustomShieldOffense' ], 10, 3 );
|
25 |
+
}
|
26 |
+
|
27 |
+
private function processOffense() {
|
28 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
29 |
+
$oMod = $this->getMod();
|
30 |
+
|
31 |
+
$oTracker = $oMod->loadOffenseTracker();
|
32 |
+
if ( !$this->getCon()->isPluginDeleting() && $oTracker->hasVisitorOffended() && $oTracker->isCommit() ) {
|
33 |
+
( new IPs\Components\ProcessOffense() )
|
34 |
+
->setMod( $oMod )
|
35 |
+
->setIp( Services::IP()->getRequestIp() )
|
36 |
+
->run();
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @param array $aMessages
|
42 |
+
* @return array
|
43 |
+
*/
|
44 |
+
public function augmentFirewallDieMessage( $aMessages ) {
|
45 |
+
if ( !is_array( $aMessages ) ) {
|
46 |
+
$aMessages = [];
|
47 |
+
}
|
48 |
+
|
49 |
+
$aMessages[] = sprintf( '<p>%s</p>', sprintf(
|
50 |
+
$this->getMod()->getTextOpt( 'text_remainingtrans' ),
|
51 |
+
( new IPs\Components\QueryRemainingOffenses() )
|
52 |
+
->setMod( $this->getMod() )
|
53 |
+
->setIP( Services::IP()->getRequestIp() )
|
54 |
+
->run()
|
55 |
+
) );
|
56 |
+
|
57 |
+
return $aMessages;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Allows 3rd parties to trigger Shield offenses
|
62 |
+
* @param string $sMessage
|
63 |
+
* @param int $nOffenseCount
|
64 |
+
* @param bool $bIncludeLoggedIn
|
65 |
+
*/
|
66 |
+
public function processCustomShieldOffense( $sMessage, $nOffenseCount = 1, $bIncludeLoggedIn = true ) {
|
67 |
+
if ( $this->getCon()->isPremiumActive() ) {
|
68 |
+
if ( empty( $sMessage ) ) {
|
69 |
+
$sMessage = __( 'No custom message provided.', 'wp-simple-firewall' );
|
70 |
+
}
|
71 |
+
|
72 |
+
if ( $bIncludeLoggedIn || !did_action( 'init' ) || !Services::WpUsers()->isUserLoggedIn() ) {
|
73 |
+
$this->getCon()
|
74 |
+
->fireEvent(
|
75 |
+
'custom_offense',
|
76 |
+
[
|
77 |
+
'audit' => [ 'message' => $sMessage ],
|
78 |
+
'offense_count' => $nOffenseCount
|
79 |
+
]
|
80 |
+
);
|
81 |
+
}
|
82 |
+
}
|
83 |
+
}
|
84 |
+
}
|
src/lib/src/Modules/IPs/Lib/BlockRequest.php
ADDED
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class BlockRequest {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
public function run() {
|
14 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
15 |
+
$oMod = $this->getMod();
|
16 |
+
|
17 |
+
$bIpBlocked = ( new IPs\Components\QueryIpBlock() )
|
18 |
+
->setMod( $oMod )
|
19 |
+
->setIp( Services::IP()->getRequestIp() )
|
20 |
+
->run();
|
21 |
+
|
22 |
+
if ( $bIpBlocked ) {
|
23 |
+
// $this->setIfLogRequest( false ); // TODO don't log traffic from killed requests
|
24 |
+
try {
|
25 |
+
if ( $this->processAutoUnblockRequest() ) {
|
26 |
+
return;
|
27 |
+
}
|
28 |
+
}
|
29 |
+
catch ( \Exception $oE ) {
|
30 |
+
}
|
31 |
+
$this->getCon()->fireEvent( 'conn_kill' );
|
32 |
+
$this->renderKillPage();
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @throws \Exception
|
38 |
+
*/
|
39 |
+
private function processAutoUnblockRequest() {
|
40 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
41 |
+
$oMod = $this->getMod();
|
42 |
+
/** @var IPs\Options $oOpts */
|
43 |
+
$oOpts = $oMod->getOptions();
|
44 |
+
$oReq = Services::Request();
|
45 |
+
|
46 |
+
if ( $oOpts->isEnabledAutoUserRecover() && $oReq->isPost()
|
47 |
+
&& $oReq->request( 'action' ) == $oMod->prefix() && $oReq->request( 'exec' ) == 'uau' ) {
|
48 |
+
|
49 |
+
if ( check_admin_referer( $oReq->request( 'exec' ), 'exec_nonce' ) !== 1 ) {
|
50 |
+
throw new \Exception( 'Nonce failed' );
|
51 |
+
}
|
52 |
+
if ( strlen( $oReq->post( 'icwp_wpsf_login_email' ) ) > 0 ) {
|
53 |
+
throw new \Exception( 'Email should not be provided in honeypot' );
|
54 |
+
}
|
55 |
+
|
56 |
+
$sIp = Services::IP()->getRequestIp();
|
57 |
+
if ( $oReq->post( 'ip' ) != $sIp ) {
|
58 |
+
throw new \Exception( 'IP does not match' );
|
59 |
+
}
|
60 |
+
|
61 |
+
$oLoginMod = $this->getCon()->getModule_LoginGuard();
|
62 |
+
$sGasp = $oReq->post( $oLoginMod->getGaspKey() );
|
63 |
+
if ( empty( $sGasp ) ) {
|
64 |
+
throw new \Exception( 'GASP failed' );
|
65 |
+
}
|
66 |
+
|
67 |
+
if ( !$oOpts->getCanIpRequestAutoUnblock( $sIp ) ) {
|
68 |
+
throw new \Exception( 'IP already processed in the last 24hrs' );
|
69 |
+
}
|
70 |
+
$oMod->updateIpRequestAutoUnblockTs( $sIp );
|
71 |
+
|
72 |
+
( new IPs\Lib\Ops\DeleteIp() )
|
73 |
+
->setDbHandler( $oMod->getDbHandler_IPs() )
|
74 |
+
->setIP( $sIp )
|
75 |
+
->fromBlacklist();
|
76 |
+
Services::Response()->redirectToHome();
|
77 |
+
}
|
78 |
+
|
79 |
+
return false;
|
80 |
+
}
|
81 |
+
|
82 |
+
private function renderKillPage() {
|
83 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
84 |
+
$oMod = $this->getMod();
|
85 |
+
/** @var IPs\Options $oOpts */
|
86 |
+
$oOpts = $oMod->getOptions();
|
87 |
+
$oCon = $this->getCon();
|
88 |
+
$oLoginMod = $oCon->getModule_LoginGuard();
|
89 |
+
|
90 |
+
$sUniqId = 'uau'.uniqid();
|
91 |
+
|
92 |
+
$sIp = Services::IP()->getRequestIp();
|
93 |
+
$nTimeRemaining = max( floor( $oOpts->getAutoExpireTime()/60 ), 0 );
|
94 |
+
$aData = [
|
95 |
+
'strings' => [
|
96 |
+
'title' => sprintf( __( "You've been blocked by the %s plugin", 'wp-simple-firewall' ),
|
97 |
+
sprintf( '<a href="%s" target="_blank">%s</a>',
|
98 |
+
$oCon->getPluginSpec()[ 'meta' ][ 'url_repo_home' ],
|
99 |
+
$oCon->getHumanName()
|
100 |
+
)
|
101 |
+
),
|
102 |
+
'lines' => [
|
103 |
+
sprintf( __( 'Time remaining on black list: %s', 'wp-simple-firewall' ),
|
104 |
+
sprintf( _n( '%s minute', '%s minutes', $nTimeRemaining, 'wp-simple-firewall' ), $nTimeRemaining )
|
105 |
+
),
|
106 |
+
sprintf( __( 'You tripped the security plugin defenses a total of %s times making you a suspect.', 'wp-simple-firewall' ), $oOpts->getOffenseLimit() ),
|
107 |
+
sprintf( __( 'If you believe this to be in error, please contact the site owner and quote your IP address below.', 'wp-simple-firewall' ) ),
|
108 |
+
],
|
109 |
+
'your_ip' => 'Your IP address',
|
110 |
+
'unblock' => [
|
111 |
+
'title' => __( 'Auto-Unblock Your IP', 'wp-simple-firewall' ),
|
112 |
+
'you_can' => __( 'You can automatically unblock your IP address by clicking the button below.', 'wp-simple-firewall' ),
|
113 |
+
'button' => __( 'Unblock My IP Address', 'wp-simple-firewall' ),
|
114 |
+
],
|
115 |
+
],
|
116 |
+
'vars' => [
|
117 |
+
'nonce' => $oMod->getNonceActionData( 'uau' ),
|
118 |
+
'ip' => $sIp,
|
119 |
+
'gasp_element' => $oMod->renderTemplate(
|
120 |
+
'snippets/gasp_js.php',
|
121 |
+
[
|
122 |
+
'sCbName' => $oLoginMod->getGaspKey(),
|
123 |
+
'sLabel' => $oLoginMod->getTextImAHuman(),
|
124 |
+
'sAlert' => $oLoginMod->getTextPleaseCheckBox(),
|
125 |
+
'sMustJs' => __( 'You MUST enable Javascript to be able to login', 'wp-simple-firewall' ),
|
126 |
+
'sUniqId' => $sUniqId,
|
127 |
+
'sUniqElem' => 'icwp_wpsf_login_p'.$sUniqId,
|
128 |
+
'strings' => [
|
129 |
+
'loading' => __( 'Loading', 'wp-simple-firewall' )
|
130 |
+
]
|
131 |
+
]
|
132 |
+
),
|
133 |
+
],
|
134 |
+
'flags' => [
|
135 |
+
'is_autorecover' => $oOpts->isEnabledAutoUserRecover(),
|
136 |
+
'is_uau_permitted' => $oOpts->getCanIpRequestAutoUnblock( $sIp ),
|
137 |
+
],
|
138 |
+
];
|
139 |
+
Services::WpGeneral()
|
140 |
+
->wpDie(
|
141 |
+
$oMod->renderTemplate( '/snippets/blacklist_die.twig', $aData, true )
|
142 |
+
);
|
143 |
+
}
|
144 |
+
}
|
src/lib/src/Modules/IPs/Lib/Ops/AddIp.php
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
|
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
/**
|
@@ -17,17 +17,24 @@ class AddIp {
|
|
17 |
|
18 |
/**
|
19 |
* @return Databases\IPs\EntryVO|null
|
|
|
20 |
*/
|
21 |
public function toAutoBlacklist() {
|
22 |
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
23 |
$oMod = $this->getMod();
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
$oIP = null;
|
26 |
-
if ( !in_array( $
|
27 |
$oIP = ( new LookupIpOnList() )
|
28 |
->setDbHandler( $oMod->getDbHandler_IPs() )
|
29 |
->setListTypeBlack()
|
30 |
-
->setIP( $
|
31 |
->lookup( false );
|
32 |
if ( !$oIP instanceof Databases\IPs\EntryVO ) {
|
33 |
$oIP = $this->add( $oMod::LIST_AUTO_BLACK, 'auto' );
|
@@ -45,18 +52,32 @@ class AddIp {
|
|
45 |
/**
|
46 |
* @param string $sLabel
|
47 |
* @return Databases\IPs\EntryVO|null
|
|
|
48 |
*/
|
49 |
public function toManualBlacklist( $sLabel = '' ) {
|
50 |
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
51 |
$oMod = $this->getMod();
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
$oIP = null;
|
54 |
-
if ( !in_array( $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
$oIP = ( new LookupIpOnList() )
|
57 |
->setDbHandler( $oMod->getDbHandler_IPs() )
|
58 |
->setListTypeBlack()
|
59 |
-
->setIP( $
|
60 |
->lookup( false );
|
61 |
|
62 |
if ( !$oIP instanceof Databases\IPs\EntryVO ) {
|
@@ -88,10 +109,25 @@ class AddIp {
|
|
88 |
/**
|
89 |
* @param string $sLabel
|
90 |
* @return Databases\IPs\EntryVO|null
|
|
|
91 |
*/
|
92 |
public function toManualWhitelist( $sLabel = '' ) {
|
93 |
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
94 |
$oMod = $this->getMod();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
$oIP = ( new LookupIpOnList() )
|
96 |
->setDbHandler( $oMod->getDbHandler_IPs() )
|
97 |
->setIP( $this->getIP() )
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
/**
|
17 |
|
18 |
/**
|
19 |
* @return Databases\IPs\EntryVO|null
|
20 |
+
* @throws \Exception
|
21 |
*/
|
22 |
public function toAutoBlacklist() {
|
23 |
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
24 |
$oMod = $this->getMod();
|
25 |
+
$oIpServ = Services::IP();
|
26 |
+
|
27 |
+
$sIP = $this->getIP();
|
28 |
+
if ( !$oIpServ->isValidIp( $sIP ) ) {
|
29 |
+
throw new \Exception( 'IP address is not valid' );
|
30 |
+
}
|
31 |
|
32 |
$oIP = null;
|
33 |
+
if ( !in_array( $sIP, Services::IP()->getServerPublicIPs() ) ) {
|
34 |
$oIP = ( new LookupIpOnList() )
|
35 |
->setDbHandler( $oMod->getDbHandler_IPs() )
|
36 |
->setListTypeBlack()
|
37 |
+
->setIP( $sIP )
|
38 |
->lookup( false );
|
39 |
if ( !$oIP instanceof Databases\IPs\EntryVO ) {
|
40 |
$oIP = $this->add( $oMod::LIST_AUTO_BLACK, 'auto' );
|
52 |
/**
|
53 |
* @param string $sLabel
|
54 |
* @return Databases\IPs\EntryVO|null
|
55 |
+
* @throws \Exception
|
56 |
*/
|
57 |
public function toManualBlacklist( $sLabel = '' ) {
|
58 |
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
59 |
$oMod = $this->getMod();
|
60 |
+
$oIpServ = Services::IP();
|
61 |
+
|
62 |
+
$sIP = $this->getIP();
|
63 |
+
if ( !$oIpServ->isValidIp( $sIP ) && !$oIpServ->isValidIpRange( $sIP ) ) {
|
64 |
+
throw new \Exception( 'IP address is not valid' );
|
65 |
+
}
|
66 |
|
67 |
$oIP = null;
|
68 |
+
if ( !in_array( $sIP, $oIpServ->getServerPublicIPs() ) ) {
|
69 |
+
|
70 |
+
if ( $oIpServ->isValidIpRange( $sIP ) ) {
|
71 |
+
( new DeleteIp() )
|
72 |
+
->setDbHandler( $oMod->getDbHandler_IPs() )
|
73 |
+
->setIP( $sIP )
|
74 |
+
->fromBlacklist();
|
75 |
+
}
|
76 |
|
77 |
$oIP = ( new LookupIpOnList() )
|
78 |
->setDbHandler( $oMod->getDbHandler_IPs() )
|
79 |
->setListTypeBlack()
|
80 |
+
->setIP( $sIP )
|
81 |
->lookup( false );
|
82 |
|
83 |
if ( !$oIP instanceof Databases\IPs\EntryVO ) {
|
109 |
/**
|
110 |
* @param string $sLabel
|
111 |
* @return Databases\IPs\EntryVO|null
|
112 |
+
* @throws \Exception
|
113 |
*/
|
114 |
public function toManualWhitelist( $sLabel = '' ) {
|
115 |
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
116 |
$oMod = $this->getMod();
|
117 |
+
$oIpServ = Services::IP();
|
118 |
+
|
119 |
+
$sIP = $this->getIP();
|
120 |
+
if ( !$oIpServ->isValidIp( $sIP ) && !$oIpServ->isValidIpRange( $sIP ) ) {
|
121 |
+
throw new \Exception( 'IP address is not valid' );
|
122 |
+
}
|
123 |
+
|
124 |
+
if ( $oIpServ->isValidIpRange( $sIP ) ) {
|
125 |
+
( new DeleteIp() )
|
126 |
+
->setDbHandler( $oMod->getDbHandler_IPs() )
|
127 |
+
->setIP( $sIP )
|
128 |
+
->fromWhiteList();
|
129 |
+
}
|
130 |
+
|
131 |
$oIP = ( new LookupIpOnList() )
|
132 |
->setDbHandler( $oMod->getDbHandler_IPs() )
|
133 |
->setIP( $this->getIP() )
|
src/lib/src/Modules/IPs/Lib/Ops/LookupIpOnList.php
CHANGED
@@ -24,10 +24,11 @@ class LookupIpOnList {
|
|
24 |
/**
|
25 |
* @param bool $bIncludeRanges
|
26 |
* @return Databases\IPs\EntryVO|null
|
|
|
27 |
*/
|
28 |
public function lookup( $bIncludeRanges = true ) {
|
29 |
-
$oIp =
|
30 |
-
if ( $bIncludeRanges
|
31 |
foreach ( $this->lookupRange() as $oMaybeIp ) {
|
32 |
try {
|
33 |
if ( Services::IP()->checkIp( $this->getIP(), $oMaybeIp->ip ) ) {
|
@@ -39,7 +40,7 @@ class LookupIpOnList {
|
|
39 |
}
|
40 |
}
|
41 |
}
|
42 |
-
return $oIp;
|
43 |
}
|
44 |
|
45 |
/**
|
@@ -123,21 +124,4 @@ class LookupIpOnList {
|
|
123 |
$this->sListType = 'white';
|
124 |
return $this;
|
125 |
}
|
126 |
-
|
127 |
-
/**
|
128 |
-
* @return string
|
129 |
-
* @deprecated 8.5
|
130 |
-
*/
|
131 |
-
public function getList() {
|
132 |
-
return '';
|
133 |
-
}
|
134 |
-
|
135 |
-
/**
|
136 |
-
* @param string $sList
|
137 |
-
* @return $this
|
138 |
-
* @deprecated 8.5
|
139 |
-
*/
|
140 |
-
public function setList( $sList ) {
|
141 |
-
return $this;
|
142 |
-
}
|
143 |
}
|
24 |
/**
|
25 |
* @param bool $bIncludeRanges
|
26 |
* @return Databases\IPs\EntryVO|null
|
27 |
+
* @version 8.6.0 - switched to lookup ranges first
|
28 |
*/
|
29 |
public function lookup( $bIncludeRanges = true ) {
|
30 |
+
$oIp = null;
|
31 |
+
if ( $bIncludeRanges ) {
|
32 |
foreach ( $this->lookupRange() as $oMaybeIp ) {
|
33 |
try {
|
34 |
if ( Services::IP()->checkIp( $this->getIP(), $oMaybeIp->ip ) ) {
|
40 |
}
|
41 |
}
|
42 |
}
|
43 |
+
return ( $oIp instanceof Databases\IPs\EntryVO ) ? $oIp : $this->lookupIp();
|
44 |
}
|
45 |
|
46 |
/**
|
124 |
$this->sListType = 'white';
|
125 |
return $this;
|
126 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
}
|
src/lib/src/Modules/License/AdminNotices.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param Shield\Utilities\AdminNotices\NoticeVO $oNotice
|
12 |
+
* @throws \Exception
|
13 |
+
*/
|
14 |
+
protected function processNotice( $oNotice ) {
|
15 |
+
switch ( $oNotice->id ) {
|
16 |
+
case 'wphashes-token-fail':
|
17 |
+
$this->buildNotice_WpHashesTokenFailure( $oNotice );
|
18 |
+
break;
|
19 |
+
default:
|
20 |
+
parent::processNotice( $oNotice );
|
21 |
+
break;
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @param Shield\Utilities\AdminNotices\NoticeVO $oNotice
|
27 |
+
*/
|
28 |
+
private function buildNotice_WpHashesTokenFailure( $oNotice ) {
|
29 |
+
$oNotice->render_data = [
|
30 |
+
'notice_attributes' => [],
|
31 |
+
'strings' => [
|
32 |
+
'title' => sprintf( '%s: %s', __( 'Warning', 'wp-simple-firewall' ),
|
33 |
+
sprintf( __( '%s API Token Missing', 'wp-simple-firewall' ), 'WPHashes.com' ) ),
|
34 |
+
'messages' => [
|
35 |
+
__( "This site appears to be activated for PRO, but there's been a problem obtaining an API token for WPHashes.com.", 'wp-simple-firewall' ),
|
36 |
+
implode( ' ', [
|
37 |
+
__( 'The WPHashes API is used for many premium features including Malware scanning.', 'wp-simple-firewall' ),
|
38 |
+
__( 'Without a valid API Token, certain Premium features wont work as expected.', 'wp-simple-firewall' ),
|
39 |
+
] ),
|
40 |
+
__( "Please contact us in our support channel if this doesn't sound right, or upgrade to PRO.", 'wp-simple-firewall' ),
|
41 |
+
],
|
42 |
+
'jump_to_support' => __( 'Click to jump to the relevant option', 'wp-simple-firewall' )
|
43 |
+
],
|
44 |
+
'hrefs' => [
|
45 |
+
'jump_to_support' => $this->getMod()->getUrl_DirectLinkToSection( 'global_enable_plugin_features' )
|
46 |
+
]
|
47 |
+
];
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @param Shield\Utilities\AdminNotices\NoticeVO $oNotice
|
52 |
+
* @return bool
|
53 |
+
*/
|
54 |
+
protected function isDisplayNeeded( $oNotice ) {
|
55 |
+
$oCon = $this->getCon();
|
56 |
+
/** @var \ICWP_WPSF_FeatureHandler_License $oMod */
|
57 |
+
$oMod = $this->getMod();
|
58 |
+
|
59 |
+
switch ( $oNotice->id ) {
|
60 |
+
|
61 |
+
case 'wphashes-token-fail':
|
62 |
+
$bNeeded = $oCon->isPremiumActive() && !$oMod->getWpHashesTokenManager()->hasToken()
|
63 |
+
&& ( Services::Request()->ts() > 1583712000 ); // @deprecated 8.6.3 i.e. remove it
|
64 |
+
break;
|
65 |
+
|
66 |
+
default:
|
67 |
+
$bNeeded = parent::isDisplayNeeded( $oNotice );
|
68 |
+
break;
|
69 |
+
}
|
70 |
+
return $bNeeded;
|
71 |
+
}
|
72 |
+
}
|
src/lib/src/Modules/License/AjaxHandler.php
CHANGED
@@ -4,6 +4,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
|
|
7 |
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
9 |
|
@@ -32,39 +33,26 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
32 |
* @return array
|
33 |
*/
|
34 |
private function ajaxExec_ConnectionDebug() {
|
35 |
-
|
36 |
-
|
37 |
-
$
|
|
|
|
|
|
|
|
|
38 |
|
39 |
-
$
|
40 |
-
|
41 |
-
add_query_arg( [ 'license_ping' => 'Y' ], $oMod->getLicenseStoreUrl() ),
|
42 |
-
[
|
43 |
-
'body' => [ 'ping' => 'pong' ]
|
44 |
-
],
|
45 |
-
'POST'
|
46 |
-
);
|
47 |
-
|
48 |
-
if ( !$oHttpReq->isSuccess() ) {
|
49 |
-
$sResult = implode( '; ', $oHttpReq->lastError->get_error_messages() );
|
50 |
}
|
51 |
-
elseif (
|
52 |
-
$
|
53 |
-
if ( isset( $aResult[ 'success' ] ) && $aResult[ 'success' ] ) {
|
54 |
-
$bSuccess = true;
|
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 {
|
62 |
-
$
|
63 |
}
|
64 |
-
|
65 |
return [
|
66 |
'success' => $bSuccess,
|
67 |
-
'message' => $
|
68 |
];
|
69 |
}
|
70 |
|
@@ -74,6 +62,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
74 |
private function ajaxExec_LicenseHandling() {
|
75 |
/** @var \ICWP_WPSF_FeatureHandler_License $oMod */
|
76 |
$oMod = $this->getMod();
|
|
|
77 |
|
78 |
$bSuccess = false;
|
79 |
$sMessage = 'Unsupported license action';
|
@@ -82,14 +71,14 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
82 |
|
83 |
if ( $sLicenseAction == 'clear' ) {
|
84 |
$bSuccess = true;
|
85 |
-
$
|
86 |
-
$
|
87 |
$sMessage = __( 'Success', 'wp-simple-firewall' ).'! '
|
88 |
.__( 'Reloading page', 'wp-simple-firewall' ).'...';
|
89 |
}
|
90 |
elseif ( $sLicenseAction == 'check' ) {
|
91 |
|
92 |
-
$nCheckInterval = $
|
93 |
if ( $nCheckInterval < 20 ) {
|
94 |
$nWait = 20 - $nCheckInterval;
|
95 |
$sMessage = sprintf(
|
@@ -98,9 +87,14 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
98 |
);
|
99 |
}
|
100 |
else {
|
101 |
-
|
102 |
-
|
103 |
-
|
|
|
|
|
|
|
|
|
|
|
104 |
}
|
105 |
}
|
106 |
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
use FernleafSystems\Wordpress\Services\Utilities\Licenses\Keyless;
|
8 |
|
9 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
10 |
|
33 |
* @return array
|
34 |
*/
|
35 |
private function ajaxExec_ConnectionDebug() {
|
36 |
+
$oIP = Services::IP();
|
37 |
+
|
38 |
+
$oPing = new Keyless\Ping();
|
39 |
+
$oPing->lookup_url_stub = $this->getOptions()->getDef( 'license_store_url_api' );
|
40 |
+
$bSuccess = $oPing->ping();
|
41 |
+
|
42 |
+
$sHost = wp_parse_url( $oPing->lookup_url_stub, PHP_URL_HOST );
|
43 |
|
44 |
+
if ( $bSuccess ) {
|
45 |
+
$sMessage = 'Successfully connected to license server.';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
}
|
47 |
+
elseif ( !$oIP->isValidIp( gethostbyname( $sHost ) ) ) {
|
48 |
+
$sMessage = sprintf( 'Could not resolve host IP address: %s', $sHost );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
50 |
else {
|
51 |
+
$sMessage = 'Failed to connect to license server.';
|
52 |
}
|
|
|
53 |
return [
|
54 |
'success' => $bSuccess,
|
55 |
+
'message' => $sMessage
|
56 |
];
|
57 |
}
|
58 |
|
62 |
private function ajaxExec_LicenseHandling() {
|
63 |
/** @var \ICWP_WPSF_FeatureHandler_License $oMod */
|
64 |
$oMod = $this->getMod();
|
65 |
+
$sHandler = $oMod->getLicenseHandler();
|
66 |
|
67 |
$bSuccess = false;
|
68 |
$sMessage = 'Unsupported license action';
|
71 |
|
72 |
if ( $sLicenseAction == 'clear' ) {
|
73 |
$bSuccess = true;
|
74 |
+
$sHandler->deactivate( false );
|
75 |
+
$sHandler->clearLicense();
|
76 |
$sMessage = __( 'Success', 'wp-simple-firewall' ).'! '
|
77 |
.__( 'Reloading page', 'wp-simple-firewall' ).'...';
|
78 |
}
|
79 |
elseif ( $sLicenseAction == 'check' ) {
|
80 |
|
81 |
+
$nCheckInterval = $sHandler->getLicenseNotCheckedForInterval();
|
82 |
if ( $nCheckInterval < 20 ) {
|
83 |
$nWait = 20 - $nCheckInterval;
|
84 |
$sMessage = sprintf(
|
87 |
);
|
88 |
}
|
89 |
else {
|
90 |
+
try {
|
91 |
+
$bSuccess = $sHandler->verify( true )
|
92 |
+
->hasValidWorkingLicense();
|
93 |
+
$sMessage = $bSuccess ? __( 'Valid license found.', 'wp-simple-firewall' ) : __( "Valid license couldn't be found.", 'wp-simple-firewall' );
|
94 |
+
}
|
95 |
+
catch ( \Exception $oE ) {
|
96 |
+
$sMessage = $oE->getMessage();
|
97 |
+
}
|
98 |
}
|
99 |
}
|
100 |
|
src/lib/src/Modules/License/Lib/LicenseEmails.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License\Lib;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class LicenseEmails {
|
9 |
+
|
10 |
+
use ModConsumer;
|
11 |
+
|
12 |
+
public function sendLicenseWarningEmail() {
|
13 |
+
/** @var \ICWP_WPSF_FeatureHandler_License $oMod */
|
14 |
+
$oMod = $this->getMod();
|
15 |
+
$oOpts = $this->getOptions();
|
16 |
+
|
17 |
+
$bCanSend = Services::Request()
|
18 |
+
->carbon()
|
19 |
+
->subDay( 1 )->timestamp > $oOpts->getOpt( 'last_warning_email_sent_at' );
|
20 |
+
|
21 |
+
if ( $bCanSend ) {
|
22 |
+
$oOpts->setOptAt( 'last_warning_email_sent_at' );
|
23 |
+
$oMod->saveModOptions();
|
24 |
+
|
25 |
+
$aMessage = [
|
26 |
+
__( 'Attempts to verify Shield Pro license has just failed.', 'wp-simple-firewall' ),
|
27 |
+
sprintf( __( 'Please check your license on-site: %s', 'wp-simple-firewall' ), $oMod->getUrl_AdminPage() ),
|
28 |
+
sprintf( __( 'If this problem persists, please contact support: %s', 'wp-simple-firewall' ), 'https://support.onedollarplugin.com/' )
|
29 |
+
];
|
30 |
+
$oMod->getEmailProcessor()
|
31 |
+
->sendEmailWithWrap(
|
32 |
+
$oMod->getPluginDefaultRecipientAddress(),
|
33 |
+
'Pro License Check Has Failed',
|
34 |
+
$aMessage
|
35 |
+
);
|
36 |
+
$this->getCon()->fireEvent( 'lic_fail_email' );
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
public function sendLicenseDeactivatedEmail() {
|
41 |
+
/** @var \ICWP_WPSF_FeatureHandler_License $oMod */
|
42 |
+
$oMod = $this->getMod();
|
43 |
+
$oOpts = $this->getOptions();
|
44 |
+
|
45 |
+
$bCanSend = Services::Request()
|
46 |
+
->carbon()
|
47 |
+
->subDay( 1 )->timestamp > $oOpts->getOpt( 'last_deactivated_email_sent_at' );
|
48 |
+
|
49 |
+
if ( $bCanSend ) {
|
50 |
+
$oOpts->setOptAt( 'last_deactivated_email_sent_at' );
|
51 |
+
$oMod->saveModOptions();
|
52 |
+
|
53 |
+
$aMessage = [
|
54 |
+
__( 'All attempts to verify Shield Pro license have failed.', 'wp-simple-firewall' ),
|
55 |
+
sprintf( __( 'Please check your license on-site: %s', 'wp-simple-firewall' ), $oMod->getUrl_AdminPage() ),
|
56 |
+
sprintf( __( 'If this problem persists, please contact support: %s', 'wp-simple-firewall' ), 'https://support.onedollarplugin.com/' )
|
57 |
+
];
|
58 |
+
$oMod->getEmailProcessor()
|
59 |
+
->sendEmailWithWrap(
|
60 |
+
$oMod->getPluginDefaultRecipientAddress(),
|
61 |
+
'[Action May Be Required] Pro License Has Been Deactivated',
|
62 |
+
$aMessage
|
63 |
+
);
|
64 |
+
}
|
65 |
+
}
|
66 |
+
}
|
src/lib/src/Modules/License/Lib/LicenseHandler.php
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License\Lib;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class LicenseHandler {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @return bool
|
15 |
+
*/
|
16 |
+
private function canCheck() {
|
17 |
+
return !in_array( $this->getCon()->getShieldAction(), [ 'keyless_handshake', 'license_check' ] )
|
18 |
+
&& $this->getIsLicenseNotCheckedFor( 20 )
|
19 |
+
&& $this->canLicenseCheck_FileFlag();
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @return $this
|
24 |
+
*/
|
25 |
+
public function clearLicense() {
|
26 |
+
$this->getMod()->clearLastErrors();
|
27 |
+
$this->getOptions()->setOpt( 'license_data', [] );
|
28 |
+
return $this;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @param bool $bSendEmail
|
33 |
+
*/
|
34 |
+
public function deactivate( $bSendEmail = true ) {
|
35 |
+
if ( $this->isActive() ) {
|
36 |
+
$this->clearLicense();
|
37 |
+
$this->getOptions()->setOptAt( 'license_deactivated_at' );
|
38 |
+
if ( $bSendEmail ) {
|
39 |
+
( new LicenseEmails() )
|
40 |
+
->setMod( $this->getMod() )
|
41 |
+
->sendLicenseDeactivatedEmail();
|
42 |
+
}
|
43 |
+
$this->getCon()->fireEvent( 'lic_fail_deactivate' );
|
44 |
+
}
|
45 |
+
// force all options to resave i.e. reset premium to defaults.
|
46 |
+
add_filter( $this->getCon()->prefix( 'force_options_resave' ), '__return_true' );
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @return int
|
51 |
+
*/
|
52 |
+
protected function getActivatedAt() {
|
53 |
+
return $this->getOptions()->getOpt( 'license_activated_at' );
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @return int
|
58 |
+
*/
|
59 |
+
protected function getDeactivatedAt() {
|
60 |
+
return $this->getOptions()->getOpt( 'license_deactivated_at' );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @return EddLicenseVO
|
65 |
+
*/
|
66 |
+
public function getLicense() {
|
67 |
+
$aData = $this->getOptions()->getOpt( 'license_data', [] );
|
68 |
+
return ( new EddLicenseVO() )->applyFromArray( is_array( $aData ) ? $aData : [] );
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @return int
|
73 |
+
*/
|
74 |
+
public function getLicenseNotCheckedForInterval() {
|
75 |
+
return Services::Request()->ts() - $this->getOptions()->getOpt( 'license_last_checked_at' );
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Use the grace period (currently 3 days) to adjust when the license registration
|
80 |
+
* expires on this site. We consider a registration as expired if the last verified
|
81 |
+
* date is past, or the actual license is expired - whichever happens earlier -
|
82 |
+
* plus the grace period.
|
83 |
+
* @return int
|
84 |
+
*/
|
85 |
+
public function getRegistrationExpiresAt() {
|
86 |
+
/** @var \ICWP_WPSF_FeatureHandler_License $oMod */
|
87 |
+
$oMod = $this->getMod();
|
88 |
+
$oOpts = $this->getOptions();
|
89 |
+
|
90 |
+
$nVerifiedExpiredDays = $oOpts->getDef( 'lic_verify_expire_days' )
|
91 |
+
+ $oOpts->getDef( 'lic_verify_expire_grace_days' );
|
92 |
+
|
93 |
+
$oLic = $oMod->getLicenseHandler()->getLicense();
|
94 |
+
return (int)min(
|
95 |
+
$oLic->getExpiresAt() + $oOpts->getDef( 'lic_verify_expire_grace_days' )*DAY_IN_SECONDS,
|
96 |
+
$oLic->last_verified_at + $nVerifiedExpiredDays*DAY_IN_SECONDS
|
97 |
+
);
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* IMPORTANT: Method used by Shield Central. Modify with care.
|
102 |
+
* We test various data points:
|
103 |
+
* 1) the key is valid format
|
104 |
+
* 2) the official license status is 'valid'
|
105 |
+
* 3) the license is marked as "active"
|
106 |
+
* 4) the license hasn't expired
|
107 |
+
* 5) the time since the last check hasn't expired
|
108 |
+
* @return bool
|
109 |
+
*/
|
110 |
+
public function hasValidWorkingLicense() {
|
111 |
+
$oLic = $this->getLicense();
|
112 |
+
return $oLic->isValid() && $this->isActive();
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @return bool
|
117 |
+
*/
|
118 |
+
public function isActive() {
|
119 |
+
return ( $this->getActivatedAt() > 0 )
|
120 |
+
&& ( $this->getDeactivatedAt() < $this->getActivatedAt() );
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @return bool
|
125 |
+
*/
|
126 |
+
public function isLastVerifiedExpired() {
|
127 |
+
return ( Services::Request()->ts() - $this->getLicense()->last_verified_at )
|
128 |
+
> $this->getOptions()->getDef( 'lic_verify_expire_days' )*DAY_IN_SECONDS;
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* @return bool
|
133 |
+
*/
|
134 |
+
public function isLastVerifiedGraceExpired() {
|
135 |
+
$oOpts = $this->getOptions();
|
136 |
+
$nGracePeriod = ( $oOpts->getDef( 'lic_verify_expire_days' )
|
137 |
+
+ $oOpts->getDef( 'lic_verify_expire_grace_days' ) )*DAY_IN_SECONDS;
|
138 |
+
return ( Services::Request()->ts() - $this->getLicense()->last_verified_at ) > $nGracePeriod;
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* @return bool
|
143 |
+
*/
|
144 |
+
private function isMaybeExpiring() {
|
145 |
+
return $this->isActive() &&
|
146 |
+
(
|
147 |
+
abs( Services::Request()->ts() - $this->getLicense()->getExpiresAt() )
|
148 |
+
< ( DAY_IN_SECONDS/2 )
|
149 |
+
);
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* @return bool
|
154 |
+
*/
|
155 |
+
public function isWithinVerifiedGraceExpired() {
|
156 |
+
return $this->isLastVerifiedExpired() && !$this->isLastVerifiedGraceExpired();
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* @return bool
|
161 |
+
*/
|
162 |
+
private function isVerifyRequired() {
|
163 |
+
return ( $this->isMaybeExpiring() && $this->getIsLicenseNotCheckedFor( HOUR_IN_SECONDS*4 ) )
|
164 |
+
|| ( $this->isActive()
|
165 |
+
&& !$this->getLicense()->isReady() && $this->getIsLicenseNotCheckedFor( HOUR_IN_SECONDS ) )
|
166 |
+
|| ( $this->hasValidWorkingLicense() && $this->isLastVerifiedExpired()
|
167 |
+
&& $this->getIsLicenseNotCheckedFor( HOUR_IN_SECONDS*4 ) );
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @param bool $bForceCheck
|
172 |
+
* @return $this
|
173 |
+
* @throws \Exception
|
174 |
+
*/
|
175 |
+
public function verify( $bForceCheck = true ) {
|
176 |
+
if ( $bForceCheck || ( $this->isVerifyRequired() && $this->canCheck() ) ) {
|
177 |
+
( new Verify() )
|
178 |
+
->setMod( $this->getMod() )
|
179 |
+
->run();
|
180 |
+
}
|
181 |
+
return $this;
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* @param int $nTimePeriod
|
186 |
+
* @return bool
|
187 |
+
*/
|
188 |
+
private function getIsLicenseNotCheckedFor( $nTimePeriod ) {
|
189 |
+
return $this->getLicenseNotCheckedForInterval() > $nTimePeriod;
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* @return bool
|
194 |
+
*/
|
195 |
+
private function canLicenseCheck_FileFlag() {
|
196 |
+
$nMtime = (int)Services::WpFs()->getModifiedTime(
|
197 |
+
$this->getCon()->getPath_Flags( 'license_check' )
|
198 |
+
);
|
199 |
+
return ( Services::Request()->ts() - $nMtime ) > MINUTE_IN_SECONDS;
|
200 |
+
}
|
201 |
+
}
|
src/lib/src/Modules/License/Lib/LookupRequest.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License\Lib;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
use FernleafSystems\Wordpress\Services\Utilities\Licenses\Keyless\Lookup;
|
8 |
+
|
9 |
+
class LookupRequest {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @return \FernleafSystems\Wordpress\Services\Utilities\Licenses\EddLicenseVO
|
15 |
+
*/
|
16 |
+
public function lookup() {
|
17 |
+
$oCon = $this->getCon();
|
18 |
+
$oOpts = $this->getOptions();
|
19 |
+
|
20 |
+
$sPass = wp_generate_password( 16, false );
|
21 |
+
$sUrl = Services::WpGeneral()->getHomeUrl( '', true );
|
22 |
+
|
23 |
+
$this->setKeylessHandshakeNonce( sha1( $sPass.$sUrl ) );
|
24 |
+
|
25 |
+
{
|
26 |
+
$oLook = new Lookup();
|
27 |
+
$oLook->lookup_url_stub = $oOpts->getDef( 'license_store_url_api' );
|
28 |
+
$oLook->item_id = $oOpts->getDef( 'license_item_id' );
|
29 |
+
$oLook->install_id = $oCon->getSiteInstallationId();
|
30 |
+
$oLook->url = $sUrl;
|
31 |
+
$oLook->nonce = $sPass;
|
32 |
+
$oLook->meta = [
|
33 |
+
'version_shield' => $oCon->getVersion(),
|
34 |
+
'version_php' => Services::Data()->getPhpVersionCleaned()
|
35 |
+
];
|
36 |
+
$oLicense = $oLook->lookup();
|
37 |
+
}
|
38 |
+
|
39 |
+
// clear the handshake data after the request has gone through
|
40 |
+
$this->setKeylessHandshakeNonce( '' );
|
41 |
+
|
42 |
+
return $oLicense;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @param string $sNonce - empty string to clear the nonce
|
47 |
+
*/
|
48 |
+
private function setKeylessHandshakeNonce( $sNonce = '' ) {
|
49 |
+
$oOpts = $this->getOptions();
|
50 |
+
$oOpts->setOpt( 'keyless_handshake_hash', $sNonce )
|
51 |
+
->setOpt( 'keyless_handshake_until',
|
52 |
+
empty( $sNonce ) ? 0 : Services::Request()->ts() + $oOpts->getDef( 'keyless_handshake_expire' )
|
53 |
+
);
|
54 |
+
$this->getMod()->saveModOptions();
|
55 |
+
}
|
56 |
+
}
|
src/lib/src/Modules/License/Lib/Verify.php
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License\Lib;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\License;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class Verify {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @throws \Exception
|
15 |
+
*/
|
16 |
+
public function run() {
|
17 |
+
$oCon = $this->getCon();
|
18 |
+
/** @var \ICWP_WPSF_FeatureHandler_License $oMod */
|
19 |
+
$oMod = $this->getMod();
|
20 |
+
/** @var License\Options $oOpts */
|
21 |
+
$oOpts = $this->getOptions();
|
22 |
+
$oHandler = $oMod->getLicenseHandler();
|
23 |
+
|
24 |
+
$this->preVerify();
|
25 |
+
|
26 |
+
$oExisting = $oHandler->getLicense();
|
27 |
+
|
28 |
+
$oLookupLicense = ( new LookupRequest() )
|
29 |
+
->setMod( $oMod )
|
30 |
+
->lookup();
|
31 |
+
|
32 |
+
$bSuccessfulApiRequest = false;
|
33 |
+
|
34 |
+
if ( $oLookupLicense->isValid() ) {
|
35 |
+
$bSuccessfulApiRequest = true;
|
36 |
+
$oExisting = $oLookupLicense;
|
37 |
+
$oExisting->updateLastVerifiedAt( true );
|
38 |
+
if ( !$oHandler->isActive() ) {
|
39 |
+
$oOpts->setOptAt( 'license_activated_at' );
|
40 |
+
}
|
41 |
+
$oMod->clearLastErrors();
|
42 |
+
$oOpts->setOpt( 'license_data', $oExisting->getRawDataAsArray() ); // need to do this before event
|
43 |
+
$oCon->fireEvent( 'lic_check_success' );
|
44 |
+
}
|
45 |
+
elseif ( $oLookupLicense->isReady() ) {
|
46 |
+
$bSuccessfulApiRequest = true;
|
47 |
+
// License lookup failed but request was successful - so use what we get
|
48 |
+
$oHandler->deactivate();
|
49 |
+
$oExisting = $oHandler->getLicense();
|
50 |
+
}
|
51 |
+
elseif ( $oExisting->isReady() ) { // Has a stored license but license HTTP request failed
|
52 |
+
|
53 |
+
$oMod->setLastErrors( [
|
54 |
+
__( 'The most recent request to verify the site license encountered a problem.', 'wp-simple-firewall' )
|
55 |
+
] );
|
56 |
+
|
57 |
+
if ( Services::Request()->ts() > $oHandler->getRegistrationExpiresAt() ) {
|
58 |
+
$oHandler->deactivate();
|
59 |
+
$oExisting = $oHandler->getLicense();
|
60 |
+
}
|
61 |
+
elseif ( $oHandler->isLastVerifiedExpired() ) {
|
62 |
+
/**
|
63 |
+
* At this stage we have a license stored, but we couldn't
|
64 |
+
* verify it, but we're within the grace period for checking.
|
65 |
+
*
|
66 |
+
* We don't remove the license yet, but we warn the user
|
67 |
+
*/
|
68 |
+
( new LicenseEmails() )
|
69 |
+
->setMod( $oMod )
|
70 |
+
->sendLicenseWarningEmail();
|
71 |
+
}
|
72 |
+
}
|
73 |
+
else { // all else fails, clear any license details entirely
|
74 |
+
$oHandler->clearLicense();
|
75 |
+
$oExisting = $oHandler->getLicense();
|
76 |
+
}
|
77 |
+
|
78 |
+
$oExisting->last_request_at = Services::Request()->ts();
|
79 |
+
$oOpts->setOpt( 'license_data', $oExisting->getRawDataAsArray() );
|
80 |
+
$this->getMod()->saveModOptions();
|
81 |
+
|
82 |
+
if ( !$bSuccessfulApiRequest ) {
|
83 |
+
throw new \Exception( 'License API HTTP Request Failed.' );
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
private function preVerify() {
|
88 |
+
/** @var License\Options $oOpts */
|
89 |
+
$oOpts = $this->getOptions();
|
90 |
+
Services::WpFs()->touch( $this->getCon()->getPath_Flags( 'license_check' ) );
|
91 |
+
$oOpts->setOptAt( 'license_last_checked_at' );
|
92 |
+
$this->getMod()->saveModOptions();
|
93 |
+
}
|
94 |
+
}
|
src/lib/src/Modules/License/Lib/WpHashes/ApiTokenManager.php
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License\Lib\WpHashes;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Token;
|
8 |
+
|
9 |
+
class ApiTokenManager {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var bool
|
15 |
+
*/
|
16 |
+
private $bCanRequestOverride = false;
|
17 |
+
|
18 |
+
public function run() {
|
19 |
+
add_action( $this->getCon()->prefix( 'event' ), function ( $sEventTag ) {
|
20 |
+
switch ( $sEventTag ) {
|
21 |
+
case 'lic_check_success':
|
22 |
+
$this->setCanRequestOverride( true )->getToken();
|
23 |
+
break;
|
24 |
+
case 'lic_fail_deactivate':
|
25 |
+
$this->storeToken( [] );
|
26 |
+
break;
|
27 |
+
default:
|
28 |
+
break;
|
29 |
+
}
|
30 |
+
} );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @return bool
|
35 |
+
*/
|
36 |
+
public function hasToken() {
|
37 |
+
$sTok = $this->getTheToken();
|
38 |
+
return strlen( $sTok ) == 40 && !$this->isExpired();
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @return string
|
43 |
+
*/
|
44 |
+
public function getToken() {
|
45 |
+
|
46 |
+
if ( $this->getCon()->getModule_License()->getLicenseHandler()->getLicense()->isValid() ) {
|
47 |
+
$aT = $this->loadToken();
|
48 |
+
if ( $this->isExpired() && $this->canRequestNewToken() ) {
|
49 |
+
$aT = $this->loadToken();
|
50 |
+
try {
|
51 |
+
$aT = array_merge( $aT, $this->solicitApiToken() );
|
52 |
+
}
|
53 |
+
catch ( \Exception $oE ) {
|
54 |
+
}
|
55 |
+
$aT[ 'attempt_at' ] = Services::Request()->ts();
|
56 |
+
$this->storeToken( $aT );
|
57 |
+
}
|
58 |
+
}
|
59 |
+
else {
|
60 |
+
$this->storeToken( [] );
|
61 |
+
}
|
62 |
+
|
63 |
+
return empty( $aT[ 'token' ] ) ? '' : $aT[ 'token' ];
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @return string
|
68 |
+
*/
|
69 |
+
private function getTheToken() {
|
70 |
+
return $this->loadToken()[ 'token' ];
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @return array - return Token exactly as it's saved currently
|
75 |
+
*/
|
76 |
+
private function loadToken() {
|
77 |
+
return array_merge(
|
78 |
+
[
|
79 |
+
'token' => '',
|
80 |
+
'expires_at' => 0,
|
81 |
+
'attempt_at' => 0,
|
82 |
+
'valid_license' => false,
|
83 |
+
],
|
84 |
+
$this->getOptions()->getOpt( 'wphashes_api_token', [] )
|
85 |
+
);
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @return bool
|
90 |
+
*/
|
91 |
+
private function canRequestNewToken() {
|
92 |
+
return $this->getCanRequestOverride() ||
|
93 |
+
(
|
94 |
+
Services::Request()->carbon()->subHours( 6 )->timestamp > $this->loadToken()[ 'attempt_at' ]
|
95 |
+
&& $this->getCon()->getModule_License()->getLicenseHandler()->getLicense()->isValid()
|
96 |
+
);
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @return bool
|
101 |
+
*/
|
102 |
+
public function getCanRequestOverride() {
|
103 |
+
return (bool)$this->bCanRequestOverride;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* @return bool
|
108 |
+
*/
|
109 |
+
public function isExpired() {
|
110 |
+
return Services::Request()->ts() > $this->loadToken()[ 'expires_at' ];
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* @param array $aToken
|
115 |
+
* @return $this
|
116 |
+
*/
|
117 |
+
private function storeToken( array $aToken = [] ) {
|
118 |
+
$this->getOptions()->setOpt( 'wphashes_api_token', $aToken );
|
119 |
+
return $this;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* @param bool $bCanRequest
|
124 |
+
* @return $this
|
125 |
+
*/
|
126 |
+
public function setCanRequestOverride( $bCanRequest ) {
|
127 |
+
$this->bCanRequestOverride = (bool)$bCanRequest;
|
128 |
+
return $this;
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* @return array
|
133 |
+
* @throws \Exception
|
134 |
+
*/
|
135 |
+
private function solicitApiToken() {
|
136 |
+
$aResp = ( new Token\Solicit() )->retrieve(
|
137 |
+
Services::WpGeneral()->getHomeUrl(),
|
138 |
+
$this->getCon()->getSiteInstallationId()
|
139 |
+
);
|
140 |
+
if ( !is_array( $aResp ) || empty( $aResp[ 'token' ] ) || strlen( $aResp[ 'token' ] ) != 40 ) {
|
141 |
+
throw new \Exception( 'Could not retrieve token' );
|
142 |
+
}
|
143 |
+
return $aResp;
|
144 |
+
}
|
145 |
+
}
|
src/lib/src/Modules/LoginGuard/AjaxHandler.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
@@ -41,11 +42,12 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
41 |
* @return array
|
42 |
*/
|
43 |
protected function ajaxExec_GenBackupCodes() {
|
44 |
-
/** @var \
|
45 |
-
$
|
46 |
-
|
47 |
-
|
48 |
-
|
|
|
49 |
|
50 |
foreach ( [ 20, 15, 10, 5 ] as $nPos ) {
|
51 |
$sPass = substr_replace( $sPass, '-', $nPos, 0 );
|
@@ -63,11 +65,10 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
63 |
private function ajaxExec_DeleteBackupCodes() {
|
64 |
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
65 |
$oMod = $this->getMod();
|
66 |
-
/** @var \
|
67 |
-
$
|
68 |
-
|
69 |
-
|
70 |
-
->deleteSecret( Services::WpUsers()->getCurrentWpUser() );
|
71 |
$oMod->setFlashAdminNotice( __( 'Multi-factor login backup code has been removed from your profile', 'wp-simple-firewall' ) );
|
72 |
return [
|
73 |
'success' => true
|
@@ -94,13 +95,15 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
94 |
private function ajaxExec_ResendEmailVerification() {
|
95 |
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
96 |
$oMod = $this->getMod();
|
|
|
|
|
97 |
$bSuccess = true;
|
98 |
|
99 |
-
if ( !$
|
100 |
$sMessage = __( 'Email 2FA option is not currently enabled.', 'wp-simple-firewall' );
|
101 |
$bSuccess = false;
|
102 |
}
|
103 |
-
elseif ( $
|
104 |
$sMessage = __( 'Email sending has already been verified.', 'wp-simple-firewall' );
|
105 |
}
|
106 |
else {
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
42 |
* @return array
|
43 |
*/
|
44 |
protected function ajaxExec_GenBackupCodes() {
|
45 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
46 |
+
$oMod = $this->getMod();
|
47 |
+
/** @var TwoFactor\Provider\Backup $oBU */
|
48 |
+
$oBU = $oMod->getLoginIntentController()
|
49 |
+
->getProviders()[ TwoFactor\Provider\Backup::SLUG ];
|
50 |
+
$sPass = $oBU->resetSecret( Services::WpUsers()->getCurrentWpUser() );
|
51 |
|
52 |
foreach ( [ 20, 15, 10, 5 ] as $nPos ) {
|
53 |
$sPass = substr_replace( $sPass, '-', $nPos, 0 );
|
65 |
private function ajaxExec_DeleteBackupCodes() {
|
66 |
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
67 |
$oMod = $this->getMod();
|
68 |
+
/** @var TwoFactor\Provider\Backup $oBU */
|
69 |
+
$oBU = $oMod->getLoginIntentController()
|
70 |
+
->getProviders()[ TwoFactor\Provider\Backup::SLUG ];
|
71 |
+
$oBU->deleteSecret( Services::WpUsers()->getCurrentWpUser() );
|
|
|
72 |
$oMod->setFlashAdminNotice( __( 'Multi-factor login backup code has been removed from your profile', 'wp-simple-firewall' ) );
|
73 |
return [
|
74 |
'success' => true
|
95 |
private function ajaxExec_ResendEmailVerification() {
|
96 |
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
97 |
$oMod = $this->getMod();
|
98 |
+
/** @var Options $oOpts */
|
99 |
+
$oOpts = $this->getOptions();
|
100 |
$bSuccess = true;
|
101 |
|
102 |
+
if ( !$oOpts->isEnabledEmailAuth() ) {
|
103 |
$sMessage = __( 'Email 2FA option is not currently enabled.', 'wp-simple-firewall' );
|
104 |
$bSuccess = false;
|
105 |
}
|
106 |
+
elseif ( $oOpts->getIfCanSendEmailVerified() ) {
|
107 |
$sMessage = __( 'Email sending has already been verified.', 'wp-simple-firewall' );
|
108 |
}
|
109 |
else {
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php
ADDED
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\AdminNotices\NoticeVO;
|
9 |
+
use FernleafSystems\Wordpress\Services\Services;
|
10 |
+
|
11 |
+
class LoginIntentPage {
|
12 |
+
|
13 |
+
use MfaControllerConsumer;
|
14 |
+
|
15 |
+
/**
|
16 |
+
*/
|
17 |
+
public function loadPage() {
|
18 |
+
echo $this->renderPage();
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @return string
|
23 |
+
*/
|
24 |
+
public function renderForm() {
|
25 |
+
$oIC = $this->getMfaCon();
|
26 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
27 |
+
$oMod = $oIC->getMod();
|
28 |
+
/** @var LoginGuard\Options $oOpts */
|
29 |
+
$oOpts = $oIC->getOptions();
|
30 |
+
$oCon = $oIC->getCon();
|
31 |
+
$oReq = Services::Request();
|
32 |
+
$oWP = Services::WpGeneral();
|
33 |
+
|
34 |
+
$aLoginIntentFields = array_map(
|
35 |
+
function ( $oProvider ) {
|
36 |
+
/** @var TwoFactor\Provider\BaseProvider $oProvider */
|
37 |
+
return $oProvider->getFormField();
|
38 |
+
},
|
39 |
+
$oIC->getProvidersForUser( Services::WpUsers()->getCurrentWpUser(), true )
|
40 |
+
);
|
41 |
+
|
42 |
+
$oNotice = $oCon->getAdminNotices()->getFlashNotice();
|
43 |
+
if ( $oNotice instanceof NoticeVO ) {
|
44 |
+
$sMessage = $oNotice->render_data[ 'message' ];
|
45 |
+
}
|
46 |
+
else {
|
47 |
+
$sMessage = $oOpts->isChainedAuth() ?
|
48 |
+
__( 'Please supply all authentication codes', 'wp-simple-firewall' )
|
49 |
+
: __( 'Please supply at least 1 authentication code', 'wp-simple-firewall' );
|
50 |
+
}
|
51 |
+
|
52 |
+
$sReferUrl = $oReq->server( 'HTTP_REFERER', '' );
|
53 |
+
if ( strpos( $sReferUrl, '?' ) ) {
|
54 |
+
list( $sReferUrl, $sReferQuery ) = explode( '?', $sReferUrl, 2 );
|
55 |
+
}
|
56 |
+
else {
|
57 |
+
$sReferQuery = '';
|
58 |
+
}
|
59 |
+
|
60 |
+
$sRedirectTo = '';
|
61 |
+
if ( !empty( $sReferQuery ) ) {
|
62 |
+
parse_str( $sReferQuery, $aReferQueryItems );
|
63 |
+
if ( !empty( $aReferQueryItems[ 'redirect_to' ] ) ) {
|
64 |
+
$sRedirectTo = rawurlencode( $aReferQueryItems[ 'redirect_to' ] );
|
65 |
+
}
|
66 |
+
}
|
67 |
+
if ( empty( $sRedirectTo ) ) {
|
68 |
+
$sRedirectTo = rawurlencode( $oReq->post( 'redirect_to', $oReq->getUri() ) );
|
69 |
+
}
|
70 |
+
|
71 |
+
$sCancelHref = $oReq->post( 'cancel_href', '' );
|
72 |
+
if ( empty( $sCancelHref ) && Services::Data()->isValidWebUrl( $sReferUrl ) ) {
|
73 |
+
$sCancelHref = rawurlencode( parse_url( $sReferUrl, PHP_URL_PATH ) );
|
74 |
+
}
|
75 |
+
|
76 |
+
$nMfaSkip = $oOpts->getMfaSkip();
|
77 |
+
$nTimeRemaining = $oMod->getSession()->login_intent_expires_at - $oReq->ts();
|
78 |
+
$aDisplayData = [
|
79 |
+
'strings' => [
|
80 |
+
'cancel' => __( 'Cancel Login', 'wp-simple-firewall' ),
|
81 |
+
'time_remaining' => __( 'Time Remaining', 'wp-simple-firewall' ),
|
82 |
+
'calculating' => __( 'Calculating', 'wp-simple-firewall' ).' ...',
|
83 |
+
'seconds' => strtolower( __( 'Seconds', 'wp-simple-firewall' ) ),
|
84 |
+
'login_expired' => __( 'Login Expired', 'wp-simple-firewall' ),
|
85 |
+
'verify_my_login' => __( 'Verify My Login', 'wp-simple-firewall' ),
|
86 |
+
'message' => $sMessage,
|
87 |
+
'skip_mfa' => sprintf(
|
88 |
+
__( "Don't ask again on this browser for %s.", 'wp-simple-firewall' ),
|
89 |
+
sprintf( _n( '%s day', '%s days', $nMfaSkip, 'wp-simple-firewall' ), $nMfaSkip )
|
90 |
+
)
|
91 |
+
],
|
92 |
+
'data' => [
|
93 |
+
'login_fields' => $aLoginIntentFields,
|
94 |
+
'time_remaining' => $nTimeRemaining,
|
95 |
+
'message_type' => 'info',
|
96 |
+
'login_intent_flag' => $oMod->getLoginIntentRequestFlag(),
|
97 |
+
],
|
98 |
+
'hrefs' => [
|
99 |
+
'form_action' => parse_url( $oWP->getAdminUrl( '', true ), PHP_URL_PATH ),
|
100 |
+
'redirect_to' => $sRedirectTo,
|
101 |
+
'cancel_href' => $sCancelHref
|
102 |
+
],
|
103 |
+
'flags' => [
|
104 |
+
'can_skip_mfa' => $oMod->getMfaSkipEnabled(),
|
105 |
+
'show_branded_links' => !$oMod->isWlEnabled(), // white label mitigation
|
106 |
+
]
|
107 |
+
];
|
108 |
+
|
109 |
+
return $oMod->renderTemplate( '/snippets/login_intent/form.twig',
|
110 |
+
Services::DataManipulation()->mergeArraysRecursive( $oMod->getBaseDisplayData(), $aDisplayData ), true );
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* @return string
|
115 |
+
*/
|
116 |
+
private function renderPage() {
|
117 |
+
$oIC = $this->getMfaCon();
|
118 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
119 |
+
$oMod = $oIC->getMod();
|
120 |
+
$oCon = $oIC->getCon();
|
121 |
+
$oReq = Services::Request();
|
122 |
+
|
123 |
+
$aLabels = $oCon->getLabels();
|
124 |
+
$sBannerUrl = empty( $aLabels[ 'url_login2fa_logourl' ] ) ? $oCon->getPluginUrl_Image( 'pluginlogo_banner-772x250.png' ) : $aLabels[ 'url_login2fa_logourl' ];
|
125 |
+
$nTimeRemaining = $oMod->getSession()->login_intent_expires_at - $oReq->ts();
|
126 |
+
$aDisplayData = [
|
127 |
+
'strings' => [
|
128 |
+
'what_is_this' => __( 'What is this?', 'wp-simple-firewall' ),
|
129 |
+
'page_title' => sprintf( __( '%s Login Verification', 'wp-simple-firewall' ), $oCon->getHumanName() ),
|
130 |
+
],
|
131 |
+
'data' => [
|
132 |
+
'time_remaining' => $nTimeRemaining,
|
133 |
+
],
|
134 |
+
'hrefs' => [
|
135 |
+
'css_bootstrap' => $oCon->getPluginUrl_Css( 'bootstrap4.min' ),
|
136 |
+
'js_bootstrap' => $oCon->getPluginUrl_Js( 'bootstrap4.min' ),
|
137 |
+
'shield_logo' => 'https://ps.w.org/wp-simple-firewall/assets/banner-772x250.png',
|
138 |
+
'what_is_this' => 'https://icontrolwp.freshdesk.com/support/solutions/articles/3000064840',
|
139 |
+
],
|
140 |
+
'imgs' => [
|
141 |
+
'banner' => $sBannerUrl,
|
142 |
+
'favicon' => $oCon->getPluginUrl_Image( 'pluginlogo_24x24.png' ),
|
143 |
+
],
|
144 |
+
'flags' => [
|
145 |
+
'show_branded_links' => !$oMod->isWlEnabled(), // white label mitigation
|
146 |
+
],
|
147 |
+
'content' => [
|
148 |
+
'form' => $this->renderForm(),
|
149 |
+
]
|
150 |
+
];
|
151 |
+
|
152 |
+
return $oMod->renderTemplate( '/pages/login_intent/index.twig',
|
153 |
+
Services::DataManipulation()->mergeArraysRecursive( $oMod->getBaseDisplayData(), $aDisplayData ), true );
|
154 |
+
}
|
155 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php
ADDED
@@ -0,0 +1,328 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Session\Update;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
|
9 |
+
use FernleafSystems\Wordpress\Services\Services;
|
10 |
+
|
11 |
+
class MfaController {
|
12 |
+
|
13 |
+
use Shield\Modules\ModConsumer;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var Provider\BaseProvider[]
|
17 |
+
*/
|
18 |
+
private $aProviders;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var bool
|
22 |
+
*/
|
23 |
+
protected $bLoginAttemptCaptured;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var LoginIntentPage
|
27 |
+
*/
|
28 |
+
private $oLoginIntentPageHandler;
|
29 |
+
|
30 |
+
public function run() {
|
31 |
+
add_action( 'init', [ $this, 'onWpInit' ], 10, 2 );
|
32 |
+
add_action( 'wp_login', [ $this, 'onWpLogin' ], 10, 2 );
|
33 |
+
if ( !Services::WpUsers()->isProfilePage() ) { // This can be fired during profile update.
|
34 |
+
add_action( 'set_logged_in_cookie', [ $this, 'onWpSetLoggedInCookie' ], 5, 4 );
|
35 |
+
}
|
36 |
+
add_action( 'wp_loaded', [ $this, 'onWpLoaded' ], 10, 2 );
|
37 |
+
}
|
38 |
+
|
39 |
+
public function onWpInit() {
|
40 |
+
$this->assessLoginIntent();
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param string $sUsername
|
45 |
+
* @param \WP_User $oUser
|
46 |
+
*/
|
47 |
+
public function onWpLogin( $sUsername, $oUser ) {
|
48 |
+
$this->captureLoginIntent( $oUser );
|
49 |
+
}
|
50 |
+
|
51 |
+
public function onWpLoaded() {
|
52 |
+
( new UserProfile() )
|
53 |
+
->setMfaController( $this )
|
54 |
+
->run();
|
55 |
+
|
56 |
+
add_shortcode( 'SHIELD_2FA_LOGIN', function () {
|
57 |
+
return $this->getLoginIntentPageHandler()->renderForm();
|
58 |
+
} );
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @param string $sCookie
|
63 |
+
* @param int $nExpire
|
64 |
+
* @param int $nExpiration
|
65 |
+
* @param int $nUserId
|
66 |
+
*/
|
67 |
+
public function onWpSetLoggedInCookie( $sCookie, $nExpire, $nExpiration, $nUserId ) {
|
68 |
+
$this->captureLoginIntent( Services::WpUsers()->getUserById( $nUserId ) );
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @param \WP_User $oUser
|
73 |
+
*/
|
74 |
+
private function captureLoginIntent( $oUser ) {
|
75 |
+
if ( empty( $this->bLoginAttemptCaptured ) && $oUser instanceof \WP_User ) {
|
76 |
+
$this->bLoginAttemptCaptured = true;
|
77 |
+
|
78 |
+
/** @var LoginGuard\Options $oOpts */
|
79 |
+
$oOpts = $this->getOptions();
|
80 |
+
if ( $this->isSubjectToLoginIntent( $oUser ) && !$this->canUserMfaSkip( $oUser ) ) {
|
81 |
+
|
82 |
+
$aProviders = $this->getProvidersForUser( $oUser );
|
83 |
+
if ( !empty( $aProviders ) ) {
|
84 |
+
foreach ( $aProviders as $oProvider ) {
|
85 |
+
$oProvider->captureLoginAttempt( $oUser );
|
86 |
+
}
|
87 |
+
|
88 |
+
$nTimeout = (int)apply_filters(
|
89 |
+
$this->getCon()->prefix( 'login_intent_timeout' ),
|
90 |
+
$oOpts->getDef( 'login_intent_timeout' )
|
91 |
+
);
|
92 |
+
$this->setLoginIntentExpiresAt(
|
93 |
+
Services::Request()->carbon()->addMinutes( $nTimeout )->timestamp
|
94 |
+
);
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Deals with the scenario when the user session has a login intent.
|
102 |
+
*/
|
103 |
+
private function assessLoginIntent() {
|
104 |
+
$oUser = Services::WpUsers()->getCurrentWpUser();
|
105 |
+
if ( $oUser instanceof \WP_User && $this->hasLoginIntent() ) {
|
106 |
+
|
107 |
+
if ( $this->isSubjectToLoginIntent( $oUser ) ) {
|
108 |
+
|
109 |
+
if ( $this->getLoginIntentExpiresAt() > Services::Request()->ts() ) {
|
110 |
+
$this->processActiveLoginIntent();
|
111 |
+
}
|
112 |
+
else {
|
113 |
+
Services::WpUsers()->logoutUser(); // clears the login and login intent
|
114 |
+
Services::Response()->redirectHere();
|
115 |
+
}
|
116 |
+
}
|
117 |
+
else {
|
118 |
+
// This handles the case where an admin changes a setting while a user is logged-in
|
119 |
+
// So to prevent this, we remove any intent for a user that isn't subject to it right now
|
120 |
+
$this->removeLoginIntent();
|
121 |
+
}
|
122 |
+
}
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* @return LoginIntentPage
|
127 |
+
*/
|
128 |
+
private function getLoginIntentPageHandler() {
|
129 |
+
if ( !isset( $this->oLoginIntentPageHandler ) ) {
|
130 |
+
$this->oLoginIntentPageHandler =( new LoginIntentPage() )->setMfaController( $this );
|
131 |
+
}
|
132 |
+
return $this->oLoginIntentPageHandler;
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* @return Provider\BaseProvider[]
|
137 |
+
*/
|
138 |
+
public function getProviders() {
|
139 |
+
if ( !is_array( $this->aProviders ) ) {
|
140 |
+
$this->aProviders = [
|
141 |
+
Provider\Email::SLUG => ( new Provider\Email() )->setMod( $this->getMod() ),
|
142 |
+
Provider\GoogleAuth::SLUG => ( new Provider\GoogleAuth() )->setMod( $this->getMod() ),
|
143 |
+
Provider\Yubikey::SLUG => ( new Provider\Yubikey() )->setMod( $this->getMod() ),
|
144 |
+
Provider\Backup::SLUG => ( new Provider\Backup() )->setMod( $this->getMod() ),
|
145 |
+
];
|
146 |
+
}
|
147 |
+
return $this->aProviders;
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Ensures that BackupCode provider isn't supplied on its own, and the user profile is setup for each.
|
152 |
+
* @param \WP_User $oUser
|
153 |
+
* @param bool $bOnlyActiveProfiles
|
154 |
+
* @return Provider\BaseProvider[]
|
155 |
+
*/
|
156 |
+
public function getProvidersForUser( $oUser, $bOnlyActiveProfiles = false ) {
|
157 |
+
$aProviders = array_filter( $this->getProviders(),
|
158 |
+
function ( $oProvider ) use ( $oUser, $bOnlyActiveProfiles ) {
|
159 |
+
/** @var Provider\BaseProvider $oProvider */
|
160 |
+
return $oProvider->isProviderAvailableToUser( $oUser )
|
161 |
+
&& ( !$bOnlyActiveProfiles || $oProvider->isProfileActive( $oUser ) );
|
162 |
+
}
|
163 |
+
);
|
164 |
+
// Backups should NEVER be the only 1 available.
|
165 |
+
if ( count( $aProviders ) === 1 && isset( $aProviders[ Provider\Backup::SLUG ] ) ) {
|
166 |
+
unset( $aProviders[ Provider\Backup::SLUG ] );
|
167 |
+
}
|
168 |
+
return $aProviders;
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* hooked to 'init' and only run if a user is logged-in (not on the login request)
|
173 |
+
*/
|
174 |
+
private function processActiveLoginIntent() {
|
175 |
+
/** @var LoginGuard\Options $oOpts */
|
176 |
+
$oOpts = $this->getOptions();
|
177 |
+
$oCon = $this->getCon();
|
178 |
+
$oReq = Services::Request();
|
179 |
+
$oWpResp = Services::Response();
|
180 |
+
$oUser = Services::WpUsers()->getCurrentWpUser();
|
181 |
+
|
182 |
+
// Is 2FA/login-intent submit
|
183 |
+
if ( $oReq->request( $this->getLoginIntentRequestFlag() ) == 1 ) {
|
184 |
+
|
185 |
+
if ( $oReq->post( 'cancel' ) == 1 ) {
|
186 |
+
Services::WpUsers()->logoutUser(); // clears the login and login intent
|
187 |
+
$sRedirectHref = $oReq->post( 'cancel_href' );
|
188 |
+
empty( $sRedirectHref ) ? $oWpResp->redirectToLogin() : $oWpResp->redirect( rawurldecode( $sRedirectHref ) );
|
189 |
+
}
|
190 |
+
elseif ( $this->validateLoginIntentRequest() ) {
|
191 |
+
|
192 |
+
if ( $oReq->post( 'skip_mfa' ) === 'Y' ) { // store the browser hash
|
193 |
+
$oCon->getUserMeta( $oUser )
|
194 |
+
->addMfaSkipAgent( $oReq->getUserAgent(), $oOpts->getMfaSkip() );
|
195 |
+
}
|
196 |
+
$oCon->fireEvent( '2fa_success' );
|
197 |
+
|
198 |
+
$sFlash = __( 'Success', 'wp-simple-firewall' ).'! '.__( 'Thank you for authenticating your login.', 'wp-simple-firewall' );
|
199 |
+
if ( $oOpts->isEnabledBackupCodes() ) {
|
200 |
+
$sFlash .= ' '.__( 'If you used your Backup Code, you will need to reset it.', 'wp-simple-firewall' ); //TODO::
|
201 |
+
}
|
202 |
+
$this->getMod()->setFlashAdminNotice( $sFlash );
|
203 |
+
|
204 |
+
$this->removeLoginIntent();
|
205 |
+
|
206 |
+
$sRedirectHref = $oReq->post( 'redirect_to' );
|
207 |
+
empty( $sRedirectHref ) ? $oWpResp->redirectHere() : $oWpResp->redirect( rawurldecode( $sRedirectHref ) );
|
208 |
+
}
|
209 |
+
else {
|
210 |
+
$oCon->getAdminNotices()
|
211 |
+
->addFlash(
|
212 |
+
__( 'One or more of your authentication codes failed or was missing.', 'wp-simple-firewall' ),
|
213 |
+
true
|
214 |
+
);
|
215 |
+
// We don't protect against loops here to prevent by-passing of the login intent page.
|
216 |
+
Services::Response()->redirect( Services::Request()->getUri(), [], true, false );
|
217 |
+
}
|
218 |
+
}
|
219 |
+
elseif ( $oOpts->isUseLoginIntentPage() ) {
|
220 |
+
$this->getLoginIntentPageHandler()->loadPage();
|
221 |
+
}
|
222 |
+
die();
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* assume that a user is logged in.
|
227 |
+
* @return bool
|
228 |
+
*/
|
229 |
+
private function validateLoginIntentRequest() {
|
230 |
+
try {
|
231 |
+
$bValid = ( new ValidateLoginIntentRequest() )
|
232 |
+
->setMfaController( $this )
|
233 |
+
->run();
|
234 |
+
}
|
235 |
+
catch ( \Exception $oE ) {
|
236 |
+
$bValid = true;
|
237 |
+
}
|
238 |
+
return $bValid;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* @param \WP_User $oUser
|
243 |
+
* @return bool
|
244 |
+
*/
|
245 |
+
private function canUserMfaSkip( $oUser ) {
|
246 |
+
/** @var LoginGuard\Options $oOpts */
|
247 |
+
$oOpts = $this->getOptions();
|
248 |
+
$oReq = Services::Request();
|
249 |
+
|
250 |
+
$oMeta = $this->getCon()->getUserMeta( $oUser );
|
251 |
+
if ( $oOpts->isMfaSkip() ) {
|
252 |
+
$aHashes = is_array( $oMeta->hash_loginmfa ) ? $oMeta->hash_loginmfa : [];
|
253 |
+
$sAgentHash = md5( $oReq->getUserAgent() );
|
254 |
+
$bCanSkip = isset( $aHashes[ $sAgentHash ] )
|
255 |
+
&& ( (int)$aHashes[ $sAgentHash ] + $oOpts->getMfaSkip() ) > $oReq->ts();
|
256 |
+
}
|
257 |
+
elseif ( $this->getCon()->isPremiumActive() && @class_exists( 'WC_Social_Login' ) ) {
|
258 |
+
// custom support for WooCommerce Social login
|
259 |
+
$oMeta = $this->getCon()->getUserMeta( $oUser );
|
260 |
+
$bCanSkip = isset( $oMeta->wc_social_login_valid ) ? $oMeta->wc_social_login_valid : false;
|
261 |
+
}
|
262 |
+
else {
|
263 |
+
/**
|
264 |
+
* TODO: remove the HTTP_REFERER bit once iCWP plugin is updated.
|
265 |
+
* We want logins from iCWP to skip 2FA. To achieve this, iCWP plugin needs
|
266 |
+
* to add a TRUE filter on 'odp-shield-2fa_skip' at the point of login.
|
267 |
+
* Until then, we'll use the HTTP referrer as an indicator
|
268 |
+
*/
|
269 |
+
$bCanSkip = apply_filters(
|
270 |
+
'odp-shield-2fa_skip',
|
271 |
+
strpos( $oReq->server( 'HTTP_REFERER' ), 'https://app.icontrolwp.com/' ) === 0
|
272 |
+
);
|
273 |
+
}
|
274 |
+
return $bCanSkip;
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* @param \WP_User $oUser
|
279 |
+
* @return bool
|
280 |
+
*/
|
281 |
+
private function isSubjectToLoginIntent( $oUser ) {
|
282 |
+
return count( $this->getProvidersForUser( $oUser, true ) ) > 0;
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* @return int
|
287 |
+
*/
|
288 |
+
private function getLoginIntentExpiresAt() {
|
289 |
+
return $this->getMod()->hasSession() ? $this->getMod()->getSession()->login_intent_expires_at : 0;
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* @return bool
|
294 |
+
*/
|
295 |
+
protected function hasLoginIntent() {
|
296 |
+
return $this->getLoginIntentExpiresAt() > 0;
|
297 |
+
}
|
298 |
+
|
299 |
+
/**
|
300 |
+
* Use this ONLY when the login intent has been successfully verified.
|
301 |
+
* @return $this
|
302 |
+
*/
|
303 |
+
private function removeLoginIntent() {
|
304 |
+
return $this->setLoginIntentExpiresAt( 0 );
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* @param int $nExpirationTime
|
309 |
+
* @return $this
|
310 |
+
*/
|
311 |
+
protected function setLoginIntentExpiresAt( $nExpirationTime ) {
|
312 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
313 |
+
$oMod = $this->getMod();
|
314 |
+
if ( $oMod->hasSession() ) {
|
315 |
+
/** @var Update $oUpd */
|
316 |
+
$oUpd = $oMod->getDbHandler_Sessions()->getQueryUpdater();
|
317 |
+
$oUpd->updateLoginIntentExpiresAt( $oMod->getSession(), $nExpirationTime );
|
318 |
+
}
|
319 |
+
return $this;
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* @return string
|
324 |
+
*/
|
325 |
+
private function getLoginIntentRequestFlag() {
|
326 |
+
return $this->getCon()->prefix( 'login-intent-request' );
|
327 |
+
}
|
328 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaControllerConsumer.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Trait MfaControllerConsumer
|
9 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor
|
10 |
+
*/
|
11 |
+
trait MfaControllerConsumer {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var MfaController
|
15 |
+
*/
|
16 |
+
private $oMfaController;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return MfaController
|
20 |
+
*/
|
21 |
+
public function getMfaCon() {
|
22 |
+
return $this->oMfaController;
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @param MfaController $oCon
|
27 |
+
* @return $this
|
28 |
+
*/
|
29 |
+
public function setMfaController( MfaController $oCon ) {
|
30 |
+
$this->oMfaController = $oCon;
|
31 |
+
return $this;
|
32 |
+
}
|
33 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Backup.php
ADDED
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class Backup extends BaseProvider {
|
9 |
+
|
10 |
+
const SLUG = 'backupcode';
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @inheritDoc
|
14 |
+
*/
|
15 |
+
public function renderUserProfileOptions( \WP_User $oUser ) {
|
16 |
+
$oCon = $this->getCon();
|
17 |
+
|
18 |
+
$aData = [
|
19 |
+
'strings' => [
|
20 |
+
'button_gen_code' => __( 'Generate ONE-Time Backup 2FA Login Code', 'wp-simple-firewall' ),
|
21 |
+
'button_del_code' => __( 'Delete Login Backup Code', 'wp-simple-firewall' ),
|
22 |
+
'not_available' => __( 'Backup login codes are not available if you do not have any other two-factor authentication modes active.', 'wp-simple-firewall' ),
|
23 |
+
'description_code' => __( 'Click to generate a backup login code for your two-factor authentication.', 'wp-simple-firewall' ),
|
24 |
+
'description_code_ext1' => sprintf( '%s: %s',
|
25 |
+
__( 'Important', 'wp-simple-firewall' ),
|
26 |
+
__( 'This code will be displayed only once and you may use it to verify your login only once.', 'wp-simple-firewall' )
|
27 |
+
.' '.__( 'Store it somewhere safe.', 'wp-simple-firewall' ) ),
|
28 |
+
'description_code_ext2' => __( 'Generating a new code will replace your existing code.', 'wp-simple-firewall' ),
|
29 |
+
'label_enter_code' => __( 'Create Backup 2FA Login Code', 'wp-simple-firewall' ),
|
30 |
+
'title' => __( 'Backup Login Code', 'wp-simple-firewall' ),
|
31 |
+
'cant_add_other_user' => sprintf( __( "Sorry, %s may not be added to another user's account.", 'wp-simple-firewall' ), 'Backup Codes' ),
|
32 |
+
'cant_remove_admins' => sprintf( __( "Sorry, %s may only be removed from another user's account by a Security Administrator.", 'wp-simple-firewall' ), __( 'Backup Codes', 'wp-simple-firewall' ) ),
|
33 |
+
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $oCon->getHumanName() ),
|
34 |
+
'remove_more_info' => sprintf( __( 'Understand how to remove Google Authenticator', 'wp-simple-firewall' ) )
|
35 |
+
]
|
36 |
+
];
|
37 |
+
|
38 |
+
return $this->getMod()
|
39 |
+
->renderTemplate(
|
40 |
+
'/snippets/user/profile/mfa/mfa_backup.twig',
|
41 |
+
Services::DataManipulation()->mergeArraysRecursive( $this->getCommonData( $oUser ), $aData ),
|
42 |
+
true
|
43 |
+
);
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @inheritDoc
|
48 |
+
*/
|
49 |
+
public function renderUserEditProfileOptions( \WP_User $oUser ) {
|
50 |
+
// Allow no actions to be taken on other user profiles
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @return array
|
55 |
+
*/
|
56 |
+
public function getFormField() {
|
57 |
+
return [
|
58 |
+
'name' => $this->getLoginFormParameter(),
|
59 |
+
'type' => 'text',
|
60 |
+
'value' => '',
|
61 |
+
'placeholder' => __( 'Please use your Backup Code to login.', 'wp-simple-firewall' ),
|
62 |
+
'text' => __( 'Login Backup Code', 'wp-simple-firewall' ),
|
63 |
+
'help_link' => '',
|
64 |
+
];
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @param \WP_User $oUser
|
69 |
+
* @return bool
|
70 |
+
*/
|
71 |
+
public function hasValidatedProfile( $oUser ) {
|
72 |
+
return $this->hasValidSecret( $oUser );
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @param \WP_User $oUser
|
77 |
+
* @return $this
|
78 |
+
*/
|
79 |
+
public function postSuccessActions( \WP_User $oUser ) {
|
80 |
+
$this->deleteSecret( $oUser );
|
81 |
+
$this->sendBackupCodeUsedEmail( $oUser );
|
82 |
+
return $this;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Backup Code are 1-time only and if you have MFA, then we need to remove all the other tracking factors
|
87 |
+
* @param \WP_User $oUser
|
88 |
+
* @param string $sOtpCode
|
89 |
+
* @return bool
|
90 |
+
*/
|
91 |
+
protected function processOtp( $oUser, $sOtpCode ) {
|
92 |
+
return $this->validateBackupCode( $oUser, $sOtpCode );
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @param \WP_User $oUser
|
97 |
+
* @param string $sOtpCode
|
98 |
+
* @return bool
|
99 |
+
*/
|
100 |
+
private function validateBackupCode( $oUser, $sOtpCode ) {
|
101 |
+
return wp_check_password( str_replace( '-', '', $sOtpCode ), $this->getSecret( $oUser ) );
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* @param \WP_User $oUser
|
106 |
+
* @param bool $bIsSuccess
|
107 |
+
*/
|
108 |
+
protected function auditLogin( $oUser, $bIsSuccess ) {
|
109 |
+
$this->getCon()->fireEvent(
|
110 |
+
$bIsSuccess ? '2fa_backupcode_verified' : '2fa_backupcode_fail',
|
111 |
+
[
|
112 |
+
'audit' => [
|
113 |
+
'user_login' => $oUser->user_login,
|
114 |
+
'method' => 'Backup Code',
|
115 |
+
]
|
116 |
+
]
|
117 |
+
);
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* @param \WP_User $oUser
|
122 |
+
* @return string
|
123 |
+
*/
|
124 |
+
protected function genNewSecret( \WP_User $oUser ) {
|
125 |
+
return wp_generate_password( 25, false );
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* @return bool
|
130 |
+
*/
|
131 |
+
public function isProviderEnabled() {
|
132 |
+
/** @var LoginGuard\Options $oOpts */
|
133 |
+
$oOpts = $this->getOptions();
|
134 |
+
return $oOpts->isEnabledBackupCodes();
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* @param \WP_User $oUser
|
139 |
+
* @param string $sNewSecret
|
140 |
+
* @return $this
|
141 |
+
*/
|
142 |
+
protected function setSecret( $oUser, $sNewSecret ) {
|
143 |
+
parent::setSecret( $oUser, wp_hash_password( $sNewSecret ) );
|
144 |
+
return $this;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* @param \WP_User $oUser
|
149 |
+
*/
|
150 |
+
private function sendBackupCodeUsedEmail( $oUser ) {
|
151 |
+
$aEmailContent = [
|
152 |
+
__( 'This is a quick notice to inform you that your Backup Login code was just used.', 'wp-simple-firewall' ),
|
153 |
+
__( "Your WordPress account had only 1 backup login code.", 'wp-simple-firewall' )
|
154 |
+
.' '.__( "You must go to your profile and regenerate a new code if you want to use this method again.", 'wp-simple-firewall' ),
|
155 |
+
'',
|
156 |
+
sprintf( '<strong>%s</strong>', __( 'Login Details', 'wp-simple-firewall' ) ),
|
157 |
+
sprintf( '%s: %s', __( 'URL', 'wp-simple-firewall' ), Services::WpGeneral()->getHomeUrl() ),
|
158 |
+
sprintf( '%s: %s', __( 'Username', 'wp-simple-firewall' ), $oUser->user_login ),
|
159 |
+
sprintf( '%s: %s', __( 'IP Address', 'wp-simple-firewall' ), Services::IP()->getRequestIp() ),
|
160 |
+
'',
|
161 |
+
__( 'Thank You.', 'wp-simple-firewall' ),
|
162 |
+
];
|
163 |
+
|
164 |
+
$sTitle = sprintf( __( "Notice: %s", 'wp-simple-firewall' ), __( "Backup Login Code Just Used", 'wp-simple-firewall' ) );
|
165 |
+
$this->getMod()
|
166 |
+
->getEmailProcessor()
|
167 |
+
->sendEmailWithWrap( $oUser->user_email, $sTitle, $aEmailContent );
|
168 |
+
}
|
169 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/BaseProvider.php
ADDED
@@ -0,0 +1,258 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
abstract class BaseProvider {
|
9 |
+
|
10 |
+
use Modules\ModConsumer;
|
11 |
+
const SLUG = '';
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Assumes this is only called on active profiles
|
15 |
+
* @param \WP_User $oUser
|
16 |
+
* @return bool
|
17 |
+
*/
|
18 |
+
public function validateLoginIntent( \WP_User $oUser ) {
|
19 |
+
$bOtpSuccess = false;
|
20 |
+
$sReqOtpCode = $this->fetchCodeFromRequest();
|
21 |
+
if ( !empty( $sReqOtpCode ) ) {
|
22 |
+
$bOtpSuccess = $this->processOtp( $oUser, $sReqOtpCode );
|
23 |
+
$this->postOtpProcessAction( $oUser, $bOtpSuccess );
|
24 |
+
}
|
25 |
+
return $bOtpSuccess;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @param \WP_User $oUser
|
30 |
+
* @return string
|
31 |
+
*/
|
32 |
+
protected function getSecret( \WP_User $oUser ) {
|
33 |
+
$sSecret = $this->getCon()->getUserMeta( $oUser )->{static::SLUG.'_secret'};
|
34 |
+
return empty( $sSecret ) ? '' : $sSecret;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @param \WP_User $oUser
|
39 |
+
* @return bool
|
40 |
+
*/
|
41 |
+
public function hasValidatedProfile( $oUser ) {
|
42 |
+
return $this->getCon()->getUserMeta( $oUser )->{static::SLUG.'_validated'} === true;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @param \WP_User $oUser
|
47 |
+
* @return bool
|
48 |
+
*/
|
49 |
+
protected function hasValidSecret( \WP_User $oUser ) {
|
50 |
+
return $this->isSecretValid( $this->getSecret( $oUser ) );
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @param \WP_User $oUser
|
55 |
+
* @return bool
|
56 |
+
*/
|
57 |
+
protected function isEnforced( $oUser ) {
|
58 |
+
return false;
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @param \WP_User $oUser
|
63 |
+
* @return bool
|
64 |
+
*/
|
65 |
+
public function isProfileActive( \WP_User $oUser ) {
|
66 |
+
return $this->hasValidSecret( $oUser );
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* @param \WP_User $oUser
|
71 |
+
* @return bool
|
72 |
+
*/
|
73 |
+
public function isProviderAvailableToUser( \WP_User $oUser ) {
|
74 |
+
return $this->isProviderEnabled();
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @return bool
|
79 |
+
*/
|
80 |
+
abstract public function isProviderEnabled();
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @param string $sSecret
|
84 |
+
* @return bool
|
85 |
+
*/
|
86 |
+
protected function isSecretValid( $sSecret ) {
|
87 |
+
return !empty( $sSecret ) && is_string( $sSecret );
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* @param \WP_User $oUser
|
92 |
+
* @return $this
|
93 |
+
*/
|
94 |
+
public function deleteSecret( $oUser ) {
|
95 |
+
$this->getCon()
|
96 |
+
->getUserMeta( $oUser )->{static::SLUG.'_secret'} = null;
|
97 |
+
return $this;
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* @param \WP_User $oUser
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
+
public function resetSecret( \WP_User $oUser ) {
|
105 |
+
$sNewSecret = $this->genNewSecret( $oUser );
|
106 |
+
$this->setSecret( $oUser, $sNewSecret );
|
107 |
+
return $sNewSecret;
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* @param \WP_User $oUser
|
112 |
+
* @param bool $bValidated set true for validated, false for invalidated
|
113 |
+
* @return $this
|
114 |
+
*/
|
115 |
+
public function setProfileValidated( $oUser, $bValidated = true ) {
|
116 |
+
$this->getCon()
|
117 |
+
->getUserMeta( $oUser )->{static::SLUG.'_validated'} = $bValidated;
|
118 |
+
return $this;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* @param \WP_User $oUser
|
123 |
+
* @param string $sNewSecret
|
124 |
+
* @return $this
|
125 |
+
*/
|
126 |
+
protected function setSecret( $oUser, $sNewSecret ) {
|
127 |
+
$this->getCon()
|
128 |
+
->getUserMeta( $oUser )->{static::SLUG.'_secret'} = $sNewSecret;
|
129 |
+
return $this;
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* @param \WP_User $oUser
|
134 |
+
* @return string
|
135 |
+
*/
|
136 |
+
protected function genNewSecret( \WP_User $oUser ) {
|
137 |
+
return '';
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @param \WP_User $oUser
|
142 |
+
* @param string $sOtpCode
|
143 |
+
* @return bool
|
144 |
+
*/
|
145 |
+
abstract protected function processOtp( $oUser, $sOtpCode );
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Only to be fired if and when Login has been completely verified.
|
149 |
+
* @param \WP_User $oUser
|
150 |
+
* @return $this
|
151 |
+
*/
|
152 |
+
public function postSuccessActions( \WP_User $oUser ) {
|
153 |
+
return $this;
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
158 |
+
* functions. Otherwise we need to be careful of mixing up users.
|
159 |
+
* @param \WP_User $oUser
|
160 |
+
* @return string
|
161 |
+
*/
|
162 |
+
public function renderUserProfileOptions( \WP_User $oUser ) {
|
163 |
+
return '';
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* ONLY TO BE HOOKED TO USER PROFILE EDIT
|
168 |
+
* @param \WP_User $oUser
|
169 |
+
* @return string
|
170 |
+
*/
|
171 |
+
public function renderUserEditProfileOptions( \WP_User $oUser ) {
|
172 |
+
return $this->renderUserProfileOptions( $oUser );
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* @param \WP_User $oUser
|
177 |
+
*/
|
178 |
+
public function handleEditOtherUserProfileSubmit( \WP_User $oUser ) {
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* @param \WP_User $oUser
|
183 |
+
*/
|
184 |
+
protected function processRemovalFromAccount( $oUser ) {
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* This MUST only ever be hooked into when the User is looking at their OWN profile,
|
189 |
+
* so we can use "current user" functions. Otherwise we need to be careful of mixing up users.
|
190 |
+
* @param \WP_User $oUser
|
191 |
+
*/
|
192 |
+
public function handleUserProfileSubmit( \WP_User $oUser ) {
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* @param \WP_User $oUser
|
197 |
+
*/
|
198 |
+
public function captureLoginAttempt( $oUser ) {
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* @return array
|
203 |
+
*/
|
204 |
+
abstract public function getFormField();
|
205 |
+
|
206 |
+
/**
|
207 |
+
* @param \WP_User $oUser
|
208 |
+
* @param bool $bIsSuccess
|
209 |
+
*/
|
210 |
+
abstract protected function auditLogin( $oUser, $bIsSuccess );
|
211 |
+
|
212 |
+
/**
|
213 |
+
* @param \WP_User $oUser
|
214 |
+
* @param bool $bIsOtpSuccess
|
215 |
+
* @return $this
|
216 |
+
*/
|
217 |
+
protected function postOtpProcessAction( $oUser, $bIsOtpSuccess ) {
|
218 |
+
$this->auditLogin( $oUser, $bIsOtpSuccess );
|
219 |
+
return $this;
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* @return string
|
224 |
+
*/
|
225 |
+
protected function getLoginFormParameter() {
|
226 |
+
return $this->getCon()->prefixOption( static::SLUG.'_otp' );
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* @return string
|
231 |
+
*/
|
232 |
+
protected function fetchCodeFromRequest() {
|
233 |
+
return esc_attr( Services::Request()->request( $this->getLoginFormParameter(), false, '' ) );
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* @param \WP_User $oUser
|
238 |
+
* @return array
|
239 |
+
*/
|
240 |
+
protected function getCommonData( \WP_User $oUser ) {
|
241 |
+
return [
|
242 |
+
'flags' => [
|
243 |
+
'has_validated_profile' => $this->hasValidatedProfile( $oUser ),
|
244 |
+
'is_enforced' => $this->isEnforced( $oUser ),
|
245 |
+
'is_profile_active' => $this->isProfileActive( $oUser ),
|
246 |
+
'is_my_user_profile' => $oUser->ID == Services::WpUsers()->getCurrentWpUserId(),
|
247 |
+
'i_am_valid_admin' => $this->getCon()->isPluginAdmin(),
|
248 |
+
'user_to_edit_is_admin' => Services::WpUsers()->isUserAdmin( $oUser ),
|
249 |
+
],
|
250 |
+
'vars' => [
|
251 |
+
'otp_field_name' => $this->getLoginFormParameter(),
|
252 |
+
],
|
253 |
+
'strings' => [
|
254 |
+
'is_enforced' => __( 'This setting is enforced by your security administrator.', 'wp-simple-firewall' ),
|
255 |
+
],
|
256 |
+
];
|
257 |
+
}
|
258 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Email.php
ADDED
@@ -0,0 +1,237 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class Email extends BaseProvider {
|
9 |
+
|
10 |
+
const SLUG = 'email';
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @param \WP_User $oUser
|
14 |
+
*/
|
15 |
+
public function captureLoginAttempt( $oUser ) {
|
16 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
17 |
+
$oMod = $this->getMod();
|
18 |
+
|
19 |
+
/** @var \FernleafSystems\Wordpress\Plugin\Shield\Databases\Session\Update $oUpd */
|
20 |
+
$oUpd = $oMod->getDbHandler_Sessions()->getQueryUpdater();
|
21 |
+
$oUpd->setLoginIntentCodeEmail( $oMod->getSession(), $this->getSecret( $oUser ) );
|
22 |
+
|
23 |
+
// Now send email with authentication link for user.
|
24 |
+
$this->sendEmailTwoFactorVerify( $oUser );
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @param \WP_User $oUser
|
29 |
+
* @param bool $bIsSuccess
|
30 |
+
*/
|
31 |
+
protected function auditLogin( $oUser, $bIsSuccess ) {
|
32 |
+
$this->getCon()->fireEvent(
|
33 |
+
$bIsSuccess ? 'email_verified' : 'email_fail',
|
34 |
+
[
|
35 |
+
'audit' => [
|
36 |
+
'user_login' => $oUser->user_login,
|
37 |
+
'method' => 'Email',
|
38 |
+
]
|
39 |
+
]
|
40 |
+
);
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param \WP_User $oUser
|
45 |
+
* @return $this
|
46 |
+
*/
|
47 |
+
public function postSuccessActions( \WP_User $oUser ) {
|
48 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
49 |
+
$oMod = $this->getMod();
|
50 |
+
/** @var \FernleafSystems\Wordpress\Plugin\Shield\Databases\Session\Update $oUpd */
|
51 |
+
$oUpd = $oMod->getDbHandler_Sessions()->getQueryUpdater();
|
52 |
+
$oUpd->clearLoginIntentCodeEmail( $oMod->getSession() );
|
53 |
+
return $this;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @param \WP_User $oUser
|
58 |
+
* @param string $sOtpCode
|
59 |
+
* @return bool
|
60 |
+
*/
|
61 |
+
protected function processOtp( $oUser, $sOtpCode ) {
|
62 |
+
return $sOtpCode == $this->getStoredSessionHashCode();
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* @return array
|
67 |
+
*/
|
68 |
+
public function getFormField() {
|
69 |
+
return [
|
70 |
+
'name' => $this->getLoginFormParameter(),
|
71 |
+
'type' => 'text',
|
72 |
+
'value' => $this->fetchCodeFromRequest(),
|
73 |
+
'placeholder' => __( 'This code was just sent to your registered Email address.', 'wp-simple-firewall' ),
|
74 |
+
'text' => __( 'Email OTP', 'wp-simple-firewall' ),
|
75 |
+
'help_link' => 'https://shsec.io/3t'
|
76 |
+
];
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* We don't use user meta as it's dependent on the particular user sessions in-use
|
81 |
+
* @param \WP_User $oUser
|
82 |
+
* @return string
|
83 |
+
*/
|
84 |
+
protected function getSecret( \WP_User $oUser ) {
|
85 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
86 |
+
$oMod = $this->getMod();
|
87 |
+
return strtoupper( substr(
|
88 |
+
hash_hmac( 'sha1', $this->getCon()->getUniqueRequestId(), $oMod->getTwoAuthSecretKey() ),
|
89 |
+
0, 6
|
90 |
+
) );
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* @return string The unique 2FA 6-digit code
|
95 |
+
*/
|
96 |
+
protected function getStoredSessionHashCode() {
|
97 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
98 |
+
$oMod = $this->getMod();
|
99 |
+
return $oMod->hasSession() ? $oMod->getSession()->getLoginIntentCodeEmail() : '';
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @inheritDoc
|
104 |
+
*/
|
105 |
+
public function handleUserProfileSubmit( \WP_User $oUser ) {
|
106 |
+
|
107 |
+
$bWasEnabled = $this->isProfileActive( $oUser );
|
108 |
+
$bToEnable = Services::Request()->post( 'shield_enable_mfaemail' ) === 'Y';
|
109 |
+
|
110 |
+
$sMsg = null;
|
111 |
+
$bError = false;
|
112 |
+
if ( $bToEnable ) {
|
113 |
+
$this->setProfileValidated( $oUser );
|
114 |
+
if ( !$bWasEnabled ) {
|
115 |
+
$sMsg = __( 'Email Two-Factor Authentication has been enabled.', 'wp-simple-firewall' );
|
116 |
+
}
|
117 |
+
}
|
118 |
+
elseif ( $this->isEnforced( $oUser ) ) {
|
119 |
+
$sMsg = __( "Email Two-Factor Authentication couldn't be disabled because it is enforced based on your user roles.", 'wp-simple-firewall' );
|
120 |
+
$bError = true;
|
121 |
+
}
|
122 |
+
else {
|
123 |
+
$this->setProfileValidated( $oUser, false );
|
124 |
+
$sMsg = __( 'Email Two-Factor Authentication was has been disabled.', 'wp-simple-firewall' );
|
125 |
+
}
|
126 |
+
|
127 |
+
if ( !empty( $sMsg ) ) {
|
128 |
+
$this->getMod()->setFlashAdminNotice( $sMsg, $bError );
|
129 |
+
}
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* @param \WP_User $oUser
|
134 |
+
* @return bool
|
135 |
+
*/
|
136 |
+
public function isProfileActive( \WP_User $oUser ) {
|
137 |
+
/** @var LoginGuard\Options $oOpts */
|
138 |
+
$oOpts = $this->getOptions();
|
139 |
+
return parent::isProfileActive( $oUser ) &&
|
140 |
+
( $this->isEnforced( $oUser ) ||
|
141 |
+
( $this->hasValidatedProfile( $oUser ) && $oOpts->isEnabledEmailAuthAnyUserSet() ) );
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @param \WP_User $oUser
|
146 |
+
* @return bool
|
147 |
+
*/
|
148 |
+
protected function isEnforced( $oUser ) {
|
149 |
+
/** @var LoginGuard\Options $oOpts */
|
150 |
+
$oOpts = $this->getOptions();
|
151 |
+
return count( array_intersect( $oOpts->getEmail2FaRoles(), $oUser->roles ) ) > 0;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* @param \WP_User $oUser
|
156 |
+
* @return $this
|
157 |
+
*/
|
158 |
+
private function sendEmailTwoFactorVerify( \WP_User $oUser ) {
|
159 |
+
$aMessage = [
|
160 |
+
__( 'Someone attempted to login into this WordPress site using your account.', 'wp-simple-firewall' ),
|
161 |
+
__( 'Login requires verification with the following code.', 'wp-simple-firewall' ),
|
162 |
+
'',
|
163 |
+
sprintf( __( 'Verification Code: %s', 'wp-simple-firewall' ), sprintf( '<strong>%s</strong>', $this->getSecret( $oUser ) ) ),
|
164 |
+
'',
|
165 |
+
sprintf( '<strong>%s</strong>', __( 'Login Details', 'wp-simple-firewall' ) ),
|
166 |
+
sprintf( '%s: %s', __( 'URL', 'wp-simple-firewall' ), Services::WpGeneral()->getHomeUrl() ),
|
167 |
+
sprintf( '%s: %s', __( 'Username', 'wp-simple-firewall' ), $oUser->user_login ),
|
168 |
+
sprintf( '%s: %s', __( 'IP Address', 'wp-simple-firewall' ), Services::IP()->getRequestIp() ),
|
169 |
+
'',
|
170 |
+
];
|
171 |
+
|
172 |
+
if ( !$this->getCon()->isRelabelled() ) {
|
173 |
+
$aMessage[] = sprintf( '- <a href="%s" target="_blank">%s</a>', 'https://shsec.io/96', __( 'Why no login link?', 'wp-simple-firewall' ) );
|
174 |
+
$aContent[] = '';
|
175 |
+
}
|
176 |
+
|
177 |
+
$bResult = $this->getMod()
|
178 |
+
->getEmailProcessor()
|
179 |
+
->sendEmailWithWrap(
|
180 |
+
$oUser->user_email,
|
181 |
+
__( 'Two-Factor Login Verification', 'wp-simple-firewall' ),
|
182 |
+
$aMessage
|
183 |
+
);
|
184 |
+
|
185 |
+
$this->getCon()->fireEvent(
|
186 |
+
$bResult ? '2fa_email_send_success' : '2fa_email_send_fail',
|
187 |
+
[
|
188 |
+
'audit' => [
|
189 |
+
'user_login' => $oUser->user_login,
|
190 |
+
]
|
191 |
+
]
|
192 |
+
);
|
193 |
+
return $this;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* @inheritDoc
|
198 |
+
*/
|
199 |
+
public function renderUserProfileOptions( \WP_User $oUser ) {
|
200 |
+
$aData = [
|
201 |
+
'strings' => [
|
202 |
+
'label_email_authentication' => __( 'Email Authentication', 'wp-simple-firewall' ),
|
203 |
+
'title' => __( 'Email Authentication', 'wp-simple-firewall' ),
|
204 |
+
'description_email_authentication_checkbox' => __( 'Check the box to enable email-based login authentication.', 'wp-simple-firewall' ),
|
205 |
+
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $this->getCon()
|
206 |
+
->getHumanName() )
|
207 |
+
]
|
208 |
+
];
|
209 |
+
|
210 |
+
return $this->getMod()
|
211 |
+
->renderTemplate(
|
212 |
+
'/snippets/user/profile/mfa/mfa_email.twig',
|
213 |
+
Services::DataManipulation()->mergeArraysRecursive( $this->getCommonData( $oUser ), $aData ),
|
214 |
+
true
|
215 |
+
);
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* @return bool
|
220 |
+
*/
|
221 |
+
public function isProviderEnabled() {
|
222 |
+
/** @var LoginGuard\Options $oOpts */
|
223 |
+
$oOpts = $this->getOptions();
|
224 |
+
return $oOpts->isEmailAuthenticationActive();
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* @param \WP_User $oUser
|
229 |
+
* @return bool
|
230 |
+
*/
|
231 |
+
public function isProviderAvailableToUser( \WP_User $oUser ) {
|
232 |
+
/** @var LoginGuard\Options $oOpts */
|
233 |
+
$oOpts = $this->getOptions();
|
234 |
+
return parent::isProviderAvailableToUser( $oUser )
|
235 |
+
&& ( $this->isEnforced( $oUser ) || $oOpts->isEnabledEmailAuthAnyUserSet() );
|
236 |
+
}
|
237 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/GoogleAuth.php
ADDED
@@ -0,0 +1,260 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
|
4 |
+
|
5 |
+
use Dolondro\GoogleAuthenticator;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class GoogleAuth extends BaseProvider {
|
10 |
+
|
11 |
+
const SLUG = 'ga';
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var GoogleAuthenticator\Secret
|
15 |
+
*/
|
16 |
+
private $oWorkingSecret;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @param \WP_User $oUser
|
20 |
+
* @return bool
|
21 |
+
*/
|
22 |
+
public function isProfileActive( \WP_User $oUser ) {
|
23 |
+
return $this->hasValidSecret( $oUser ) && $this->hasValidatedProfile( $oUser );
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @inheritDoc
|
28 |
+
*/
|
29 |
+
public function renderUserProfileOptions( \WP_User $oUser ) {
|
30 |
+
$oCon = $this->getCon();
|
31 |
+
|
32 |
+
$bValidatedProfile = $this->hasValidatedProfile( $oUser );
|
33 |
+
|
34 |
+
$aData = [
|
35 |
+
'hrefs' => [
|
36 |
+
'src_chart_url' => $bValidatedProfile ? '' : $this->getGaRegisterChartUrl( $oUser ),
|
37 |
+
],
|
38 |
+
'vars' => [
|
39 |
+
'ga_secret' => $bValidatedProfile ? $this->getSecret( $oUser ) : $this->resetSecret( $oUser ),
|
40 |
+
],
|
41 |
+
'strings' => [
|
42 |
+
'enter_auth_app_code' => __( 'Enter the 6-digit code from your Authenticator App', 'wp-simple-firewall' ),
|
43 |
+
'description_otp_code' => __( 'Provide the current code generated by your Google Authenticator app.', 'wp-simple-firewall' ),
|
44 |
+
'description_chart_url' => __( 'Use your Google Authenticator app to scan this QR code and enter the 6-digit one time password.', 'wp-simple-firewall' ),
|
45 |
+
'description_ga_secret' => __( 'If you have a problem with scanning the QR code enter the long code manually into the app.', 'wp-simple-firewall' ),
|
46 |
+
'desc_remove' => __( 'Check the box to remove Google Authenticator login authentication.', 'wp-simple-firewall' ),
|
47 |
+
'label_check_to_remove' => sprintf( __( 'Remove %s', 'wp-simple-firewall' ), __( 'Google Authenticator', 'wp-simple-firewall' ) ),
|
48 |
+
'label_enter_code' => __( 'Google Authenticator Code', 'wp-simple-firewall' ),
|
49 |
+
'label_ga_secret' => __( 'Manual Code', 'wp-simple-firewall' ),
|
50 |
+
'label_scan_qr_code' => __( 'Scan This QR Code', 'wp-simple-firewall' ),
|
51 |
+
'title' => __( 'Google Authenticator', 'wp-simple-firewall' ),
|
52 |
+
'cant_add_other_user' => sprintf( __( "Sorry, %s may not be added to another user's account.", 'wp-simple-firewall' ), 'Google Authenticator' ),
|
53 |
+
'cant_remove_admins' => sprintf( __( "Sorry, %s may only be removed from another user's account by a Security Administrator.", 'wp-simple-firewall' ), __( 'Google Authenticator', 'wp-simple-firewall' ) ),
|
54 |
+
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $oCon->getHumanName() ),
|
55 |
+
'remove_more_info' => sprintf( __( 'Understand how to remove Google Authenticator', 'wp-simple-firewall' ) )
|
56 |
+
],
|
57 |
+
];
|
58 |
+
|
59 |
+
return $this->getMod()
|
60 |
+
->renderTemplate(
|
61 |
+
'/snippets/user/profile/mfa/mfa_ga.twig',
|
62 |
+
Services::DataManipulation()->mergeArraysRecursive( $this->getCommonData( $oUser ), $aData ),
|
63 |
+
true
|
64 |
+
);
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @param \WP_User $oUser
|
69 |
+
* @return string
|
70 |
+
*/
|
71 |
+
public function getGaRegisterChartUrl( $oUser ) {
|
72 |
+
$sUrl = '';
|
73 |
+
if ( !empty( $oUser ) ) {
|
74 |
+
try {
|
75 |
+
$sUrl = ( new GoogleAuthenticator\QrImageGenerator\GoogleQrImageGenerator () )
|
76 |
+
->generateUri(
|
77 |
+
$this->getGaSecret( $oUser )
|
78 |
+
);
|
79 |
+
}
|
80 |
+
catch ( \InvalidArgumentException $e ) {
|
81 |
+
}
|
82 |
+
}
|
83 |
+
return $sUrl;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* The only thing we can do is REMOVE Google Authenticator from an account that is not our own
|
88 |
+
* But, only admins can do this. If Security Admin feature is enabled, then only they can do it.
|
89 |
+
* @inheritDoc
|
90 |
+
*/
|
91 |
+
public function handleEditOtherUserProfileSubmit( \WP_User $oUser ) {
|
92 |
+
|
93 |
+
// Can only edit other users if you're admin/security-admin
|
94 |
+
if ( $this->getCon()->isPluginAdmin() && Services::Request()->post( 'shield_turn_off_ga' ) === 'Y' ) {
|
95 |
+
$this->processRemovalFromAccount( $oUser );
|
96 |
+
$sMsg = __( 'Google Authenticator was successfully removed from the account.', 'wp-simple-firewall' );
|
97 |
+
$this->getMod()->setFlashAdminNotice( $sMsg );
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @param \WP_User $oUser
|
103 |
+
* @return $this
|
104 |
+
*/
|
105 |
+
protected function processRemovalFromAccount( $oUser ) {
|
106 |
+
$this->setProfileValidated( $oUser, false )
|
107 |
+
->resetSecret( $oUser );
|
108 |
+
return $this;
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* @inheritDoc
|
113 |
+
*/
|
114 |
+
public function handleUserProfileSubmit( \WP_User $oUser ) {
|
115 |
+
$sOtp = $this->fetchCodeFromRequest();
|
116 |
+
|
117 |
+
if ( Services::Request()->post( 'shield_turn_off_ga' ) === 'Y' ) {
|
118 |
+
$sFlash = __( 'Google Authenticator was successfully removed from the account.', 'wp-simple-firewall' );
|
119 |
+
$this->processRemovalFromAccount( $oUser );
|
120 |
+
$this->getMod()->setFlashAdminNotice( $sFlash );
|
121 |
+
/**
|
122 |
+
* $sFlash = __( 'An email has been sent to you in order to confirm Google Authenticator removal', 'wp-simple-firewall' );
|
123 |
+
* $sFlash = __( 'We tried to send an email for you to confirm Google Authenticator removal but it failed.', 'wp-simple-firewall' );
|
124 |
+
*/
|
125 |
+
}
|
126 |
+
elseif ( !empty( $sOtp ) && !$this->hasValidatedProfile( $oUser ) ) { // Add GA to profile
|
127 |
+
$bValidOtp = $this->processOtp( $oUser, $sOtp );
|
128 |
+
if ( $bValidOtp ) {
|
129 |
+
$this->setProfileValidated( $oUser );
|
130 |
+
$sFlash = sprintf(
|
131 |
+
__( '%s was successfully added to your account.', 'wp-simple-firewall' ),
|
132 |
+
__( 'Google Authenticator', 'wp-simple-firewall' )
|
133 |
+
);
|
134 |
+
}
|
135 |
+
else {
|
136 |
+
$this->resetSecret( $oUser );
|
137 |
+
$sFlash = __( 'One Time Password (OTP) was not valid.', 'wp-simple-firewall' )
|
138 |
+
.' '.__( 'Please try again.', 'wp-simple-firewall' );
|
139 |
+
}
|
140 |
+
$this->getMod()->setFlashAdminNotice( $sFlash, !$bValidOtp );
|
141 |
+
}
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @return array
|
146 |
+
*/
|
147 |
+
public function getFormField() {
|
148 |
+
return [
|
149 |
+
'name' => $this->getLoginFormParameter(),
|
150 |
+
'type' => 'text',
|
151 |
+
'value' => '',
|
152 |
+
'placeholder' => __( 'Please use your Google Authenticator App to retrieve your code.', 'wp-simple-firewall' ),
|
153 |
+
'text' => __( 'Google Authenticator Code', 'wp-simple-firewall' ),
|
154 |
+
'help_link' => 'https://shsec.io/wpsf42',
|
155 |
+
'extras' => [
|
156 |
+
'onkeyup' => "this.value=this.value.replace(/[^\d]/g,'')"
|
157 |
+
]
|
158 |
+
];
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* @param \WP_User $oUser
|
163 |
+
* @param string $sOtpCode
|
164 |
+
* @return bool
|
165 |
+
*/
|
166 |
+
protected function processOtp( $oUser, $sOtpCode ) {
|
167 |
+
return $this->validateGaCode( $oUser, $sOtpCode );
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @param \WP_User $oUser
|
172 |
+
* @param string $sOtpCode
|
173 |
+
* @return bool
|
174 |
+
*/
|
175 |
+
public function validateGaCode( $oUser, $sOtpCode ) {
|
176 |
+
$bValidOtp = false;
|
177 |
+
if ( preg_match( '#^[0-9]{6}$#', $sOtpCode ) ) {
|
178 |
+
try {
|
179 |
+
$bValidOtp = ( new GoogleAuthenticator\GoogleAuthenticator() )
|
180 |
+
->authenticate( $this->getSecret( $oUser ), $sOtpCode );
|
181 |
+
}
|
182 |
+
catch ( \Exception $oE ) {
|
183 |
+
}
|
184 |
+
catch ( \Psr\Cache\CacheException $oE ) {
|
185 |
+
}
|
186 |
+
}
|
187 |
+
return $bValidOtp;
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* @param \WP_User $oUser
|
192 |
+
* @param bool $bIsSuccess
|
193 |
+
*/
|
194 |
+
protected function auditLogin( $oUser, $bIsSuccess ) {
|
195 |
+
$this->getCon()->fireEvent(
|
196 |
+
$bIsSuccess ? 'googleauth_verified' : 'googleauth_fail',
|
197 |
+
[
|
198 |
+
'audit' => [
|
199 |
+
'user_login' => $oUser->user_login,
|
200 |
+
'method' => 'Google Authenticator',
|
201 |
+
]
|
202 |
+
]
|
203 |
+
);
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* @param \WP_User $oUser
|
208 |
+
* @return string
|
209 |
+
*/
|
210 |
+
protected function genNewSecret( \WP_User $oUser ) {
|
211 |
+
try {
|
212 |
+
return $this->getGaSecret( $oUser )->getSecretKey();
|
213 |
+
}
|
214 |
+
catch ( \InvalidArgumentException $oE ) {
|
215 |
+
return '';
|
216 |
+
}
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* @param \WP_User $oUser
|
221 |
+
* @return GoogleAuthenticator\Secret
|
222 |
+
* @throws \InvalidArgumentException
|
223 |
+
*/
|
224 |
+
private function getGaSecret( $oUser ) {
|
225 |
+
if ( !isset( $this->oWorkingSecret ) ) {
|
226 |
+
$this->oWorkingSecret = ( new GoogleAuthenticator\SecretFactory() )
|
227 |
+
->create(
|
228 |
+
sanitize_user( $oUser->user_login ),
|
229 |
+
preg_replace( '#[^0-9a-z]#i', '', Services::WpGeneral()->getSiteName() )
|
230 |
+
);
|
231 |
+
}
|
232 |
+
return $this->oWorkingSecret;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* @param \WP_User $oUser
|
237 |
+
* @return string
|
238 |
+
*/
|
239 |
+
protected function getSecret( \WP_User $oUser ) {
|
240 |
+
$sSec = parent::getSecret( $oUser );
|
241 |
+
return empty( $sSec ) ? $this->resetSecret( $oUser ) : $sSec;
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* @param string $sSecret
|
246 |
+
* @return bool
|
247 |
+
*/
|
248 |
+
protected function isSecretValid( $sSecret ) {
|
249 |
+
return parent::isSecretValid( $sSecret ) && ( strlen( $sSecret ) == 16 );
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* @return bool
|
254 |
+
*/
|
255 |
+
public function isProviderEnabled() {
|
256 |
+
/** @var LoginGuard\Options $oOpts */
|
257 |
+
$oOpts = $this->getOptions();
|
258 |
+
return $oOpts->isEnabledGoogleAuthenticator();
|
259 |
+
}
|
260 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Yubikey.php
ADDED
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class Yubikey extends BaseProvider {
|
9 |
+
|
10 |
+
const SLUG = 'yubi';
|
11 |
+
const OTP_LENGTH = 12;
|
12 |
+
const URL_YUBIKEY_VERIFY = 'https://api.yubico.com/wsapi/2.0/verify';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param \WP_User $oUser
|
16 |
+
* @return bool
|
17 |
+
*/
|
18 |
+
public function isProfileActive( \WP_User $oUser ) {
|
19 |
+
return $this->hasValidSecret( $oUser );
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @inheritDoc
|
24 |
+
*/
|
25 |
+
public function renderUserProfileOptions( \WP_User $oUser ) {
|
26 |
+
$oCon = $this->getCon();
|
27 |
+
|
28 |
+
$aData = [
|
29 |
+
'vars' => [
|
30 |
+
'yubi_ids' => $this->getYubiIds( $oUser ),
|
31 |
+
],
|
32 |
+
'strings' => [
|
33 |
+
'current_yubi_ids' => __( 'Registered Yubikey devices', 'wp-simple-firewall' ),
|
34 |
+
'no_active_yubi_ids' => __( 'There are no registered Yubikey devices on this profile.', 'wp-simple-firewall' ),
|
35 |
+
'enter_otp' => __( 'To register a new Yubikey device, enter a One Time Password from the Yubikey.', 'wp-simple-firewall' ),
|
36 |
+
'to_remove_device' => __( 'To remove a Yubikey device, enter the registered device ID and save.', 'wp-simple-firewall' ),
|
37 |
+
'multiple_for_pro' => sprintf( '[%s] %s', __( 'Pro Only', 'wp-simple-firewall' ),
|
38 |
+
__( 'You may add as many Yubikey devices to your profile as you need to.', 'wp-simple-firewall' ) ),
|
39 |
+
'description_otp_code' => __( 'This is your unique Yubikey Device ID.', 'wp-simple-firewall' ),
|
40 |
+
'description_otp' => __( 'Provide a One Time Password from your Yubikey.', 'wp-simple-firewall' ),
|
41 |
+
'label_enter_code' => __( 'Yubikey ID', 'wp-simple-firewall' ),
|
42 |
+
'label_enter_otp' => __( 'Yubikey OTP', 'wp-simple-firewall' ),
|
43 |
+
'title' => __( 'Yubikey Authentication', 'wp-simple-firewall' ),
|
44 |
+
'cant_add_other_user' => sprintf( __( "Sorry, %s may not be added to another user's account.", 'wp-simple-firewall' ), 'Yubikey' ),
|
45 |
+
'cant_remove_admins' => sprintf( __( "Sorry, %s may only be removed from another user's account by a Security Administrator.", 'wp-simple-firewall' ), __( 'Yubikey', 'wp-simple-firewall' ) ),
|
46 |
+
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $oCon->getHumanName() ),
|
47 |
+
'remove_more_info' => sprintf( __( 'Understand how to remove Google Authenticator', 'wp-simple-firewall' ) )
|
48 |
+
],
|
49 |
+
];
|
50 |
+
|
51 |
+
return $this->getMod()
|
52 |
+
->renderTemplate(
|
53 |
+
'/snippets/user/profile/mfa/mfa_yubikey.twig',
|
54 |
+
Services::DataManipulation()->mergeArraysRecursive( $this->getCommonData( $oUser ), $aData ),
|
55 |
+
true
|
56 |
+
);
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @inheritDoc
|
61 |
+
*/
|
62 |
+
public function handleUserProfileSubmit( \WP_User $oUser ) {
|
63 |
+
|
64 |
+
// If it's your own account, you CANT do anything without your OTP (except turn off via email).
|
65 |
+
$sOtpOrDeviceId = trim( (string)$this->fetchCodeFromRequest() );
|
66 |
+
if ( empty( $sOtpOrDeviceId ) ) {
|
67 |
+
return;
|
68 |
+
}
|
69 |
+
|
70 |
+
$bError = true;
|
71 |
+
$aRegisteredDevices = $this->getYubiIds( $oUser );
|
72 |
+
|
73 |
+
if ( strlen( $sOtpOrDeviceId ) < self::OTP_LENGTH ) {
|
74 |
+
$sMsg = __( 'The Yubikey device ID was not valid.', 'wp-simple-firewall' )
|
75 |
+
.' '.__( 'Please try again.', 'wp-simple-firewall' );
|
76 |
+
}
|
77 |
+
else {
|
78 |
+
$sDeviceId = substr( $sOtpOrDeviceId, 0, self::OTP_LENGTH );
|
79 |
+
$bDeviceRegistered = in_array( $sDeviceId, $aRegisteredDevices );
|
80 |
+
|
81 |
+
if ( $bDeviceRegistered || strlen( $sOtpOrDeviceId ) == self::OTP_LENGTH ) { // attempt to remove device
|
82 |
+
|
83 |
+
if ( $bDeviceRegistered ) {
|
84 |
+
$this->addRemoveRegisteredYubiId( $oUser, $sDeviceId, false );
|
85 |
+
$sMsg = sprintf(
|
86 |
+
__( '%s was removed from your profile.', 'wp-simple-firewall' ),
|
87 |
+
__( 'Yubikey Device', 'wp-simple-firewall' ).sprintf( ' (%s)', $sDeviceId )
|
88 |
+
);
|
89 |
+
$bError = false;
|
90 |
+
}
|
91 |
+
else {
|
92 |
+
$sMsg = __( "That Yubikey device ID wasn't found on your profile", 'wp-simple-firewall' );
|
93 |
+
}
|
94 |
+
}
|
95 |
+
elseif ( $this->sendYubiOtpRequest( $sOtpOrDeviceId ) ) { // A full OTP was provided so we're adding a new one
|
96 |
+
if ( count( $aRegisteredDevices ) == 0 || $this->getCon()->isPremiumActive() ) {
|
97 |
+
$this->addRemoveRegisteredYubiId( $oUser, $sDeviceId, true );
|
98 |
+
$sMsg = sprintf(
|
99 |
+
__( '%s was added to your profile.', 'wp-simple-firewall' ),
|
100 |
+
__( 'Yubikey Device', 'wp-simple-firewall' ).sprintf( ' (%s)', $sDeviceId )
|
101 |
+
);
|
102 |
+
$bError = false;
|
103 |
+
}
|
104 |
+
else {
|
105 |
+
$sMsg = __( 'No further Yubikey devices may be added to your account at this time.', 'wp-simple-firewall' );
|
106 |
+
}
|
107 |
+
}
|
108 |
+
else {
|
109 |
+
$sMsg = __( 'One Time Password (OTP) was not valid.', 'wp-simple-firewall' )
|
110 |
+
.' '.__( 'Please try again.', 'wp-simple-firewall' );
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
$this->setProfileValidated( $oUser, $this->hasValidSecret( $oUser ) );
|
115 |
+
$this->getMod()->setFlashAdminNotice( $sMsg, $bError );
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* @param \WP_User $oUser
|
120 |
+
* @return array
|
121 |
+
*/
|
122 |
+
private function getYubiIds( \WP_User $oUser ) {
|
123 |
+
return explode( ',', $this->getSecret( $oUser ) );
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* @param \WP_User $oUser
|
128 |
+
* @param string $sOneTimePassword
|
129 |
+
* @return bool
|
130 |
+
*/
|
131 |
+
protected function processOtp( $oUser, $sOneTimePassword ) {
|
132 |
+
$bSuccess = false;
|
133 |
+
|
134 |
+
foreach ( $this->getYubiIds( $oUser ) as $sKey ) {
|
135 |
+
if ( strpos( $sOneTimePassword, $sKey ) === 0
|
136 |
+
&& $this->sendYubiOtpRequest( $sOneTimePassword ) ) {
|
137 |
+
$bSuccess = true;
|
138 |
+
break;
|
139 |
+
}
|
140 |
+
if ( !$this->getCon()->isPremiumActive() ) { // Test 1 key if not Pro
|
141 |
+
break;
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
return $bSuccess;
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* @param string $sOTP
|
150 |
+
* @return bool
|
151 |
+
*/
|
152 |
+
private function sendYubiOtpRequest( $sOTP ) {
|
153 |
+
/** @var LoginGuard\Options $oOpts */
|
154 |
+
$oOpts = $this->getOptions();
|
155 |
+
$sOTP = trim( $sOTP );
|
156 |
+
$bSuccess = false;
|
157 |
+
|
158 |
+
if ( preg_match( '#^[a-z]{44}$#', $sOTP ) ) {
|
159 |
+
$aParts = [
|
160 |
+
'otp' => $sOTP,
|
161 |
+
'nonce' => md5( uniqid( $this->getCon()->getUniqueRequestId() ) ),
|
162 |
+
'id' => $oOpts->getYubikeyAppId()
|
163 |
+
];
|
164 |
+
|
165 |
+
$sResp = Services::HttpRequest()->getContent(
|
166 |
+
add_query_arg( $aParts, self::URL_YUBIKEY_VERIFY )
|
167 |
+
);
|
168 |
+
|
169 |
+
unset( $aParts[ 'id' ] );
|
170 |
+
$aParts[ 'status' ] = 'OK';
|
171 |
+
|
172 |
+
$bSuccess = true;
|
173 |
+
foreach ( $aParts as $sKey => $mVal ) {
|
174 |
+
if ( !preg_match( sprintf( '#%s=%s#', $sKey, $mVal ), $sResp ) ) {
|
175 |
+
$bSuccess = false;
|
176 |
+
break;
|
177 |
+
}
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
+
return $bSuccess;
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* @param \WP_User $oUser
|
186 |
+
* @param string $sKey
|
187 |
+
* @param bool $bAdd - true to add; false to remove
|
188 |
+
* @return $this
|
189 |
+
*/
|
190 |
+
private function addRemoveRegisteredYubiId( \WP_User $oUser, $sKey, $bAdd = true ) {
|
191 |
+
$aIDs = $this->getYubiIds( $oUser );
|
192 |
+
if ( $bAdd ) {
|
193 |
+
$aIDs[] = $sKey;
|
194 |
+
}
|
195 |
+
else {
|
196 |
+
$aIDs = Services::DataManipulation()->removeFromArrayByValue( $aIDs, $sKey );
|
197 |
+
}
|
198 |
+
return $this->setSecret( $oUser, implode( ',', array_unique( array_filter( $aIDs ) ) ) );
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* @param \WP_User $oUser
|
203 |
+
* @param bool $bIsSuccess
|
204 |
+
*/
|
205 |
+
protected function auditLogin( $oUser, $bIsSuccess ) {
|
206 |
+
$this->getCon()->fireEvent(
|
207 |
+
$bIsSuccess ? 'yubikey_verified' : 'yubikey_fail',
|
208 |
+
[
|
209 |
+
'audit' => [
|
210 |
+
'user_login' => $oUser->user_login,
|
211 |
+
'method' => 'Yubikey',
|
212 |
+
]
|
213 |
+
]
|
214 |
+
);
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* @return array
|
219 |
+
*/
|
220 |
+
public function getFormField() {
|
221 |
+
return [
|
222 |
+
'name' => $this->getLoginFormParameter(),
|
223 |
+
'type' => 'text',
|
224 |
+
'placeholder' => __( 'Use your Yubikey to generate a new code.', 'wp-simple-firewall' ),
|
225 |
+
'value' => '',
|
226 |
+
'text' => __( 'Yubikey OTP', 'wp-simple-firewall' ),
|
227 |
+
'help_link' => 'https://shsec.io/4i'
|
228 |
+
];
|
229 |
+
}
|
230 |
+
|
231 |
+
/**
|
232 |
+
* @return bool
|
233 |
+
*/
|
234 |
+
public function isProviderEnabled() {
|
235 |
+
/** @var LoginGuard\Options $oOpts */
|
236 |
+
$oOpts = $this->getOptions();
|
237 |
+
return $oOpts->isEnabledYubikey();
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* @param string $sSecret
|
242 |
+
* @return bool
|
243 |
+
*/
|
244 |
+
protected function isSecretValid( $sSecret ) {
|
245 |
+
$bValid = parent::isSecretValid( $sSecret );
|
246 |
+
if ( $bValid ) {
|
247 |
+
foreach ( explode( ',', $sSecret ) as $sId ) {
|
248 |
+
$bValid = $bValid &&
|
249 |
+
preg_match( sprintf( '#^[a-z]{%s}$#', self::OTP_LENGTH ), $sId );
|
250 |
+
}
|
251 |
+
}
|
252 |
+
return $bValid;
|
253 |
+
}
|
254 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/UserProfile.php
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class UserProfile {
|
9 |
+
|
10 |
+
use MfaControllerConsumer;
|
11 |
+
|
12 |
+
public function run() {
|
13 |
+
if ( is_admin() ) { // TODO: standalone UI based on shortcodes
|
14 |
+
add_action( 'show_user_profile', [ $this, 'addOptionsToUserProfile' ] );
|
15 |
+
add_action( 'personal_options_update', [ $this, 'handleUserProfileSubmit' ] );
|
16 |
+
if ( $this->getMfaCon()->getCon()->isPluginAdmin() ) {
|
17 |
+
add_action( 'edit_user_profile', [ $this, 'addOptionsToUserEditProfile' ] );
|
18 |
+
add_action( 'edit_user_profile_update', [ $this, 'handleEditOtherUserProfileSubmit' ] );
|
19 |
+
}
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
25 |
+
* functions. Otherwise we need to be careful of mixing up users.
|
26 |
+
* @param \WP_User $oUser
|
27 |
+
*/
|
28 |
+
public function addOptionsToUserProfile( $oUser ) {
|
29 |
+
$oMC = $this->getMfaCon();
|
30 |
+
$oWpUsers = Services::WpUsers();
|
31 |
+
$aProviders = $oMC->getProvidersForUser( $oUser );
|
32 |
+
if ( count( $aProviders ) > 0 ) {
|
33 |
+
$aRows = [];
|
34 |
+
foreach ( $aProviders as $oProvider ) {
|
35 |
+
$aRows[ $oProvider::SLUG ] = $oProvider->renderUserProfileOptions( $oUser );
|
36 |
+
}
|
37 |
+
|
38 |
+
$aData = [
|
39 |
+
'is_my_user_profile' => ( $oUser->ID == $oWpUsers->getCurrentWpUserId() ),
|
40 |
+
'i_am_valid_admin' => $oMC->getCon()->isPluginAdmin(),
|
41 |
+
'user_to_edit_is_admin' => $oWpUsers->isUserAdmin( $oUser ),
|
42 |
+
'strings' => [
|
43 |
+
'title' => __( 'Multi-Factor Authentication', 'wp-simple-firewall' ),
|
44 |
+
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $oMC->getCon()
|
45 |
+
->getHumanName() )
|
46 |
+
],
|
47 |
+
'mfa_rows' => $aRows
|
48 |
+
];
|
49 |
+
|
50 |
+
echo $oMC->getMod()
|
51 |
+
->renderTemplate(
|
52 |
+
'/snippets/user/profile/mfa/mfa_container.twig',
|
53 |
+
$aData,
|
54 |
+
true
|
55 |
+
);
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* This MUST only ever be hooked into when the User is looking at their OWN profile,
|
61 |
+
* so we can use "current user" functions. Otherwise we need to be careful of mixing up users.
|
62 |
+
* @param int $nSavingUserId
|
63 |
+
*/
|
64 |
+
public function handleUserProfileSubmit( $nSavingUserId ) {
|
65 |
+
$oUser = Services::WpUsers()->getUserById( $nSavingUserId );
|
66 |
+
foreach ( $this->getMfaCon()->getProvidersForUser( $oUser ) as $oProvider ) {
|
67 |
+
$oProvider->handleUserProfileSubmit( $oUser );
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* ONLY TO BE HOOKED TO USER PROFILE EDIT
|
73 |
+
* @param \WP_User $oUser
|
74 |
+
*/
|
75 |
+
public function addOptionsToUserEditProfile( $oUser ) {
|
76 |
+
$this->addOptionsToUserProfile( $oUser );
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* The only thing we can do is REMOVE Google Authenticator from an account that is not our own
|
81 |
+
* But, only admins can do this. If Security Admin feature is enabled, then only they can do it.
|
82 |
+
* @param int $nSavingUserId
|
83 |
+
*/
|
84 |
+
public function handleEditOtherUserProfileSubmit( $nSavingUserId ) {
|
85 |
+
$oUser = Services::WpUsers()->getUserById( $nSavingUserId );
|
86 |
+
foreach ( $this->getMfaCon()->getProvidersForUser( $oUser ) as $oProvider ) {
|
87 |
+
$oProvider->handleEditOtherUserProfileSubmit( $oUser );
|
88 |
+
}
|
89 |
+
}
|
90 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/ValidateLoginIntentRequest.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
|
8 |
+
use FernleafSystems\Wordpress\Services\Services;
|
9 |
+
|
10 |
+
class ValidateLoginIntentRequest {
|
11 |
+
|
12 |
+
use MfaControllerConsumer;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return bool
|
16 |
+
* @throws \Exception
|
17 |
+
*/
|
18 |
+
public function run() {
|
19 |
+
$oMfaCon = $this->getMfaCon();
|
20 |
+
/** @var LoginGuard\Options $oOpts */
|
21 |
+
$oOpts = $oMfaCon->getOptions();
|
22 |
+
|
23 |
+
$oUser = Services::WpUsers()->getCurrentWpUser();
|
24 |
+
if ( !$oUser instanceof \WP_User ) {
|
25 |
+
throw new \Exception( 'No user logged-in.' );
|
26 |
+
}
|
27 |
+
$aProviders = $oMfaCon->getProvidersForUser( $oUser, true );
|
28 |
+
if ( empty( $aProviders ) ) {
|
29 |
+
throw new \Exception( 'No valid providers' );
|
30 |
+
}
|
31 |
+
|
32 |
+
$aSuccessfulProviders = [];
|
33 |
+
|
34 |
+
$bValidated = false;
|
35 |
+
{ // Backup code is special case
|
36 |
+
if ( isset( $aProviders[ Provider\Backup::SLUG ] ) ) {
|
37 |
+
if ( $aProviders[ Provider\Backup::SLUG ]->validateLoginIntent( $oUser ) ) {
|
38 |
+
$bValidated = true;
|
39 |
+
$aSuccessfulProviders[] = $aProviders[ Provider\Backup::SLUG ];
|
40 |
+
}
|
41 |
+
unset( $aProviders[ Provider\Backup::SLUG ] );
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
if ( !$bValidated ) {
|
46 |
+
$aStates = [];
|
47 |
+
foreach ( $aProviders as $sSlug => $oProvider ) {
|
48 |
+
$aStates[ $sSlug ] = $oProvider->validateLoginIntent( $oUser );
|
49 |
+
if ( $aStates[ $sSlug ] ) {
|
50 |
+
$aSuccessfulProviders[] = $oProvider;
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
$nSuccessful = count( array_filter( $aStates ) );
|
55 |
+
$bValidated = $oOpts->isChainedAuth() ? $nSuccessful == count( $aProviders ) : $nSuccessful > 0;
|
56 |
+
}
|
57 |
+
|
58 |
+
if ( $bValidated ) {
|
59 |
+
// Some cleanup can only run if login is completely tested and completely valid.
|
60 |
+
foreach ( $aSuccessfulProviders as $oProvider ) {
|
61 |
+
$oProvider->postSuccessActions( $oUser );
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
return $bValidated;
|
66 |
+
}
|
67 |
+
}
|
src/lib/src/Modules/LoginGuard/Options.php
CHANGED
@@ -10,6 +10,65 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
10 |
*/
|
11 |
class Options extends Base\ShieldOptions {
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
/**
|
14 |
* @return bool
|
15 |
*/
|
@@ -18,9 +77,61 @@ class Options extends Base\ShieldOptions {
|
|
18 |
}
|
19 |
|
20 |
/**
|
21 |
-
*
|
|
|
22 |
*/
|
23 |
-
public function
|
24 |
-
return (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
}
|
10 |
*/
|
11 |
class Options extends Base\ShieldOptions {
|
12 |
|
13 |
+
/**
|
14 |
+
* @return int
|
15 |
+
*/
|
16 |
+
public function getCooldownInterval() {
|
17 |
+
return (int)$this->getOpt( 'login_limit_interval' );
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @return array
|
22 |
+
*/
|
23 |
+
public function getEmail2FaRoles() {
|
24 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
25 |
+
$oMod = $this->getMod();
|
26 |
+
$aRoles = $this->getOpt( 'two_factor_auth_user_roles', [] );
|
27 |
+
if ( empty( $aRoles ) || !is_array( $aRoles ) ) {
|
28 |
+
$aRoles = $oMod->getOptEmailTwoFactorRolesDefaults();
|
29 |
+
$this->setOpt( 'two_factor_auth_user_roles', $aRoles );
|
30 |
+
}
|
31 |
+
if ( $this->isPremium() ) {
|
32 |
+
$aRoles = apply_filters( 'odp-shield-2fa_email_user_roles', $aRoles );
|
33 |
+
}
|
34 |
+
return is_array( $aRoles ) ? $aRoles : $oMod->getOptEmailTwoFactorRolesDefaults();
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @return bool
|
39 |
+
*/
|
40 |
+
public function getIfCanSendEmailVerified() {
|
41 |
+
return (int)$this->getOpt( 'email_can_send_verified_at' ) > 0;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @return int - seconds
|
46 |
+
*/
|
47 |
+
public function getMfaSkip() {
|
48 |
+
return DAY_IN_SECONDS*( $this->isPremium() ? (int)$this->getOpt( 'mfa_skip', 0 ) : 0 );
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @return string
|
53 |
+
*/
|
54 |
+
public function getYubikeyAppId() {
|
55 |
+
return (string)$this->getOpt( 'yubikey_app_id', '' );
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @return bool
|
60 |
+
*/
|
61 |
+
public function isMfaSkip() {
|
62 |
+
return $this->getMfaSkip() > 0;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* @return bool
|
67 |
+
*/
|
68 |
+
public function isChainedAuth() {
|
69 |
+
return $this->isOpt( 'enable_chained_authentication', 'Y' );
|
70 |
+
}
|
71 |
+
|
72 |
/**
|
73 |
* @return bool
|
74 |
*/
|
77 |
}
|
78 |
|
79 |
/**
|
80 |
+
* Also considers whether email sending ability has been verified
|
81 |
+
* @return bool
|
82 |
*/
|
83 |
+
public function isEmailAuthenticationActive() {
|
84 |
+
return $this->getIfCanSendEmailVerified() && $this->isEnabledEmailAuth();
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @return bool
|
89 |
+
*/
|
90 |
+
public function isEnabledEmailAuth() {
|
91 |
+
return $this->isOpt( 'enable_email_authentication', 'Y' );
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @return bool
|
96 |
+
*/
|
97 |
+
public function isEnabledEmailAuthAnyUserSet() {
|
98 |
+
return $this->isEmailAuthenticationActive() && $this->isOpt( 'email_any_user_set', 'Y' ) && $this->isPremium();
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @return bool
|
103 |
+
*/
|
104 |
+
public function isEnabledBackupCodes() {
|
105 |
+
return $this->isPremium() && $this->isOpt( 'allow_backupcodes', 'Y' );
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @return bool
|
110 |
+
*/
|
111 |
+
public function isEnabledGoogleAuthenticator() {
|
112 |
+
return $this->isOpt( 'enable_google_authenticator', 'Y' );
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @return bool
|
117 |
+
*/
|
118 |
+
public function isUseLoginIntentPage() {
|
119 |
+
return $this->isOpt( 'use_login_intent_page', true );
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* @return bool
|
124 |
+
*/
|
125 |
+
public function isEnabledYubikey() {
|
126 |
+
return $this->isOpt( 'enable_yubikey', 'Y' ) && $this->isYubikeyConfigReady();
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* @return bool
|
131 |
+
*/
|
132 |
+
private function isYubikeyConfigReady() {
|
133 |
+
$sAppId = $this->getOpt( 'yubikey_app_id' );
|
134 |
+
$sApiKey = $this->getOpt( 'yubikey_api_key' );
|
135 |
+
return !empty( $sAppId ) && !empty( $sApiKey );
|
136 |
}
|
137 |
}
|
src/lib/src/Modules/LoginGuard/Strings.php
CHANGED
@@ -206,6 +206,12 @@ class Strings extends Base\Strings {
|
|
206 |
$sDescription = __( 'All users will be required to verify their login by email-based two-factor authentication.', 'wp-simple-firewall' );
|
207 |
break;
|
208 |
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
case 'two_factor_auth_user_roles' :
|
210 |
$sName = sprintf( '%s - %s', __( 'Enforce', 'wp-simple-firewall' ), __( 'Email Authentication', 'wp-simple-firewall' ) );
|
211 |
$sSummary = __( 'All User Roles Subject To Email Authentication', 'wp-simple-firewall' );
|
206 |
$sDescription = __( 'All users will be required to verify their login by email-based two-factor authentication.', 'wp-simple-firewall' );
|
207 |
break;
|
208 |
|
209 |
+
case 'email_any_user_set' :
|
210 |
+
$sName = __( 'Allow Any User', 'wp-simple-firewall' );
|
211 |
+
$sSummary = __( 'Allow Any User To Turn-On Two-Factor Authentication By Email.', 'wp-simple-firewall' );
|
212 |
+
$sDescription = __( 'Any user can turn on two-factor authentication by email from their profile.', 'wp-simple-firewall' );
|
213 |
+
break;
|
214 |
+
|
215 |
case 'two_factor_auth_user_roles' :
|
216 |
$sName = sprintf( '%s - %s', __( 'Enforce', 'wp-simple-firewall' ), __( 'Email Authentication', 'wp-simple-firewall' ) );
|
217 |
$sSummary = __( 'All User Roles Subject To Email Authentication', 'wp-simple-firewall' );
|
src/lib/src/Modules/Plugin/AdminNotices.php
CHANGED
@@ -287,13 +287,14 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
287 |
* @return bool
|
288 |
*/
|
289 |
protected function isDisplayNeeded( $oNotice ) {
|
|
|
290 |
/** @var Options $oOpts */
|
291 |
$oOpts = $this->getOptions();
|
292 |
|
293 |
switch ( $oNotice->id ) {
|
294 |
|
295 |
case 'override-forceoff':
|
296 |
-
$bNeeded = $
|
297 |
break;
|
298 |
|
299 |
case 'plugin-disabled':
|
287 |
* @return bool
|
288 |
*/
|
289 |
protected function isDisplayNeeded( $oNotice ) {
|
290 |
+
$oCon = $this->getCon();
|
291 |
/** @var Options $oOpts */
|
292 |
$oOpts = $this->getOptions();
|
293 |
|
294 |
switch ( $oNotice->id ) {
|
295 |
|
296 |
case 'override-forceoff':
|
297 |
+
$bNeeded = $oCon->getIfForceOffActive();
|
298 |
break;
|
299 |
|
300 |
case 'plugin-disabled':
|
src/lib/src/Modules/Plugin/Lib/WpHashesTokenManager.php
CHANGED
@@ -6,6 +6,11 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Token;
|
8 |
|
|
|
|
|
|
|
|
|
|
|
9 |
class WpHashesTokenManager {
|
10 |
|
11 |
use ModConsumer;
|
@@ -15,12 +20,21 @@ class WpHashesTokenManager {
|
|
15 |
*/
|
16 |
private $bCanRequestOverride = false;
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
/**
|
19 |
* @return string
|
20 |
*/
|
21 |
public function getToken() {
|
22 |
|
23 |
-
if ( $this->getCon()->
|
24 |
$aT = $this->loadToken();
|
25 |
if ( $this->isExpired() && $this->canRequestNewToken() ) {
|
26 |
$aT = $this->loadToken();
|
@@ -60,7 +74,10 @@ class WpHashesTokenManager {
|
|
60 |
*/
|
61 |
private function canRequestNewToken() {
|
62 |
return $this->getCanRequestOverride() ||
|
63 |
-
|
|
|
|
|
|
|
64 |
}
|
65 |
|
66 |
/**
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Token;
|
8 |
|
9 |
+
/**
|
10 |
+
* Class WpHashesTokenManager
|
11 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib
|
12 |
+
* @deprecated 8.6.2
|
13 |
+
*/
|
14 |
class WpHashesTokenManager {
|
15 |
|
16 |
use ModConsumer;
|
20 |
*/
|
21 |
private $bCanRequestOverride = false;
|
22 |
|
23 |
+
public function run() {
|
24 |
+
add_action( $this->getCon()->prefix( 'event' ), function ( $sEventTag ) {
|
25 |
+
if ( $sEventTag === 'lic_check_success' ) {
|
26 |
+
$this->setCanRequestOverride( true )
|
27 |
+
->getToken();
|
28 |
+
}
|
29 |
+
} );
|
30 |
+
}
|
31 |
+
|
32 |
/**
|
33 |
* @return string
|
34 |
*/
|
35 |
public function getToken() {
|
36 |
|
37 |
+
if ( $this->getCon()->getModule_License()->getLicenseHandler()->getLicense()->isValid() ) {
|
38 |
$aT = $this->loadToken();
|
39 |
if ( $this->isExpired() && $this->canRequestNewToken() ) {
|
40 |
$aT = $this->loadToken();
|
74 |
*/
|
75 |
private function canRequestNewToken() {
|
76 |
return $this->getCanRequestOverride() ||
|
77 |
+
(
|
78 |
+
Services::Request()->carbon()->subHours( 6 )->timestamp > $this->loadToken()[ 'attempt_at' ]
|
79 |
+
&& $this->getCon()->getModule_License()->getLicenseHandler()->getLicense()->isValid()
|
80 |
+
);
|
81 |
}
|
82 |
|
83 |
/**
|
src/lib/src/Modules/Plugin/Options.php
CHANGED
@@ -130,21 +130,4 @@ class Options extends Base\ShieldOptions {
|
|
130 |
return $this->setOpt( 'enable_tracking', $bOnOrOff ? 'Y' : 'N' )
|
131 |
->setOpt( 'tracking_permission_set_at', Services::Request()->ts() );
|
132 |
}
|
133 |
-
|
134 |
-
/**
|
135 |
-
* @return array
|
136 |
-
* @deprecated 8.5.1
|
137 |
-
*/
|
138 |
-
public function getServerIpDetails() {
|
139 |
-
return [];
|
140 |
-
}
|
141 |
-
|
142 |
-
/**
|
143 |
-
* @param array $aDetails
|
144 |
-
* @return $this
|
145 |
-
* @deprecated 8.5.1
|
146 |
-
*/
|
147 |
-
public function updateServerIpDetails( $aDetails ) {
|
148 |
-
return $this;
|
149 |
-
}
|
150 |
}
|
130 |
return $this->setOpt( 'enable_tracking', $bOnOrOff ? 'Y' : 'N' )
|
131 |
->setOpt( 'tracking_permission_set_at', Services::Request()->ts() );
|
132 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
}
|
src/lib/src/Modules/Plugin/Strings.php
CHANGED
@@ -443,5 +443,8 @@ class Strings extends Base\Strings {
|
|
443 |
__( 'Medium', 'wp-simple-firewall' );
|
444 |
__( 'High', 'wp-simple-firewall' );
|
445 |
__( 'Full', 'wp-simple-firewall' );
|
|
|
|
|
|
|
446 |
}
|
447 |
}
|
443 |
__( 'Medium', 'wp-simple-firewall' );
|
444 |
__( 'High', 'wp-simple-firewall' );
|
445 |
__( 'Full', 'wp-simple-firewall' );
|
446 |
+
|
447 |
+
__( 'Last Offense', 'wp-simple-firewall' );
|
448 |
+
__( 'Automatic license verification failed.', 'wp-simple-firewall' );
|
449 |
}
|
450 |
}
|
src/lib/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php
ADDED
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\WhiteLabel;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class ApplyLabels {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
/**
|
14 |
+
*/
|
15 |
+
public function run() {
|
16 |
+
$oCon = $this->getCon();
|
17 |
+
add_action( 'init', [ $this, 'onWpInit' ] );
|
18 |
+
add_filter( $oCon->prefix( 'is_relabelled' ), '__return_true' );
|
19 |
+
add_filter( $oCon->prefix( 'plugin_labels' ), [ $this, 'applyPluginLabels' ] );
|
20 |
+
add_filter( 'plugin_row_meta', [ $this, 'removePluginMetaLinks' ], 200, 2 );
|
21 |
+
add_action( 'admin_print_footer_scripts-plugin-editor.php', [ $this, 'hideFromPluginEditor' ] );
|
22 |
+
}
|
23 |
+
|
24 |
+
public function onWpInit() {
|
25 |
+
/** @var SecurityAdmin\Options $oOpts */
|
26 |
+
$oOpts = $this->getOptions();
|
27 |
+
if ( $oOpts->isWlHideUpdates() && $this->isNeedToHideUpdates() && !$this->getCon()->isPluginAdmin() ) {
|
28 |
+
$this->hideUpdates();
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Depending on the page, we hide the update data,
|
34 |
+
* or we adjust the number of displayed updates counts
|
35 |
+
*/
|
36 |
+
protected function hideUpdates() {
|
37 |
+
if ( in_array( Services::WpPost()->getCurrentPage(), [ 'plugins.php', 'update-core.php' ] ) ) {
|
38 |
+
add_filter( 'site_transient_update_plugins', [ $this, 'hidePluginUpdatesFromUI' ] );
|
39 |
+
}
|
40 |
+
else {
|
41 |
+
add_filter( 'wp_get_update_data', [ $this, 'adjustUpdateDataCount' ] );
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Adjusts the available updates count so as not to include Shield updates if they're hidden
|
47 |
+
* @param array $aUpdateData
|
48 |
+
* @return array
|
49 |
+
*/
|
50 |
+
public function adjustUpdateDataCount( $aUpdateData ) {
|
51 |
+
|
52 |
+
$sFile = $this->getCon()->getPluginBaseFile();
|
53 |
+
if ( Services::WpPlugins()->isUpdateAvailable( $sFile ) ) {
|
54 |
+
$aUpdateData[ 'counts' ][ 'total' ]--;
|
55 |
+
$aUpdateData[ 'counts' ][ 'plugins' ]--;
|
56 |
+
}
|
57 |
+
|
58 |
+
return $aUpdateData;
|
59 |
+
}
|
60 |
+
|
61 |
+
public function hideFromPluginEditor() {
|
62 |
+
$oCon = $this->getCon();
|
63 |
+
$sJs = Services::Data()->readFileContentsUsingInclude( $oCon->getPath_AssetJs( 'whitelabel.js' ) );
|
64 |
+
echo sprintf( '<script type="text/javascript">%s</script>', sprintf( $sJs, $oCon->getPluginBaseFile() ) );
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @param array $aPluginLabels
|
69 |
+
* @return array
|
70 |
+
*/
|
71 |
+
public function applyPluginLabels( $aPluginLabels ) {
|
72 |
+
/** @var \ICWP_WPSF_FeatureHandler_AdminAccessRestriction $oMod */
|
73 |
+
$oMod = $this->getMod();
|
74 |
+
|
75 |
+
$aWhiteLabels = $oMod->getWhitelabelOptions();
|
76 |
+
|
77 |
+
// these are the old white labelling keys which will be replaced upon final release of white labelling.
|
78 |
+
$sServiceName = $aWhiteLabels[ 'name_main' ];
|
79 |
+
$aPluginLabels[ 'Name' ] = $sServiceName;
|
80 |
+
$aPluginLabels[ 'Title' ] = $sServiceName;
|
81 |
+
$aPluginLabels[ 'Author' ] = $aWhiteLabels[ 'name_company' ];
|
82 |
+
$aPluginLabels[ 'AuthorName' ] = $aWhiteLabels[ 'name_company' ];
|
83 |
+
$aPluginLabels[ 'MenuTitle' ] = $aWhiteLabels[ 'name_menu' ];
|
84 |
+
|
85 |
+
$sTagLine = $aWhiteLabels[ 'description' ];
|
86 |
+
if ( !empty( $sTagLine ) ) {
|
87 |
+
$aPluginLabels[ 'Description' ] = $sTagLine;
|
88 |
+
}
|
89 |
+
|
90 |
+
$sUrl = $aWhiteLabels[ 'url_home' ];
|
91 |
+
if ( !empty( $sUrl ) ) {
|
92 |
+
$aPluginLabels[ 'PluginURI' ] = $sUrl;
|
93 |
+
$aPluginLabels[ 'AuthorURI' ] = $sUrl;
|
94 |
+
}
|
95 |
+
|
96 |
+
$sIconUrl = $aWhiteLabels[ 'url_icon' ];
|
97 |
+
if ( !empty( $sIconUrl ) ) {
|
98 |
+
$aPluginLabels[ 'icon_url_16x16' ] = $sIconUrl;
|
99 |
+
$aPluginLabels[ 'icon_url_32x32' ] = $sIconUrl;
|
100 |
+
}
|
101 |
+
|
102 |
+
$sLogoUrl = $aWhiteLabels[ 'url_dashboardlogourl' ];
|
103 |
+
if ( !empty( $sLogoUrl ) ) {
|
104 |
+
$aPluginLabels[ 'icon_url_128x128' ] = $sLogoUrl;
|
105 |
+
}
|
106 |
+
|
107 |
+
return array_merge( $aWhiteLabels, $aPluginLabels );
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* @filter
|
112 |
+
* @param array $aPluginMeta
|
113 |
+
* @param string $sPluginBaseFileName
|
114 |
+
* @return array
|
115 |
+
*/
|
116 |
+
public function removePluginMetaLinks( $aPluginMeta, $sPluginBaseFileName ) {
|
117 |
+
if ( $sPluginBaseFileName == $this->getCon()->getPluginBaseFile() ) {
|
118 |
+
unset( $aPluginMeta[ 2 ] ); // View details
|
119 |
+
unset( $aPluginMeta[ 3 ] ); // Rate 5*
|
120 |
+
}
|
121 |
+
return $aPluginMeta;
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Hides the update if the page loaded is the plugins page or the updates page.
|
126 |
+
* @param \stdClass $oPlugins
|
127 |
+
* @return \stdClass
|
128 |
+
*/
|
129 |
+
public function hidePluginUpdatesFromUI( $oPlugins ) {
|
130 |
+
$sFile = $this->getCon()->getPluginBaseFile();
|
131 |
+
if ( isset( $oPlugins->response[ $sFile ] ) ) {
|
132 |
+
unset( $oPlugins->response[ $sFile ] );
|
133 |
+
}
|
134 |
+
return $oPlugins;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* @return bool
|
139 |
+
*/
|
140 |
+
private function isNeedToHideUpdates() {
|
141 |
+
return is_admin() && !Services::WpGeneral()->isCron();
|
142 |
+
}
|
143 |
+
}
|
src/lib/src/Modules/UserManagement/Lib/Registration/EmailValidate.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\UserManagement\Lib\Registration;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\UserManagement;
|
7 |
+
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Verify\Email;
|
8 |
+
|
9 |
+
class EmailValidate {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
private $aTrack;
|
14 |
+
|
15 |
+
public function run() {
|
16 |
+
/** @var UserManagement\Options $oOpts */
|
17 |
+
$oOpts = $this->getOptions();
|
18 |
+
if ( $oOpts->getValidateEmailOnRegistration() != 'disabled' ) {
|
19 |
+
add_filter( 'wp_pre_insert_user_data', [ $this, 'validateNewUserEmail' ] );
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @param array $aUserData
|
25 |
+
* @return array
|
26 |
+
*/
|
27 |
+
public function validateNewUserEmail( $aUserData ) {
|
28 |
+
$sEmail = $aUserData[ 'user_email' ];
|
29 |
+
/** @var UserManagement\Options $oOpts */
|
30 |
+
|
31 |
+
if ( !is_array( $this->aTrack ) ) {
|
32 |
+
$this->aTrack = [];
|
33 |
+
}
|
34 |
+
|
35 |
+
// This hook seems to be called twice on any given registration.
|
36 |
+
if ( !in_array( $sEmail, $this->aTrack ) ) {
|
37 |
+
$this->aTrack[] = $sEmail;
|
38 |
+
|
39 |
+
$oOpts = $this->getOptions();
|
40 |
+
$sInvalidBecause = null;
|
41 |
+
if ( !is_email( $sEmail ) ) {
|
42 |
+
$sInvalidBecause = 'syntax';
|
43 |
+
}
|
44 |
+
else {
|
45 |
+
$sApiToken = $this->getCon()
|
46 |
+
->getModule_License()
|
47 |
+
->getWpHashesTokenManager()
|
48 |
+
->getToken();
|
49 |
+
if ( !empty( $sApiToken ) ) {
|
50 |
+
$aChecks = $oOpts->getEmailValidationChecks();
|
51 |
+
foreach ( ( new Email( $sApiToken ) )->getEmailVerification( $sEmail ) as $sValidation => $bIsValid ) {
|
52 |
+
if ( !$bIsValid && in_array( $sValidation, $aChecks ) ) {
|
53 |
+
$sInvalidBecause = $sValidation;
|
54 |
+
break;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
if ( !empty( $sInvalidBecause ) ) {
|
61 |
+
$sOpt = $oOpts->getValidateEmailOnRegistration();
|
62 |
+
$this->getCon()->fireEvent(
|
63 |
+
'reg_email_invalid',
|
64 |
+
[
|
65 |
+
'audit' => [
|
66 |
+
'email' => sanitize_email( $sEmail ),
|
67 |
+
'reason' => sanitize_key( $sInvalidBecause ),
|
68 |
+
],
|
69 |
+
'offense_count' => $sOpt == 'log' ? 0 : 1,
|
70 |
+
'block' => $sOpt == 'block',
|
71 |
+
]
|
72 |
+
);
|
73 |
+
|
74 |
+
if ( $sOpt == 'block' ) {
|
75 |
+
wp_die( 'Attempted user registration with invalid email addressed has been blocked.' );
|
76 |
+
}
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
return $aUserData;
|
81 |
+
}
|
82 |
+
}
|
src/lib/src/Modules/UserManagement/Options.php
CHANGED
@@ -146,4 +146,20 @@ class Options extends Base\ShieldOptions {
|
|
146 |
public function isSuspendManualEnabled() {
|
147 |
return $this->isOpt( 'manual_suspend', 'Y' );
|
148 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
}
|
146 |
public function isSuspendManualEnabled() {
|
147 |
return $this->isOpt( 'manual_suspend', 'Y' );
|
148 |
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* @return string
|
152 |
+
*/
|
153 |
+
public function getValidateEmailOnRegistration() {
|
154 |
+
return $this->isPremium() ?
|
155 |
+
$this->getOpt( 'reg_email_validate', 'disabled' )
|
156 |
+
: 'disabled';
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* @return string[]
|
161 |
+
*/
|
162 |
+
public function getEmailValidationChecks() {
|
163 |
+
return $this->getOpt( 'email_checks', [] );
|
164 |
+
}
|
165 |
}
|
src/lib/src/Modules/UserManagement/Strings.php
CHANGED
@@ -159,6 +159,18 @@ class Strings extends Base\Strings {
|
|
159 |
.'<br />'.__( "Zero (0) will allow unlimited simultaneous sessions.", 'wp-simple-firewall' );
|
160 |
break;
|
161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
case 'enable_password_policies' :
|
163 |
$sName = __( 'Enable Password Policies', 'wp-simple-firewall' );
|
164 |
$sSummary = __( 'Enable The Password Policies Detailed Below', 'wp-simple-firewall' );
|
@@ -249,6 +261,10 @@ class Strings extends Base\Strings {
|
|
249 |
*/
|
250 |
protected function getAuditMessages() {
|
251 |
return [
|
|
|
|
|
|
|
|
|
252 |
'pass_expired' => [
|
253 |
__( 'Forcing user to update expired password.', 'wp-simple-firewall' ),
|
254 |
],
|
159 |
.'<br />'.__( "Zero (0) will allow unlimited simultaneous sessions.", 'wp-simple-firewall' );
|
160 |
break;
|
161 |
|
162 |
+
case 'reg_email_validate' :
|
163 |
+
$sName = __( 'Validate Email Addresses', 'wp-simple-firewall' );
|
164 |
+
$sSummary = __( 'Validate Email Addresses When User Attempts To Register', 'wp-simple-firewall' );
|
165 |
+
$sDesc = __( 'Validate Email Addresses When User Attempts To Register.', 'wp-simple-firewall' );
|
166 |
+
break;
|
167 |
+
|
168 |
+
case 'email_checks' :
|
169 |
+
$sName = __( 'Email Validation Checks', 'wp-simple-firewall' );
|
170 |
+
$sSummary = __( 'The Email Address Properties That Will Be Tested', 'wp-simple-firewall' );
|
171 |
+
$sDesc = __( 'Select the properties that should be tested during email address validation.', 'wp-simple-firewall' );
|
172 |
+
break;
|
173 |
+
|
174 |
case 'enable_password_policies' :
|
175 |
$sName = __( 'Enable Password Policies', 'wp-simple-firewall' );
|
176 |
$sSummary = __( 'Enable The Password Policies Detailed Below', 'wp-simple-firewall' );
|
261 |
*/
|
262 |
protected function getAuditMessages() {
|
263 |
return [
|
264 |
+
'reg_email_invalid' => [
|
265 |
+
__( 'Detected user registration with invalid email address (%s).', 'wp-simple-firewall' ),
|
266 |
+
__( 'Email verification test that failed: %s' )
|
267 |
+
],
|
268 |
'pass_expired' => [
|
269 |
__( 'Forcing user to update expired password.', 'wp-simple-firewall' ),
|
270 |
],
|
src/lib/src/Modules/UserManagement/Suspend/Idle.php
CHANGED
@@ -16,10 +16,8 @@ class Idle extends Base {
|
|
16 |
protected function processUser( $oUser, $oMeta ) {
|
17 |
/** @var UserManagement\Options $oOpts */
|
18 |
$oOpts = $this->getOptions();
|
19 |
-
/** @var \ICWP_WPSF_FeatureHandler_UserManagement $oMod */
|
20 |
-
$oMod = $this->getMod();
|
21 |
|
22 |
-
$aRoles = array_intersect( $
|
23 |
|
24 |
if ( count( $aRoles ) > 0 && $this->isLastVerifiedAtExpired( $oMeta ) ) {
|
25 |
$oUser = new \WP_Error(
|
@@ -42,8 +40,8 @@ class Idle extends Base {
|
|
42 |
* @return bool
|
43 |
*/
|
44 |
protected function isLastVerifiedAtExpired( $oMeta ) {
|
45 |
-
/** @var \
|
46 |
-
$
|
47 |
-
return ( Services::Request()->ts() - $oMeta->getLastVerifiedAt() > $
|
48 |
}
|
49 |
}
|
16 |
protected function processUser( $oUser, $oMeta ) {
|
17 |
/** @var UserManagement\Options $oOpts */
|
18 |
$oOpts = $this->getOptions();
|
|
|
|
|
19 |
|
20 |
+
$aRoles = array_intersect( $oOpts->getSuspendAutoIdleUserRoles(), array_map( 'strtolower', $oUser->roles ) );
|
21 |
|
22 |
if ( count( $aRoles ) > 0 && $this->isLastVerifiedAtExpired( $oMeta ) ) {
|
23 |
$oUser = new \WP_Error(
|
40 |
* @return bool
|
41 |
*/
|
42 |
protected function isLastVerifiedAtExpired( $oMeta ) {
|
43 |
+
/** @var UserManagement\Options $oOpts */
|
44 |
+
$oOpts = $this->getOptions();
|
45 |
+
return ( Services::Request()->ts() - $oMeta->getLastVerifiedAt() > $oOpts->getSuspendAutoIdleTime() );
|
46 |
}
|
47 |
}
|
src/lib/src/Modules/UserManagement/Suspend/PasswordExpiry.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\UserManagement\Suspend;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Users\ShieldUserMeta;
|
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
/**
|
@@ -44,12 +45,12 @@ class PasswordExpiry extends Base {
|
|
44 |
* @return bool
|
45 |
*/
|
46 |
private function isPassExpired( $oMeta ) {
|
47 |
-
/** @var \
|
48 |
-
$
|
49 |
if ( empty( $oMeta->pass_started_at ) ) {
|
50 |
$oMeta->pass_started_at = $oMeta->first_seen_at;
|
51 |
}
|
52 |
-
return ( Services::Request()->ts() - $oMeta->pass_started_at > $
|
53 |
}
|
54 |
|
55 |
/**
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\UserManagement\Suspend;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Users\ShieldUserMeta;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\UserManagement;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
/**
|
45 |
* @return bool
|
46 |
*/
|
47 |
private function isPassExpired( $oMeta ) {
|
48 |
+
/** @var UserManagement\Options $oOpts */
|
49 |
+
$oOpts = $this->getOptions();
|
50 |
if ( empty( $oMeta->pass_started_at ) ) {
|
51 |
$oMeta->pass_started_at = $oMeta->first_seen_at;
|
52 |
}
|
53 |
+
return ( Services::Request()->ts() - $oMeta->pass_started_at > $oOpts->getPassExpireTimeout() );
|
54 |
}
|
55 |
|
56 |
/**
|
src/lib/src/Scans/Mal/Utilities/FalsePositiveQuery.php
CHANGED
@@ -46,8 +46,11 @@ class FalsePositiveQuery {
|
|
46 |
/** @var Modules\HackGuard\Options $oOpts */
|
47 |
$oOpts = $this->getOptions();
|
48 |
if ( $oOpts->isMalUseNetworkIntelligence() ) {
|
49 |
-
|
50 |
-
|
|
|
|
|
|
|
51 |
if ( isset( $aData[ 'score' ] ) ) {
|
52 |
$nFpConfidence = (int)$aData[ 'score' ];
|
53 |
}
|
@@ -66,9 +69,12 @@ class FalsePositiveQuery {
|
|
66 |
/** @var Modules\HackGuard\Options $oOpts */
|
67 |
$oOpts = $this->getOptions();
|
68 |
if ( $oOpts->isMalUseNetworkIntelligence() ) {
|
69 |
-
|
|
|
|
|
|
|
70 |
try {
|
71 |
-
$aData = ( new Malware\Confidence\Retrieve() )->retrieveForFileLine( $sFile, $sLine );
|
72 |
if ( isset( $aData[ 'score' ] ) ) {
|
73 |
$nFpConfidence = (int)$aData[ 'score' ];
|
74 |
}
|
46 |
/** @var Modules\HackGuard\Options $oOpts */
|
47 |
$oOpts = $this->getOptions();
|
48 |
if ( $oOpts->isMalUseNetworkIntelligence() ) {
|
49 |
+
$sApiToken = $this->getCon()
|
50 |
+
->getModule_License()
|
51 |
+
->getWpHashesTokenManager()
|
52 |
+
->getToken();
|
53 |
+
$aData = ( new Malware\Confidence\Retrieve( $sApiToken ) )->retrieveForFile( $sFullPath );
|
54 |
if ( isset( $aData[ 'score' ] ) ) {
|
55 |
$nFpConfidence = (int)$aData[ 'score' ];
|
56 |
}
|
69 |
/** @var Modules\HackGuard\Options $oOpts */
|
70 |
$oOpts = $this->getOptions();
|
71 |
if ( $oOpts->isMalUseNetworkIntelligence() ) {
|
72 |
+
$sApiToken = $this->getCon()
|
73 |
+
->getModule_License()
|
74 |
+
->getWpHashesTokenManager()
|
75 |
+
->getToken();
|
76 |
try {
|
77 |
+
$aData = ( new Malware\Confidence\Retrieve( $sApiToken ) )->retrieveForFileLine( $sFile, $sLine );
|
78 |
if ( isset( $aData[ 'score' ] ) ) {
|
79 |
$nFpConfidence = (int)$aData[ 'score' ];
|
80 |
}
|
src/lib/src/Scans/Mal/Utilities/FalsePositiveReporter.php
CHANGED
@@ -63,9 +63,15 @@ class FalsePositiveReporter {
|
|
63 |
sha1( Services::DataManipulation()->convertLineEndingsDosToLinux( $sFullPath ) ),
|
64 |
$bIsFalsePositive
|
65 |
] ) );
|
|
|
66 |
if ( !$oOpts->isMalFalsePositiveReported( $sReportHash ) ) {
|
67 |
-
$
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
69 |
}
|
70 |
$this->updateReportedCache( $sReportHash );
|
71 |
}
|
@@ -91,8 +97,12 @@ class FalsePositiveReporter {
|
|
91 |
$sReportHash = md5( $sFile.$sLine.( $bIsFalsePositive ? 'true' : 'false' ) );
|
92 |
if ( !$oOpts->isMalFalsePositiveReported( $sReportHash ) ) {
|
93 |
try {
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
96 |
->report( $sFile, $sLine, $bIsFalsePositive );
|
97 |
}
|
98 |
}
|
63 |
sha1( Services::DataManipulation()->convertLineEndingsDosToLinux( $sFullPath ) ),
|
64 |
$bIsFalsePositive
|
65 |
] ) );
|
66 |
+
|
67 |
if ( !$oOpts->isMalFalsePositiveReported( $sReportHash ) ) {
|
68 |
+
$sApiToken = $this->getCon()
|
69 |
+
->getModule_License()
|
70 |
+
->getWpHashesTokenManager()
|
71 |
+
->getToken();
|
72 |
+
$bReported = !empty( $sApiToken ) &&
|
73 |
+
( new Malware\Whitelist\ReportFalsePositive( $sApiToken ) )
|
74 |
+
->report( $sFullPath, static::HASH_ALGO, $bIsFalsePositive );
|
75 |
}
|
76 |
$this->updateReportedCache( $sReportHash );
|
77 |
}
|
97 |
$sReportHash = md5( $sFile.$sLine.( $bIsFalsePositive ? 'true' : 'false' ) );
|
98 |
if ( !$oOpts->isMalFalsePositiveReported( $sReportHash ) ) {
|
99 |
try {
|
100 |
+
$sApiToken = $this->getCon()
|
101 |
+
->getModule_License()
|
102 |
+
->getWpHashesTokenManager()
|
103 |
+
->getToken();
|
104 |
+
if ( !empty( $sApiToken ) && !$bIsFalsePositive || count( file( $sFile ) ) > 1 ) {
|
105 |
+
$bReported = ( new Malware\Signatures\ReportFalsePositive( $sApiToken ) )
|
106 |
->report( $sFile, $sLine, $bIsFalsePositive );
|
107 |
}
|
108 |
}
|
src/lib/src/Scans/Mal/Utilities/Patterns.php
CHANGED
@@ -32,9 +32,12 @@ class Patterns {
|
|
32 |
}
|
33 |
|
34 |
if ( empty( $oCacheDef->data ) ) {
|
35 |
-
|
|
|
|
|
|
|
36 |
// First attempt to download from WP Hashes API.
|
37 |
-
$aPatts = ( new Malware\Patterns\Retrieve() )->getPatterns();
|
38 |
|
39 |
// Fallback to original method
|
40 |
if ( !is_array( $aPatts ) || empty( $aPatts[ 'simple' ] ) || empty( $aPatts[ 'regex' ] ) ) {
|
32 |
}
|
33 |
|
34 |
if ( empty( $oCacheDef->data ) ) {
|
35 |
+
$sApiToken = $this->getCon()
|
36 |
+
->getModule_License()
|
37 |
+
->getWpHashesTokenManager()
|
38 |
+
->getToken();
|
39 |
// First attempt to download from WP Hashes API.
|
40 |
+
$aPatts = ( new Malware\Patterns\Retrieve( $sApiToken ) )->getPatterns();
|
41 |
|
42 |
// Fallback to original method
|
43 |
if ( !is_array( $aPatts ) || empty( $aPatts[ 'simple' ] ) || empty( $aPatts[ 'regex' ] ) ) {
|
src/lib/src/Scans/Ptg/ScannerBase.php
DELETED
@@ -1,53 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Class ScannerBase
|
9 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
|
10 |
-
* @deprecated 8.5
|
11 |
-
*/
|
12 |
-
abstract class ScannerBase {
|
13 |
-
|
14 |
-
const CONTEXT = '';
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @param array[] $aPreExistingHashes - key is the slug/base-file name and value is the file hashes
|
18 |
-
* @return ResultsSet
|
19 |
-
*/
|
20 |
-
public function run( $aPreExistingHashes ) {
|
21 |
-
return new ResultsSet();
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @param string $sAssetSlug
|
26 |
-
* @return string[]
|
27 |
-
*/
|
28 |
-
public function hashAssetFiles( $sAssetSlug ) {
|
29 |
-
return [];
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @param string $sSlug
|
34 |
-
* @return string
|
35 |
-
*/
|
36 |
-
abstract protected function getDirFromItemSlug( $sSlug );
|
37 |
-
|
38 |
-
/**
|
39 |
-
* @param int $nDepth
|
40 |
-
* @return $this
|
41 |
-
*/
|
42 |
-
public function setDepth( $nDepth ) {
|
43 |
-
return $this;
|
44 |
-
}
|
45 |
-
|
46 |
-
/**
|
47 |
-
* @param string[] $aExts
|
48 |
-
* @return $this
|
49 |
-
*/
|
50 |
-
public function setFileExts( $aExts ) {
|
51 |
-
return $this;
|
52 |
-
}
|
53 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Scans/Ptg/ScannerPlugins.php
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Services\Services;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Class ScannerPlugins
|
9 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
|
10 |
-
* @deprecated 8.5
|
11 |
-
*/
|
12 |
-
class ScannerPlugins extends ScannerBase {
|
13 |
-
|
14 |
-
const CONTEXT = 'plugins';
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @param string $sSlug
|
18 |
-
* @return string
|
19 |
-
*/
|
20 |
-
protected function getDirFromItemSlug( $sSlug ) {
|
21 |
-
return Services::WpPlugins()->getInstallationDir( $sSlug );
|
22 |
-
}
|
23 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Scans/Wpv/Scan.php
CHANGED
@@ -38,6 +38,11 @@ class Scan extends Shield\Scans\Base\BaseScan {
|
|
38 |
protected function scanItem( $sContext, $sFile ) {
|
39 |
$oResultsSet = new ResultsSet();
|
40 |
|
|
|
|
|
|
|
|
|
|
|
41 |
if ( $sContext == 'plugins' ) {
|
42 |
$oWpPlugins = Services::WpPlugins();
|
43 |
$sSlug = $oWpPlugins->getSlug( $sFile );
|
@@ -45,12 +50,12 @@ class Scan extends Shield\Scans\Base\BaseScan {
|
|
45 |
$sSlug = dirname( $sFile );
|
46 |
}
|
47 |
$sVersion = $oWpPlugins->getPluginAsVo( $sFile )->Version;
|
48 |
-
$oLookup = new Vulnerabilities\Plugin();
|
49 |
}
|
50 |
else {
|
51 |
$sSlug = $sFile;
|
52 |
$sVersion = Services::WpThemes()->getTheme( $sSlug )->get( 'Version' );
|
53 |
-
$oLookup = new Vulnerabilities\Theme();
|
54 |
}
|
55 |
|
56 |
$aVulns = $oLookup->getVulnerabilities( $sSlug, $sVersion );
|
38 |
protected function scanItem( $sContext, $sFile ) {
|
39 |
$oResultsSet = new ResultsSet();
|
40 |
|
41 |
+
$sApiToken = $this->getCon()
|
42 |
+
->getModule_License()
|
43 |
+
->getWpHashesTokenManager()
|
44 |
+
->getToken();
|
45 |
+
|
46 |
if ( $sContext == 'plugins' ) {
|
47 |
$oWpPlugins = Services::WpPlugins();
|
48 |
$sSlug = $oWpPlugins->getSlug( $sFile );
|
50 |
$sSlug = dirname( $sFile );
|
51 |
}
|
52 |
$sVersion = $oWpPlugins->getPluginAsVo( $sFile )->Version;
|
53 |
+
$oLookup = new Vulnerabilities\Plugin( $sApiToken );
|
54 |
}
|
55 |
else {
|
56 |
$sSlug = $sFile;
|
57 |
$sVersion = Services::WpThemes()->getTheme( $sSlug )->get( 'Version' );
|
58 |
+
$oLookup = new Vulnerabilities\Theme( $sApiToken );
|
59 |
}
|
60 |
|
61 |
$aVulns = $oLookup->getVulnerabilities( $sSlug, $sVersion );
|
src/lib/src/Tables/Build/Ip.php
CHANGED
@@ -26,6 +26,8 @@ class Ip extends BaseBuild {
|
|
26 |
$oSelector->filterByIp( $aParams[ 'fIp' ] );
|
27 |
}
|
28 |
|
|
|
|
|
29 |
return $this;
|
30 |
}
|
31 |
|
26 |
$oSelector->filterByIp( $aParams[ 'fIp' ] );
|
27 |
}
|
28 |
|
29 |
+
$oSelector->setOrderBy( 'last_access_at', 'DESC', true );
|
30 |
+
|
31 |
return $this;
|
32 |
}
|
33 |
|
src/lib/src/Tables/Render/IpBlack.php
CHANGED
@@ -9,10 +9,17 @@ class IpBlack extends IpBase {
|
|
9 |
* @return string
|
10 |
*/
|
11 |
public function column_details( $aItem ) {
|
|
|
12 |
return implode( '<br/>', [
|
13 |
sprintf( '%s: %s', __( 'Blocked', 'wp-simple-firewall' ), $aItem[ 'blocked' ] ),
|
14 |
-
sprintf( '%s
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
] );
|
17 |
}
|
18 |
|
9 |
* @return string
|
10 |
*/
|
11 |
public function column_details( $aItem ) {
|
12 |
+
$bAutoBlock = $aItem[ 'list' ] === \ICWP_WPSF_FeatureHandler_Ips::LIST_AUTO_BLACK;
|
13 |
return implode( '<br/>', [
|
14 |
sprintf( '%s: %s', __( 'Blocked', 'wp-simple-firewall' ), $aItem[ 'blocked' ] ),
|
15 |
+
sprintf( '%s / %s',
|
16 |
+
$aItem[ 'is_range' ] ? __( 'IP Range', 'wp-simple-firewall' ) : __( 'Single IP', 'wp-simple-firewall' ),
|
17 |
+
$bAutoBlock ? __( 'Automatic', 'wp-simple-firewall' ) : __( 'Manual', 'wp-simple-firewall' )
|
18 |
+
),
|
19 |
+
sprintf( '%s - %s',
|
20 |
+
sprintf( _n( '%s Offense', '%s Offenses', $aItem[ 'transgressions' ], 'wp-simple-firewall' ), $aItem[ 'transgressions' ] ),
|
21 |
+
sprintf( '%s: %s', __( 'Last Access', 'wp-simple-firewall' ), $aItem[ 'last_trans_at' ] )
|
22 |
+
),
|
23 |
] );
|
24 |
}
|
25 |
|
src/lib/src/Users/ShieldUserMeta.php
CHANGED
@@ -29,6 +29,23 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
29 |
*/
|
30 |
class ShieldUserMeta extends \FernleafSystems\Wordpress\Services\Utilities\PluginUserMeta {
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
/**
|
33 |
* @return int
|
34 |
*/
|
29 |
*/
|
30 |
class ShieldUserMeta extends \FernleafSystems\Wordpress\Services\Utilities\PluginUserMeta {
|
31 |
|
32 |
+
/**
|
33 |
+
* @param string $sAgent
|
34 |
+
* @param int|null $nMaxExpires - allows us to clean out old entries
|
35 |
+
*/
|
36 |
+
public function addMfaSkipAgent( $sAgent, $nMaxExpires = null ) {
|
37 |
+
$aHashes = is_array( $this->hash_loginmfa ) ? $this->hash_loginmfa : [];
|
38 |
+
$aHashes[ md5( $sAgent ) ] = Services::Request()->ts();
|
39 |
+
if ( !empty( $nMaxExpires ) ) {
|
40 |
+
$aHashes = array_filter( $aHashes,
|
41 |
+
function ( $nTS ) use ( $nMaxExpires ) {
|
42 |
+
return Services::Request()->ts() - $nTS < $nMaxExpires;
|
43 |
+
}
|
44 |
+
);
|
45 |
+
}
|
46 |
+
$this->hash_loginmfa = $aHashes;
|
47 |
+
}
|
48 |
+
|
49 |
/**
|
50 |
* @return int
|
51 |
*/
|
src/lib/src/Utilities/AdminNotices/Controller.php
CHANGED
@@ -84,7 +84,7 @@ class Controller {
|
|
84 |
/**
|
85 |
* @return NoticeVO|null
|
86 |
*/
|
87 |
-
|
88 |
$oNotice = null;
|
89 |
$aM = $this->retrieveFlashMessage();
|
90 |
if ( is_array( $aM ) ) {
|
84 |
/**
|
85 |
* @return NoticeVO|null
|
86 |
*/
|
87 |
+
public function getFlashNotice() {
|
88 |
$oNotice = null;
|
89 |
$aM = $this->retrieveFlashMessage();
|
90 |
if ( is_array( $aM ) ) {
|
src/lib/vendor/composer/autoload_classmap.php
CHANGED
@@ -51,6 +51,9 @@ return array(
|
|
51 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Snapshot\\Collate' => $baseDir . '/src/ChangeTrack/Snapshot/Collate.php',
|
52 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Snapshot\\SnapshotsConsumer' => $baseDir . '/src/ChangeTrack/Snapshot/SnapshotsConsumer.php',
|
53 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Controller' => $baseDir . '/src/Controller/Controller.php',
|
|
|
|
|
|
|
54 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Crons\\StandardCron' => $baseDir . '/src/Crons/StandardCron.php',
|
55 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AdminNotes\\Delete' => $baseDir . '/src/Databases/AdminNotes/Delete.php',
|
56 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AdminNotes\\EntryVO' => $baseDir . '/src/Databases/AdminNotes/EntryVO.php',
|
@@ -195,7 +198,6 @@ return array(
|
|
195 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseAction' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseAction.php',
|
196 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseBulk' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseBulk.php',
|
197 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\Build' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Build.php',
|
198 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BuildAll' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BuildAll.php',
|
199 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\CleanAll' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CleanAll.php',
|
200 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\CreateNew' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CreateNew.php',
|
201 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\Delete' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Delete.php',
|
@@ -253,6 +255,9 @@ return array(
|
|
253 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryIpBlock' => $baseDir . '/src/Modules/IPs/Components/QueryIpBlock.php',
|
254 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryRemainingOffenses' => $baseDir . '/src/Modules/IPs/Components/QueryRemainingOffenses.php',
|
255 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => $baseDir . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
|
|
|
|
|
|
|
256 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => $baseDir . '/src/Modules/IPs/Lib/OffenseTracker.php',
|
257 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\AddIp' => $baseDir . '/src/Modules/IPs/Lib/Ops/AddIp.php',
|
258 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\DeleteIp' => $baseDir . '/src/Modules/IPs/Lib/Ops/DeleteIp.php',
|
@@ -262,7 +267,13 @@ return array(
|
|
262 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Strings' => $baseDir . '/src/Modules/IPs/Strings.php',
|
263 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Options' => $baseDir . '/src/Modules/Insights/Options.php',
|
264 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Strings' => $baseDir . '/src/Modules/Insights/Strings.php',
|
|
|
265 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\AjaxHandler' => $baseDir . '/src/Modules/License/AjaxHandler.php',
|
|
|
|
|
|
|
|
|
|
|
266 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Options' => $baseDir . '/src/Modules/License/Options.php',
|
267 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Strings' => $baseDir . '/src/Modules/License/Strings.php',
|
268 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Lockdown\\Options' => $baseDir . '/src/Modules/Lockdown/Options.php',
|
@@ -271,6 +282,16 @@ return array(
|
|
271 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\AjaxHandler' => $baseDir . '/src/Modules/LoginGuard/AjaxHandler.php',
|
272 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownFlagFile' => $baseDir . '/src/Modules/LoginGuard/Lib/CooldownFlagFile.php',
|
273 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownRedirect' => $baseDir . '/src/Modules/LoginGuard/Lib/CooldownRedirect.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Options' => $baseDir . '/src/Modules/LoginGuard/Options.php',
|
275 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Strings' => $baseDir . '/src/Modules/LoginGuard/Strings.php',
|
276 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\ModConsumer' => $baseDir . '/src/Modules/ModConsumer.php',
|
@@ -288,6 +309,7 @@ return array(
|
|
288 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => $baseDir . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
289 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AjaxHandler' => $baseDir . '/src/Modules/SecurityAdmin/AjaxHandler.php',
|
290 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\Actions\\RemoveSecAdmin' => $baseDir . '/src/Modules/SecurityAdmin/Lib/Actions/RemoveSecAdmin.php',
|
|
|
291 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Options' => $baseDir . '/src/Modules/SecurityAdmin/Options.php',
|
292 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Strings' => $baseDir . '/src/Modules/SecurityAdmin/Strings.php',
|
293 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\Ops\\Terminate' => $baseDir . '/src/Modules/Sessions/Lib/Ops/Terminate.php',
|
@@ -302,6 +324,7 @@ return array(
|
|
302 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Strings' => $baseDir . '/src/Modules/Traffic/Strings.php',
|
303 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\AjaxHandler' => $baseDir . '/src/Modules/UserManagement/AjaxHandler.php',
|
304 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Lib\\CleanExpired' => $baseDir . '/src/Modules/UserManagement/Lib/CleanExpired.php',
|
|
|
305 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Lib\\RetrieveActive' => $baseDir . '/src/Modules/UserManagement/Lib/RetrieveActive.php',
|
306 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Options' => $baseDir . '/src/Modules/UserManagement/Options.php',
|
307 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Strings' => $baseDir . '/src/Modules/UserManagement/Strings.php',
|
@@ -365,8 +388,6 @@ return array(
|
|
365 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Scan' => $baseDir . '/src/Scans/Ptg/Scan.php',
|
366 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScanActionVO' => $baseDir . '/src/Scans/Ptg/ScanActionVO.php',
|
367 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScanFromFileMap' => $baseDir . '/src/Scans/Ptg/ScanFromFileMap.php',
|
368 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerBase' => $baseDir . '/src/Scans/Ptg/ScannerBase.php',
|
369 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerPlugins' => $baseDir . '/src/Scans/Ptg/ScannerPlugins.php',
|
370 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Table\\EntryFormatter' => $baseDir . '/src/Scans/Ptg/Table/EntryFormatter.php',
|
371 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Ptg/Utilities/ItemActionHandler.php',
|
372 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\Repair' => $baseDir . '/src/Scans/Ptg/Utilities/Repair.php',
|
@@ -461,6 +482,7 @@ return array(
|
|
461 |
'FernleafSystems\\Wordpress\\Services\\Core\\Respond' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Respond.php',
|
462 |
'FernleafSystems\\Wordpress\\Services\\Core\\Response' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Response.php',
|
463 |
'FernleafSystems\\Wordpress\\Services\\Core\\Rest' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Rest.php',
|
|
|
464 |
'FernleafSystems\\Wordpress\\Services\\Core\\Themes' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Themes.php',
|
465 |
'FernleafSystems\\Wordpress\\Services\\Core\\Track' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Track.php',
|
466 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\BulkPluginUpgraderSkin' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/BulkPluginUpgraderSkin.php',
|
@@ -546,9 +568,14 @@ return array(
|
|
546 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Iterators\\WpUserIterator' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php',
|
547 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\EddActions' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddActions.php',
|
548 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\EddLicenseVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php',
|
|
|
|
|
|
|
549 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\Lookup' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/Lookup.php',
|
550 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
|
551 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Obfuscate' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Obfuscate.php',
|
|
|
|
|
552 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
|
553 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
|
554 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
|
@@ -604,7 +631,6 @@ return array(
|
|
604 |
'ICWP_WPSF_FeatureHandler_Sessions' => $baseDir . '/../features/sessions.php',
|
605 |
'ICWP_WPSF_FeatureHandler_Traffic' => $baseDir . '/../features/traffic.php',
|
606 |
'ICWP_WPSF_FeatureHandler_UserManagement' => $baseDir . '/../features/user_management.php',
|
607 |
-
'ICWP_WPSF_Foundation' => $baseDir . '/../common/icwp-foundation.php',
|
608 |
'ICWP_WPSF_Processor_AdminAccessRestriction' => $baseDir . '/../processors/admin_access_restriction.php',
|
609 |
'ICWP_WPSF_Processor_AdminAccess_Whitelabel' => $baseDir . '/../processors/adminaccess_whitelabel.php',
|
610 |
'ICWP_WPSF_Processor_AuditTrail' => $baseDir . '/../processors/audit_trail.php',
|
@@ -623,7 +649,6 @@ return array(
|
|
623 |
'ICWP_WPSF_Processor_HackProtect_Mal' => $baseDir . '/../processors/hackprotect_scan_mal.php',
|
624 |
'ICWP_WPSF_Processor_HackProtect_Ptg' => $baseDir . '/../processors/hackprotect_scan_ptg.php',
|
625 |
'ICWP_WPSF_Processor_HackProtect_Realtime' => $baseDir . '/../processors/hackprotect_realtime.php',
|
626 |
-
'ICWP_WPSF_Processor_HackProtect_ScanAssetsBase' => $baseDir . '/../processors/hackprotect_scan_assets_base.php',
|
627 |
'ICWP_WPSF_Processor_HackProtect_Scanner' => $baseDir . '/../processors/hackprotect_scanner.php',
|
628 |
'ICWP_WPSF_Processor_HackProtect_Ufc' => $baseDir . '/../processors/hackprotect_scan_ufc.php',
|
629 |
'ICWP_WPSF_Processor_HackProtect_Wcf' => $baseDir . '/../processors/hackprotect_scan_wcf.php',
|
@@ -659,12 +684,10 @@ return array(
|
|
659 |
'ICWP_WPSF_Processor_UserManagement_Passwords' => $baseDir . '/../processors/usermanagement_passwords.php',
|
660 |
'ICWP_WPSF_Processor_UserManagement_Sessions' => $baseDir . '/../processors/usermanagement_sessions.php',
|
661 |
'ICWP_WPSF_Processor_UserManagement_Suspend' => $baseDir . '/../processors/usermanagement_suspend.php',
|
662 |
-
'ICWP_WPSF_ServiceProviders' => $baseDir . '/../common/icwp-serviceproviders.php',
|
663 |
'ICWP_WPSF_Wizard_Base' => $baseDir . '/../wizards/base.php',
|
664 |
'ICWP_WPSF_Wizard_BaseWpsf' => $baseDir . '/../wizards/base_wpsf.php',
|
665 |
'ICWP_WPSF_Wizard_LoginProtect' => $baseDir . '/../wizards/login_protect.php',
|
666 |
'ICWP_WPSF_Wizard_Plugin' => $baseDir . '/../wizards/plugin.php',
|
667 |
-
'ICWP_WPSF_WpCron' => $baseDir . '/../common/icwp-wpcron.php',
|
668 |
'JsonSerializable' => $vendorDir . '/nesbot/carbon/src/JsonSerializable.php',
|
669 |
'LZCompressor\\LZContext' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php',
|
670 |
'LZCompressor\\LZData' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZData.php',
|
51 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Snapshot\\Collate' => $baseDir . '/src/ChangeTrack/Snapshot/Collate.php',
|
52 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Snapshot\\SnapshotsConsumer' => $baseDir . '/src/ChangeTrack/Snapshot/SnapshotsConsumer.php',
|
53 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Controller' => $baseDir . '/src/Controller/Controller.php',
|
54 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Crons\\BaseCron' => $baseDir . '/src/Crons/BaseCron.php',
|
55 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Crons\\DailyCron' => $baseDir . '/src/Crons/DailyCron.php',
|
56 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Crons\\HourlyCron' => $baseDir . '/src/Crons/HourlyCron.php',
|
57 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Crons\\StandardCron' => $baseDir . '/src/Crons/StandardCron.php',
|
58 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AdminNotes\\Delete' => $baseDir . '/src/Databases/AdminNotes/Delete.php',
|
59 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AdminNotes\\EntryVO' => $baseDir . '/src/Databases/AdminNotes/EntryVO.php',
|
198 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseAction' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseAction.php',
|
199 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseBulk' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseBulk.php',
|
200 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\Build' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Build.php',
|
|
|
201 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\CleanAll' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CleanAll.php',
|
202 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\CreateNew' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CreateNew.php',
|
203 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\Delete' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Delete.php',
|
255 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryIpBlock' => $baseDir . '/src/Modules/IPs/Components/QueryIpBlock.php',
|
256 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryRemainingOffenses' => $baseDir . '/src/Modules/IPs/Components/QueryRemainingOffenses.php',
|
257 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => $baseDir . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
|
258 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlacklistHandler' => $baseDir . '/src/Modules/IPs/Lib/BlacklistHandler.php',
|
259 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlackmarkRequest' => $baseDir . '/src/Modules/IPs/Lib/BlackmarkRequest.php',
|
260 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlockRequest' => $baseDir . '/src/Modules/IPs/Lib/BlockRequest.php',
|
261 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => $baseDir . '/src/Modules/IPs/Lib/OffenseTracker.php',
|
262 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\AddIp' => $baseDir . '/src/Modules/IPs/Lib/Ops/AddIp.php',
|
263 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\DeleteIp' => $baseDir . '/src/Modules/IPs/Lib/Ops/DeleteIp.php',
|
267 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Strings' => $baseDir . '/src/Modules/IPs/Strings.php',
|
268 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Options' => $baseDir . '/src/Modules/Insights/Options.php',
|
269 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Strings' => $baseDir . '/src/Modules/Insights/Strings.php',
|
270 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\AdminNotices' => $baseDir . '/src/Modules/License/AdminNotices.php',
|
271 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\AjaxHandler' => $baseDir . '/src/Modules/License/AjaxHandler.php',
|
272 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Lib\\LicenseEmails' => $baseDir . '/src/Modules/License/Lib/LicenseEmails.php',
|
273 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Lib\\LicenseHandler' => $baseDir . '/src/Modules/License/Lib/LicenseHandler.php',
|
274 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Lib\\LookupRequest' => $baseDir . '/src/Modules/License/Lib/LookupRequest.php',
|
275 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Lib\\Verify' => $baseDir . '/src/Modules/License/Lib/Verify.php',
|
276 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Lib\\WpHashes\\ApiTokenManager' => $baseDir . '/src/Modules/License/Lib/WpHashes/ApiTokenManager.php',
|
277 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Options' => $baseDir . '/src/Modules/License/Options.php',
|
278 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Strings' => $baseDir . '/src/Modules/License/Strings.php',
|
279 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Lockdown\\Options' => $baseDir . '/src/Modules/Lockdown/Options.php',
|
282 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\AjaxHandler' => $baseDir . '/src/Modules/LoginGuard/AjaxHandler.php',
|
283 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownFlagFile' => $baseDir . '/src/Modules/LoginGuard/Lib/CooldownFlagFile.php',
|
284 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownRedirect' => $baseDir . '/src/Modules/LoginGuard/Lib/CooldownRedirect.php',
|
285 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\LoginIntentPage' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php',
|
286 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\MfaController' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php',
|
287 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\MfaControllerConsumer' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/MfaControllerConsumer.php',
|
288 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\Provider\\Backup' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Backup.php',
|
289 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\Provider\\BaseProvider' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/Provider/BaseProvider.php',
|
290 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\Provider\\Email' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Email.php',
|
291 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\Provider\\GoogleAuth' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/Provider/GoogleAuth.php',
|
292 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\Provider\\Yubikey' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Yubikey.php',
|
293 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\UserProfile' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/UserProfile.php',
|
294 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\ValidateLoginIntentRequest' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/ValidateLoginIntentRequest.php',
|
295 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Options' => $baseDir . '/src/Modules/LoginGuard/Options.php',
|
296 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Strings' => $baseDir . '/src/Modules/LoginGuard/Strings.php',
|
297 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\ModConsumer' => $baseDir . '/src/Modules/ModConsumer.php',
|
309 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => $baseDir . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
310 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AjaxHandler' => $baseDir . '/src/Modules/SecurityAdmin/AjaxHandler.php',
|
311 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\Actions\\RemoveSecAdmin' => $baseDir . '/src/Modules/SecurityAdmin/Lib/Actions/RemoveSecAdmin.php',
|
312 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\WhiteLabel\\ApplyLabels' => $baseDir . '/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php',
|
313 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Options' => $baseDir . '/src/Modules/SecurityAdmin/Options.php',
|
314 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Strings' => $baseDir . '/src/Modules/SecurityAdmin/Strings.php',
|
315 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\Ops\\Terminate' => $baseDir . '/src/Modules/Sessions/Lib/Ops/Terminate.php',
|
324 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Strings' => $baseDir . '/src/Modules/Traffic/Strings.php',
|
325 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\AjaxHandler' => $baseDir . '/src/Modules/UserManagement/AjaxHandler.php',
|
326 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Lib\\CleanExpired' => $baseDir . '/src/Modules/UserManagement/Lib/CleanExpired.php',
|
327 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Lib\\Registration\\EmailValidate' => $baseDir . '/src/Modules/UserManagement/Lib/Registration/EmailValidate.php',
|
328 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Lib\\RetrieveActive' => $baseDir . '/src/Modules/UserManagement/Lib/RetrieveActive.php',
|
329 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Options' => $baseDir . '/src/Modules/UserManagement/Options.php',
|
330 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Strings' => $baseDir . '/src/Modules/UserManagement/Strings.php',
|
388 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Scan' => $baseDir . '/src/Scans/Ptg/Scan.php',
|
389 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScanActionVO' => $baseDir . '/src/Scans/Ptg/ScanActionVO.php',
|
390 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScanFromFileMap' => $baseDir . '/src/Scans/Ptg/ScanFromFileMap.php',
|
|
|
|
|
391 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Table\\EntryFormatter' => $baseDir . '/src/Scans/Ptg/Table/EntryFormatter.php',
|
392 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Ptg/Utilities/ItemActionHandler.php',
|
393 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\Repair' => $baseDir . '/src/Scans/Ptg/Utilities/Repair.php',
|
482 |
'FernleafSystems\\Wordpress\\Services\\Core\\Respond' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Respond.php',
|
483 |
'FernleafSystems\\Wordpress\\Services\\Core\\Response' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Response.php',
|
484 |
'FernleafSystems\\Wordpress\\Services\\Core\\Rest' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Rest.php',
|
485 |
+
'FernleafSystems\\Wordpress\\Services\\Core\\System' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/System.php',
|
486 |
'FernleafSystems\\Wordpress\\Services\\Core\\Themes' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Themes.php',
|
487 |
'FernleafSystems\\Wordpress\\Services\\Core\\Track' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Track.php',
|
488 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\BulkPluginUpgraderSkin' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/BulkPluginUpgraderSkin.php',
|
568 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Iterators\\WpUserIterator' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php',
|
569 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\EddActions' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddActions.php',
|
570 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\EddLicenseVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php',
|
571 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\Keyless\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Base.php',
|
572 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\Keyless\\Lookup' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Lookup.php',
|
573 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\Keyless\\Ping' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Ping.php',
|
574 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\Lookup' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/Lookup.php',
|
575 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
|
576 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Obfuscate' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Obfuscate.php',
|
577 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Options\\TestCanUseTransients' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Options/TestCanUseTransients.php',
|
578 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Options\\Transient' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Options/Transient.php',
|
579 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
|
580 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
|
581 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
|
631 |
'ICWP_WPSF_FeatureHandler_Sessions' => $baseDir . '/../features/sessions.php',
|
632 |
'ICWP_WPSF_FeatureHandler_Traffic' => $baseDir . '/../features/traffic.php',
|
633 |
'ICWP_WPSF_FeatureHandler_UserManagement' => $baseDir . '/../features/user_management.php',
|
|
|
634 |
'ICWP_WPSF_Processor_AdminAccessRestriction' => $baseDir . '/../processors/admin_access_restriction.php',
|
635 |
'ICWP_WPSF_Processor_AdminAccess_Whitelabel' => $baseDir . '/../processors/adminaccess_whitelabel.php',
|
636 |
'ICWP_WPSF_Processor_AuditTrail' => $baseDir . '/../processors/audit_trail.php',
|
649 |
'ICWP_WPSF_Processor_HackProtect_Mal' => $baseDir . '/../processors/hackprotect_scan_mal.php',
|
650 |
'ICWP_WPSF_Processor_HackProtect_Ptg' => $baseDir . '/../processors/hackprotect_scan_ptg.php',
|
651 |
'ICWP_WPSF_Processor_HackProtect_Realtime' => $baseDir . '/../processors/hackprotect_realtime.php',
|
|
|
652 |
'ICWP_WPSF_Processor_HackProtect_Scanner' => $baseDir . '/../processors/hackprotect_scanner.php',
|
653 |
'ICWP_WPSF_Processor_HackProtect_Ufc' => $baseDir . '/../processors/hackprotect_scan_ufc.php',
|
654 |
'ICWP_WPSF_Processor_HackProtect_Wcf' => $baseDir . '/../processors/hackprotect_scan_wcf.php',
|
684 |
'ICWP_WPSF_Processor_UserManagement_Passwords' => $baseDir . '/../processors/usermanagement_passwords.php',
|
685 |
'ICWP_WPSF_Processor_UserManagement_Sessions' => $baseDir . '/../processors/usermanagement_sessions.php',
|
686 |
'ICWP_WPSF_Processor_UserManagement_Suspend' => $baseDir . '/../processors/usermanagement_suspend.php',
|
|
|
687 |
'ICWP_WPSF_Wizard_Base' => $baseDir . '/../wizards/base.php',
|
688 |
'ICWP_WPSF_Wizard_BaseWpsf' => $baseDir . '/../wizards/base_wpsf.php',
|
689 |
'ICWP_WPSF_Wizard_LoginProtect' => $baseDir . '/../wizards/login_protect.php',
|
690 |
'ICWP_WPSF_Wizard_Plugin' => $baseDir . '/../wizards/plugin.php',
|
|
|
691 |
'JsonSerializable' => $vendorDir . '/nesbot/carbon/src/JsonSerializable.php',
|
692 |
'LZCompressor\\LZContext' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php',
|
693 |
'LZCompressor\\LZData' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZData.php',
|
src/lib/vendor/composer/autoload_static.php
CHANGED
@@ -200,6 +200,9 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
200 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Snapshot\\Collate' => __DIR__ . '/../..' . '/src/ChangeTrack/Snapshot/Collate.php',
|
201 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Snapshot\\SnapshotsConsumer' => __DIR__ . '/../..' . '/src/ChangeTrack/Snapshot/SnapshotsConsumer.php',
|
202 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Controller' => __DIR__ . '/../..' . '/src/Controller/Controller.php',
|
|
|
|
|
|
|
203 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Crons\\StandardCron' => __DIR__ . '/../..' . '/src/Crons/StandardCron.php',
|
204 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AdminNotes\\Delete' => __DIR__ . '/../..' . '/src/Databases/AdminNotes/Delete.php',
|
205 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AdminNotes\\EntryVO' => __DIR__ . '/../..' . '/src/Databases/AdminNotes/EntryVO.php',
|
@@ -344,7 +347,6 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
344 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseAction' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseAction.php',
|
345 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseBulk' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseBulk.php',
|
346 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\Build' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Build.php',
|
347 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BuildAll' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BuildAll.php',
|
348 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\CleanAll' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CleanAll.php',
|
349 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\CreateNew' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CreateNew.php',
|
350 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\Delete' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Delete.php',
|
@@ -402,6 +404,9 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
402 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryIpBlock' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/QueryIpBlock.php',
|
403 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryRemainingOffenses' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/QueryRemainingOffenses.php',
|
404 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
|
|
|
|
|
|
|
405 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/OffenseTracker.php',
|
406 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\AddIp' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/AddIp.php',
|
407 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\DeleteIp' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/DeleteIp.php',
|
@@ -411,7 +416,13 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
411 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Strings' => __DIR__ . '/../..' . '/src/Modules/IPs/Strings.php',
|
412 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Options' => __DIR__ . '/../..' . '/src/Modules/Insights/Options.php',
|
413 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Strings' => __DIR__ . '/../..' . '/src/Modules/Insights/Strings.php',
|
|
|
414 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/License/AjaxHandler.php',
|
|
|
|
|
|
|
|
|
|
|
415 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Options' => __DIR__ . '/../..' . '/src/Modules/License/Options.php',
|
416 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Strings' => __DIR__ . '/../..' . '/src/Modules/License/Strings.php',
|
417 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Lockdown\\Options' => __DIR__ . '/../..' . '/src/Modules/Lockdown/Options.php',
|
@@ -420,6 +431,16 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
420 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/AjaxHandler.php',
|
421 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownFlagFile' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/CooldownFlagFile.php',
|
422 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownRedirect' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/CooldownRedirect.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
423 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Options' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Options.php',
|
424 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Strings' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Strings.php',
|
425 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\ModConsumer' => __DIR__ . '/../..' . '/src/Modules/ModConsumer.php',
|
@@ -437,6 +458,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
437 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
438 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/AjaxHandler.php',
|
439 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\Actions\\RemoveSecAdmin' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/Actions/RemoveSecAdmin.php',
|
|
|
440 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Options' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Options.php',
|
441 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Strings' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Strings.php',
|
442 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\Ops\\Terminate' => __DIR__ . '/../..' . '/src/Modules/Sessions/Lib/Ops/Terminate.php',
|
@@ -451,6 +473,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
451 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Strings' => __DIR__ . '/../..' . '/src/Modules/Traffic/Strings.php',
|
452 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/UserManagement/AjaxHandler.php',
|
453 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Lib\\CleanExpired' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Lib/CleanExpired.php',
|
|
|
454 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Lib\\RetrieveActive' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Lib/RetrieveActive.php',
|
455 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Options' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Options.php',
|
456 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Strings' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Strings.php',
|
@@ -514,8 +537,6 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
514 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Scan' => __DIR__ . '/../..' . '/src/Scans/Ptg/Scan.php',
|
515 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Ptg/ScanActionVO.php',
|
516 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScanFromFileMap' => __DIR__ . '/../..' . '/src/Scans/Ptg/ScanFromFileMap.php',
|
517 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerBase' => __DIR__ . '/../..' . '/src/Scans/Ptg/ScannerBase.php',
|
518 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerPlugins' => __DIR__ . '/../..' . '/src/Scans/Ptg/ScannerPlugins.php',
|
519 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Table\\EntryFormatter' => __DIR__ . '/../..' . '/src/Scans/Ptg/Table/EntryFormatter.php',
|
520 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Ptg/Utilities/ItemActionHandler.php',
|
521 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Ptg/Utilities/Repair.php',
|
@@ -610,6 +631,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
610 |
'FernleafSystems\\Wordpress\\Services\\Core\\Respond' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Respond.php',
|
611 |
'FernleafSystems\\Wordpress\\Services\\Core\\Response' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Response.php',
|
612 |
'FernleafSystems\\Wordpress\\Services\\Core\\Rest' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Rest.php',
|
|
|
613 |
'FernleafSystems\\Wordpress\\Services\\Core\\Themes' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Themes.php',
|
614 |
'FernleafSystems\\Wordpress\\Services\\Core\\Track' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Track.php',
|
615 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\BulkPluginUpgraderSkin' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/BulkPluginUpgraderSkin.php',
|
@@ -695,9 +717,14 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
695 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Iterators\\WpUserIterator' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php',
|
696 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\EddActions' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddActions.php',
|
697 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\EddLicenseVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php',
|
|
|
|
|
|
|
698 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\Lookup' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/Lookup.php',
|
699 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
|
700 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Obfuscate' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Obfuscate.php',
|
|
|
|
|
701 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
|
702 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
|
703 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
|
@@ -753,7 +780,6 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
753 |
'ICWP_WPSF_FeatureHandler_Sessions' => __DIR__ . '/../..' . '/../features/sessions.php',
|
754 |
'ICWP_WPSF_FeatureHandler_Traffic' => __DIR__ . '/../..' . '/../features/traffic.php',
|
755 |
'ICWP_WPSF_FeatureHandler_UserManagement' => __DIR__ . '/../..' . '/../features/user_management.php',
|
756 |
-
'ICWP_WPSF_Foundation' => __DIR__ . '/../..' . '/../common/icwp-foundation.php',
|
757 |
'ICWP_WPSF_Processor_AdminAccessRestriction' => __DIR__ . '/../..' . '/../processors/admin_access_restriction.php',
|
758 |
'ICWP_WPSF_Processor_AdminAccess_Whitelabel' => __DIR__ . '/../..' . '/../processors/adminaccess_whitelabel.php',
|
759 |
'ICWP_WPSF_Processor_AuditTrail' => __DIR__ . '/../..' . '/../processors/audit_trail.php',
|
@@ -772,7 +798,6 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
772 |
'ICWP_WPSF_Processor_HackProtect_Mal' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_mal.php',
|
773 |
'ICWP_WPSF_Processor_HackProtect_Ptg' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_ptg.php',
|
774 |
'ICWP_WPSF_Processor_HackProtect_Realtime' => __DIR__ . '/../..' . '/../processors/hackprotect_realtime.php',
|
775 |
-
'ICWP_WPSF_Processor_HackProtect_ScanAssetsBase' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_assets_base.php',
|
776 |
'ICWP_WPSF_Processor_HackProtect_Scanner' => __DIR__ . '/../..' . '/../processors/hackprotect_scanner.php',
|
777 |
'ICWP_WPSF_Processor_HackProtect_Ufc' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_ufc.php',
|
778 |
'ICWP_WPSF_Processor_HackProtect_Wcf' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_wcf.php',
|
@@ -808,12 +833,10 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
808 |
'ICWP_WPSF_Processor_UserManagement_Passwords' => __DIR__ . '/../..' . '/../processors/usermanagement_passwords.php',
|
809 |
'ICWP_WPSF_Processor_UserManagement_Sessions' => __DIR__ . '/../..' . '/../processors/usermanagement_sessions.php',
|
810 |
'ICWP_WPSF_Processor_UserManagement_Suspend' => __DIR__ . '/../..' . '/../processors/usermanagement_suspend.php',
|
811 |
-
'ICWP_WPSF_ServiceProviders' => __DIR__ . '/../..' . '/../common/icwp-serviceproviders.php',
|
812 |
'ICWP_WPSF_Wizard_Base' => __DIR__ . '/../..' . '/../wizards/base.php',
|
813 |
'ICWP_WPSF_Wizard_BaseWpsf' => __DIR__ . '/../..' . '/../wizards/base_wpsf.php',
|
814 |
'ICWP_WPSF_Wizard_LoginProtect' => __DIR__ . '/../..' . '/../wizards/login_protect.php',
|
815 |
'ICWP_WPSF_Wizard_Plugin' => __DIR__ . '/../..' . '/../wizards/plugin.php',
|
816 |
-
'ICWP_WPSF_WpCron' => __DIR__ . '/../..' . '/../common/icwp-wpcron.php',
|
817 |
'JsonSerializable' => __DIR__ . '/..' . '/nesbot/carbon/src/JsonSerializable.php',
|
818 |
'LZCompressor\\LZContext' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php',
|
819 |
'LZCompressor\\LZData' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZData.php',
|
200 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Snapshot\\Collate' => __DIR__ . '/../..' . '/src/ChangeTrack/Snapshot/Collate.php',
|
201 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Snapshot\\SnapshotsConsumer' => __DIR__ . '/../..' . '/src/ChangeTrack/Snapshot/SnapshotsConsumer.php',
|
202 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Controller' => __DIR__ . '/../..' . '/src/Controller/Controller.php',
|
203 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Crons\\BaseCron' => __DIR__ . '/../..' . '/src/Crons/BaseCron.php',
|
204 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Crons\\DailyCron' => __DIR__ . '/../..' . '/src/Crons/DailyCron.php',
|
205 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Crons\\HourlyCron' => __DIR__ . '/../..' . '/src/Crons/HourlyCron.php',
|
206 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Crons\\StandardCron' => __DIR__ . '/../..' . '/src/Crons/StandardCron.php',
|
207 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AdminNotes\\Delete' => __DIR__ . '/../..' . '/src/Databases/AdminNotes/Delete.php',
|
208 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AdminNotes\\EntryVO' => __DIR__ . '/../..' . '/src/Databases/AdminNotes/EntryVO.php',
|
347 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseAction' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseAction.php',
|
348 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseBulk' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseBulk.php',
|
349 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\Build' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Build.php',
|
|
|
350 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\CleanAll' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CleanAll.php',
|
351 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\CreateNew' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CreateNew.php',
|
352 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\Delete' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Delete.php',
|
404 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryIpBlock' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/QueryIpBlock.php',
|
405 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryRemainingOffenses' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/QueryRemainingOffenses.php',
|
406 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
|
407 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlacklistHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/BlacklistHandler.php',
|
408 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlackmarkRequest' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/BlackmarkRequest.php',
|
409 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlockRequest' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/BlockRequest.php',
|
410 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/OffenseTracker.php',
|
411 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\AddIp' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/AddIp.php',
|
412 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\DeleteIp' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/DeleteIp.php',
|
416 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Strings' => __DIR__ . '/../..' . '/src/Modules/IPs/Strings.php',
|
417 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Options' => __DIR__ . '/../..' . '/src/Modules/Insights/Options.php',
|
418 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Strings' => __DIR__ . '/../..' . '/src/Modules/Insights/Strings.php',
|
419 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\AdminNotices' => __DIR__ . '/../..' . '/src/Modules/License/AdminNotices.php',
|
420 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/License/AjaxHandler.php',
|
421 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Lib\\LicenseEmails' => __DIR__ . '/../..' . '/src/Modules/License/Lib/LicenseEmails.php',
|
422 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Lib\\LicenseHandler' => __DIR__ . '/../..' . '/src/Modules/License/Lib/LicenseHandler.php',
|
423 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Lib\\LookupRequest' => __DIR__ . '/../..' . '/src/Modules/License/Lib/LookupRequest.php',
|
424 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Lib\\Verify' => __DIR__ . '/../..' . '/src/Modules/License/Lib/Verify.php',
|
425 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Lib\\WpHashes\\ApiTokenManager' => __DIR__ . '/../..' . '/src/Modules/License/Lib/WpHashes/ApiTokenManager.php',
|
426 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Options' => __DIR__ . '/../..' . '/src/Modules/License/Options.php',
|
427 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\License\\Strings' => __DIR__ . '/../..' . '/src/Modules/License/Strings.php',
|
428 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Lockdown\\Options' => __DIR__ . '/../..' . '/src/Modules/Lockdown/Options.php',
|
431 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/AjaxHandler.php',
|
432 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownFlagFile' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/CooldownFlagFile.php',
|
433 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownRedirect' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/CooldownRedirect.php',
|
434 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\LoginIntentPage' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php',
|
435 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\MfaController' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php',
|
436 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\MfaControllerConsumer' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/MfaControllerConsumer.php',
|
437 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\Provider\\Backup' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Backup.php',
|
438 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\Provider\\BaseProvider' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/Provider/BaseProvider.php',
|
439 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\Provider\\Email' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Email.php',
|
440 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\Provider\\GoogleAuth' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/Provider/GoogleAuth.php',
|
441 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\Provider\\Yubikey' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Yubikey.php',
|
442 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\UserProfile' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/UserProfile.php',
|
443 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\ValidateLoginIntentRequest' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/ValidateLoginIntentRequest.php',
|
444 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Options' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Options.php',
|
445 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Strings' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Strings.php',
|
446 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\ModConsumer' => __DIR__ . '/../..' . '/src/Modules/ModConsumer.php',
|
458 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
459 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/AjaxHandler.php',
|
460 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\Actions\\RemoveSecAdmin' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/Actions/RemoveSecAdmin.php',
|
461 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\WhiteLabel\\ApplyLabels' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php',
|
462 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Options' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Options.php',
|
463 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Strings' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Strings.php',
|
464 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\Ops\\Terminate' => __DIR__ . '/../..' . '/src/Modules/Sessions/Lib/Ops/Terminate.php',
|
473 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Strings' => __DIR__ . '/../..' . '/src/Modules/Traffic/Strings.php',
|
474 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/UserManagement/AjaxHandler.php',
|
475 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Lib\\CleanExpired' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Lib/CleanExpired.php',
|
476 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Lib\\Registration\\EmailValidate' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Lib/Registration/EmailValidate.php',
|
477 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Lib\\RetrieveActive' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Lib/RetrieveActive.php',
|
478 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Options' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Options.php',
|
479 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Strings' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Strings.php',
|
537 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Scan' => __DIR__ . '/../..' . '/src/Scans/Ptg/Scan.php',
|
538 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Ptg/ScanActionVO.php',
|
539 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScanFromFileMap' => __DIR__ . '/../..' . '/src/Scans/Ptg/ScanFromFileMap.php',
|
|
|
|
|
540 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Table\\EntryFormatter' => __DIR__ . '/../..' . '/src/Scans/Ptg/Table/EntryFormatter.php',
|
541 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Ptg/Utilities/ItemActionHandler.php',
|
542 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Ptg/Utilities/Repair.php',
|
631 |
'FernleafSystems\\Wordpress\\Services\\Core\\Respond' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Respond.php',
|
632 |
'FernleafSystems\\Wordpress\\Services\\Core\\Response' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Response.php',
|
633 |
'FernleafSystems\\Wordpress\\Services\\Core\\Rest' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Rest.php',
|
634 |
+
'FernleafSystems\\Wordpress\\Services\\Core\\System' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/System.php',
|
635 |
'FernleafSystems\\Wordpress\\Services\\Core\\Themes' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Themes.php',
|
636 |
'FernleafSystems\\Wordpress\\Services\\Core\\Track' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Track.php',
|
637 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\BulkPluginUpgraderSkin' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/BulkPluginUpgraderSkin.php',
|
717 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Iterators\\WpUserIterator' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php',
|
718 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\EddActions' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddActions.php',
|
719 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\EddLicenseVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php',
|
720 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\Keyless\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Base.php',
|
721 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\Keyless\\Lookup' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Lookup.php',
|
722 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\Keyless\\Ping' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Ping.php',
|
723 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\Lookup' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/Lookup.php',
|
724 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
|
725 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Obfuscate' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Obfuscate.php',
|
726 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Options\\TestCanUseTransients' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Options/TestCanUseTransients.php',
|
727 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Options\\Transient' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Options/Transient.php',
|
728 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
|
729 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
|
730 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
|
780 |
'ICWP_WPSF_FeatureHandler_Sessions' => __DIR__ . '/../..' . '/../features/sessions.php',
|
781 |
'ICWP_WPSF_FeatureHandler_Traffic' => __DIR__ . '/../..' . '/../features/traffic.php',
|
782 |
'ICWP_WPSF_FeatureHandler_UserManagement' => __DIR__ . '/../..' . '/../features/user_management.php',
|
|
|
783 |
'ICWP_WPSF_Processor_AdminAccessRestriction' => __DIR__ . '/../..' . '/../processors/admin_access_restriction.php',
|
784 |
'ICWP_WPSF_Processor_AdminAccess_Whitelabel' => __DIR__ . '/../..' . '/../processors/adminaccess_whitelabel.php',
|
785 |
'ICWP_WPSF_Processor_AuditTrail' => __DIR__ . '/../..' . '/../processors/audit_trail.php',
|
798 |
'ICWP_WPSF_Processor_HackProtect_Mal' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_mal.php',
|
799 |
'ICWP_WPSF_Processor_HackProtect_Ptg' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_ptg.php',
|
800 |
'ICWP_WPSF_Processor_HackProtect_Realtime' => __DIR__ . '/../..' . '/../processors/hackprotect_realtime.php',
|
|
|
801 |
'ICWP_WPSF_Processor_HackProtect_Scanner' => __DIR__ . '/../..' . '/../processors/hackprotect_scanner.php',
|
802 |
'ICWP_WPSF_Processor_HackProtect_Ufc' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_ufc.php',
|
803 |
'ICWP_WPSF_Processor_HackProtect_Wcf' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_wcf.php',
|
833 |
'ICWP_WPSF_Processor_UserManagement_Passwords' => __DIR__ . '/../..' . '/../processors/usermanagement_passwords.php',
|
834 |
'ICWP_WPSF_Processor_UserManagement_Sessions' => __DIR__ . '/../..' . '/../processors/usermanagement_sessions.php',
|
835 |
'ICWP_WPSF_Processor_UserManagement_Suspend' => __DIR__ . '/../..' . '/../processors/usermanagement_suspend.php',
|
|
|
836 |
'ICWP_WPSF_Wizard_Base' => __DIR__ . '/../..' . '/../wizards/base.php',
|
837 |
'ICWP_WPSF_Wizard_BaseWpsf' => __DIR__ . '/../..' . '/../wizards/base_wpsf.php',
|
838 |
'ICWP_WPSF_Wizard_LoginProtect' => __DIR__ . '/../..' . '/../wizards/login_protect.php',
|
839 |
'ICWP_WPSF_Wizard_Plugin' => __DIR__ . '/../..' . '/../wizards/plugin.php',
|
|
|
840 |
'JsonSerializable' => __DIR__ . '/..' . '/nesbot/carbon/src/JsonSerializable.php',
|
841 |
'LZCompressor\\LZContext' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php',
|
842 |
'LZCompressor\\LZData' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZData.php',
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/General.php
CHANGED
@@ -4,6 +4,7 @@ namespace FernleafSystems\Wordpress\Services\Core;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes;
|
|
|
7 |
|
8 |
class General {
|
9 |
|
@@ -12,6 +13,13 @@ class General {
|
|
12 |
*/
|
13 |
protected $sWpVersion;
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
/**
|
16 |
* @return null|string
|
17 |
*/
|
@@ -579,27 +587,30 @@ class General {
|
|
579 |
/**
|
580 |
* @param string $sKey
|
581 |
* @param $sValue
|
|
|
582 |
* @return bool
|
583 |
*/
|
584 |
-
public function updateOption( $sKey, $sValue ) {
|
585 |
-
return $this->isMultisite() ? update_site_option( $sKey, $sValue ) : update_option( $sKey, $sValue );
|
586 |
}
|
587 |
|
588 |
/**
|
589 |
* @param string $sKey
|
590 |
* @param mixed $mDefault
|
|
|
591 |
* @return mixed
|
592 |
*/
|
593 |
-
public function getOption( $sKey, $mDefault = false ) {
|
594 |
-
return $this->isMultisite() ? get_site_option( $sKey, $mDefault ) : get_option( $sKey, $mDefault );
|
595 |
}
|
596 |
|
597 |
/**
|
598 |
* @param string $sKey
|
599 |
-
* @
|
|
|
600 |
*/
|
601 |
-
public function deleteOption( $sKey ) {
|
602 |
-
return $this->isMultisite() ? delete_site_option( $sKey ) : delete_option( $sKey );
|
603 |
}
|
604 |
|
605 |
/**
|
4 |
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes;
|
7 |
+
use FernleafSystems\Wordpress\Services\Utilities\Options\TestCanUseTransients;
|
8 |
|
9 |
class General {
|
10 |
|
13 |
*/
|
14 |
protected $sWpVersion;
|
15 |
|
16 |
+
/**
|
17 |
+
* @return bool
|
18 |
+
*/
|
19 |
+
public function canUseTransients() {
|
20 |
+
return ( new TestCanUseTransients() )->run();
|
21 |
+
}
|
22 |
+
|
23 |
/**
|
24 |
* @return null|string
|
25 |
*/
|
587 |
/**
|
588 |
* @param string $sKey
|
589 |
* @param $sValue
|
590 |
+
* @param bool $bIgnoreWPMS
|
591 |
* @return bool
|
592 |
*/
|
593 |
+
public function updateOption( $sKey, $sValue, $bIgnoreWPMS = false ) {
|
594 |
+
return ( $this->isMultisite() && !$bIgnoreWPMS ) ? update_site_option( $sKey, $sValue ) : update_option( $sKey, $sValue );
|
595 |
}
|
596 |
|
597 |
/**
|
598 |
* @param string $sKey
|
599 |
* @param mixed $mDefault
|
600 |
+
* @param bool $bIgnoreWPMS
|
601 |
* @return mixed
|
602 |
*/
|
603 |
+
public function getOption( $sKey, $mDefault = false, $bIgnoreWPMS = false ) {
|
604 |
+
return ( $this->isMultisite() && !$bIgnoreWPMS ) ? get_site_option( $sKey, $mDefault ) : get_option( $sKey, $mDefault );
|
605 |
}
|
606 |
|
607 |
/**
|
608 |
* @param string $sKey
|
609 |
+
* @param bool $bIgnoreWPMS
|
610 |
+
* @return bool
|
611 |
*/
|
612 |
+
public function deleteOption( $sKey, $bIgnoreWPMS = false ) {
|
613 |
+
return ( $this->isMultisite() && !$bIgnoreWPMS ) ? delete_site_option( $sKey ) : delete_option( $sKey );
|
614 |
}
|
615 |
|
616 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/System.php
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Services\Core;
|
4 |
+
|
5 |
+
class System {
|
6 |
+
|
7 |
+
const PREFIX = 'aptoweb_';
|
8 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Data.php
CHANGED
@@ -464,6 +464,7 @@ class Data {
|
|
464 |
'PATH',
|
465 |
'DOCUMENT_ROOT',
|
466 |
'SERVER_ADDR',
|
|
|
467 |
] )
|
468 |
) )
|
469 |
) );
|
464 |
'PATH',
|
465 |
'DOCUMENT_ROOT',
|
466 |
'SERVER_ADDR',
|
467 |
+
'SERVER_NAME',
|
468 |
] )
|
469 |
) )
|
470 |
) );
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php
CHANGED
@@ -16,6 +16,8 @@ abstract class ApiBase {
|
|
16 |
const REQUEST_TYPE = 'GET';
|
17 |
const RESPONSE_DATA_KEY = '';
|
18 |
|
|
|
|
|
19 |
/**
|
20 |
* @var RequestVO
|
21 |
*/
|
@@ -31,18 +33,26 @@ abstract class ApiBase {
|
|
31 |
*/
|
32 |
private static $aQueryCache = [];
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
/**
|
35 |
* @return string
|
36 |
*/
|
37 |
protected function getApiUrl() {
|
38 |
-
return
|
39 |
}
|
40 |
|
41 |
/**
|
42 |
* @return array
|
43 |
*/
|
44 |
protected function getQueryData() {
|
45 |
-
return [];
|
46 |
}
|
47 |
|
48 |
/**
|
@@ -104,7 +114,7 @@ abstract class ApiBase {
|
|
104 |
protected function fireRequest_GET() {
|
105 |
$sResponse = null;
|
106 |
|
107 |
-
$sUrl = add_query_arg(
|
108 |
$sSig = md5( $sUrl );
|
109 |
|
110 |
if ( $this->isUseQueryCache() && isset( self::$aQueryCache[ $sSig ] ) ) {
|
@@ -128,7 +138,7 @@ abstract class ApiBase {
|
|
128 |
$oHttp = new HttpRequest();
|
129 |
$oHttp
|
130 |
->post(
|
131 |
-
add_query_arg(
|
132 |
[ 'body' => $this->getRequestVO()->getRawDataAsArray() ]
|
133 |
);
|
134 |
return $oHttp->isSuccess() ? $oHttp->lastResponse->body : null;
|
@@ -141,6 +151,17 @@ abstract class ApiBase {
|
|
141 |
return (bool)$this->bUseQueryCache;
|
142 |
}
|
143 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
/**
|
145 |
* @param bool $bUseQueryCache
|
146 |
* @return $this
|
16 |
const REQUEST_TYPE = 'GET';
|
17 |
const RESPONSE_DATA_KEY = '';
|
18 |
|
19 |
+
protected static $API_TOKEN;
|
20 |
+
|
21 |
/**
|
22 |
* @var RequestVO
|
23 |
*/
|
33 |
*/
|
34 |
private static $aQueryCache = [];
|
35 |
|
36 |
+
/**
|
37 |
+
* ApiBase constructor.
|
38 |
+
* @param string $sApiToken
|
39 |
+
*/
|
40 |
+
public function __construct( $sApiToken = null ) {
|
41 |
+
$this->setApiToken( $sApiToken );
|
42 |
+
}
|
43 |
+
|
44 |
/**
|
45 |
* @return string
|
46 |
*/
|
47 |
protected function getApiUrl() {
|
48 |
+
return static::API_URL.static::API_ENDPOINT;
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
* @return array
|
53 |
*/
|
54 |
protected function getQueryData() {
|
55 |
+
return empty( static::$API_TOKEN ) ? [] : [ 'token' => static::$API_TOKEN ];
|
56 |
}
|
57 |
|
58 |
/**
|
114 |
protected function fireRequest_GET() {
|
115 |
$sResponse = null;
|
116 |
|
117 |
+
$sUrl = add_query_arg( $this->getQueryData(), $this->getApiUrl() );
|
118 |
$sSig = md5( $sUrl );
|
119 |
|
120 |
if ( $this->isUseQueryCache() && isset( self::$aQueryCache[ $sSig ] ) ) {
|
138 |
$oHttp = new HttpRequest();
|
139 |
$oHttp
|
140 |
->post(
|
141 |
+
add_query_arg( $this->getQueryData(), $this->getApiUrl() ),
|
142 |
[ 'body' => $this->getRequestVO()->getRawDataAsArray() ]
|
143 |
);
|
144 |
return $oHttp->isSuccess() ? $oHttp->lastResponse->body : null;
|
151 |
return (bool)$this->bUseQueryCache;
|
152 |
}
|
153 |
|
154 |
+
/**
|
155 |
+
* @param string $sToken
|
156 |
+
* @return $this
|
157 |
+
*/
|
158 |
+
public function setApiToken( $sToken ) {
|
159 |
+
if ( is_string( $sToken ) && preg_match( '#^[a-z0-9]{32,}$#', $sToken ) ) {
|
160 |
+
static::$API_TOKEN = $sToken;
|
161 |
+
}
|
162 |
+
return $this;
|
163 |
+
}
|
164 |
+
|
165 |
/**
|
166 |
* @param bool $bUseQueryCache
|
167 |
* @return $this
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ApiInfo.php
CHANGED
@@ -21,6 +21,6 @@ class ApiInfo extends Base {
|
|
21 |
* @return string
|
22 |
*/
|
23 |
protected function getApiUrl() {
|
24 |
-
return parent::getApiUrl().'info';
|
25 |
}
|
26 |
}
|
21 |
* @return string
|
22 |
*/
|
23 |
protected function getApiUrl() {
|
24 |
+
return parent::getApiUrl().'/info';
|
25 |
}
|
26 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/AssetHashesBase.php
CHANGED
@@ -2,8 +2,6 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
|
6 |
-
|
7 |
abstract class AssetHashesBase extends Base {
|
8 |
|
9 |
const DEFAULT_HASH_ALGO = 'md5';
|
@@ -14,7 +12,7 @@ abstract class AssetHashesBase extends Base {
|
|
14 |
* @return string
|
15 |
*/
|
16 |
protected function getApiUrl() {
|
17 |
-
$aData = array_filter( array_merge(
|
18 |
[
|
19 |
'type' => false,
|
20 |
'slug' => false,
|
@@ -23,8 +21,8 @@ abstract class AssetHashesBase extends Base {
|
|
23 |
'hash' => false,
|
24 |
],
|
25 |
$this->getRequestVO()->getRawDataAsArray()
|
26 |
-
) );
|
27 |
-
return sprintf( '%s
|
28 |
}
|
29 |
|
30 |
/**
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes;
|
4 |
|
|
|
|
|
5 |
abstract class AssetHashesBase extends Base {
|
6 |
|
7 |
const DEFAULT_HASH_ALGO = 'md5';
|
12 |
* @return string
|
13 |
*/
|
14 |
protected function getApiUrl() {
|
15 |
+
$aData = array_map( 'strtolower', array_filter( array_merge(
|
16 |
[
|
17 |
'type' => false,
|
18 |
'slug' => false,
|
21 |
'hash' => false,
|
22 |
],
|
23 |
$this->getRequestVO()->getRawDataAsArray()
|
24 |
+
) ) );
|
25 |
+
return sprintf( '%s/%s', parent::getApiUrl(), implode( '/', $aData ) );
|
26 |
}
|
27 |
|
28 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Base.php
CHANGED
@@ -6,5 +6,5 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
|
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
-
const API_ENDPOINT = 'hashes
|
10 |
}
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
+
const API_ENDPOINT = 'hashes';
|
10 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/PluginThemeBase.php
CHANGED
@@ -17,9 +17,9 @@ abstract class PluginThemeBase extends AssetHashesBase {
|
|
17 |
public function getHashes( $sSlug, $sVersion, $sHashAlgo = null ) {
|
18 |
/** @var RequestVO $oReq */
|
19 |
$oReq = $this->getRequestVO();
|
|
|
20 |
$oReq->version = $sVersion;
|
21 |
$oReq->hash = $sHashAlgo;
|
22 |
-
$oReq->slug = $sSlug;
|
23 |
return $this->query();
|
24 |
}
|
25 |
}
|
17 |
public function getHashes( $sSlug, $sVersion, $sHashAlgo = null ) {
|
18 |
/** @var RequestVO $oReq */
|
19 |
$oReq = $this->getRequestVO();
|
20 |
+
$oReq->slug = $sSlug;
|
21 |
$oReq->version = $sVersion;
|
22 |
$oReq->hash = $sHashAlgo;
|
|
|
23 |
return $this->query();
|
24 |
}
|
25 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Base.php
CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
|
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
-
const API_ENDPOINT = 'malware/fpconfidence
|
10 |
|
11 |
/**
|
12 |
* @return RequestVO
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
+
const API_ENDPOINT = 'malware/fpconfidence';
|
10 |
|
11 |
/**
|
12 |
* @return RequestVO
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Retrieve.php
CHANGED
@@ -25,7 +25,7 @@ class Retrieve extends Base {
|
|
25 |
],
|
26 |
$this->getRequestVO()->getRawDataAsArray()
|
27 |
) );
|
28 |
-
return sprintf( '%s
|
29 |
}
|
30 |
|
31 |
/**
|
25 |
],
|
26 |
$this->getRequestVO()->getRawDataAsArray()
|
27 |
) );
|
28 |
+
return sprintf( '%s/%s', parent::getApiUrl(), implode( '/', $aData ) );
|
29 |
}
|
30 |
|
31 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Services/Base.php
CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
|
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
-
const API_ENDPOINT = 'services
|
10 |
|
11 |
/**
|
12 |
* @return RequestVO
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
+
const API_ENDPOINT = 'services';
|
10 |
|
11 |
/**
|
12 |
* @return RequestVO
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Services/IPs.php
CHANGED
@@ -21,6 +21,6 @@ class IPs extends Base {
|
|
21 |
* @return string
|
22 |
*/
|
23 |
protected function getApiUrl() {
|
24 |
-
return parent::getApiUrl().'ips';
|
25 |
}
|
26 |
}
|
21 |
* @return string
|
22 |
*/
|
23 |
protected function getApiUrl() {
|
24 |
+
return parent::getApiUrl().'/ips';
|
25 |
}
|
26 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Token/Base.php
CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
|
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
-
const API_ENDPOINT = 'token
|
10 |
const RESPONSE_DATA_KEY = 'token';
|
11 |
|
12 |
/**
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
+
const API_ENDPOINT = 'token';
|
10 |
const RESPONSE_DATA_KEY = 'token';
|
11 |
|
12 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Token/Solicit.php
CHANGED
@@ -2,8 +2,6 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Token;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Services\Utilities\Licenses\EddActions;
|
6 |
-
|
7 |
/**
|
8 |
* Class Solicit
|
9 |
* @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Token
|
@@ -20,22 +18,27 @@ class Solicit extends Base {
|
|
20 |
$oReq = $this->getRequestVO();
|
21 |
$oReq->action = 'solicit';
|
22 |
$oReq->install_id = $sInstallId;
|
23 |
-
$oReq->url =
|
24 |
return $this->query();
|
25 |
}
|
26 |
|
27 |
/**
|
28 |
-
* @
|
29 |
*/
|
30 |
protected function getApiUrl() {
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Token;
|
4 |
|
|
|
|
|
5 |
/**
|
6 |
* Class Solicit
|
7 |
* @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Token
|
18 |
$oReq = $this->getRequestVO();
|
19 |
$oReq->action = 'solicit';
|
20 |
$oReq->install_id = $sInstallId;
|
21 |
+
$oReq->url = strpos( $sUrl, '?' ) ? explode( '?', $sUrl, 2 )[ 0 ] : $sUrl;
|
22 |
return $this->query();
|
23 |
}
|
24 |
|
25 |
/**
|
26 |
+
* @inheritDoc
|
27 |
*/
|
28 |
protected function getApiUrl() {
|
29 |
+
/** @var RequestVO $oReq */
|
30 |
+
$oReq = $this->getRequestVO();
|
31 |
+
return sprintf( '%s/%s/%s', parent::getApiUrl(), $oReq->action, $oReq->install_id );
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @inheritDoc
|
36 |
+
*/
|
37 |
+
protected function getQueryData() {
|
38 |
+
/** @var RequestVO $oReq */
|
39 |
+
$oReq = $this->getRequestVO();
|
40 |
+
$aData = parent::getQueryData();
|
41 |
+
$aData[ 'url' ] = $oReq->url;
|
42 |
+
return $aData;
|
43 |
}
|
44 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Verify/Base.php
CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
|
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
-
const API_ENDPOINT = 'verify
|
10 |
const RESPONSE_DATA_KEY = 'verification';
|
11 |
|
12 |
/**
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
+
const API_ENDPOINT = 'verify';
|
10 |
const RESPONSE_DATA_KEY = 'verification';
|
11 |
|
12 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Verify/Email.php
CHANGED
@@ -30,6 +30,6 @@ class Email extends Base {
|
|
30 |
],
|
31 |
$this->getRequestVO()->getRawDataAsArray()
|
32 |
) ) );
|
33 |
-
return sprintf( '%s
|
34 |
}
|
35 |
}
|
30 |
],
|
31 |
$this->getRequestVO()->getRawDataAsArray()
|
32 |
) ) );
|
33 |
+
return sprintf( '%s/%s', parent::getApiUrl(), implode( '/', $aData ) );
|
34 |
}
|
35 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Vulnerabilities/Base.php
CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
|
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
-
const API_ENDPOINT = 'vulnerabilities
|
10 |
const ASSET_TYPE = '';
|
11 |
const RESPONSE_DATA_KEY = 'vulnerabilities';
|
12 |
|
@@ -21,7 +21,7 @@ abstract class Base extends WpHashes\ApiBase {
|
|
21 |
* @return string
|
22 |
*/
|
23 |
protected function getApiUrl() {
|
24 |
-
return parent::getApiUrl().$this->getRequestVO()->type
|
25 |
}
|
26 |
|
27 |
/**
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
+
const API_ENDPOINT = 'vulnerabilities';
|
10 |
const ASSET_TYPE = '';
|
11 |
const RESPONSE_DATA_KEY = 'vulnerabilities';
|
12 |
|
21 |
* @return string
|
22 |
*/
|
23 |
protected function getApiUrl() {
|
24 |
+
return parent::getApiUrl().'/'.$this->getRequestVO()->type;
|
25 |
}
|
26 |
|
27 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Vulnerabilities/BasePluginTheme.php
CHANGED
@@ -15,7 +15,7 @@ abstract class BasePluginTheme extends Base {
|
|
15 |
*/
|
16 |
public function getVulnerabilities( $sSlug, $sVersion ) {
|
17 |
$oReq = $this->getRequestVO();
|
18 |
-
$oReq->slug = $sSlug;
|
19 |
$oReq->version = $sVersion;
|
20 |
return $this->query();
|
21 |
}
|
@@ -25,6 +25,6 @@ abstract class BasePluginTheme extends Base {
|
|
25 |
*/
|
26 |
protected function getApiUrl() {
|
27 |
$oReq = $this->getRequestVO();
|
28 |
-
return sprintf( '%s
|
29 |
}
|
30 |
}
|
15 |
*/
|
16 |
public function getVulnerabilities( $sSlug, $sVersion ) {
|
17 |
$oReq = $this->getRequestVO();
|
18 |
+
$oReq->slug = strtolower( $sSlug );
|
19 |
$oReq->version = $sVersion;
|
20 |
return $this->query();
|
21 |
}
|
25 |
*/
|
26 |
protected function getApiUrl() {
|
27 |
$oReq = $this->getRequestVO();
|
28 |
+
return sprintf( '%s/%s/%s', parent::getApiUrl(), $oReq->slug, $oReq->version );
|
29 |
}
|
30 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php
CHANGED
@@ -379,164 +379,4 @@ class IpUtils {
|
|
379 |
$this->sIp = $sIp;
|
380 |
return $this;
|
381 |
}
|
382 |
-
|
383 |
-
/**
|
384 |
-
* @param string $sIp
|
385 |
-
* @return bool
|
386 |
-
* @throws \Exception
|
387 |
-
* @deprecated 0.1.43
|
388 |
-
*/
|
389 |
-
public function isCloudFlareIp( $sIp ) {
|
390 |
-
return Services::ServiceProviders()->isIp_Cloudflare( $sIp );
|
391 |
-
}
|
392 |
-
|
393 |
-
/**
|
394 |
-
* Checks:
|
395 |
-
* - valid public remote IP
|
396 |
-
* - Not CloudFlare
|
397 |
-
* - Not the IP of the currently running server if this is provided
|
398 |
-
* @param string $sIp
|
399 |
-
* @param string $sHostIp
|
400 |
-
* @return bool
|
401 |
-
* @deprecated 0.1.43
|
402 |
-
*/
|
403 |
-
public function isViablePublicVisitorIp( $sIp, $sHostIp = '' ) {
|
404 |
-
return !empty( $sIp ) && $this->isValidIp_PublicRemote( $sIp )
|
405 |
-
&& !Services::ServiceProviders()->isIp_Cloudflare( $sIp )
|
406 |
-
&& ( empty( $sHostIp ) || !$this->checkIp( $sIp, $sHostIp ) );
|
407 |
-
}
|
408 |
-
|
409 |
-
/**
|
410 |
-
* @return string
|
411 |
-
* @deprecated 0.1.43
|
412 |
-
*/
|
413 |
-
public function discoverViableRequestIpSource() {
|
414 |
-
return $this->findViableVisitorIp()[ 'source' ];
|
415 |
-
}
|
416 |
-
|
417 |
-
/**
|
418 |
-
* @param bool $bRemoteVerify
|
419 |
-
* @return string[]
|
420 |
-
* @deprecated 0.1.43
|
421 |
-
*/
|
422 |
-
protected function findViableVisitorIp( $bRemoteVerify = false ) {
|
423 |
-
return [
|
424 |
-
'source' => $this->getIpDetector()->getLastSuccessfulSource(),
|
425 |
-
'ip' => $this->getRequestIp()
|
426 |
-
];
|
427 |
-
}
|
428 |
-
|
429 |
-
/**
|
430 |
-
* @return string[]
|
431 |
-
* @deprecated 0.1.43
|
432 |
-
*/
|
433 |
-
protected function getCloudFlareIpsV4() {
|
434 |
-
return Services::ServiceProviders()->getIps_iControlWP()[ 4 ];
|
435 |
-
}
|
436 |
-
|
437 |
-
/**
|
438 |
-
* @return string[]
|
439 |
-
* @deprecated 0.1.43
|
440 |
-
*/
|
441 |
-
protected function getCloudFlareIpsV6() {
|
442 |
-
return Services::ServiceProviders()->getIps_iControlWP()[ 6 ];
|
443 |
-
}
|
444 |
-
|
445 |
-
/**
|
446 |
-
* @param int $sIpVersion
|
447 |
-
* @return string[]
|
448 |
-
* @deprecated 0.1.43
|
449 |
-
*/
|
450 |
-
public function getServiceIps_Pingdom( $sIpVersion = 4 ) {
|
451 |
-
return Services::ServiceProviders()->getIps_Pingdom( true );
|
452 |
-
}
|
453 |
-
|
454 |
-
/**
|
455 |
-
* @return string[]
|
456 |
-
* @deprecated 0.1.43
|
457 |
-
*/
|
458 |
-
public function getServiceIps_StatusCake() {
|
459 |
-
return Services::ServiceProviders()->getIps_Statuscake( true );
|
460 |
-
}
|
461 |
-
|
462 |
-
/**
|
463 |
-
* @param int $sIpVersion
|
464 |
-
* @return string[]
|
465 |
-
* @deprecated 0.1.43
|
466 |
-
*/
|
467 |
-
public function getServiceIps_UptimeRobot( $sIpVersion = 4 ) {
|
468 |
-
return Services::ServiceProviders()->getIps_UptimeRobot( true );
|
469 |
-
}
|
470 |
-
|
471 |
-
/**
|
472 |
-
* @param string $sIp
|
473 |
-
* @param string $sUserAgent
|
474 |
-
* @return bool
|
475 |
-
* @deprecated 0.1.43
|
476 |
-
*/
|
477 |
-
public function isIpBingBot( $sIp, $sUserAgent = '' ) {
|
478 |
-
return Services::ServiceProviders()->isIp_BingBot( $sIp, $sUserAgent );
|
479 |
-
}
|
480 |
-
|
481 |
-
/**
|
482 |
-
* https://duckduckgo.com/duckduckbot
|
483 |
-
* @param string $sIp
|
484 |
-
* @param string $sUserAgent
|
485 |
-
* @return bool
|
486 |
-
* @deprecated 0.1.43
|
487 |
-
*/
|
488 |
-
public function isIpDuckDuckGoBot( $sIp, $sUserAgent = '' ) {
|
489 |
-
return Services::ServiceProviders()->isIp_DuckDuckGoBot( $sIp, $sUserAgent );
|
490 |
-
}
|
491 |
-
|
492 |
-
/**
|
493 |
-
* @param string $sIp
|
494 |
-
* @param string $sUserAgent
|
495 |
-
* @return bool
|
496 |
-
* @deprecated 0.1.43
|
497 |
-
*/
|
498 |
-
public function isIpGoogleBot( $sIp, $sUserAgent = '' ) {
|
499 |
-
return Services::ServiceProviders()->isIp_GoogleBot( $sIp, $sUserAgent );
|
500 |
-
}
|
501 |
-
|
502 |
-
/**
|
503 |
-
* @param string $sIp
|
504 |
-
* @param string $sUserAgent
|
505 |
-
* @return bool
|
506 |
-
* @deprecated 0.1.43
|
507 |
-
*/
|
508 |
-
public function isIpYandexBot( $sIp, $sUserAgent = '' ) {
|
509 |
-
return Services::ServiceProviders()->isIp_YandexBot( $sIp, $sUserAgent );
|
510 |
-
}
|
511 |
-
|
512 |
-
/**
|
513 |
-
* https://support.apple.com/en-gb/HT204683
|
514 |
-
* https://discussions.apple.com/thread/7090135
|
515 |
-
* Apple IPs start with '17.'
|
516 |
-
* @param string $sIp
|
517 |
-
* @param string $sUserAgent
|
518 |
-
* @return bool
|
519 |
-
* @deprecated 0.1.43
|
520 |
-
*/
|
521 |
-
public function isIpAppleBot( $sIp, $sUserAgent = '' ) {
|
522 |
-
return Services::ServiceProviders()->isIp_AppleBot( $sIp, $sUserAgent );
|
523 |
-
}
|
524 |
-
|
525 |
-
/**
|
526 |
-
* @return string|null
|
527 |
-
* @deprecated 0.1.39
|
528 |
-
*/
|
529 |
-
public function whatIsMyIp() {
|
530 |
-
$aIPs = $this->getServerPublicIPs();
|
531 |
-
return array_shift( $aIPs );
|
532 |
-
}
|
533 |
-
|
534 |
-
/**
|
535 |
-
* @param string $sIp
|
536 |
-
* @return $this
|
537 |
-
* @deprecated 0.1.39
|
538 |
-
*/
|
539 |
-
public function setServerIpAddress( $sIp ) {
|
540 |
-
return $this;
|
541 |
-
}
|
542 |
}
|
379 |
$this->sIp = $sIp;
|
380 |
return $this;
|
381 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
382 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddActions.php
CHANGED
@@ -9,8 +9,10 @@ class EddActions {
|
|
9 |
* @return string
|
10 |
*/
|
11 |
public static function CleanUrl( $sUrl ) {
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
15 |
}
|
16 |
}
|
9 |
* @return string
|
10 |
*/
|
11 |
public static function CleanUrl( $sUrl ) {
|
12 |
+
$sUrl = preg_replace( '#^(https?:/{1,2})?(www\.)?#', '', mb_strtolower( trim( $sUrl ) ) );
|
13 |
+
if ( strpos( $sUrl, '?' ) ) {
|
14 |
+
$sUrl = explode( '?', $sUrl, 2 )[ 0 ];
|
15 |
+
}
|
16 |
+
return sanitize_text_field( trailingslashit( $sUrl ) );
|
17 |
}
|
18 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php
CHANGED
@@ -12,6 +12,8 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
12 |
* @property string $checksum
|
13 |
* @property string $customer_name
|
14 |
* @property string $item_name
|
|
|
|
|
15 |
* @property int $last_request_at
|
16 |
* @property int $last_verified_at
|
17 |
* @property int $license_limit
|
@@ -29,8 +31,7 @@ class EddLicenseVO {
|
|
29 |
* @return int
|
30 |
*/
|
31 |
public function getExpiresAt() {
|
32 |
-
|
33 |
-
return ( $sTime == 'lifetime' ) ? PHP_INT_MAX : strtotime( $sTime );
|
34 |
}
|
35 |
|
36 |
/**
|
@@ -73,7 +74,8 @@ class EddLicenseVO {
|
|
73 |
* @return $this
|
74 |
*/
|
75 |
public function updateLastVerifiedAt( $bAddRandom = false ) {
|
76 |
-
$
|
77 |
-
|
|
|
78 |
}
|
79 |
}
|
12 |
* @property string $checksum
|
13 |
* @property string $customer_name
|
14 |
* @property string $item_name
|
15 |
+
* @property string $expires - date string or "lifetime"
|
16 |
+
* @property int $expires_at - unix timestamp
|
17 |
* @property int $last_request_at
|
18 |
* @property int $last_verified_at
|
19 |
* @property int $license_limit
|
31 |
* @return int
|
32 |
*/
|
33 |
public function getExpiresAt() {
|
34 |
+
return ( $this->expires == 'lifetime' ) ? PHP_INT_MAX : strtotime( $this->expires );
|
|
|
35 |
}
|
36 |
|
37 |
/**
|
74 |
* @return $this
|
75 |
*/
|
76 |
public function updateLastVerifiedAt( $bAddRandom = false ) {
|
77 |
+
$this->last_verified_at = (int)$this->last_request_at +
|
78 |
+
( $bAddRandom ? rand( -6, 18 )*HOUR_IN_SECONDS : 0 );
|
79 |
+
return $this;
|
80 |
}
|
81 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Base.php
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Services\Utilities\Licenses\Keyless;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
use FernleafSystems\Wordpress\Services\Utilities\HttpRequest;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class Lookup
|
11 |
+
* @package FernleafSystems\Wordpress\Services\Utilities\Licenses\Keyless
|
12 |
+
* @property string $lookup_url_stub
|
13 |
+
* @property string $request_method
|
14 |
+
* @property int $timeout
|
15 |
+
* @property HttpRequest $last_http_req
|
16 |
+
*/
|
17 |
+
abstract class Base {
|
18 |
+
|
19 |
+
use StdClassAdapter {
|
20 |
+
__get as __adapterGet;
|
21 |
+
}
|
22 |
+
const DEFAULT_URL_STUB = 'https://www.shieldsecurity.io/wp-json/odp-eddkeyless/v1';
|
23 |
+
const API_ACTION = '';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @return array|null
|
27 |
+
*/
|
28 |
+
protected function sendReq() {
|
29 |
+
$oHttpReq = Services::HttpRequest();
|
30 |
+
|
31 |
+
$aParams = [
|
32 |
+
'timeout' => $this->timeout,
|
33 |
+
'body' => array_intersect_key(
|
34 |
+
$this->getRawDataAsArray(),
|
35 |
+
array_flip( $this->getRequestBodyParamKeys() )
|
36 |
+
)
|
37 |
+
];
|
38 |
+
|
39 |
+
switch ( $this->request_method ) {
|
40 |
+
case 'post':
|
41 |
+
$bReqSuccess = $oHttpReq->post( $this->getApiRequestUrl(), $aParams );
|
42 |
+
break;
|
43 |
+
case 'get':
|
44 |
+
default:
|
45 |
+
$bReqSuccess = $oHttpReq->get( $this->getApiRequestUrl(), $aParams );
|
46 |
+
break;
|
47 |
+
}
|
48 |
+
|
49 |
+
if ( $bReqSuccess ) {
|
50 |
+
$aResponse = empty( $oHttpReq->lastResponse->body ) ? [] : @json_decode( $oHttpReq->lastResponse->body, true );
|
51 |
+
}
|
52 |
+
else {
|
53 |
+
$aResponse = null;
|
54 |
+
}
|
55 |
+
|
56 |
+
$this->last_http_req = $oHttpReq;
|
57 |
+
return $aResponse;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @return string
|
62 |
+
*/
|
63 |
+
protected function getApiRequestUrl() {
|
64 |
+
return sprintf( '%s/%s', $this->lookup_url_stub, static::API_ACTION );
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @return string[]
|
69 |
+
*/
|
70 |
+
protected function getRequestBodyParamKeys() {
|
71 |
+
return [];
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @param string $sProperty
|
76 |
+
* @return mixed
|
77 |
+
*/
|
78 |
+
public function __get( $sProperty ) {
|
79 |
+
|
80 |
+
$mValue = $this->__adapterGet( $sProperty );
|
81 |
+
|
82 |
+
switch ( $sProperty ) {
|
83 |
+
|
84 |
+
case 'request_method':
|
85 |
+
if ( empty( $mValue ) ) {
|
86 |
+
$mValue = 'get';
|
87 |
+
}
|
88 |
+
$mValue = strtolower( $mValue );
|
89 |
+
break;
|
90 |
+
|
91 |
+
case 'lookup_url_stub':
|
92 |
+
if ( empty( $mValue ) ) {
|
93 |
+
$mValue = static::DEFAULT_URL_STUB;
|
94 |
+
}
|
95 |
+
$mValue = rtrim( $mValue, '/' );
|
96 |
+
break;
|
97 |
+
|
98 |
+
case 'timeout':
|
99 |
+
if ( empty( $mValue ) || !is_numeric( $mValue ) ) {
|
100 |
+
$mValue = 60;
|
101 |
+
}
|
102 |
+
break;
|
103 |
+
|
104 |
+
default:
|
105 |
+
break;
|
106 |
+
}
|
107 |
+
|
108 |
+
return $mValue;
|
109 |
+
}
|
110 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Lookup.php
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Services\Utilities\Licenses\Keyless;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
use FernleafSystems\Wordpress\Services\Utilities\Licenses\EddLicenseVO;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Lookup
|
10 |
+
* @package FernleafSystems\Wordpress\Services\Utilities\Licenses\Keyless
|
11 |
+
* @property int $item_id
|
12 |
+
* @property string $install_id
|
13 |
+
* @property string $url
|
14 |
+
* @property string $nonce
|
15 |
+
* @property array $meta
|
16 |
+
*/
|
17 |
+
class Lookup extends Base {
|
18 |
+
|
19 |
+
const API_ACTION = 'lookup';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @return EddLicenseVO
|
23 |
+
*/
|
24 |
+
public function lookup() {
|
25 |
+
if ( empty( $this->url ) ) {
|
26 |
+
$this->url = Services::WpGeneral()->getHomeUrl( '', true );
|
27 |
+
}
|
28 |
+
|
29 |
+
$aRaw = $this->sendReq();
|
30 |
+
if ( is_array( $aRaw ) && !empty( $aRaw[ 'keyless' ] ) && !empty( $aRaw[ 'keyless' ][ 'license' ] ) ) {
|
31 |
+
$aLicenseInfo = $aRaw[ 'keyless' ][ 'license' ];
|
32 |
+
}
|
33 |
+
else {
|
34 |
+
$aLicenseInfo = [];
|
35 |
+
}
|
36 |
+
|
37 |
+
$oLic = ( new EddLicenseVO() )->applyFromArray( $aLicenseInfo );
|
38 |
+
$oLic->last_request_at = Services::Request()->ts();
|
39 |
+
return $oLic;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return string
|
44 |
+
*/
|
45 |
+
protected function getApiRequestUrl() {
|
46 |
+
return sprintf( '%s/%s/%s', parent::getApiRequestUrl(), $this->item_id, $this->install_id );
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @return string[]
|
51 |
+
*/
|
52 |
+
protected function getRequestBodyParamKeys() {
|
53 |
+
return [
|
54 |
+
'url',
|
55 |
+
'nonce',
|
56 |
+
'meta',
|
57 |
+
];
|
58 |
+
}
|
59 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/Keyless/Ping.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Services\Utilities\Licenses\Keyless;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Ping
|
7 |
+
* @package FernleafSystems\Wordpress\Services\Utilities\Licenses\Keyless
|
8 |
+
*/
|
9 |
+
class Ping extends Base {
|
10 |
+
|
11 |
+
const API_ACTION = 'ping';
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @return bool
|
15 |
+
*/
|
16 |
+
public function ping() {
|
17 |
+
$sPong = '';
|
18 |
+
|
19 |
+
$aRaw = $this->sendReq();
|
20 |
+
if ( is_array( $aRaw ) && !empty( $aRaw[ 'keyless' ] ) && !empty( $aRaw[ 'keyless' ][ self::API_ACTION ] ) ) {
|
21 |
+
$sPong = $aRaw[ 'keyless' ][ self::API_ACTION ];
|
22 |
+
}
|
23 |
+
|
24 |
+
return $sPong === 'pong';
|
25 |
+
}
|
26 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/Lookup.php
CHANGED
@@ -4,6 +4,11 @@ namespace FernleafSystems\Wordpress\Services\Utilities\Licenses;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
|
|
|
|
|
|
|
|
|
|
|
7 |
class Lookup {
|
8 |
|
9 |
/**
|
@@ -94,7 +99,6 @@ class Lookup {
|
|
94 |
'license' => $sKey,
|
95 |
'item_id' => $sItemId,
|
96 |
'url' => $oWp->getHomeUrl( '', true ),
|
97 |
-
'alt_url' => $oWp->getWpUrl()
|
98 |
],
|
99 |
$this->getRequestParams()
|
100 |
)
|
4 |
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
|
7 |
+
/**
|
8 |
+
* Class Lookup
|
9 |
+
* @package FernleafSystems\Wordpress\Services\Utilities\Licenses
|
10 |
+
* @deprecated 0.1.60
|
11 |
+
*/
|
12 |
class Lookup {
|
13 |
|
14 |
/**
|
99 |
'license' => $sKey,
|
100 |
'item_id' => $sItemId,
|
101 |
'url' => $oWp->getHomeUrl( '', true ),
|
|
|
102 |
],
|
103 |
$this->getRequestParams()
|
104 |
)
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Options/TestCanUseTransients.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Services\Utilities\Options;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Core\System;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Remarkably, it seems that some WordPress sites can't actually store WordPress Transients
|
10 |
+
* so we run a quick test to see.
|
11 |
+
*
|
12 |
+
* Class Transient
|
13 |
+
* @package FernleafSystems\Wordpress\Services\Utilities\Options
|
14 |
+
*/
|
15 |
+
class TestCanUseTransients {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var bool
|
19 |
+
*/
|
20 |
+
private static $bCan;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @return bool
|
24 |
+
*/
|
25 |
+
public function run() {
|
26 |
+
if ( isset( self::$bCan ) ) {
|
27 |
+
return self::$bCan;
|
28 |
+
}
|
29 |
+
|
30 |
+
$oWP = Services::WpGeneral();
|
31 |
+
$sOptPrefix = System::PREFIX.'can_trans_';
|
32 |
+
$mCan = $oWP->getOption( $sOptPrefix.'confirmed', false, true );
|
33 |
+
|
34 |
+
if ( !in_array( $mCan, [ 'Y', 'N' ] ) ) {
|
35 |
+
$nStartedAt = $oWP->getOption( $sOptPrefix.'started', false, true );
|
36 |
+
if ( is_numeric( $nStartedAt ) && $nStartedAt > 0 ) {
|
37 |
+
$sTransResult = $oWP->getTransient( $sOptPrefix.'test' );
|
38 |
+
if ( $sTransResult === System::PREFIX.'test_value' ) {
|
39 |
+
$mCan = 'Y';
|
40 |
+
}
|
41 |
+
else {
|
42 |
+
$mCan = 'N';
|
43 |
+
}
|
44 |
+
$oWP->deleteOption( $sOptPrefix.'started', true );
|
45 |
+
$oWP->updateOption( $sOptPrefix.'confirmed', $mCan, true );
|
46 |
+
}
|
47 |
+
else {
|
48 |
+
$mCan = 'Y'; // We temporarily state that we can use transients
|
49 |
+
$oWP->setTransient( $sOptPrefix.'test', System::PREFIX.'test_value', 3600 );
|
50 |
+
$oWP->updateOption( $sOptPrefix.'started', Services::Request()->ts(), true );
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
self::$bCan = ( $mCan === 'Y' );
|
55 |
+
return self::$bCan;
|
56 |
+
}
|
57 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Options/Transient.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Services\Utilities\Options;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Core\System;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Remarkably, it seems that some WordPress sites can't actually store WordPress Transients.
|
10 |
+
* Class Transient
|
11 |
+
* @package FernleafSystems\Wordpress\Services\Utilities\Options
|
12 |
+
*/
|
13 |
+
class Transient {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @param string $sKey
|
17 |
+
* @param bool $bIgnoreWPMS
|
18 |
+
* @return bool
|
19 |
+
*/
|
20 |
+
public static function Delete( $sKey, $bIgnoreWPMS = true ) {
|
21 |
+
$oWP = Services::WpGeneral();
|
22 |
+
return $oWP->canUseTransients() ?
|
23 |
+
$oWP->deleteTransient( $sKey )
|
24 |
+
: Services::WpGeneral()->deleteOption( System::PREFIX.'trans_'.$sKey, $bIgnoreWPMS );
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @param string $sKey
|
29 |
+
* @param null $mDefault
|
30 |
+
* @param bool $bIgnoreWPMS
|
31 |
+
* @return mixed|null
|
32 |
+
*/
|
33 |
+
public static function Get( $sKey, $mDefault = null, $bIgnoreWPMS = true ) {
|
34 |
+
$mVal = null;
|
35 |
+
|
36 |
+
$oWP = Services::WpGeneral();
|
37 |
+
|
38 |
+
if ( $oWP->canUseTransients() ) {
|
39 |
+
$mVal = $oWP->getTransient( $sKey );
|
40 |
+
}
|
41 |
+
else {
|
42 |
+
$aData = $oWP->getOption( System::PREFIX.'trans_'.$sKey, null, $bIgnoreWPMS );
|
43 |
+
if ( !empty( $aData ) && is_array( $aData ) && isset( $aData[ 'data' ] )
|
44 |
+
&& isset( $aData[ 'expires_at' ] ) ) {
|
45 |
+
if ( $aData[ 'expires_at' ] === 0 || Services::Request()->ts() < $aData[ 'expires_at' ] ) {
|
46 |
+
$mVal = $aData[ 'data' ];
|
47 |
+
}
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
return is_null( $mVal ) ? $mDefault : $mVal;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @param string $sKey
|
56 |
+
* @param mixed $mData
|
57 |
+
* @param int $nLifeTime
|
58 |
+
* @param bool $bIgnoreWPMS
|
59 |
+
* @return bool
|
60 |
+
*/
|
61 |
+
public static function Set( $sKey, $mData, $nLifeTime = 0, $bIgnoreWPMS = true ) {
|
62 |
+
if ( is_null( $mData ) ) {
|
63 |
+
self::Delete( $sKey );
|
64 |
+
}
|
65 |
+
|
66 |
+
$oWP = Services::WpGeneral();
|
67 |
+
|
68 |
+
if ( $oWP->canUseTransients() ) {
|
69 |
+
return $oWP->setTransient( $sKey, $mData, $nLifeTime );
|
70 |
+
}
|
71 |
+
else {
|
72 |
+
return $oWP->updateOption(
|
73 |
+
System::PREFIX.'trans_'.$sKey,
|
74 |
+
[
|
75 |
+
'data' => $mData,
|
76 |
+
'expires_at' => empty( $nLifeTime ) ? 0 : Services::Request()->ts() + max( 0, $nLifeTime ),
|
77 |
+
],
|
78 |
+
$bIgnoreWPMS
|
79 |
+
);
|
80 |
+
}
|
81 |
+
}
|
82 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php
CHANGED
@@ -4,6 +4,7 @@ namespace FernleafSystems\Wordpress\Services\Utilities;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Services\IPs;
|
|
|
7 |
|
8 |
/**
|
9 |
* Class ServiceProviders
|
@@ -32,12 +33,10 @@ class ServiceProviders {
|
|
32 |
* @return string[][][]|null
|
33 |
*/
|
34 |
protected function getAllServiceIPs() {
|
35 |
-
$
|
36 |
-
$sStoreKey = $this->getPrefixedStoreKey( 'serviceips_wphashes_all' );
|
37 |
-
$aIps = $oWp->getTransient( $sStoreKey );
|
38 |
if ( empty( $aIps ) ) {
|
39 |
$aIps = ( new IPs() )->getIPs();
|
40 |
-
$
|
41 |
}
|
42 |
return $aIps;
|
43 |
}
|
4 |
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Services\IPs;
|
7 |
+
use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
|
8 |
|
9 |
/**
|
10 |
* Class ServiceProviders
|
33 |
* @return string[][][]|null
|
34 |
*/
|
35 |
protected function getAllServiceIPs() {
|
36 |
+
$aIps = Transient::Get( 'serviceips_all' );
|
|
|
|
|
37 |
if ( empty( $aIps ) ) {
|
38 |
$aIps = ( new IPs() )->getIPs();
|
39 |
+
$aIps = Transient::Set( 'serviceips_all',$aIps, WEEK_IN_SECONDS );
|
40 |
}
|
41 |
return $aIps;
|
42 |
}
|
src/lib/vendor/symfony/polyfill-mbstring/Mbstring.php
CHANGED
@@ -545,7 +545,14 @@ final class Mbstring
|
|
545 |
}
|
546 |
|
547 |
if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
|
548 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
549 |
}
|
550 |
|
551 |
$result = array();
|
545 |
}
|
546 |
|
547 |
if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
|
548 |
+
$rx = '/(';
|
549 |
+
while (65535 < $split_length) {
|
550 |
+
$rx .= '.{65535}';
|
551 |
+
$split_length -= 65535;
|
552 |
+
}
|
553 |
+
$rx .= '.{'.$split_length.'})/us';
|
554 |
+
|
555 |
+
return preg_split($rx, $string, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
556 |
}
|
557 |
|
558 |
$result = array();
|
src/processors/admin_access_restriction.php
CHANGED
@@ -18,7 +18,9 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends Modules\BaseShield\Shie
|
|
18 |
add_filter( $this->getCon()->prefix( 'is_plugin_admin' ), [ $this, 'adjustUserAdminPermissions' ] );
|
19 |
|
20 |
if ( $oOpts->isEnabledWhitelabel() ) {
|
21 |
-
|
|
|
|
|
22 |
}
|
23 |
}
|
24 |
|
@@ -74,22 +76,6 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends Modules\BaseShield\Shie
|
|
74 |
}
|
75 |
}
|
76 |
|
77 |
-
/**
|
78 |
-
* @return \ICWP_WPSF_Processor_AdminAccess_Whitelabel|mixed
|
79 |
-
*/
|
80 |
-
protected function getSubProWhitelabel() {
|
81 |
-
return $this->getSubPro( 'wl' );
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* @return array
|
86 |
-
*/
|
87 |
-
protected function getSubProMap() {
|
88 |
-
return [
|
89 |
-
'wl' => 'ICWP_WPSF_Processor_AdminAccess_Whitelabel',
|
90 |
-
];
|
91 |
-
}
|
92 |
-
|
93 |
/**
|
94 |
* Override the original collection to then add plugin statistics to the mix
|
95 |
* @param $aData
|
18 |
add_filter( $this->getCon()->prefix( 'is_plugin_admin' ), [ $this, 'adjustUserAdminPermissions' ] );
|
19 |
|
20 |
if ( $oOpts->isEnabledWhitelabel() ) {
|
21 |
+
( new SecurityAdmin\Lib\WhiteLabel\ApplyLabels() )
|
22 |
+
->setMod( $this->getMod() )
|
23 |
+
->run();
|
24 |
}
|
25 |
}
|
26 |
|
76 |
}
|
77 |
}
|
78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
/**
|
80 |
* Override the original collection to then add plugin statistics to the mix
|
81 |
* @param $aData
|
src/processors/adminaccess_whitelabel.php
CHANGED
@@ -3,15 +3,18 @@
|
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
|
|
|
|
|
|
|
|
6 |
class ICWP_WPSF_Processor_AdminAccess_Whitelabel extends Modules\BaseShield\ShieldProcessor {
|
7 |
|
8 |
/**
|
9 |
*/
|
10 |
public function run() {
|
11 |
-
|
12 |
-
|
13 |
-
add_filter( $
|
14 |
-
add_filter( $oMod->prefix( 'plugin_labels' ), [ $this, 'doRelabelPlugin' ] );
|
15 |
add_filter( 'plugin_row_meta', [ $this, 'fRemoveDetailsMetaLink' ], 200, 2 );
|
16 |
add_action( 'admin_print_footer_scripts-plugin-editor.php', [ $this, 'hideFromPluginEditor' ] );
|
17 |
}
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
+
/**
|
7 |
+
* Class ICWP_WPSF_Processor_AdminAccess_Whitelabel
|
8 |
+
* @deprecated 8.6.2
|
9 |
+
*/
|
10 |
class ICWP_WPSF_Processor_AdminAccess_Whitelabel extends Modules\BaseShield\ShieldProcessor {
|
11 |
|
12 |
/**
|
13 |
*/
|
14 |
public function run() {
|
15 |
+
$oCon = $this->getCon();
|
16 |
+
add_filter( $oCon->prefix( 'is_relabelled' ), '__return_true' );
|
17 |
+
add_filter( $oCon->prefix( 'plugin_labels' ), [ $this, 'doRelabelPlugin' ] );
|
|
|
18 |
add_filter( 'plugin_row_meta', [ $this, 'fRemoveDetailsMetaLink' ], 200, 2 );
|
19 |
add_action( 'admin_print_footer_scripts-plugin-editor.php', [ $this, 'hideFromPluginEditor' ] );
|
20 |
}
|
src/processors/autoupdates.php
CHANGED
@@ -5,30 +5,11 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
5 |
|
6 |
class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor {
|
7 |
|
8 |
-
/**
|
9 |
-
* @var bool
|
10 |
-
*/
|
11 |
-
protected $bDoForceRunAutoupdates = false;
|
12 |
-
|
13 |
/**
|
14 |
* @var array
|
15 |
*/
|
16 |
private $aAssetsVersions = [];
|
17 |
|
18 |
-
/**
|
19 |
-
* @param bool $bDoForceRun
|
20 |
-
*/
|
21 |
-
public function setForceRunAutoupdates( $bDoForceRun ) {
|
22 |
-
$this->bDoForceRunAutoupdates = $bDoForceRun;
|
23 |
-
}
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @return bool
|
27 |
-
*/
|
28 |
-
public function getIfForceRunAutoupdates() {
|
29 |
-
return apply_filters( $this->getMod()->prefix( 'force_autoupdate' ), $this->bDoForceRunAutoupdates );
|
30 |
-
}
|
31 |
-
|
32 |
/**
|
33 |
* The allow_* core filters are run first in a "should_update" query. Then comes the "auto_update_core"
|
34 |
* filter. What this filter decides will ultimately determine the fate of any core upgrade.
|
@@ -47,15 +28,10 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
47 |
add_filter( 'allow_major_auto_core_updates', [ $this, 'autoupdate_core_major' ], $nPriority );
|
48 |
}
|
49 |
|
50 |
-
add_filter( 'auto_update_translation', [ $this, 'autoupdate_translations' ], $nPriority, 1 );
|
51 |
add_filter( 'auto_update_plugin', [ $this, 'autoupdate_plugins' ], $nPriority, 2 );
|
52 |
add_filter( 'auto_update_theme', [ $this, 'autoupdate_themes' ], $nPriority, 2 );
|
53 |
add_filter( 'auto_update_core', [ $this, 'autoupdate_core' ], $nPriority, 2 );
|
54 |
|
55 |
-
if ( $oOpts->isOpt( 'enable_autoupdate_ignore_vcs', 'Y' ) ) {
|
56 |
-
add_filter( 'automatic_updates_is_vcs_checkout', '__return_false', $nPriority );
|
57 |
-
}
|
58 |
-
|
59 |
if ( !$oOpts->isDisableAllAutoUpdates() ) {
|
60 |
//more parameter options here for later
|
61 |
add_filter( 'auto_core_update_send_email', [ $this, 'autoupdate_send_email' ], $nPriority, 1 );
|
@@ -83,9 +59,6 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
83 |
if ( $oOpts->isDisableAllAutoUpdates() ) {
|
84 |
$this->disableAllAutoUpdates();
|
85 |
}
|
86 |
-
else {
|
87 |
-
$this->forceRunAutoUpdates();
|
88 |
-
}
|
89 |
}
|
90 |
|
91 |
private function disableAllAutoUpdates() {
|
@@ -193,15 +166,6 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
193 |
}
|
194 |
}
|
195 |
|
196 |
-
/**
|
197 |
-
* Will force-run the WordPress automatic updates process and then redirect to the updates screen.
|
198 |
-
*/
|
199 |
-
private function forceRunAutoUpdates() {
|
200 |
-
if ( $this->getIfForceRunAutoupdates() ) {
|
201 |
-
Services::WpGeneral()->doForceRunAutomaticUpdates();
|
202 |
-
}
|
203 |
-
}
|
204 |
-
|
205 |
/**
|
206 |
* This is a filter method designed to say whether a major core WordPress upgrade should be permitted,
|
207 |
* based on the plugin settings.
|
@@ -241,16 +205,6 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
241 |
return $bUpdate;
|
242 |
}
|
243 |
|
244 |
-
/**
|
245 |
-
* This is a filter method designed to say whether a WordPress translations upgrades should be permitted,
|
246 |
-
* based on the plugin settings.
|
247 |
-
* @param bool $bUpdate
|
248 |
-
* @return bool
|
249 |
-
*/
|
250 |
-
public function autoupdate_translations( $bUpdate ) {
|
251 |
-
return $this->getOptions()->isOpt( 'enable_autoupdate_translations', 'Y' );
|
252 |
-
}
|
253 |
-
|
254 |
/**
|
255 |
* @param bool $bDoAutoUpdate
|
256 |
* @param \stdClass $oCoreUpdate
|
@@ -399,7 +353,7 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
399 |
* @return array
|
400 |
*/
|
401 |
public function autoupdate_email_override( $aEmailParams ) {
|
402 |
-
$sOverride = $this->
|
403 |
if ( Services::Data()->validEmail( $sOverride ) ) {
|
404 |
$aEmailParams[ 'to' ] = $sOverride;
|
405 |
}
|
@@ -470,7 +424,7 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
470 |
// Are there really updates?
|
471 |
$bReallyUpdates = false;
|
472 |
|
473 |
-
$
|
474 |
sprintf(
|
475 |
__( 'This is a quick notification from the %s that WordPress Automatic Updates just completed on your site with the following results.', 'wp-simple-firewall' ),
|
476 |
$this->getCon()->getHumanName()
|
@@ -501,7 +455,7 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
501 |
|
502 |
if ( $bHasPluginUpdates ) {
|
503 |
$bReallyUpdates = true;
|
504 |
-
$
|
505 |
}
|
506 |
}
|
507 |
|
@@ -526,7 +480,7 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
526 |
|
527 |
if ( $bHasThemesUpdates ) {
|
528 |
$bReallyUpdates = true;
|
529 |
-
$
|
530 |
}
|
531 |
}
|
532 |
|
@@ -543,7 +497,7 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
543 |
|
544 |
if ( $bHasCoreUpdates ) {
|
545 |
$bReallyUpdates = true;
|
546 |
-
$
|
547 |
}
|
548 |
}
|
549 |
|
@@ -551,11 +505,11 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
551 |
return;
|
552 |
}
|
553 |
|
554 |
-
$
|
555 |
|
556 |
$sTitle = sprintf( __( "Notice: %s", 'wp-simple-firewall' ), __( "Automatic Updates Completed", 'wp-simple-firewall' ) );
|
557 |
$this->getEmailProcessor()
|
558 |
-
->sendEmailWithWrap( $this->
|
559 |
die();
|
560 |
}
|
561 |
|
@@ -604,4 +558,21 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
604 |
protected function getHookPriority() {
|
605 |
return $this->getOptions()->getDef( 'action_hook_priority' );
|
606 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
607 |
}
|
5 |
|
6 |
class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor {
|
7 |
|
|
|
|
|
|
|
|
|
|
|
8 |
/**
|
9 |
* @var array
|
10 |
*/
|
11 |
private $aAssetsVersions = [];
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
/**
|
14 |
* The allow_* core filters are run first in a "should_update" query. Then comes the "auto_update_core"
|
15 |
* filter. What this filter decides will ultimately determine the fate of any core upgrade.
|
28 |
add_filter( 'allow_major_auto_core_updates', [ $this, 'autoupdate_core_major' ], $nPriority );
|
29 |
}
|
30 |
|
|
|
31 |
add_filter( 'auto_update_plugin', [ $this, 'autoupdate_plugins' ], $nPriority, 2 );
|
32 |
add_filter( 'auto_update_theme', [ $this, 'autoupdate_themes' ], $nPriority, 2 );
|
33 |
add_filter( 'auto_update_core', [ $this, 'autoupdate_core' ], $nPriority, 2 );
|
34 |
|
|
|
|
|
|
|
|
|
35 |
if ( !$oOpts->isDisableAllAutoUpdates() ) {
|
36 |
//more parameter options here for later
|
37 |
add_filter( 'auto_core_update_send_email', [ $this, 'autoupdate_send_email' ], $nPriority, 1 );
|
59 |
if ( $oOpts->isDisableAllAutoUpdates() ) {
|
60 |
$this->disableAllAutoUpdates();
|
61 |
}
|
|
|
|
|
|
|
62 |
}
|
63 |
|
64 |
private function disableAllAutoUpdates() {
|
166 |
}
|
167 |
}
|
168 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
/**
|
170 |
* This is a filter method designed to say whether a major core WordPress upgrade should be permitted,
|
171 |
* based on the plugin settings.
|
205 |
return $bUpdate;
|
206 |
}
|
207 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
/**
|
209 |
* @param bool $bDoAutoUpdate
|
210 |
* @param \stdClass $oCoreUpdate
|
353 |
* @return array
|
354 |
*/
|
355 |
public function autoupdate_email_override( $aEmailParams ) {
|
356 |
+
$sOverride = $this->getOptions()->getOpt( 'override_email_address', '' );
|
357 |
if ( Services::Data()->validEmail( $sOverride ) ) {
|
358 |
$aEmailParams[ 'to' ] = $sOverride;
|
359 |
}
|
424 |
// Are there really updates?
|
425 |
$bReallyUpdates = false;
|
426 |
|
427 |
+
$aBody = [
|
428 |
sprintf(
|
429 |
__( 'This is a quick notification from the %s that WordPress Automatic Updates just completed on your site with the following results.', 'wp-simple-firewall' ),
|
430 |
$this->getCon()->getHumanName()
|
455 |
|
456 |
if ( $bHasPluginUpdates ) {
|
457 |
$bReallyUpdates = true;
|
458 |
+
$aBody = array_merge( $aBody, $aTempContent );
|
459 |
}
|
460 |
}
|
461 |
|
480 |
|
481 |
if ( $bHasThemesUpdates ) {
|
482 |
$bReallyUpdates = true;
|
483 |
+
$aBody = array_merge( $aBody, $aTempContent );
|
484 |
}
|
485 |
}
|
486 |
|
497 |
|
498 |
if ( $bHasCoreUpdates ) {
|
499 |
$bReallyUpdates = true;
|
500 |
+
$aBody = array_merge( $aBody, $aTempContent );
|
501 |
}
|
502 |
}
|
503 |
|
505 |
return;
|
506 |
}
|
507 |
|
508 |
+
$aBody[] = __( 'Thank you.', 'wp-simple-firewall' );
|
509 |
|
510 |
$sTitle = sprintf( __( "Notice: %s", 'wp-simple-firewall' ), __( "Automatic Updates Completed", 'wp-simple-firewall' ) );
|
511 |
$this->getEmailProcessor()
|
512 |
+
->sendEmailWithWrap( $this->getOptions()->getOpt( 'override_email_address' ), $sTitle, $aBody );
|
513 |
die();
|
514 |
}
|
515 |
|
558 |
protected function getHookPriority() {
|
559 |
return $this->getOptions()->getDef( 'action_hook_priority' );
|
560 |
}
|
561 |
+
|
562 |
+
/**
|
563 |
+
* This is a filter method designed to say whether a WordPress translations upgrades should be permitted,
|
564 |
+
* based on the plugin settings.
|
565 |
+
* @param bool $bUpdate
|
566 |
+
* @return bool
|
567 |
+
* @deprecated 8.6.2
|
568 |
+
*/
|
569 |
+
public function autoupdate_translations( $bUpdate ) {
|
570 |
+
return $bUpdate;
|
571 |
+
}
|
572 |
+
|
573 |
+
/**
|
574 |
+
* @deprecated 8.6.2
|
575 |
+
*/
|
576 |
+
private function forceRunAutoUpdates() {
|
577 |
+
}
|
578 |
}
|
src/processors/comments_filter.php
CHANGED
@@ -26,7 +26,7 @@ class ICWP_WPSF_Processor_CommentsFilter extends Modules\BaseShield\ShieldProces
|
|
26 |
if ( $bLoadComProc ) {
|
27 |
|
28 |
if ( $oMod->isGoogleRecaptchaEnabled() ) {
|
29 |
-
$this->
|
30 |
}
|
31 |
|
32 |
if ( Services::Request()->isPost() ) {
|
@@ -36,7 +36,7 @@ class ICWP_WPSF_Processor_CommentsFilter extends Modules\BaseShield\ShieldProces
|
|
36 |
add_filter( 'comment_notification_recipients', [ $this, 'clearCommentNotificationEmail' ], 100, 1 );
|
37 |
}
|
38 |
elseif ( $oMod->isEnabledGaspCheck() ) {
|
39 |
-
$this->
|
40 |
}
|
41 |
}
|
42 |
}
|
@@ -59,20 +59,6 @@ class ICWP_WPSF_Processor_CommentsFilter extends Modules\BaseShield\ShieldProces
|
|
59 |
];
|
60 |
}
|
61 |
|
62 |
-
/**
|
63 |
-
* @return \ICWP_WPSF_Processor_CommentsFilter_BotSpam
|
64 |
-
*/
|
65 |
-
private function getSubProGasp() {
|
66 |
-
return $this->getSubPro( 'bot' );
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* @return \ICWP_WPSF_Processor_CommentsFilter_GoogleRecaptcha
|
71 |
-
*/
|
72 |
-
private function getSubProRecaptcha() {
|
73 |
-
return $this->getSubPro( 'recaptcha' );
|
74 |
-
}
|
75 |
-
|
76 |
/**
|
77 |
* When you set a new comment as anything but 'spam' a notification email is sent to the post author.
|
78 |
* We suppress this for when we mark as trash by emptying the email notifications list.
|
26 |
if ( $bLoadComProc ) {
|
27 |
|
28 |
if ( $oMod->isGoogleRecaptchaEnabled() ) {
|
29 |
+
$this->getSubPro( 'recaptcha' )->execute();
|
30 |
}
|
31 |
|
32 |
if ( Services::Request()->isPost() ) {
|
36 |
add_filter( 'comment_notification_recipients', [ $this, 'clearCommentNotificationEmail' ], 100, 1 );
|
37 |
}
|
38 |
elseif ( $oMod->isEnabledGaspCheck() ) {
|
39 |
+
$this->getSubPro( 'bot' )->execute();
|
40 |
}
|
41 |
}
|
42 |
}
|
59 |
];
|
60 |
}
|
61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
/**
|
63 |
* When you set a new comment as anything but 'spam' a notification email is sent to the post author.
|
64 |
* We suppress this for when we mark as trash by emptying the email notifications list.
|
src/processors/commentsfilter_botspam.php
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
|
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
class ICWP_WPSF_Processor_CommentsFilter_BotSpam extends Modules\BaseShield\ShieldProcessor {
|
@@ -28,10 +29,12 @@ class ICWP_WPSF_Processor_CommentsFilter_BotSpam extends Modules\BaseShield\Shie
|
|
28 |
public function onWpEnqueueJs() {
|
29 |
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $oMod */
|
30 |
$oMod = $this->getMod();
|
|
|
|
|
31 |
$oConn = $this->getCon();
|
32 |
|
33 |
$sAsset = 'shield-comments';
|
34 |
-
$sUnique = $
|
35 |
wp_register_script(
|
36 |
$sUnique,
|
37 |
$oConn->getPluginUrl_Js( $sAsset ),
|
@@ -58,8 +61,8 @@ class ICWP_WPSF_Processor_CommentsFilter_BotSpam extends Modules\BaseShield\Shie
|
|
58 |
'botts' => $nTs,
|
59 |
'token' => 'not created',
|
60 |
'uniq' => $this->getUniqueFormId(),
|
61 |
-
'cooldown' => $
|
62 |
-
'expires' => $
|
63 |
],
|
64 |
'strings' => [
|
65 |
'label' => $oMod->getTextOpt( 'custom_message_checkbox' ),
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
4 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter\Options;
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
|
7 |
class ICWP_WPSF_Processor_CommentsFilter_BotSpam extends Modules\BaseShield\ShieldProcessor {
|
29 |
public function onWpEnqueueJs() {
|
30 |
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $oMod */
|
31 |
$oMod = $this->getMod();
|
32 |
+
/** @var Options $oOpts */
|
33 |
+
$oOpts = $this->getOptions();
|
34 |
$oConn = $this->getCon();
|
35 |
|
36 |
$sAsset = 'shield-comments';
|
37 |
+
$sUnique = $oConn->prefix( 'shield-comments' );
|
38 |
wp_register_script(
|
39 |
$sUnique,
|
40 |
$oConn->getPluginUrl_Js( $sAsset ),
|
61 |
'botts' => $nTs,
|
62 |
'token' => 'not created',
|
63 |
'uniq' => $this->getUniqueFormId(),
|
64 |
+
'cooldown' => $oOpts->getTokenCooldown(),
|
65 |
+
'expires' => $oOpts->getTokenExpireInterval(),
|
66 |
],
|
67 |
'strings' => [
|
68 |
'label' => $oMod->getTextOpt( 'custom_message_checkbox' ),
|
src/processors/email.php
CHANGED
@@ -9,42 +9,40 @@ class ICWP_WPSF_Processor_Email extends Modules\BaseShield\ShieldProcessor {
|
|
9 |
|
10 |
/**
|
11 |
* @var string
|
|
|
12 |
*/
|
13 |
protected static $sModeFile_EmailThrottled;
|
14 |
|
15 |
/**
|
16 |
* @var int
|
|
|
17 |
*/
|
18 |
protected static $nThrottleInterval = 1;
|
19 |
|
20 |
/**
|
21 |
* @var int
|
|
|
22 |
*/
|
23 |
protected $nEmailThrottleLimit;
|
24 |
|
25 |
/**
|
26 |
* @var int
|
|
|
27 |
*/
|
28 |
protected $nEmailThrottleTime;
|
29 |
|
30 |
/**
|
31 |
* @var int
|
|
|
32 |
*/
|
33 |
protected $nEmailThrottleCount;
|
34 |
|
35 |
/**
|
36 |
* @var bool
|
|
|
37 |
*/
|
38 |
protected $bEmailIsThrottled;
|
39 |
|
40 |
-
public function init() {
|
41 |
-
parent::init();
|
42 |
-
self::$sModeFile_EmailThrottled = path_join( __DIR__, '/../mode.email_throttled' );
|
43 |
-
}
|
44 |
-
|
45 |
-
public function run() {
|
46 |
-
}
|
47 |
-
|
48 |
/**
|
49 |
* @return array
|
50 |
*/
|
@@ -97,10 +95,6 @@ class ICWP_WPSF_Processor_Email extends Modules\BaseShield\ShieldProcessor {
|
|
97 |
* @uses wp_mail
|
98 |
*/
|
99 |
public function send( $sAddress = '', $sSubject = '', $sMessageBody = '' ) {
|
100 |
-
$this->updateEmailThrottle();
|
101 |
-
if ( $this->bEmailIsThrottled ) {
|
102 |
-
return true;
|
103 |
-
}
|
104 |
|
105 |
$this->emailFilters( true );
|
106 |
$bSuccess = wp_mail(
|
@@ -193,59 +187,17 @@ class ICWP_WPSF_Processor_Email extends Modules\BaseShield\ShieldProcessor {
|
|
193 |
* system object telling us we're throttled.
|
194 |
* The file system object takes precedence.
|
195 |
* @return bool
|
|
|
196 |
*/
|
197 |
protected function updateEmailThrottle() {
|
198 |
-
$nNow = Services::Request()->ts();
|
199 |
-
|
200 |
-
// Throttling Is Effectively Off
|
201 |
-
if ( $this->getThrottleLimit() <= 0 ) {
|
202 |
-
$this->setThrottledFile( false );
|
203 |
-
return $this->bEmailIsThrottled;
|
204 |
-
}
|
205 |
-
|
206 |
-
// Check that there is an email throttle file. If it exists and its modified time is greater than the
|
207 |
-
// current $this->m_nEmailThrottleTime it suggests another process has touched the file and updated it
|
208 |
-
// concurrently. So, we update our $this->m_nEmailThrottleTime accordingly.
|
209 |
-
if ( is_file( self::$sModeFile_EmailThrottled ) ) {
|
210 |
-
$nModifiedTime = filemtime( self::$sModeFile_EmailThrottled );
|
211 |
-
if ( $nModifiedTime > $this->nEmailThrottleTime ) {
|
212 |
-
$this->nEmailThrottleTime = $nModifiedTime;
|
213 |
-
}
|
214 |
-
}
|
215 |
-
|
216 |
-
if ( !isset( $this->nEmailThrottleTime ) || $this->nEmailThrottleTime > $nNow ) {
|
217 |
-
$this->nEmailThrottleTime = $nNow;
|
218 |
-
}
|
219 |
-
if ( !isset( $this->nEmailThrottleCount ) ) {
|
220 |
-
$this->nEmailThrottleCount = 0;
|
221 |
-
}
|
222 |
-
|
223 |
-
// If $nNow is greater than throttle interval (1s) we turn off the file throttle and reset the count
|
224 |
-
$nDiff = $nNow - $this->nEmailThrottleTime;
|
225 |
-
if ( $nDiff > self::$nThrottleInterval ) {
|
226 |
-
$this->nEmailThrottleTime = $nNow;
|
227 |
-
$this->nEmailThrottleCount = 1; //we set to 1 assuming that this was called because we're about to send, or have just sent, an email.
|
228 |
-
$this->setThrottledFile( false );
|
229 |
-
}
|
230 |
-
elseif ( is_file( self::$sModeFile_EmailThrottled ) || ( $this->nEmailThrottleCount >= $this->getThrottleLimit() ) ) {
|
231 |
-
$this->setThrottledFile( true );
|
232 |
-
}
|
233 |
-
else {
|
234 |
-
$this->nEmailThrottleCount++;
|
235 |
-
}
|
236 |
return true;
|
237 |
}
|
238 |
|
|
|
|
|
|
|
|
|
239 |
public function setThrottledFile( $infOn = false ) {
|
240 |
-
|
241 |
-
$this->bEmailIsThrottled = $infOn;
|
242 |
-
|
243 |
-
if ( $infOn && !is_file( self::$sModeFile_EmailThrottled ) && function_exists( 'touch' ) ) {
|
244 |
-
@touch( self::$sModeFile_EmailThrottled );
|
245 |
-
}
|
246 |
-
elseif ( !$infOn && is_file( self::$sModeFile_EmailThrottled ) ) {
|
247 |
-
@unlink( self::$sModeFile_EmailThrottled );
|
248 |
-
}
|
249 |
}
|
250 |
|
251 |
/**
|
@@ -256,10 +208,11 @@ class ICWP_WPSF_Processor_Email extends Modules\BaseShield\ShieldProcessor {
|
|
256 |
return Services::Data()->validEmail( $sEmail ) ? $sEmail : Services::WpGeneral()->getSiteAdminEmail();
|
257 |
}
|
258 |
|
|
|
|
|
|
|
|
|
259 |
public function getThrottleLimit() {
|
260 |
-
|
261 |
-
$this->nEmailThrottleLimit = $this->getOption( 'send_email_throttle_limit' );
|
262 |
-
}
|
263 |
-
return $this->nEmailThrottleLimit;
|
264 |
}
|
265 |
}
|
9 |
|
10 |
/**
|
11 |
* @var string
|
12 |
+
* @deprecated 8.6.2
|
13 |
*/
|
14 |
protected static $sModeFile_EmailThrottled;
|
15 |
|
16 |
/**
|
17 |
* @var int
|
18 |
+
* @deprecated 8.6.2
|
19 |
*/
|
20 |
protected static $nThrottleInterval = 1;
|
21 |
|
22 |
/**
|
23 |
* @var int
|
24 |
+
* @deprecated 8.6.2
|
25 |
*/
|
26 |
protected $nEmailThrottleLimit;
|
27 |
|
28 |
/**
|
29 |
* @var int
|
30 |
+
* @deprecated 8.6.2
|
31 |
*/
|
32 |
protected $nEmailThrottleTime;
|
33 |
|
34 |
/**
|
35 |
* @var int
|
36 |
+
* @deprecated 8.6.2
|
37 |
*/
|
38 |
protected $nEmailThrottleCount;
|
39 |
|
40 |
/**
|
41 |
* @var bool
|
42 |
+
* @deprecated 8.6.2
|
43 |
*/
|
44 |
protected $bEmailIsThrottled;
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
/**
|
47 |
* @return array
|
48 |
*/
|
95 |
* @uses wp_mail
|
96 |
*/
|
97 |
public function send( $sAddress = '', $sSubject = '', $sMessageBody = '' ) {
|
|
|
|
|
|
|
|
|
98 |
|
99 |
$this->emailFilters( true );
|
100 |
$bSuccess = wp_mail(
|
187 |
* system object telling us we're throttled.
|
188 |
* The file system object takes precedence.
|
189 |
* @return bool
|
190 |
+
* @deprecated 8.6.2
|
191 |
*/
|
192 |
protected function updateEmailThrottle() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
return true;
|
194 |
}
|
195 |
|
196 |
+
/**
|
197 |
+
* @param bool $infOn
|
198 |
+
* @deprecated 8.6.2
|
199 |
+
*/
|
200 |
public function setThrottledFile( $infOn = false ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
}
|
202 |
|
203 |
/**
|
208 |
return Services::Data()->validEmail( $sEmail ) ? $sEmail : Services::WpGeneral()->getSiteAdminEmail();
|
209 |
}
|
210 |
|
211 |
+
|
212 |
+
/**
|
213 |
+
* @deprecated 8.6.2
|
214 |
+
*/
|
215 |
public function getThrottleLimit() {
|
216 |
+
return 0;
|
|
|
|
|
|
|
217 |
}
|
218 |
}
|
src/processors/events.php
CHANGED
@@ -29,8 +29,6 @@ class ICWP_WPSF_Processor_Events extends Shield\Modules\BaseShield\ShieldProcess
|
|
29 |
return $this->oStatsWriter;
|
30 |
}
|
31 |
|
32 |
-
/**
|
33 |
-
*/
|
34 |
public function statsWidget() {
|
35 |
/** @var Databases\Events\Select $oSelEvents */
|
36 |
$oSelEvents = $this->getCon()
|
@@ -100,12 +98,6 @@ class ICWP_WPSF_Processor_Events extends Shield\Modules\BaseShield\ShieldProcess
|
|
100 |
return $aData;
|
101 |
}
|
102 |
|
103 |
-
/**
|
104 |
-
* @deprecated 8.5
|
105 |
-
*/
|
106 |
-
private function commitEvents() {
|
107 |
-
}
|
108 |
-
|
109 |
public function runDailyCron() {
|
110 |
( new Events\Consolidate\ConsolidateAllEvents() )
|
111 |
->setMod( $this->getMod() )
|
29 |
return $this->oStatsWriter;
|
30 |
}
|
31 |
|
|
|
|
|
32 |
public function statsWidget() {
|
33 |
/** @var Databases\Events\Select $oSelEvents */
|
34 |
$oSelEvents = $this->getCon()
|
98 |
return $aData;
|
99 |
}
|
100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
public function runDailyCron() {
|
102 |
( new Events\Consolidate\ConsolidateAllEvents() )
|
103 |
->setMod( $this->getMod() )
|
src/processors/hackprotect_integrity.php
CHANGED
@@ -24,7 +24,8 @@ class ICWP_WPSF_Processor_HackProtect_Integrity extends ShieldProcessor {
|
|
24 |
* @return array[] - associative arrays where keys are $this->getStandardUserFields()
|
25 |
*/
|
26 |
public function getSnapshotUsers() {
|
27 |
-
|
|
|
28 |
}
|
29 |
|
30 |
/**
|
24 |
* @return array[] - associative arrays where keys are $this->getStandardUserFields()
|
25 |
*/
|
26 |
public function getSnapshotUsers() {
|
27 |
+
$aUs = $this->getOptions()->getOpt( 'snapshot_users' );
|
28 |
+
return is_array( $aUs ) ? $aUs : [];
|
29 |
}
|
30 |
|
31 |
/**
|
src/processors/hackprotect_scan_assets_base.php
DELETED
@@ -1,29 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
-
use FernleafSystems\Wordpress\Services;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Class ICWP_WPSF_Processor_HackProtect_ScanAssetsBase
|
8 |
-
* @deprecated 8.5
|
9 |
-
*/
|
10 |
-
abstract class ICWP_WPSF_Processor_HackProtect_ScanAssetsBase extends ICWP_WPSF_Processor_ScanBase {
|
11 |
-
|
12 |
-
const CONTEXT_PLUGINS = 'plugins';
|
13 |
-
const CONTEXT_THEMES = 'themes';
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @param string $sSlug
|
17 |
-
* @return Services\Core\VOs\WpPluginVo|Services\Core\VOs\WpThemeVo|null
|
18 |
-
* @deprecated 8.5
|
19 |
-
*/
|
20 |
-
protected function getAssetFromSlug( $sSlug ) {
|
21 |
-
if ( Services\Services::WpPlugins()->isInstalled( $sSlug ) ) {
|
22 |
-
$oAsset = Services\Services::WpPlugins()->getPluginAsVo( $sSlug );
|
23 |
-
}
|
24 |
-
elseif ( Services\Services::WpThemes()->isInstalled( $sSlug ) ) {
|
25 |
-
$oAsset = Services\Services::WpThemes()->getThemeAsVo( $sSlug );
|
26 |
-
}
|
27 |
-
return $oAsset;
|
28 |
-
}
|
29 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/processors/hackprotect_scan_base.php
CHANGED
@@ -89,61 +89,4 @@ abstract class ICWP_WPSF_Processor_ScanBase extends Shield\Modules\BaseShield\Sh
|
|
89 |
$oMod = $this->getMod();
|
90 |
return $oMod->getScanCon( static::SCAN_SLUG );
|
91 |
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* @param \ICWP_WPSF_Processor_HackProtect_Scanner $oScanner
|
95 |
-
* @return $this
|
96 |
-
* @deprecated 8.5
|
97 |
-
*/
|
98 |
-
public function setScannerDb( $oScanner ) {
|
99 |
-
return $this;
|
100 |
-
}
|
101 |
-
|
102 |
-
/**
|
103 |
-
* @return bool
|
104 |
-
* @deprecated 8.5
|
105 |
-
*/
|
106 |
-
public function isRestricted() {
|
107 |
-
return false;
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* @return bool
|
112 |
-
* @deprecated 8.5
|
113 |
-
*/
|
114 |
-
public function isAvailable() {
|
115 |
-
return $this->getThisScanCon()->isScanningAvailable();
|
116 |
-
}
|
117 |
-
|
118 |
-
/**
|
119 |
-
* @return bool
|
120 |
-
* @deprecated 8.5
|
121 |
-
*/
|
122 |
-
protected function isCronAutoRepair() {
|
123 |
-
return $this->getThisScanCon()->isCronAutoRepair();
|
124 |
-
}
|
125 |
-
|
126 |
-
/**
|
127 |
-
* @return bool
|
128 |
-
* @deprecated 8.5
|
129 |
-
*/
|
130 |
-
public function isEnabled() {
|
131 |
-
return $this->getThisScanCon()->isEnabled();
|
132 |
-
}
|
133 |
-
|
134 |
-
/**
|
135 |
-
* Override this to provide the correct VO
|
136 |
-
* @return Shield\Scans\Base\BaseScanActionVO|mixed
|
137 |
-
* @deprecated 8.5
|
138 |
-
*/
|
139 |
-
protected function getNewActionVO() {
|
140 |
-
return $this->getThisScanCon()->getScanActionVO();
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* @param Shield\Scans\Base\BaseResultsSet $oRes
|
145 |
-
* @deprecated 8.5
|
146 |
-
*/
|
147 |
-
protected function runCronAutoRepair( $oRes ) {
|
148 |
-
}
|
149 |
}
|
89 |
$oMod = $this->getMod();
|
90 |
return $oMod->getScanCon( static::SCAN_SLUG );
|
91 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
}
|
src/processors/hackprotect_scan_ptg.php
CHANGED
@@ -183,121 +183,4 @@ class ICWP_WPSF_Processor_HackProtect_Ptg extends ICWP_WPSF_Processor_ScanBase {
|
|
183 |
]
|
184 |
);
|
185 |
}
|
186 |
-
|
187 |
-
/**
|
188 |
-
* @param string $sBaseName
|
189 |
-
* @deprecated 8.5
|
190 |
-
*/
|
191 |
-
public function onActivatePlugin( $sBaseName ) {
|
192 |
-
}
|
193 |
-
|
194 |
-
/**
|
195 |
-
* @deprecated 8.5
|
196 |
-
*/
|
197 |
-
public function onActivateTheme() {
|
198 |
-
}
|
199 |
-
|
200 |
-
/**
|
201 |
-
* @param string $sBaseName
|
202 |
-
* @deprecated 8.5
|
203 |
-
*/
|
204 |
-
public function onDeactivatePlugin( $sBaseName ) {
|
205 |
-
}
|
206 |
-
|
207 |
-
/**
|
208 |
-
* Only snaps active.
|
209 |
-
*
|
210 |
-
* @param string $sSlug - the basename for plugin, or stylesheet for theme.
|
211 |
-
* @param string $sContext
|
212 |
-
* @return $this
|
213 |
-
* @deprecated 8.5
|
214 |
-
*/
|
215 |
-
public function updateItemInSnapshot( $sSlug, $sContext = null ) {
|
216 |
-
return $this;
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* @param string $sSlug
|
221 |
-
* @deprecated 8.5
|
222 |
-
*/
|
223 |
-
public function updateThemeSnapshot( $sSlug ) {
|
224 |
-
}
|
225 |
-
|
226 |
-
/**
|
227 |
-
* @return bool
|
228 |
-
* @deprecated 8.5
|
229 |
-
*/
|
230 |
-
private function snapshotThemes() {
|
231 |
-
return true;
|
232 |
-
}
|
233 |
-
|
234 |
-
/**
|
235 |
-
* Will also remove a plugin if it's found to be in-active
|
236 |
-
* Careful: Cannot use this for the activate and deactivate hooks as the WP option
|
237 |
-
* wont be updated
|
238 |
-
*
|
239 |
-
* @param string $sBaseName
|
240 |
-
* @deprecated 8.5
|
241 |
-
*/
|
242 |
-
public function updatePluginSnapshot( $sBaseName ) {
|
243 |
-
}
|
244 |
-
|
245 |
-
/**
|
246 |
-
* @param string $sSlug
|
247 |
-
* @return $this
|
248 |
-
* @deprecated 8.5
|
249 |
-
*/
|
250 |
-
protected function removeItemSnapshot( $sSlug ) {
|
251 |
-
return $this;
|
252 |
-
}
|
253 |
-
|
254 |
-
/**
|
255 |
-
* @param WP_Upgrader $oUpgrader
|
256 |
-
* @param array $aInfo Upgrade/Install Information
|
257 |
-
* @deprecated 8.5
|
258 |
-
*/
|
259 |
-
public function updateSnapshotAfterUpgrade( $oUpgrader, $aInfo ) {
|
260 |
-
}
|
261 |
-
|
262 |
-
/**
|
263 |
-
* @return $this
|
264 |
-
* @deprecated 8.5
|
265 |
-
*/
|
266 |
-
private function snapshotPlugins() {
|
267 |
-
return $this;
|
268 |
-
}
|
269 |
-
|
270 |
-
/**
|
271 |
-
* @param string $sBaseFile
|
272 |
-
* @return array
|
273 |
-
* @deprecated 8.5
|
274 |
-
*/
|
275 |
-
private function buildSnapshotPlugin( $sBaseFile ) {
|
276 |
-
return [];
|
277 |
-
}
|
278 |
-
|
279 |
-
/**
|
280 |
-
* @param string $sSlug
|
281 |
-
* @return array
|
282 |
-
* @deprecated 8.5
|
283 |
-
*/
|
284 |
-
private function buildSnapshotTheme( $sSlug ) {
|
285 |
-
return [];
|
286 |
-
}
|
287 |
-
|
288 |
-
/**
|
289 |
-
* @return null
|
290 |
-
* @deprecated 8.5
|
291 |
-
*/
|
292 |
-
private function getStore_Plugins() {
|
293 |
-
return null;
|
294 |
-
}
|
295 |
-
|
296 |
-
/**
|
297 |
-
* @return null
|
298 |
-
* @deprecated 8.5
|
299 |
-
*/
|
300 |
-
private function getStore_Themes() {
|
301 |
-
return null;
|
302 |
-
}
|
303 |
}
|
183 |
]
|
184 |
);
|
185 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
}
|
src/processors/hackprotect_scan_ufc.php
CHANGED
@@ -12,9 +12,9 @@ class ICWP_WPSF_Processor_HackProtect_Ufc extends ICWP_WPSF_Processor_ScanBase {
|
|
12 |
* @return bool - true if user notified
|
13 |
*/
|
14 |
protected function runCronUserNotify( $oRes ) {
|
15 |
-
/** @var \
|
16 |
-
$
|
17 |
-
$bSend = $
|
18 |
if ( $bSend ) {
|
19 |
$this->emailResults( $oRes );
|
20 |
}
|
12 |
* @return bool - true if user notified
|
13 |
*/
|
14 |
protected function runCronUserNotify( $oRes ) {
|
15 |
+
/** @var Shield\Modules\HackGuard\Options $oOpts */
|
16 |
+
$oOpts = $this->getOptions();
|
17 |
+
$bSend = $oOpts->isUfcSendReport();
|
18 |
if ( $bSend ) {
|
19 |
$this->emailResults( $oRes );
|
20 |
}
|
src/processors/hackprotect_scan_wcf.php
CHANGED
@@ -50,6 +50,8 @@ class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
|
|
50 |
private function buildEmailBodyFromFiles( $oResults ) {
|
51 |
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
|
52 |
$oMod = $this->getMod();
|
|
|
|
|
53 |
$sName = $this->getCon()->getHumanName();
|
54 |
$sHomeUrl = Services::WpGeneral()->getHomeUrl();
|
55 |
|
@@ -58,11 +60,11 @@ class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
|
|
58 |
sprintf( '%s: %s', __( 'Site URL', 'wp-simple-firewall' ), sprintf( '<a href="%s" target="_blank">%s</a>', $sHomeUrl, $sHomeUrl ) ),
|
59 |
];
|
60 |
|
61 |
-
if ( $
|
62 |
$aContent = array_merge( $aContent, $this->buildListOfFilesForEmail( $oResults ) );
|
63 |
$aContent[] = '';
|
64 |
|
65 |
-
if ( $
|
66 |
$aContent[] = '<strong>'.sprintf( __( "%s has already attempted to repair the files.", 'wp-simple-firewall' ), $sName ).'</strong>'
|
67 |
.' '.__( 'But, you should always check these files to ensure everything is as you expect.', 'wp-simple-firewall' );
|
68 |
}
|
50 |
private function buildEmailBodyFromFiles( $oResults ) {
|
51 |
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
|
52 |
$oMod = $this->getMod();
|
53 |
+
/** @var Shield\Modules\HackGuard\Options $oOpts */
|
54 |
+
$oOpts = $this->getOptions();
|
55 |
$sName = $this->getCon()->getHumanName();
|
56 |
$sHomeUrl = Services::WpGeneral()->getHomeUrl();
|
57 |
|
60 |
sprintf( '%s: %s', __( 'Site URL', 'wp-simple-firewall' ), sprintf( '<a href="%s" target="_blank">%s</a>', $sHomeUrl, $sHomeUrl ) ),
|
61 |
];
|
62 |
|
63 |
+
if ( $oOpts->isWcfScanAutoRepair() || $oMod->isIncludeFileLists() ) {
|
64 |
$aContent = array_merge( $aContent, $this->buildListOfFilesForEmail( $oResults ) );
|
65 |
$aContent[] = '';
|
66 |
|
67 |
+
if ( $oOpts->isWcfScanAutoRepair() ) {
|
68 |
$aContent[] = '<strong>'.sprintf( __( "%s has already attempted to repair the files.", 'wp-simple-firewall' ), $sName ).'</strong>'
|
69 |
.' '.__( 'But, you should always check these files to ensure everything is as you expect.', 'wp-simple-firewall' );
|
70 |
}
|
src/processors/hackprotect_scanner.php
CHANGED
@@ -160,13 +160,4 @@ class ICWP_WPSF_Processor_HackProtect_Scanner extends ShieldProcessor {
|
|
160 |
protected function getCronName() {
|
161 |
return $this->getCon()->prefix( $this->getOptions()->getDef( 'cron_all_scans' ) );
|
162 |
}
|
163 |
-
|
164 |
-
/**
|
165 |
-
* @param string $sSlug
|
166 |
-
* @return \ICWP_WPSF_Processor_ScanBase|null
|
167 |
-
* @deprecated 8.5
|
168 |
-
*/
|
169 |
-
public function getScannerFromSlug( $sSlug ) {
|
170 |
-
return $this->getSubPro( $sSlug );
|
171 |
-
}
|
172 |
}
|
160 |
protected function getCronName() {
|
161 |
return $this->getCon()->prefix( $this->getOptions()->getDef( 'cron_all_scans' ) );
|
162 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
}
|
src/processors/headers.php
CHANGED
@@ -97,7 +97,7 @@ class ICWP_WPSF_Processor_Headers extends Modules\BaseShield\ShieldProcessor {
|
|
97 |
* @return array|null
|
98 |
*/
|
99 |
private function getXFrameHeader() {
|
100 |
-
switch ( $this->
|
101 |
case 'on_sameorigin':
|
102 |
$sXFrameOption = 'SAMEORIGIN';
|
103 |
break;
|
97 |
* @return array|null
|
98 |
*/
|
99 |
private function getXFrameHeader() {
|
100 |
+
switch ( $this->getOptions()->getOpt( 'x_frame' ) ) {
|
101 |
case 'on_sameorigin':
|
102 |
$sXFrameOption = 'SAMEORIGIN';
|
103 |
break;
|
src/processors/ips.php
CHANGED
@@ -1,429 +1,21 @@
|
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield\ShieldProcessor;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
7 |
-
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
-
class ICWP_WPSF_Processor_Ips extends ShieldProcessor {
|
10 |
|
11 |
/**
|
12 |
*/
|
13 |
public function run() {
|
14 |
-
|
15 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
16 |
-
$oMod = $this->getMod();
|
17 |
-
/** @var IPs\Options $oOpts */
|
18 |
-
$oOpts = $this->getOptions();
|
19 |
-
if ( $oOpts->isEnabledAutoBlackList() ) {
|
20 |
-
|
21 |
-
( new IPs\Components\UnblockIpByFlag() )
|
22 |
-
->setMod( $oMod )
|
23 |
-
->run();
|
24 |
-
|
25 |
-
if ( !$oMod->isVisitorWhitelisted() && !$this->isRequestWhitelisted() ) {
|
26 |
-
$oMod->loadOffenseTracker()->setIfCommit( true );
|
27 |
-
|
28 |
-
$this->processBlacklist();
|
29 |
-
$oCon = $this->getCon();
|
30 |
-
add_filter( $oCon->prefix( 'firewall_die_message' ), [ $this, 'fAugmentFirewallDieMessage' ] );
|
31 |
-
add_action( $oCon->prefix( 'pre_plugin_shutdown' ), function () {
|
32 |
-
$this->doBlackMarkCurrentVisitor();
|
33 |
-
} );
|
34 |
-
add_action( 'shield_security_offense', [ $this, 'processCustomShieldOffense' ], 10, 3 );
|
35 |
-
}
|
36 |
-
}
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* @return bool
|
41 |
-
*/
|
42 |
-
private function isRequestWhitelisted() {
|
43 |
-
/** @var IPs\Options $oOpts */
|
44 |
-
$oOpts = $this->getOptions();
|
45 |
-
$bWhitelisted = false;
|
46 |
-
$aWhitelist = $oOpts->getRequestWhitelistAsRegex();
|
47 |
-
if ( !empty( $aWhitelist ) ) {
|
48 |
-
$sPath = strtolower( '/'.ltrim( (string)Services::Request()->getPath(), '/' ) );
|
49 |
-
foreach ( $aWhitelist as $sRule ) {
|
50 |
-
if ( preg_match( $sRule, $sPath ) ) {
|
51 |
-
$bWhitelisted = true;
|
52 |
-
break;
|
53 |
-
}
|
54 |
-
}
|
55 |
-
}
|
56 |
-
return $bWhitelisted;
|
57 |
-
}
|
58 |
-
|
59 |
-
public function onWpInit() {
|
60 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
61 |
-
$oMod = $this->getMod();
|
62 |
-
/** @var IPs\Options $oOpts */
|
63 |
-
$oOpts = $oMod->getOptions();
|
64 |
-
|
65 |
-
if ( $oOpts->isEnabledAutoBlackList() && !Services::WpUsers()->isUserLoggedIn() ) {
|
66 |
-
|
67 |
-
if ( !$oMod->isVerifiedBot() ) {
|
68 |
-
if ( $oOpts->isEnabledTrackXmlRpc() ) {
|
69 |
-
( new IPs\BotTrack\TrackXmlRpc() )
|
70 |
-
->setMod( $oMod )
|
71 |
-
->run();
|
72 |
-
}
|
73 |
-
if ( $oOpts->isEnabledTrack404() ) {
|
74 |
-
( new IPs\BotTrack\Track404() )
|
75 |
-
->setMod( $oMod )
|
76 |
-
->run();
|
77 |
-
}
|
78 |
-
if ( $oOpts->isEnabledTrackLoginFailed() ) {
|
79 |
-
( new IPs\BotTrack\TrackLoginFailed() )
|
80 |
-
->setMod( $oMod )
|
81 |
-
->run();
|
82 |
-
}
|
83 |
-
if ( $oOpts->isEnabledTrackLoginInvalid() ) {
|
84 |
-
( new IPs\BotTrack\TrackLoginInvalid() )
|
85 |
-
->setMod( $oMod )
|
86 |
-
->run();
|
87 |
-
}
|
88 |
-
if ( $oOpts->isEnabledTrackFakeWebCrawler() ) {
|
89 |
-
( new IPs\BotTrack\TrackFakeWebCrawler() )
|
90 |
-
->setMod( $oMod )
|
91 |
-
->run();
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
/** Always run link cheese regardless of the verified bot or not */
|
96 |
-
if ( $oOpts->isEnabledTrackLinkCheese() ) {
|
97 |
-
( new IPs\BotTrack\TrackLinkCheese() )
|
98 |
-
->setMod( $oMod )
|
99 |
-
->run();
|
100 |
-
}
|
101 |
-
}
|
102 |
-
}
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Allows 3rd parties to trigger Shield offenses
|
106 |
-
* @param string $sMessage
|
107 |
-
* @param int $nOffenseCount
|
108 |
-
* @param bool $bIncludeLoggedIn
|
109 |
-
*/
|
110 |
-
public function processCustomShieldOffense( $sMessage, $nOffenseCount = 1, $bIncludeLoggedIn = true ) {
|
111 |
-
if ( $this->getCon()->isPremiumActive() ) {
|
112 |
-
if ( empty( $sMessage ) ) {
|
113 |
-
$sMessage = __( 'No custom message provided.', 'wp-simple-firewall' );
|
114 |
-
}
|
115 |
-
|
116 |
-
if ( $bIncludeLoggedIn || !did_action( 'init' ) || !Services::WpUsers()->isUserLoggedIn() ) {
|
117 |
-
$this->getCon()
|
118 |
-
->fireEvent(
|
119 |
-
'custom_offense',
|
120 |
-
[
|
121 |
-
'audit' => [ 'message' => $sMessage ],
|
122 |
-
'offense_count' => $nOffenseCount
|
123 |
-
]
|
124 |
-
);
|
125 |
-
}
|
126 |
-
}
|
127 |
-
}
|
128 |
-
|
129 |
-
/**
|
130 |
-
* @param array $aMessages
|
131 |
-
* @return array
|
132 |
-
*/
|
133 |
-
public function fAugmentFirewallDieMessage( $aMessages ) {
|
134 |
-
if ( !is_array( $aMessages ) ) {
|
135 |
-
$aMessages = [];
|
136 |
-
}
|
137 |
-
|
138 |
-
$aMessages[] = sprintf( '<p>%s</p>', sprintf(
|
139 |
-
$this->getMod()->getTextOpt( 'text_remainingtrans' ),
|
140 |
-
( new IPs\Components\QueryRemainingOffenses() )
|
141 |
-
->setMod( $this->getMod() )
|
142 |
-
->setIP( Services::IP()->getRequestIp() )
|
143 |
-
->run()
|
144 |
-
) );
|
145 |
-
|
146 |
-
return $aMessages;
|
147 |
-
}
|
148 |
-
|
149 |
-
private function processBlacklist() {
|
150 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
151 |
-
$oMod = $this->getMod();
|
152 |
-
|
153 |
-
$bIpBlocked = ( new IPs\Components\QueryIpBlock() )
|
154 |
-
->setMod( $oMod )
|
155 |
-
->setIp( Services::IP()->getRequestIp() )
|
156 |
-
->run();
|
157 |
-
|
158 |
-
if ( $bIpBlocked ) {
|
159 |
-
$this->setIfLogRequest( false ); // don't log traffic from killed requests
|
160 |
-
try {
|
161 |
-
if ( $this->processAutoUnblockRequest() ) {
|
162 |
-
return;
|
163 |
-
}
|
164 |
-
}
|
165 |
-
catch ( \Exception $oE ) {
|
166 |
-
}
|
167 |
-
$this->getCon()->fireEvent( 'conn_kill' );
|
168 |
-
$this->renderKillPage();
|
169 |
-
}
|
170 |
-
}
|
171 |
-
|
172 |
-
/**
|
173 |
-
* @throws \Exception
|
174 |
-
*/
|
175 |
-
private function processAutoUnblockRequest() {
|
176 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
177 |
-
$oMod = $this->getMod();
|
178 |
-
/** @var IPs\Options $oOpts */
|
179 |
-
$oOpts = $oMod->getOptions();
|
180 |
-
$oReq = Services::Request();
|
181 |
-
|
182 |
-
if ( $oOpts->isEnabledAutoUserRecover() && $oReq->isPost()
|
183 |
-
&& $oReq->request( 'action' ) == $oMod->prefix() && $oReq->request( 'exec' ) == 'uau' ) {
|
184 |
-
|
185 |
-
if ( check_admin_referer( $oReq->request( 'exec' ), 'exec_nonce' ) !== 1 ) {
|
186 |
-
throw new \Exception( 'Nonce failed' );
|
187 |
-
}
|
188 |
-
if ( strlen( $oReq->post( 'icwp_wpsf_login_email' ) ) > 0 ) {
|
189 |
-
throw new \Exception( 'Email should not be provided in honeypot' );
|
190 |
-
}
|
191 |
-
|
192 |
-
$sIp = Services::IP()->getRequestIp();
|
193 |
-
if ( $oReq->post( 'ip' ) != $sIp ) {
|
194 |
-
throw new \Exception( 'IP does not match' );
|
195 |
-
}
|
196 |
-
|
197 |
-
$oLoginMod = $this->getCon()->getModule_LoginGuard();
|
198 |
-
$sGasp = $oReq->post( $oLoginMod->getGaspKey() );
|
199 |
-
if ( empty( $sGasp ) ) {
|
200 |
-
throw new \Exception( 'GASP failed' );
|
201 |
-
}
|
202 |
-
|
203 |
-
if ( !$oOpts->getCanIpRequestAutoUnblock( $sIp ) ) {
|
204 |
-
throw new \Exception( 'IP already processed in the last 24hrs' );
|
205 |
-
}
|
206 |
-
$oMod->updateIpRequestAutoUnblockTs( $sIp );
|
207 |
-
|
208 |
-
( new IPs\Lib\Ops\DeleteIp() )
|
209 |
-
->setDbHandler( $oMod->getDbHandler_IPs() )
|
210 |
-
->setIP( $sIp )
|
211 |
-
->fromBlacklist();
|
212 |
-
Services::Response()->redirectToHome();
|
213 |
-
}
|
214 |
-
|
215 |
-
return false;
|
216 |
-
}
|
217 |
-
|
218 |
-
private function renderKillPage() {
|
219 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
220 |
-
$oMod = $this->getMod();
|
221 |
-
/** @var IPs\Options $oOpts */
|
222 |
-
$oOpts = $oMod->getOptions();
|
223 |
-
$oCon = $this->getCon();
|
224 |
-
$oLoginMod = $oCon->getModule_LoginGuard();
|
225 |
-
|
226 |
-
$sUniqId = 'uau'.uniqid();
|
227 |
-
|
228 |
-
$sIp = Services::IP()->getRequestIp();
|
229 |
-
$nTimeRemaining = max( floor( $oOpts->getAutoExpireTime()/60 ), 0 );
|
230 |
-
$aData = [
|
231 |
-
'strings' => [
|
232 |
-
'title' => sprintf( __( "You've been blocked by the %s plugin", 'wp-simple-firewall' ),
|
233 |
-
sprintf( '<a href="%s" target="_blank">%s</a>',
|
234 |
-
$oCon->getPluginSpec()[ 'meta' ][ 'url_repo_home' ],
|
235 |
-
$oCon->getHumanName()
|
236 |
-
)
|
237 |
-
),
|
238 |
-
'lines' => [
|
239 |
-
sprintf( __( 'Time remaining on black list: %s', 'wp-simple-firewall' ),
|
240 |
-
sprintf( _n( '%s minute', '%s minutes', $nTimeRemaining, 'wp-simple-firewall' ), $nTimeRemaining )
|
241 |
-
),
|
242 |
-
sprintf( __( 'You tripped the security plugin defenses a total of %s times making you a suspect.', 'wp-simple-firewall' ), $oOpts->getOffenseLimit() ),
|
243 |
-
sprintf( __( 'If you believe this to be in error, please contact the site owner and quote your IP address below.', 'wp-simple-firewall' ) ),
|
244 |
-
],
|
245 |
-
'your_ip' => 'Your IP address',
|
246 |
-
'unblock' => [
|
247 |
-
'title' => __( 'Auto-Unblock Your IP', 'wp-simple-firewall' ),
|
248 |
-
'you_can' => __( 'You can automatically unblock your IP address by clicking the button below.', 'wp-simple-firewall' ),
|
249 |
-
'button' => __( 'Unblock My IP Address', 'wp-simple-firewall' ),
|
250 |
-
],
|
251 |
-
],
|
252 |
-
'vars' => [
|
253 |
-
'nonce' => $oMod->getNonceActionData( 'uau' ),
|
254 |
-
'ip' => $sIp,
|
255 |
-
'gasp_element' => $oMod->renderTemplate(
|
256 |
-
'snippets/gasp_js.php',
|
257 |
-
[
|
258 |
-
'sCbName' => $oLoginMod->getGaspKey(),
|
259 |
-
'sLabel' => $oLoginMod->getTextImAHuman(),
|
260 |
-
'sAlert' => $oLoginMod->getTextPleaseCheckBox(),
|
261 |
-
'sMustJs' => __( 'You MUST enable Javascript to be able to login', 'wp-simple-firewall' ),
|
262 |
-
'sUniqId' => $sUniqId,
|
263 |
-
'sUniqElem' => 'icwp_wpsf_login_p'.$sUniqId,
|
264 |
-
'strings' => [
|
265 |
-
'loading' => __( 'Loading', 'wp-simple-firewall' )
|
266 |
-
]
|
267 |
-
]
|
268 |
-
),
|
269 |
-
],
|
270 |
-
'flags' => [
|
271 |
-
'is_autorecover' => $oOpts->isEnabledAutoUserRecover(),
|
272 |
-
'is_uau_permitted' => $oOpts->getCanIpRequestAutoUnblock( $sIp ),
|
273 |
-
],
|
274 |
-
];
|
275 |
-
Services::WpGeneral()
|
276 |
-
->wpDie(
|
277 |
-
$oMod->renderTemplate( '/snippets/blacklist_die.twig', $aData, true )
|
278 |
-
);
|
279 |
-
}
|
280 |
-
|
281 |
-
/**
|
282 |
-
* TODO 8.6: make private
|
283 |
-
*/
|
284 |
-
public function doBlackMarkCurrentVisitor() {
|
285 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
286 |
-
$oMod = $this->getMod();
|
287 |
-
|
288 |
-
$oTracker = $oMod->loadOffenseTracker();
|
289 |
-
if ( !$this->getCon()->isPluginDeleting()
|
290 |
-
&& $oTracker->hasVisitorOffended() && $oTracker->isCommit()
|
291 |
-
&& !$oMod->isVerifiedBot() ) {
|
292 |
-
|
293 |
-
( new IPs\Components\ProcessOffense() )
|
294 |
-
->setMod( $oMod )
|
295 |
-
->setIp( Services::IP()->getRequestIp() )
|
296 |
-
->run();
|
297 |
-
}
|
298 |
-
}
|
299 |
-
|
300 |
-
/**
|
301 |
-
* @deprecated 8.5
|
302 |
-
*/
|
303 |
-
private function processTransgression() {
|
304 |
-
return;
|
305 |
-
}
|
306 |
-
|
307 |
-
/**
|
308 |
-
* @return string
|
309 |
-
* @deprecated 8.5
|
310 |
-
*/
|
311 |
-
public function getRemainingTransgressions() {
|
312 |
-
return 0;
|
313 |
-
}
|
314 |
-
|
315 |
-
/**
|
316 |
-
* @param string $sIp
|
317 |
-
* @return int
|
318 |
-
* @deprecated 8.5
|
319 |
-
*/
|
320 |
-
private function getTransgressions( $sIp ) {
|
321 |
-
return 0;
|
322 |
-
}
|
323 |
-
|
324 |
-
/**
|
325 |
-
* @return string
|
326 |
-
* @deprecated 8.5
|
327 |
-
*/
|
328 |
-
private function getTextOfRemainingTransgressions() {
|
329 |
-
return '';
|
330 |
-
}
|
331 |
-
|
332 |
-
/**
|
333 |
-
* @return Databases\IPs\EntryVO[]
|
334 |
-
* @deprecated 8.5
|
335 |
-
*/
|
336 |
-
public function getWhitelistIpsData() {
|
337 |
-
return [];
|
338 |
-
}
|
339 |
-
|
340 |
-
/**
|
341 |
-
* @return string[]
|
342 |
-
* @deprecated 8.5
|
343 |
-
*/
|
344 |
-
public function getWhitelistIps() {
|
345 |
-
return [];
|
346 |
-
}
|
347 |
-
|
348 |
-
/**
|
349 |
-
* @param string $sIp
|
350 |
-
* @param string $sLabel
|
351 |
-
* @return Databases\IPs\EntryVO|null
|
352 |
-
* @deprecated 8.5
|
353 |
-
*/
|
354 |
-
public function addIpToWhiteList( $sIp, $sLabel = '' ) {
|
355 |
-
return ( new IPs\Lib\Ops\AddIp() )
|
356 |
->setMod( $this->getMod() )
|
357 |
-
->
|
358 |
-
->toManualWhitelist( $sLabel );
|
359 |
-
}
|
360 |
-
|
361 |
-
/**
|
362 |
-
* @param string $sIp
|
363 |
-
* @param string $sList
|
364 |
-
* @param string $sLabel
|
365 |
-
* @return Databases\IPs\EntryVO|null
|
366 |
-
* @deprecated 8.5
|
367 |
-
*/
|
368 |
-
private function addIpToManualList( $sIp, $sList, $sLabel = '' ) {
|
369 |
-
return null;
|
370 |
-
}
|
371 |
-
|
372 |
-
/**
|
373 |
-
* ADDITION OF ANY IP TO ANY LIST SHOULD GO THROUGH HERE.
|
374 |
-
* @param string $sIp
|
375 |
-
* @param string $sList
|
376 |
-
* @param string $sLabel
|
377 |
-
* @return Databases\IPs\EntryVO|null
|
378 |
-
* @deprecated 8.5
|
379 |
-
*/
|
380 |
-
private function addIpToList( $sIp, $sList, $sLabel = '' ) {
|
381 |
-
return null;
|
382 |
-
}
|
383 |
-
|
384 |
-
/**
|
385 |
-
* The auto black list isn't a simple lookup, but rather has an auto expiration
|
386 |
-
* @param string $sIp
|
387 |
-
* @return Databases\IPs\EntryVO|null
|
388 |
-
* @deprecated 8.5
|
389 |
-
*/
|
390 |
-
protected function getBlackListIp( $sIp ) {
|
391 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
392 |
-
$oMod = $this->getMod();
|
393 |
-
/** @var IPs\Options $oOpts */
|
394 |
-
$oOpts = $oMod->getOptions();
|
395 |
-
/** @var Databases\IPs\Select $oSelect */
|
396 |
-
$oSelect = $oMod->getDbHandler_IPs()->getQuerySelector();
|
397 |
-
/** @var Databases\IPs\EntryVO $oIp */
|
398 |
-
$oIp = $oSelect->filterByIp( $sIp )
|
399 |
-
->filterByBlacklist()
|
400 |
-
->filterByLastAccessAfter( Services::Request()->ts() - $oOpts->getAutoExpireTime() )
|
401 |
-
->first();
|
402 |
-
return $oIp;
|
403 |
-
}
|
404 |
-
|
405 |
-
/**
|
406 |
-
* The auto black list isn't a simple lookup, but rather has an auto expiration
|
407 |
-
* @param string $sIp
|
408 |
-
* @return Databases\IPs\EntryVO|null
|
409 |
-
* @deprecated 8.5
|
410 |
-
*/
|
411 |
-
protected function getAutoBlackListIp( $sIp ) {
|
412 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
413 |
-
$oMod = $this->getMod();
|
414 |
-
/** @var IPs\Options $oOpts */
|
415 |
-
$oOpts = $oMod->getOptions();
|
416 |
-
/** @var Databases\IPs\Select $oSelect */
|
417 |
-
$oSelect = $oMod->getDbHandler_IPs()->getQuerySelector();
|
418 |
-
return $oSelect->filterByIp( $sIp )
|
419 |
-
->filterByList( $oMod::LIST_AUTO_BLACK )
|
420 |
-
->filterByLastAccessAfter( Services::Request()->ts() - $oOpts->getAutoExpireTime() )
|
421 |
-
->first();
|
422 |
}
|
423 |
|
424 |
/**
|
425 |
-
* @deprecated 8.
|
426 |
*/
|
427 |
-
private function
|
428 |
}
|
429 |
}
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
|
|
4 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
|
|
5 |
|
6 |
+
class ICWP_WPSF_Processor_Ips extends Shield\Modules\BaseShield\ShieldProcessor {
|
7 |
|
8 |
/**
|
9 |
*/
|
10 |
public function run() {
|
11 |
+
( new IPs\Lib\BlacklistHandler() )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
->setMod( $this->getMod() )
|
13 |
+
->run();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
}
|
15 |
|
16 |
/**
|
17 |
+
* @deprecated 8.6.2
|
18 |
*/
|
19 |
+
private function doBlackMarkCurrentVisitor() {
|
20 |
}
|
21 |
}
|
src/processors/license.php
CHANGED
@@ -5,32 +5,37 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
5 |
|
6 |
class ICWP_WPSF_Processor_License extends Modules\BaseShield\ShieldProcessor {
|
7 |
|
8 |
-
/**
|
9 |
-
*/
|
10 |
public function run() {
|
11 |
-
|
12 |
-
|
|
|
13 |
$oReq = Services::Request();
|
14 |
|
15 |
-
// performs the license check
|
16 |
-
add_action( $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
-
switch ( $
|
19 |
|
20 |
case 'keyless_handshake':
|
21 |
$sNonce = $oReq->query( 'nonce' );
|
22 |
-
if ( !empty( $sNonce ) && $sNonce
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
}
|
27 |
-
die( json_encode( $aHandshakeData ) );
|
28 |
}
|
29 |
break;
|
30 |
|
31 |
case 'license_check':
|
32 |
-
if ( !wp_next_scheduled( $
|
33 |
-
wp_schedule_single_event( $oReq->ts() + 20, $
|
34 |
}
|
35 |
break;
|
36 |
}
|
5 |
|
6 |
class ICWP_WPSF_Processor_License extends Modules\BaseShield\ShieldProcessor {
|
7 |
|
|
|
|
|
8 |
public function run() {
|
9 |
+
$oCon = $this->getCon();
|
10 |
+
/** @var Modules\License\Options $oOpts */
|
11 |
+
$oOpts = $this->getOptions();
|
12 |
$oReq = Services::Request();
|
13 |
|
14 |
+
// performs the license check on-demand
|
15 |
+
add_action( $oCon->prefix( 'adhoc_cron_license_check' ), function () {
|
16 |
+
/** @var \ICWP_WPSF_FeatureHandler_License $oMod */
|
17 |
+
$oMod = $this->getMod();
|
18 |
+
try {
|
19 |
+
$oMod->getLicenseHandler()->verify( true );
|
20 |
+
}
|
21 |
+
catch ( \Exception $oE ) {
|
22 |
+
}
|
23 |
+
} );
|
24 |
|
25 |
+
switch ( $oCon->getShieldAction() ) {
|
26 |
|
27 |
case 'keyless_handshake':
|
28 |
$sNonce = $oReq->query( 'nonce' );
|
29 |
+
if ( !empty( $sNonce ) && $sNonce === $oOpts->getOpt( 'keyless_handshake_hash' ) ) {
|
30 |
+
die( json_encode( [
|
31 |
+
'success' => $oOpts->getOpt( 'keyless_handshake_until', 0 ) >= $oReq->ts()
|
32 |
+
] ) );
|
|
|
|
|
33 |
}
|
34 |
break;
|
35 |
|
36 |
case 'license_check':
|
37 |
+
if ( !wp_next_scheduled( $oCon->prefix( 'adhoc_cron_license_check' ) ) ) {
|
38 |
+
wp_schedule_single_event( $oReq->ts() + 20, $oCon->prefix( 'adhoc_cron_license_check' ) );
|
39 |
}
|
40 |
break;
|
41 |
}
|
src/processors/lockdown.php
CHANGED
@@ -13,7 +13,7 @@ class ICWP_WPSF_Processor_Lockdown extends Modules\BaseShield\ShieldProcessor {
|
|
13 |
$this->blockFileEditing();
|
14 |
}
|
15 |
|
16 |
-
$sWpVersionMask = $this->
|
17 |
if ( !empty( $sWpVersionMask ) ) {
|
18 |
global $wp_version;
|
19 |
$wp_version = $sWpVersionMask;
|
13 |
$this->blockFileEditing();
|
14 |
}
|
15 |
|
16 |
+
$sWpVersionMask = $this->getOptions()->getOpt( 'mask_wordpress_version' );
|
17 |
if ( !empty( $sWpVersionMask ) ) {
|
18 |
global $wp_version;
|
19 |
$wp_version = $sWpVersionMask;
|
src/processors/login_protect.php
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
|
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
class ICWP_WPSF_Processor_LoginProtect extends Modules\BaseShield\ShieldProcessor {
|
@@ -20,30 +21,25 @@ class ICWP_WPSF_Processor_LoginProtect extends Modules\BaseShield\ShieldProcesso
|
|
20 |
|
21 |
// So we can allow access to the login pages if IP is whitelisted
|
22 |
if ( $oMod->isCustomLoginPathEnabled() ) {
|
23 |
-
$this->
|
24 |
}
|
25 |
|
26 |
if ( !$oMod->isVisitorWhitelisted() ) {
|
27 |
if ( $oMod->isEnabledGaspCheck() ) {
|
28 |
-
$this->
|
29 |
}
|
30 |
|
31 |
if ( $oOpts->isCooldownEnabled() ) {
|
32 |
if ( Services::Request()->isPost() ) {
|
33 |
-
$this->
|
34 |
}
|
35 |
-
/*
|
36 |
-
( new Modules\LoginGuard\Lib\CooldownRedirect() )
|
37 |
-
->setMod( $oMod )
|
38 |
-
->run();
|
39 |
-
*/
|
40 |
}
|
41 |
|
42 |
if ( $oMod->isGoogleRecaptchaEnabled() ) {
|
43 |
-
$this->
|
44 |
}
|
45 |
|
46 |
-
$
|
47 |
}
|
48 |
}
|
49 |
|
@@ -117,6 +113,7 @@ class ICWP_WPSF_Processor_LoginProtect extends Modules\BaseShield\ShieldProcesso
|
|
117 |
|
118 |
/**
|
119 |
* @return \ICWP_WPSF_Processor_LoginProtect_Cooldown
|
|
|
120 |
*/
|
121 |
private function getSubProCooldown() {
|
122 |
return $this->getSubPro( 'cooldown' );
|
@@ -124,20 +121,15 @@ class ICWP_WPSF_Processor_LoginProtect extends Modules\BaseShield\ShieldProcesso
|
|
124 |
|
125 |
/**
|
126 |
* @return \ICWP_WPSF_Processor_LoginProtect_Gasp
|
|
|
127 |
*/
|
128 |
private function getSubProGasp() {
|
129 |
return $this->getSubPro( 'gasp' );
|
130 |
}
|
131 |
|
132 |
-
/**
|
133 |
-
* @return \ICWP_WPSF_Processor_LoginProtect_Intent
|
134 |
-
*/
|
135 |
-
public function getSubProIntent() {
|
136 |
-
return $this->getSubPro( 'intent' );
|
137 |
-
}
|
138 |
-
|
139 |
/**
|
140 |
* @return \ICWP_WPSF_Processor_LoginProtect_GoogleRecaptcha
|
|
|
141 |
*/
|
142 |
private function getSubProRecaptcha() {
|
143 |
return $this->getSubPro( 'recaptcha' );
|
@@ -145,8 +137,17 @@ class ICWP_WPSF_Processor_LoginProtect extends Modules\BaseShield\ShieldProcesso
|
|
145 |
|
146 |
/**
|
147 |
* @return \ICWP_WPSF_Processor_LoginProtect_WpLogin
|
|
|
148 |
*/
|
149 |
private function getSubProRename() {
|
150 |
return $this->getSubPro( 'rename' );
|
151 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
}
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
4 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
|
7 |
class ICWP_WPSF_Processor_LoginProtect extends Modules\BaseShield\ShieldProcessor {
|
21 |
|
22 |
// So we can allow access to the login pages if IP is whitelisted
|
23 |
if ( $oMod->isCustomLoginPathEnabled() ) {
|
24 |
+
$this->getSubPro( 'rename' )->execute();
|
25 |
}
|
26 |
|
27 |
if ( !$oMod->isVisitorWhitelisted() ) {
|
28 |
if ( $oMod->isEnabledGaspCheck() ) {
|
29 |
+
$this->getSubPro( 'gasp' )->execute();
|
30 |
}
|
31 |
|
32 |
if ( $oOpts->isCooldownEnabled() ) {
|
33 |
if ( Services::Request()->isPost() ) {
|
34 |
+
$this->getSubPro( 'cooldown' )->execute();
|
35 |
}
|
|
|
|
|
|
|
|
|
|
|
36 |
}
|
37 |
|
38 |
if ( $oMod->isGoogleRecaptchaEnabled() ) {
|
39 |
+
$this->getSubPro( 'recaptcha' )->execute();
|
40 |
}
|
41 |
|
42 |
+
$oMod->getLoginIntentController()->run();
|
43 |
}
|
44 |
}
|
45 |
|
113 |
|
114 |
/**
|
115 |
* @return \ICWP_WPSF_Processor_LoginProtect_Cooldown
|
116 |
+
* @deprecated 8.6.0
|
117 |
*/
|
118 |
private function getSubProCooldown() {
|
119 |
return $this->getSubPro( 'cooldown' );
|
121 |
|
122 |
/**
|
123 |
* @return \ICWP_WPSF_Processor_LoginProtect_Gasp
|
124 |
+
* @deprecated 8.6.0
|
125 |
*/
|
126 |
private function getSubProGasp() {
|
127 |
return $this->getSubPro( 'gasp' );
|
128 |
}
|
129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
/**
|
131 |
* @return \ICWP_WPSF_Processor_LoginProtect_GoogleRecaptcha
|
132 |
+
* @deprecated 8.6.0
|
133 |
*/
|
134 |
private function getSubProRecaptcha() {
|
135 |
return $this->getSubPro( 'recaptcha' );
|
137 |
|
138 |
/**
|
139 |
* @return \ICWP_WPSF_Processor_LoginProtect_WpLogin
|
140 |
+
* @deprecated 8.6.0
|
141 |
*/
|
142 |
private function getSubProRename() {
|
143 |
return $this->getSubPro( 'rename' );
|
144 |
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* @return \ICWP_WPSF_Processor_LoginProtect_Intent
|
148 |
+
* @deprecated 8.6.0
|
149 |
+
*/
|
150 |
+
public function getSubProIntent() {
|
151 |
+
return $this->getSubPro( 'intent' );
|
152 |
+
}
|
153 |
}
|
src/processors/loginprotect_intent.php
CHANGED
@@ -1,8 +1,11 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
use FernleafSystems\Wordpress\Services\Services;
|
4 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
5 |
|
|
|
|
|
|
|
6 |
class ICWP_WPSF_Processor_LoginProtect_Intent extends Shield\Modules\BaseShield\ShieldProcessor {
|
7 |
|
8 |
/**
|
@@ -18,168 +21,26 @@ class ICWP_WPSF_Processor_LoginProtect_Intent extends Shield\Modules\BaseShield\
|
|
18 |
/**
|
19 |
*/
|
20 |
public function run() {
|
21 |
-
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
22 |
-
$oMod = $this->getMod();
|
23 |
-
add_action( 'wp_logout', [ $this, 'onWpLogout' ] );
|
24 |
-
|
25 |
-
// 100 priority is important as this takes priority
|
26 |
-
// add_filter( $oMod->prefix( 'user_subject_to_login_intent' ), array( $this, 'applyUserCanMfaSkip' ), 100, 2 );
|
27 |
-
|
28 |
-
if ( $oMod->getIfSupport3rdParty() ) {
|
29 |
-
add_action( 'wc_social_login_before_user_login', [ $this, 'onWcSocialLogin' ] );
|
30 |
-
}
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
* @param int $nUserId
|
35 |
*/
|
36 |
public function onWcSocialLogin( $nUserId ) {
|
37 |
-
$oUser = Services::WpUsers()->getUserById( $nUserId );
|
38 |
-
if ( $oUser instanceof WP_User ) {
|
39 |
-
$this->getCon()->getUserMeta( $oUser )->wc_social_login_valid = true;
|
40 |
-
}
|
41 |
-
}
|
42 |
-
|
43 |
-
public function onWpInit() {
|
44 |
-
$this->setupLoginIntent();
|
45 |
}
|
46 |
|
47 |
protected function setupLoginIntent() {
|
48 |
-
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $oFO */
|
49 |
-
$oFO = $this->getMod();
|
50 |
-
|
51 |
-
if ( $oFO->isEnabledGoogleAuthenticator() ) {
|
52 |
-
$this->getProcessorGoogleAuthenticator()->execute();
|
53 |
-
}
|
54 |
-
|
55 |
-
if ( $oFO->isEmailAuthenticationActive() ) {
|
56 |
-
$this->getProcessorEmailAuth()->execute();
|
57 |
-
}
|
58 |
-
|
59 |
-
if ( $oFO->isYubikeyActive() ) {
|
60 |
-
$this->getProcessorYubikey()->execute();
|
61 |
-
}
|
62 |
-
|
63 |
-
if ( $oFO->isEnabledBackupCodes() ) {
|
64 |
-
$this->getProcessorBackupCodes()->execute();
|
65 |
-
}
|
66 |
-
|
67 |
-
if ( $this->getLoginTrack()->hasFactorsRemainingToTrack() ) {
|
68 |
-
if ( Services::WpGeneral()->isLoginRequest() || $oFO->getIfSupport3rdParty() ) {
|
69 |
-
/** 20180925 - now using set cookie auth instead so we can capture session */
|
70 |
-
// add_action( 'authenticate', array( $this, 'initLoginIntent' ), 100, 1 );
|
71 |
-
}
|
72 |
-
|
73 |
-
// process the current login intent
|
74 |
-
$oWpUsers = Services::WpUsers();
|
75 |
-
if ( $oWpUsers->isUserLoggedIn() ) {
|
76 |
-
if ( $this->isUserSubjectToLoginIntent() && !$oFO->canUserMfaSkip( $oWpUsers->getCurrentWpUser() ) ) {
|
77 |
-
$this->processLoginIntent();
|
78 |
-
}
|
79 |
-
elseif ( $this->hasLoginIntent() ) {
|
80 |
-
// This handles the case where an admin changes a setting while a user is logged-in
|
81 |
-
// So to prevent this, we remove any intent for a user that isn't subject to it right now
|
82 |
-
$this->removeLoginIntent();
|
83 |
-
}
|
84 |
-
}
|
85 |
-
}
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* @param string $sUsername
|
90 |
-
* @param WP_User $oUser
|
91 |
-
*/
|
92 |
-
public function onWpLogin( $sUsername, $oUser ) {
|
93 |
-
$this->initLoginIntent( $oUser );
|
94 |
-
}
|
95 |
-
|
96 |
-
/**
|
97 |
-
* @param string $sCookie
|
98 |
-
* @param int $nExpire
|
99 |
-
* @param int $nExpiration
|
100 |
-
* @param int $nUserId
|
101 |
-
*/
|
102 |
-
public function onWpSetLoggedInCookie( $sCookie, $nExpire, $nExpiration, $nUserId ) {
|
103 |
-
$this->initLoginIntent( Services::WpUsers()->getUserById( $nUserId ) );
|
104 |
}
|
105 |
|
106 |
/**
|
107 |
* @param WP_User|WP_Error $oUser
|
108 |
*/
|
109 |
-
protected function initLoginIntent( $oUser ) {
|
110 |
-
|
111 |
-
if ( !$this->isLoginCaptured() && $oUser instanceof WP_User
|
112 |
-
&& $this->getLoginTrack()->hasFactorsRemainingToTrack() ) {
|
113 |
-
|
114 |
-
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oF */
|
115 |
-
$oF = $this->getMod();
|
116 |
-
if ( !$oF->canUserMfaSkip( $oUser ) ) {
|
117 |
-
$nTimeout = (int)apply_filters( $oF->prefix( 'login_intent_timeout' ), $oF->getDef( 'login_intent_timeout' ) );
|
118 |
-
$this->setLoginIntentExpiresAt( Services::Request()->ts() + MINUTE_IN_SECONDS*$nTimeout );
|
119 |
-
}
|
120 |
-
}
|
121 |
-
}
|
122 |
|
123 |
/**
|
124 |
* hooked to 'init' and only run if a user is logged-in (not on the login request)
|
125 |
*/
|
126 |
-
private function processLoginIntent() {
|
127 |
-
$oWpResp = Services::Response();
|
128 |
-
$oWpUsers = Services::WpUsers();
|
129 |
-
|
130 |
-
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oFO */
|
131 |
-
$oFO = $this->getMod();
|
132 |
-
|
133 |
-
if ( $this->hasValidLoginIntent() ) { // ie. valid login intent present
|
134 |
-
$oReq = Services::Request();
|
135 |
-
|
136 |
-
// Is 2FA/login-intent submit
|
137 |
-
if ( $oReq->request( $oFO->getLoginIntentRequestFlag() ) == 1 ) {
|
138 |
-
|
139 |
-
if ( $oReq->post( 'cancel' ) == 1 ) {
|
140 |
-
$oWpUsers->logoutUser(); // clears the login and login intent
|
141 |
-
$sRedirectHref = $oReq->post( 'cancel_href' );
|
142 |
-
empty( $sRedirectHref ) ? $oWpResp->redirectToLogin() : $oWpResp->redirect( rawurldecode( $sRedirectHref ) );
|
143 |
-
}
|
144 |
-
elseif ( $this->isLoginIntentValid() ) {
|
145 |
-
|
146 |
-
if ( $oReq->post( 'skip_mfa' ) === 'Y' ) { // store the browser hash
|
147 |
-
$oFO->addMfaLoginHash( $oWpUsers->getCurrentWpUser() );
|
148 |
-
}
|
149 |
-
|
150 |
-
$this->removeLoginIntent();
|
151 |
-
$sFlash = __( 'Success', 'wp-simple-firewall' ).'! '.__( 'Thank you for authenticating your login.', 'wp-simple-firewall' );
|
152 |
-
if ( $oFO->isEnabledBackupCodes() ) {
|
153 |
-
$sFlash .= ' '.__( 'If you used your Backup Code, you will need to reset it.', 'wp-simple-firewall' ); //TODO::
|
154 |
-
}
|
155 |
-
|
156 |
-
$this->getCon()->fireEvent( '2fa_success' );
|
157 |
-
$oFO->setFlashAdminNotice( $sFlash );
|
158 |
-
|
159 |
-
$sRedirectHref = $oReq->post( 'redirect_to' );
|
160 |
-
empty( $sRedirectHref ) ? $oWpResp->redirectHere() : $oWpResp->redirect( rawurldecode( $sRedirectHref ) );
|
161 |
-
}
|
162 |
-
else {
|
163 |
-
$oFO->setFlashAdminNotice( __( 'One or more of your authentication codes failed or was missing', 'wp-simple-firewall' ), true );
|
164 |
-
// We don't protect against loops here to prevent by-passing of the login intent page.
|
165 |
-
Services::Response()->redirect( Services::Request()->getUri(), [], true, false );
|
166 |
-
}
|
167 |
-
return; // we've redirected anyway.
|
168 |
-
}
|
169 |
-
if ( $this->printLoginIntentForm() ) {
|
170 |
-
die();
|
171 |
-
}
|
172 |
-
}
|
173 |
-
elseif ( $this->hasLoginIntent() ) { // there was an old login intent
|
174 |
-
$oWpUsers->logoutUser(); // clears the login and login intent
|
175 |
-
$oWpResp->redirectHere();
|
176 |
-
}
|
177 |
-
else {
|
178 |
-
// no login intent present -
|
179 |
-
// the login has already been fully validated and the login intent was deleted.
|
180 |
-
// also means new installation don't get booted out
|
181 |
-
}
|
182 |
-
}
|
183 |
|
184 |
/**
|
185 |
* Use this ONLY when the login intent has been successfully verified.
|
@@ -194,13 +55,6 @@ class ICWP_WPSF_Processor_LoginProtect_Intent extends Shield\Modules\BaseShield\
|
|
194 |
* @return $this
|
195 |
*/
|
196 |
protected function setLoginIntentExpiresAt( $nExpirationTime ) {
|
197 |
-
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
198 |
-
$oMod = $this->getMod();
|
199 |
-
if ( $oMod->hasSession() ) {
|
200 |
-
/** @var Shield\Databases\Session\Update $oUpd */
|
201 |
-
$oUpd = $oMod->getDbHandler_Sessions()->getQueryUpdater();
|
202 |
-
$oUpd->updateLoginIntentExpiresAt( $oMod->getSession(), $nExpirationTime );
|
203 |
-
}
|
204 |
return $this;
|
205 |
}
|
206 |
|
@@ -228,157 +82,17 @@ class ICWP_WPSF_Processor_LoginProtect_Intent extends Shield\Modules\BaseShield\
|
|
228 |
}
|
229 |
|
230 |
/**
|
231 |
-
* @return bool true if valid form printed, false otherwise. Should die() if true
|
232 |
*/
|
233 |
-
private function printLoginIntentForm() {
|
234 |
-
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
235 |
-
$oMod = $this->getMod();
|
236 |
-
$oCon = $this->getCon();
|
237 |
-
$oReq = Services::Request();
|
238 |
-
$oWP = Services::WpGeneral();
|
239 |
-
$aLoginIntentFields = apply_filters( $oCon->prefix( 'login-intent-form-fields' ), [] );
|
240 |
-
|
241 |
-
if ( empty( $aLoginIntentFields ) ) {
|
242 |
-
return false; // a final guard against displaying an empty form.
|
243 |
-
}
|
244 |
-
|
245 |
-
if ( $oMod->isChainedAuth() ) {
|
246 |
-
$sMessage = __( 'Please supply all authentication codes', 'wp-simple-firewall' );
|
247 |
-
}
|
248 |
-
else {
|
249 |
-
$sMessage = __( 'Please supply at least 1 authentication code', 'wp-simple-firewall' );
|
250 |
-
}
|
251 |
-
|
252 |
-
$sReferUrl = $oReq->server( 'HTTP_REFERER', '' );
|
253 |
-
if ( strpos( $sReferUrl, '?' ) ) {
|
254 |
-
list( $sReferUrl, $sReferQuery ) = explode( '?', $sReferUrl, 2 );
|
255 |
-
}
|
256 |
-
else {
|
257 |
-
$sReferQuery = '';
|
258 |
-
}
|
259 |
-
|
260 |
-
$sRedirectTo = '';
|
261 |
-
if ( !empty( $sReferQuery ) ) {
|
262 |
-
parse_str( $sReferQuery, $aReferQueryItems );
|
263 |
-
if ( !empty( $aReferQueryItems[ 'redirect_to' ] ) ) {
|
264 |
-
$sRedirectTo = rawurlencode( $aReferQueryItems[ 'redirect_to' ] );
|
265 |
-
}
|
266 |
-
}
|
267 |
-
if ( empty( $sRedirectTo ) ) {
|
268 |
-
$sRedirectTo = rawurlencode( $oReq->post( 'redirect_to', $oReq->getUri() ) );
|
269 |
-
}
|
270 |
-
|
271 |
-
$sCancelHref = $oReq->post( 'cancel_href', '' );
|
272 |
-
if ( empty( $sCancelHref ) && Services::Data()->isValidWebUrl( $sReferUrl ) ) {
|
273 |
-
$sCancelHref = rawurlencode( parse_url( $sReferUrl, PHP_URL_PATH ) );
|
274 |
-
}
|
275 |
-
|
276 |
-
$aLabels = $oCon->getLabels();
|
277 |
-
$sBannerUrl = empty( $aLabels[ 'url_login2fa_logourl' ] ) ? $oCon->getPluginUrl_Image( 'pluginlogo_banner-772x250.png' ) : $aLabels[ 'url_login2fa_logourl' ];
|
278 |
-
$nMfaSkip = $oMod->getMfaSkip();
|
279 |
-
$aDisplayData = [
|
280 |
-
'strings' => [
|
281 |
-
'cancel' => __( 'Cancel Login', 'wp-simple-firewall' ),
|
282 |
-
'time_remaining' => __( 'Time Remaining', 'wp-simple-firewall' ),
|
283 |
-
'calculating' => __( 'Calculating', 'wp-simple-firewall' ).' ...',
|
284 |
-
'seconds' => strtolower( __( 'Seconds', 'wp-simple-firewall' ) ),
|
285 |
-
'login_expired' => __( 'Login Expired', 'wp-simple-firewall' ),
|
286 |
-
'verify_my_login' => __( 'Verify My Login', 'wp-simple-firewall' ),
|
287 |
-
'more_info' => __( 'More Info', 'wp-simple-firewall' ),
|
288 |
-
'what_is_this' => __( 'What is this?', 'wp-simple-firewall' ),
|
289 |
-
'message' => $sMessage,
|
290 |
-
'page_title' => sprintf( __( '%s Login Verification', 'wp-simple-firewall' ), $oCon->getHumanName() ),
|
291 |
-
'skip_mfa' => sprintf(
|
292 |
-
__( "Don't ask again on this browser for %s.", 'wp-simple-firewall' ),
|
293 |
-
sprintf( _n( '%s day', '%s days', $nMfaSkip, 'wp-simple-firewall' ), $nMfaSkip )
|
294 |
-
)
|
295 |
-
],
|
296 |
-
'data' => [
|
297 |
-
'login_fields' => $aLoginIntentFields,
|
298 |
-
'time_remaining' => $this->getLoginIntentExpiresAt() - $oReq->ts(),
|
299 |
-
'message_type' => 'info',
|
300 |
-
'login_intent_flag' => $oMod->getLoginIntentRequestFlag(),
|
301 |
-
'page_locale' => $oWP->getLocale( '-' )
|
302 |
-
],
|
303 |
-
'hrefs' => [
|
304 |
-
'form_action' => parse_url( $oWP->getAdminUrl( '', true ), PHP_URL_PATH ),
|
305 |
-
'css_bootstrap' => $oCon->getPluginUrl_Css( 'bootstrap4.min' ),
|
306 |
-
'js_bootstrap' => $oCon->getPluginUrl_Js( 'bootstrap4.min' ),
|
307 |
-
'shield_logo' => 'https://ps.w.org/wp-simple-firewall/assets/banner-772x250.png',
|
308 |
-
'redirect_to' => $sRedirectTo,
|
309 |
-
'what_is_this' => 'https://icontrolwp.freshdesk.com/support/solutions/articles/3000064840',
|
310 |
-
'cancel_href' => $sCancelHref
|
311 |
-
],
|
312 |
-
'imgs' => [
|
313 |
-
'banner' => $sBannerUrl,
|
314 |
-
'favicon' => $oCon->getPluginUrl_Image( 'pluginlogo_24x24.png' ),
|
315 |
-
],
|
316 |
-
'flags' => [
|
317 |
-
'can_skip_mfa' => $oMod->getMfaSkipEnabled(),
|
318 |
-
'show_branded_links' => !$oMod->isWlEnabled(), // white label mitigation
|
319 |
-
]
|
320 |
-
];
|
321 |
-
|
322 |
-
echo $oMod->renderTemplate( '/pages/login_intent/index.twig',
|
323 |
-
Services::DataManipulation()->mergeArraysRecursive( $oMod->getBaseDisplayData(), $aDisplayData ), true );
|
324 |
-
|
325 |
-
return true;
|
326 |
-
}
|
327 |
-
|
328 |
/**
|
329 |
*/
|
330 |
public function onWpLogout() {
|
331 |
-
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $oFO */
|
332 |
-
$oFO = $this->getMod();
|
333 |
-
|
334 |
-
$this->removeLoginIntent();
|
335 |
-
|
336 |
-
// support for WooCommerce Social Login
|
337 |
-
$oMeta = $this->getCon()->getCurrentUserMeta();
|
338 |
-
if ( $oFO->getIfSupport3rdParty() && $oMeta instanceof Shield\Users\ShieldUserMeta ) {
|
339 |
-
$oMeta->wc_social_login_valid = false;
|
340 |
-
}
|
341 |
-
}
|
342 |
-
|
343 |
-
/**
|
344 |
-
* @return ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth
|
345 |
-
*/
|
346 |
-
protected function getProcessorEmailAuth() {
|
347 |
-
return ( new ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth( $this->getMod() ) )
|
348 |
-
->setLoginTrack( $this->getLoginTrack() );
|
349 |
-
}
|
350 |
-
|
351 |
-
/**
|
352 |
-
* @return ICWP_WPSF_Processor_LoginProtect_Yubikey
|
353 |
-
*/
|
354 |
-
protected function getProcessorYubikey() {
|
355 |
-
return ( new ICWP_WPSF_Processor_LoginProtect_Yubikey( $this->getMod() ) )
|
356 |
-
->setLoginTrack( $this->getLoginTrack() );
|
357 |
-
}
|
358 |
-
|
359 |
-
/**
|
360 |
-
* @return ICWP_WPSF_Processor_LoginProtect_BackupCodes
|
361 |
-
*/
|
362 |
-
public function getProcessorBackupCodes() {
|
363 |
-
return ( new ICWP_WPSF_Processor_LoginProtect_BackupCodes( $this->getMod() ) )
|
364 |
-
->setLoginTrack( $this->getLoginTrack() );
|
365 |
-
}
|
366 |
-
|
367 |
-
/**
|
368 |
-
* @return ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator
|
369 |
-
*/
|
370 |
-
public function getProcessorGoogleAuthenticator() {
|
371 |
-
return ( new ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator( $this->getMod() ) )
|
372 |
-
->setLoginTrack( $this->getLoginTrack() );
|
373 |
}
|
374 |
|
375 |
/**
|
376 |
* @return ICWP_WPSF_Processor_LoginProtect_Track
|
377 |
*/
|
378 |
public function getLoginTrack() {
|
379 |
-
if ( !isset( $this->oLoginTrack ) ) {
|
380 |
-
$this->oLoginTrack = new ICWP_WPSF_Processor_LoginProtect_Track();
|
381 |
-
}
|
382 |
return $this->oLoginTrack;
|
383 |
}
|
384 |
|
@@ -387,43 +101,20 @@ class ICWP_WPSF_Processor_LoginProtect_Intent extends Shield\Modules\BaseShield\
|
|
387 |
* @return bool
|
388 |
*/
|
389 |
private function isLoginIntentValid() {
|
390 |
-
|
391 |
-
$oFO = $this->getMod();
|
392 |
-
if ( !$this->isLoginIntentProcessed() ) {
|
393 |
-
// This action sets up the necessary login tracker info
|
394 |
-
do_action( $oFO->prefix( 'login-intent-validation' ), Services::WpUsers()->getCurrentWpUser() );
|
395 |
-
$this->setLoginIntentProcessed();
|
396 |
-
}
|
397 |
-
$oTrk = $this->getLoginTrack();
|
398 |
-
|
399 |
-
// 1st: if backup code was used, then chained auth is irrelevant
|
400 |
-
$sBackupStub = ICWP_WPSF_Processor_LoginProtect_Track::Factor_BackupCode;
|
401 |
-
|
402 |
-
// if backup code used, that's successful; or
|
403 |
-
// It's not chained and you have any 1 successful; or
|
404 |
-
// It's chained (and then you must exclude the backup code.
|
405 |
-
$bSuccess = in_array( $sBackupStub, $oTrk->getFactorsSuccessful() )
|
406 |
-
|| ( !$oFO->isChainedAuth() && $oTrk->hasSuccessfulFactor() );
|
407 |
-
if ( !$bSuccess && $oFO->isChainedAuth() ) {
|
408 |
-
$bSuccess = !$oTrk->hasUnSuccessfulFactor()
|
409 |
-
|| ( $oTrk->getCountFactorsUnsuccessful() == 1 && in_array( $sBackupStub, $oTrk->getFactorsUnsuccessful() ) );
|
410 |
-
}
|
411 |
-
|
412 |
-
return $bSuccess;
|
413 |
}
|
414 |
|
415 |
/**
|
416 |
* @return bool
|
417 |
*/
|
418 |
public function isLoginIntentProcessed() {
|
419 |
-
return
|
420 |
}
|
421 |
|
422 |
/**
|
423 |
* @return $this
|
424 |
*/
|
425 |
public function setLoginIntentProcessed() {
|
426 |
-
$this->bLoginIntentProcessed = true;
|
427 |
return $this;
|
428 |
}
|
429 |
|
@@ -432,7 +123,6 @@ class ICWP_WPSF_Processor_LoginProtect_Intent extends Shield\Modules\BaseShield\
|
|
432 |
* @return $this
|
433 |
*/
|
434 |
public function setLoginTrack( $oLoginTrack ) {
|
435 |
-
$this->oLoginTrack = $oLoginTrack;
|
436 |
return $this;
|
437 |
}
|
438 |
}
|
1 |
<?php
|
2 |
|
|
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
+
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
+
/**
|
7 |
+
* @deprecated 8.6.0
|
8 |
+
*/
|
9 |
class ICWP_WPSF_Processor_LoginProtect_Intent extends Shield\Modules\BaseShield\ShieldProcessor {
|
10 |
|
11 |
/**
|
21 |
/**
|
22 |
*/
|
23 |
public function run() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
}
|
25 |
|
26 |
/**
|
27 |
* @param int $nUserId
|
28 |
*/
|
29 |
public function onWcSocialLogin( $nUserId ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
|
32 |
protected function setupLoginIntent() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
}
|
34 |
|
35 |
/**
|
36 |
* @param WP_User|WP_Error $oUser
|
37 |
*/
|
38 |
+
protected function initLoginIntent( $oUser ) {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
/**
|
41 |
* hooked to 'init' and only run if a user is logged-in (not on the login request)
|
42 |
*/
|
43 |
+
private function processLoginIntent() {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
/**
|
46 |
* Use this ONLY when the login intent has been successfully verified.
|
55 |
* @return $this
|
56 |
*/
|
57 |
protected function setLoginIntentExpiresAt( $nExpirationTime ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
return $this;
|
59 |
}
|
60 |
|
82 |
}
|
83 |
|
84 |
/**
|
|
|
85 |
*/
|
86 |
+
private function printLoginIntentForm() {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
/**
|
88 |
*/
|
89 |
public function onWpLogout() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
}
|
91 |
|
92 |
/**
|
93 |
* @return ICWP_WPSF_Processor_LoginProtect_Track
|
94 |
*/
|
95 |
public function getLoginTrack() {
|
|
|
|
|
|
|
96 |
return $this->oLoginTrack;
|
97 |
}
|
98 |
|
101 |
* @return bool
|
102 |
*/
|
103 |
private function isLoginIntentValid() {
|
104 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
* @return bool
|
109 |
*/
|
110 |
public function isLoginIntentProcessed() {
|
111 |
+
return true;
|
112 |
}
|
113 |
|
114 |
/**
|
115 |
* @return $this
|
116 |
*/
|
117 |
public function setLoginIntentProcessed() {
|
|
|
118 |
return $this;
|
119 |
}
|
120 |
|
123 |
* @return $this
|
124 |
*/
|
125 |
public function setLoginTrack( $oLoginTrack ) {
|
|
|
126 |
return $this;
|
127 |
}
|
128 |
}
|
src/processors/loginprotect_intent_tracker.php
CHANGED
@@ -1,5 +1,9 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
3 |
class ICWP_WPSF_Processor_LoginProtect_Track {
|
4 |
|
5 |
const Factor_Google_Authenticator = 'ga';
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
+
* Class ICWP_WPSF_Processor_LoginProtect_Track
|
5 |
+
* @deprecated 8.6.0
|
6 |
+
*/
|
7 |
class ICWP_WPSF_Processor_LoginProtect_Track {
|
8 |
|
9 |
const Factor_Google_Authenticator = 'ga';
|
src/processors/loginprotect_intentprovider_backup.php
CHANGED
@@ -2,55 +2,11 @@
|
|
2 |
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
|
|
|
|
|
|
|
5 |
class ICWP_WPSF_Processor_LoginProtect_BackupCodes extends ICWP_WPSF_Processor_LoginProtect_IntentProviderBase {
|
6 |
|
7 |
-
/**
|
8 |
-
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
9 |
-
* functions. Otherwise we need to be careful of mixing up users.
|
10 |
-
* @param \WP_User $oUser
|
11 |
-
*/
|
12 |
-
public function addOptionsToUserProfile( $oUser ) {
|
13 |
-
$oCon = $this->getCon();
|
14 |
-
|
15 |
-
$bValidatedProfile = $this->hasValidatedProfile( $oUser );
|
16 |
-
$aData = [
|
17 |
-
'has_mfa' => $this->isUserSubjectToLoginIntent( $oUser ),
|
18 |
-
'has_validated_profile' => $bValidatedProfile,
|
19 |
-
'user_google_authenticator_secret' => $this->getSecret( $oUser ),
|
20 |
-
'is_my_user_profile' => ( $oUser->ID == Services::WpUsers()->getCurrentWpUserId() ),
|
21 |
-
'i_am_valid_admin' => $oCon->isPluginAdmin(),
|
22 |
-
'user_to_edit_is_admin' => Services::WpUsers()->isUserAdmin( $oUser ),
|
23 |
-
'strings' => [
|
24 |
-
'button_gen_code' => __( 'Generate ONE-Time Backup 2FA Login Code', 'wp-simple-firewall' ),
|
25 |
-
'button_del_code' => __( 'Delete Login Backup Code', 'wp-simple-firewall' ),
|
26 |
-
'not_available' => __( 'Backup login codes are not available if you do not have any other two-factor authentication modes active.', 'wp-simple-firewall' ),
|
27 |
-
'description_code' => __( 'Click to generate a backup login code for your two-factor authentication.', 'wp-simple-firewall' ),
|
28 |
-
'description_code_ext1' => sprintf( '%s: %s',
|
29 |
-
__( 'Important', 'wp-simple-firewall' ),
|
30 |
-
__( 'This code will be displayed only once and you may use it to verify your login only once.', 'wp-simple-firewall' )
|
31 |
-
.' '.__( 'Store it somewhere safe.', 'wp-simple-firewall' ) ),
|
32 |
-
'description_code_ext2' => __( 'Generating a new code will replace your existing code.', 'wp-simple-firewall' ),
|
33 |
-
'description_chart_url' => __( 'Use your Google Authenticator app to scan this QR code and enter the one time password below.', 'wp-simple-firewall' ),
|
34 |
-
'description_ga_secret' => __( 'If you have a problem with scanning the QR code enter this code manually into the app.', 'wp-simple-firewall' ),
|
35 |
-
'desc_remove' => __( 'Check the box to remove Google Authenticator login authentication.', 'wp-simple-firewall' ),
|
36 |
-
'label_check_to_remove' => sprintf( __( 'Remove %s', 'wp-simple-firewall' ), __( 'Google Authenticator', 'wp-simple-firewall' ) ),
|
37 |
-
'label_enter_code' => __( 'Create Backup 2FA Login Code', 'wp-simple-firewall' ),
|
38 |
-
'label_ga_secret' => __( 'Manual Code', 'wp-simple-firewall' ),
|
39 |
-
'label_scan_qr_code' => __( 'Scan This QR Code', 'wp-simple-firewall' ),
|
40 |
-
'title' => __( 'Backup Login Code', 'wp-simple-firewall' ),
|
41 |
-
'cant_add_other_user' => sprintf( __( "Sorry, %s may not be added to another user's account.", 'wp-simple-firewall' ), 'Backup Codes' ),
|
42 |
-
'cant_remove_admins' => sprintf( __( "Sorry, %s may only be removed from another user's account by a Security Administrator.", 'wp-simple-firewall' ), __( 'Backup Codes', 'wp-simple-firewall' ) ),
|
43 |
-
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $oCon->getHumanName() ),
|
44 |
-
'remove_more_info' => sprintf( __( 'Understand how to remove Google Authenticator', 'wp-simple-firewall' ) )
|
45 |
-
],
|
46 |
-
'data' => [
|
47 |
-
'otp_field_name' => $this->getLoginFormParameter()
|
48 |
-
]
|
49 |
-
];
|
50 |
-
|
51 |
-
echo $this->getMod()->renderTemplate( 'snippets/user_profile_backupcode.php', $aData );
|
52 |
-
}
|
53 |
-
|
54 |
/**
|
55 |
* @param \WP_User $oUser
|
56 |
*/
|
@@ -135,43 +91,6 @@ class ICWP_WPSF_Processor_LoginProtect_BackupCodes extends ICWP_WPSF_Processor_L
|
|
135 |
);
|
136 |
}
|
137 |
|
138 |
-
/**
|
139 |
-
* @param \WP_User $oUser
|
140 |
-
* @param bool $bIsOtpSuccess
|
141 |
-
* @param bool $bOtpProvided - whether a OTP was actually provided
|
142 |
-
* @return $this
|
143 |
-
*/
|
144 |
-
protected function postOtpProcessAction( $oUser, $bIsOtpSuccess, $bOtpProvided ) {
|
145 |
-
parent::postOtpProcessAction( $oUser, $bIsOtpSuccess, $bOtpProvided );
|
146 |
-
|
147 |
-
if ( $bOtpProvided && $bIsOtpSuccess ) {
|
148 |
-
$this->sendBackupCodeUsedEmail( $oUser );
|
149 |
-
}
|
150 |
-
return $this;
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* @param \WP_User $oUser
|
155 |
-
*/
|
156 |
-
private function sendBackupCodeUsedEmail( $oUser ) {
|
157 |
-
$aEmailContent = [
|
158 |
-
__( 'This is a quick notice to inform you that your Backup Login code was just used.', 'wp-simple-firewall' ),
|
159 |
-
__( "Your WordPress account had only 1 backup login code.", 'wp-simple-firewall' )
|
160 |
-
.' '.__( "You must go to your profile and regenerate a new code if you want to use this method again.", 'wp-simple-firewall' ),
|
161 |
-
'',
|
162 |
-
sprintf( '<strong>%s</strong>', __( 'Login Details', 'wp-simple-firewall' ) ),
|
163 |
-
sprintf( '%s: %s', __( 'URL', 'wp-simple-firewall' ), Services::WpGeneral()->getHomeUrl() ),
|
164 |
-
sprintf( '%s: %s', __( 'Username', 'wp-simple-firewall' ), $oUser->user_login ),
|
165 |
-
sprintf( '%s: %s', __( 'IP Address', 'wp-simple-firewall' ), Services::IP()->getRequestIp() ),
|
166 |
-
'',
|
167 |
-
__( 'Thank You.', 'wp-simple-firewall' ),
|
168 |
-
];
|
169 |
-
|
170 |
-
$sTitle = sprintf( __( "Notice: %s", 'wp-simple-firewall' ), __( "Backup Login Code Just Used", 'wp-simple-firewall' ) );
|
171 |
-
$this->getEmailProcessor()
|
172 |
-
->sendEmailWithWrap( $oUser->user_email, $sTitle, $aEmailContent );
|
173 |
-
}
|
174 |
-
|
175 |
/**
|
176 |
* @param \WP_User $oUser
|
177 |
* @return string
|
2 |
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
|
5 |
+
/**
|
6 |
+
* @deprecated 8.6.0
|
7 |
+
*/
|
8 |
class ICWP_WPSF_Processor_LoginProtect_BackupCodes extends ICWP_WPSF_Processor_LoginProtect_IntentProviderBase {
|
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
/**
|
11 |
* @param \WP_User $oUser
|
12 |
*/
|
91 |
);
|
92 |
}
|
93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
/**
|
95 |
* @param \WP_User $oUser
|
96 |
* @return string
|
src/processors/loginprotect_intentprovider_base.php
CHANGED
@@ -3,6 +3,9 @@
|
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
|
|
|
|
|
|
6 |
abstract class ICWP_WPSF_Processor_LoginProtect_IntentProviderBase extends Modules\BaseShield\ShieldProcessor {
|
7 |
|
8 |
/**
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
+
/**
|
7 |
+
* @deprecated 8.6.0
|
8 |
+
*/
|
9 |
abstract class ICWP_WPSF_Processor_LoginProtect_IntentProviderBase extends Modules\BaseShield\ShieldProcessor {
|
10 |
|
11 |
/**
|
src/processors/loginprotect_intentprovider_email.php
CHANGED
@@ -2,6 +2,9 @@
|
|
2 |
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
|
|
|
|
|
|
|
5 |
class ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth extends ICWP_WPSF_Processor_LoginProtect_IntentProviderBase {
|
6 |
|
7 |
/**
|
@@ -21,8 +24,7 @@ class ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth extends ICWP_WPSF_Processor
|
|
21 |
$oUpd->setLoginIntentCodeEmail( $oMod->getSession(), $this->getSecret( $oUser ) );
|
22 |
|
23 |
// Now send email with authentication link for user.
|
24 |
-
$this->
|
25 |
-
->setLoginCaptured();
|
26 |
}
|
27 |
return $oUser;
|
28 |
}
|
@@ -131,79 +133,6 @@ class ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth extends ICWP_WPSF_Processor
|
|
131 |
return !empty( $sHash );
|
132 |
}
|
133 |
|
134 |
-
/**
|
135 |
-
* @param \WP_User $oUser
|
136 |
-
* @return $this
|
137 |
-
*/
|
138 |
-
private function sendEmailTwoFactorVerify( \WP_User $oUser ) {
|
139 |
-
$aMessage = [
|
140 |
-
__( 'Someone attempted to login into this WordPress site using your account.', 'wp-simple-firewall' ),
|
141 |
-
__( 'Login requires verification with the following code.', 'wp-simple-firewall' ),
|
142 |
-
'',
|
143 |
-
sprintf( __( 'Verification Code: %s', 'wp-simple-firewall' ), sprintf( '<strong>%s</strong>', $this->getSecret( $oUser ) ) ),
|
144 |
-
'',
|
145 |
-
sprintf( '<strong>%s</strong>', __( 'Login Details', 'wp-simple-firewall' ) ),
|
146 |
-
sprintf( '%s: %s', __( 'URL', 'wp-simple-firewall' ), Services::WpGeneral()->getHomeUrl() ),
|
147 |
-
sprintf( '%s: %s', __( 'Username', 'wp-simple-firewall' ), $oUser->user_login ),
|
148 |
-
sprintf( '%s: %s', __( 'IP Address', 'wp-simple-firewall' ), Services::IP()->getRequestIp() ),
|
149 |
-
'',
|
150 |
-
];
|
151 |
-
|
152 |
-
if ( !$this->getCon()->isRelabelled() ) {
|
153 |
-
$aMessage[] = sprintf( '- <a href="%s" target="_blank">%s</a>', 'https://shsec.io/96', __( 'Why no login link?', 'wp-simple-firewall' ) );
|
154 |
-
$aContent[] = '';
|
155 |
-
}
|
156 |
-
|
157 |
-
$bResult = $this->getEmailProcessor()
|
158 |
-
->sendEmailWithWrap(
|
159 |
-
$oUser->user_email,
|
160 |
-
__( 'Two-Factor Login Verification', 'wp-simple-firewall' ),
|
161 |
-
$aMessage
|
162 |
-
);
|
163 |
-
|
164 |
-
$this->getCon()->fireEvent(
|
165 |
-
$bResult ? '2fa_email_send_success' : '2fa_email_send_fail',
|
166 |
-
[
|
167 |
-
'audit' => [
|
168 |
-
'user_login' => $oUser->user_login,
|
169 |
-
]
|
170 |
-
]
|
171 |
-
);
|
172 |
-
return $this;
|
173 |
-
}
|
174 |
-
|
175 |
-
/**
|
176 |
-
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
177 |
-
* functions. Otherwise we need to be careful of mixing up users.
|
178 |
-
* @param WP_User $oUser
|
179 |
-
*/
|
180 |
-
public function addOptionsToUserProfile( $oUser ) {
|
181 |
-
$oWp = Services::WpUsers();
|
182 |
-
$bValidatedProfile = $this->hasValidatedProfile( $oUser );
|
183 |
-
$aData = [
|
184 |
-
'user_has_email_authentication_active' => $bValidatedProfile,
|
185 |
-
'user_has_email_authentication_enforced' => $this->isSubjectToEmailAuthentication( $oUser ),
|
186 |
-
'is_my_user_profile' => ( $oUser->ID == $oWp->getCurrentWpUserId() ),
|
187 |
-
'i_am_valid_admin' => $this->getCon()->isPluginAdmin(),
|
188 |
-
'user_to_edit_is_admin' => $oWp->isUserAdmin( $oUser ),
|
189 |
-
'strings' => [
|
190 |
-
'label_email_authentication' => __( 'Email Authentication', 'wp-simple-firewall' ),
|
191 |
-
'title' => __( 'Email Authentication', 'wp-simple-firewall' ),
|
192 |
-
'description_email_authentication_checkbox' => __( 'Check the box to enable email-based login authentication.', 'wp-simple-firewall' ),
|
193 |
-
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $this->getCon()
|
194 |
-
->getHumanName() )
|
195 |
-
]
|
196 |
-
];
|
197 |
-
|
198 |
-
$aData[ 'bools' ] = [
|
199 |
-
'checked' => $bValidatedProfile || $aData[ 'user_has_email_authentication_enforced' ],
|
200 |
-
'disabled' => true || $aData[ 'user_has_email_authentication_enforced' ]
|
201 |
-
//TODO: Make email authentication a per-user setting
|
202 |
-
];
|
203 |
-
|
204 |
-
echo $this->getMod()->renderTemplate( 'snippets/user_profile_emailauthentication.php', $aData );
|
205 |
-
}
|
206 |
-
|
207 |
/**
|
208 |
* @return string
|
209 |
*/
|
2 |
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
|
5 |
+
/**
|
6 |
+
* @deprecated 8.6.0
|
7 |
+
*/
|
8 |
class ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth extends ICWP_WPSF_Processor_LoginProtect_IntentProviderBase {
|
9 |
|
10 |
/**
|
24 |
$oUpd->setLoginIntentCodeEmail( $oMod->getSession(), $this->getSecret( $oUser ) );
|
25 |
|
26 |
// Now send email with authentication link for user.
|
27 |
+
$this->setLoginCaptured();
|
|
|
28 |
}
|
29 |
return $oUser;
|
30 |
}
|
133 |
return !empty( $sHash );
|
134 |
}
|
135 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
/**
|
137 |
* @return string
|
138 |
*/
|
src/processors/loginprotect_intentprovider_ga.php
CHANGED
@@ -3,6 +3,9 @@
|
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
use Dolondro\GoogleAuthenticator;
|
5 |
|
|
|
|
|
|
|
6 |
class ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator extends ICWP_WPSF_Processor_LoginProtect_IntentProviderBase {
|
7 |
|
8 |
/**
|
@@ -19,54 +22,6 @@ class ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator extends ICWP_WPSF_Pro
|
|
19 |
}
|
20 |
}
|
21 |
|
22 |
-
/**
|
23 |
-
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
24 |
-
* functions. Otherwise we need to be careful of mixing up users.
|
25 |
-
* @param WP_User $oUser
|
26 |
-
*/
|
27 |
-
public function addOptionsToUserProfile( $oUser ) {
|
28 |
-
$oCon = $this->getCon();
|
29 |
-
|
30 |
-
$bValidatedProfile = $this->hasValidatedProfile( $oUser );
|
31 |
-
|
32 |
-
if ( !$bValidatedProfile ) {
|
33 |
-
$this->resetSecret( $oUser );
|
34 |
-
}
|
35 |
-
|
36 |
-
$aData = [
|
37 |
-
'has_validated_profile' => $bValidatedProfile,
|
38 |
-
'user_google_authenticator_secret' => $this->getSecret( $oUser ),
|
39 |
-
'is_my_user_profile' => ( $oUser->ID == Services::WpUsers()->getCurrentWpUserId() ),
|
40 |
-
'i_am_valid_admin' => $oCon->isPluginAdmin(),
|
41 |
-
'user_to_edit_is_admin' => Services::WpUsers()->isUserAdmin( $oUser ),
|
42 |
-
'strings' => [
|
43 |
-
'description_otp_code' => __( 'Provide the current code generated by your Google Authenticator app.', 'wp-simple-firewall' ),
|
44 |
-
'description_otp_code_ext' => __( 'To reset this QR Code enter fake data here.', 'wp-simple-firewall' ),
|
45 |
-
'description_chart_url' => __( 'Use your Google Authenticator app to scan this QR code and enter the one time password below.', 'wp-simple-firewall' ),
|
46 |
-
'description_ga_secret' => __( 'If you have a problem with scanning the QR code enter this code manually into the app.', 'wp-simple-firewall' ),
|
47 |
-
'desc_remove' => __( 'Check the box to remove Google Authenticator login authentication.', 'wp-simple-firewall' ),
|
48 |
-
'label_check_to_remove' => sprintf( __( 'Remove %s', 'wp-simple-firewall' ), __( 'Google Authenticator', 'wp-simple-firewall' ) ),
|
49 |
-
'label_enter_code' => __( 'Google Authenticator Code', 'wp-simple-firewall' ),
|
50 |
-
'label_ga_secret' => __( 'Manual Code', 'wp-simple-firewall' ),
|
51 |
-
'label_scan_qr_code' => __( 'Scan This QR Code', 'wp-simple-firewall' ),
|
52 |
-
'title' => __( 'Google Authenticator', 'wp-simple-firewall' ),
|
53 |
-
'cant_add_other_user' => sprintf( __( "Sorry, %s may not be added to another user's account.", 'wp-simple-firewall' ), 'Google Authenticator' ),
|
54 |
-
'cant_remove_admins' => sprintf( __( "Sorry, %s may only be removed from another user's account by a Security Administrator.", 'wp-simple-firewall' ), __( 'Google Authenticator', 'wp-simple-firewall' ) ),
|
55 |
-
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $oCon->getHumanName() ),
|
56 |
-
'remove_more_info' => sprintf( __( 'Understand how to remove Google Authenticator', 'wp-simple-firewall' ) )
|
57 |
-
],
|
58 |
-
'data' => [
|
59 |
-
'otp_field_name' => $this->getLoginFormParameter()
|
60 |
-
]
|
61 |
-
];
|
62 |
-
|
63 |
-
if ( !$bValidatedProfile ) {
|
64 |
-
$aData[ 'chart_url' ] = $this->getGaRegisterChartUrl( $oUser );
|
65 |
-
}
|
66 |
-
|
67 |
-
echo $this->getMod()->renderTemplate( 'snippets/user_profile_googleauthenticator.php', $aData );
|
68 |
-
}
|
69 |
-
|
70 |
/**
|
71 |
* @param \WP_User $oUser
|
72 |
* @return string
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
use Dolondro\GoogleAuthenticator;
|
5 |
|
6 |
+
/**
|
7 |
+
* @deprecated 8.6.0
|
8 |
+
*/
|
9 |
class ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator extends ICWP_WPSF_Processor_LoginProtect_IntentProviderBase {
|
10 |
|
11 |
/**
|
22 |
}
|
23 |
}
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
/**
|
26 |
* @param \WP_User $oUser
|
27 |
* @return string
|
src/processors/loginprotect_intentprovider_yubikey.php
CHANGED
@@ -2,6 +2,9 @@
|
|
2 |
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
|
|
|
|
|
|
|
5 |
class ICWP_WPSF_Processor_LoginProtect_Yubikey extends ICWP_WPSF_Processor_LoginProtect_IntentProviderBase {
|
6 |
|
7 |
const OTP_LENGTH = 12;
|
@@ -10,49 +13,6 @@ class ICWP_WPSF_Processor_LoginProtect_Yubikey extends ICWP_WPSF_Processor_Login
|
|
10 |
*/
|
11 |
const URL_YUBIKEY_VERIFY = 'https://api.yubico.com/wsapi/2.0/verify';
|
12 |
|
13 |
-
/**
|
14 |
-
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
15 |
-
* functions. Otherwise we need to be careful of mixing up users.
|
16 |
-
* @param WP_User $oUser
|
17 |
-
*/
|
18 |
-
public function addOptionsToUserProfile( $oUser ) {
|
19 |
-
$oCon = $this->getCon();
|
20 |
-
$oWpUsers = Services::WpUsers();
|
21 |
-
|
22 |
-
$bValidatedProfile = $this->hasValidatedProfile( $oUser );
|
23 |
-
$aData = [
|
24 |
-
'has_validated_profile' => $bValidatedProfile,
|
25 |
-
'is_my_user_profile' => ( $oUser->ID == $oWpUsers->getCurrentWpUserId() ),
|
26 |
-
'i_am_valid_admin' => $oCon->isPluginAdmin(),
|
27 |
-
'user_to_edit_is_admin' => $oWpUsers->isUserAdmin( $oUser ),
|
28 |
-
'strings' => [
|
29 |
-
'description_otp_code' => __( 'This is your unique Yubikey Device ID.', 'wp-simple-firewall' ),
|
30 |
-
'description_otp_code_ext' => '['.__( 'Pro Only', 'wp-simple-firewall' ).'] '
|
31 |
-
.__( 'Multiple Yubikey Device IDs are separated by a comma.', 'wp-simple-firewall' ),
|
32 |
-
'description_otp' => __( 'Provide a One Time Password from your Yubikey.', 'wp-simple-firewall' ),
|
33 |
-
'description_otp_ext' => $bValidatedProfile ?
|
34 |
-
__( 'This will remove the Yubikey Device ID from your profile.', 'wp-simple-firewall' )
|
35 |
-
: __( 'This will add the Yubikey Device ID to your profile.', 'wp-simple-firewall' ),
|
36 |
-
'description_otp_ext_2' => $bValidatedProfile ?
|
37 |
-
'['.__( 'Pro Only', 'wp-simple-firewall' ).'] '.__( 'If you provide a OTP from an alternative Yubikey device, it will also be added to your profile.', 'wp-simple-firewall' )
|
38 |
-
: '',
|
39 |
-
'label_enter_code' => __( 'Yubikey ID', 'wp-simple-firewall' ),
|
40 |
-
'label_enter_otp' => __( 'Yubikey OTP', 'wp-simple-firewall' ),
|
41 |
-
'title' => __( 'Yubikey Authentication', 'wp-simple-firewall' ),
|
42 |
-
'cant_add_other_user' => sprintf( __( "Sorry, %s may not be added to another user's account.", 'wp-simple-firewall' ), 'Yubikey' ),
|
43 |
-
'cant_remove_admins' => sprintf( __( "Sorry, %s may only be removed from another user's account by a Security Administrator.", 'wp-simple-firewall' ), __( 'Yubikey', 'wp-simple-firewall' ) ),
|
44 |
-
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $oCon->getHumanName() ),
|
45 |
-
'remove_more_info' => sprintf( __( 'Understand how to remove Google Authenticator', 'wp-simple-firewall' ) )
|
46 |
-
],
|
47 |
-
'data' => [
|
48 |
-
'otp_field_name' => $this->getLoginFormParameter(),
|
49 |
-
'secret' => str_replace( ',', ', ', $this->getSecret( $oUser ) ),
|
50 |
-
]
|
51 |
-
];
|
52 |
-
|
53 |
-
echo $this->getMod()->renderTemplate( 'snippets/user_profile_yubikey.php', $aData );
|
54 |
-
}
|
55 |
-
|
56 |
/**
|
57 |
* This MUST only ever be hooked into when the User is looking at their OWN profile,
|
58 |
* so we can use "current user" functions. Otherwise we need to be careful of mixing up users.
|
@@ -175,7 +135,7 @@ class ICWP_WPSF_Processor_LoginProtect_Yubikey extends ICWP_WPSF_Processor_Login
|
|
175 |
$aParts = [
|
176 |
'otp' => $sOTP,
|
177 |
'nonce' => md5( uniqid( rand() ) ),
|
178 |
-
'id' => $this->
|
179 |
];
|
180 |
|
181 |
$sReqUrl = add_query_arg( $aParts, self::URL_YUBIKEY_VERIFY );
|
2 |
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
|
5 |
+
/**
|
6 |
+
* @deprecated 8.6.0
|
7 |
+
*/
|
8 |
class ICWP_WPSF_Processor_LoginProtect_Yubikey extends ICWP_WPSF_Processor_LoginProtect_IntentProviderBase {
|
9 |
|
10 |
const OTP_LENGTH = 12;
|
13 |
*/
|
14 |
const URL_YUBIKEY_VERIFY = 'https://api.yubico.com/wsapi/2.0/verify';
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
/**
|
17 |
* This MUST only ever be hooked into when the User is looking at their OWN profile,
|
18 |
* so we can use "current user" functions. Otherwise we need to be careful of mixing up users.
|
135 |
$aParts = [
|
136 |
'otp' => $sOTP,
|
137 |
'nonce' => md5( uniqid( rand() ) ),
|
138 |
+
'id' => $this->getOptions()->getOpt( 'yubikey_app_id' )
|
139 |
];
|
140 |
|
141 |
$sReqUrl = add_query_arg( $aParts, self::URL_YUBIKEY_VERIFY );
|
src/processors/plugin.php
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
<?php
|
2 |
|
|
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
4 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
@@ -13,11 +14,14 @@ class ICWP_WPSF_Processor_Plugin extends Modules\BaseShield\ShieldProcessor {
|
|
13 |
/** @var Plugin\Options $oOpts */
|
14 |
$oOpts = $this->getOptions();
|
15 |
|
16 |
-
$this->getSubPro( 'crondaily' )->execute();
|
17 |
-
$this->getSubPro( 'cronhourly' )->execute();
|
18 |
-
|
19 |
$this->removePluginConflicts();
|
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
( new Plugin\Components\PluginBadge() )
|
22 |
->setMod( $this->getMod() )
|
23 |
->run();
|
@@ -81,12 +85,6 @@ class ICWP_WPSF_Processor_Plugin extends Modules\BaseShield\ShieldProcessor {
|
|
81 |
);
|
82 |
}
|
83 |
|
84 |
-
/**
|
85 |
-
* @deprecated 8.5.7
|
86 |
-
*/
|
87 |
-
public function gatherPluginWidgetContent() {
|
88 |
-
}
|
89 |
-
|
90 |
/**
|
91 |
* @return \ICWP_WPSF_Processor_Plugin_Tracking
|
92 |
*/
|
@@ -108,8 +106,6 @@ class ICWP_WPSF_Processor_Plugin extends Modules\BaseShield\ShieldProcessor {
|
|
108 |
return [
|
109 |
'importexport' => 'ICWP_WPSF_Processor_Plugin_ImportExport',
|
110 |
'tracking' => 'ICWP_WPSF_Processor_Plugin_Tracking',
|
111 |
-
'crondaily' => 'ICWP_WPSF_Processor_Plugin_CronDaily',
|
112 |
-
'cronhourly' => 'ICWP_WPSF_Processor_Plugin_CronHourly',
|
113 |
];
|
114 |
}
|
115 |
|
1 |
<?php
|
2 |
|
3 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
14 |
/** @var Plugin\Options $oOpts */
|
15 |
$oOpts = $this->getOptions();
|
16 |
|
|
|
|
|
|
|
17 |
$this->removePluginConflicts();
|
18 |
|
19 |
+
( new Shield\Crons\HourlyCron() )
|
20 |
+
->setMod( $this->getMod() )
|
21 |
+
->run();
|
22 |
+
( new Shield\Crons\DailyCron() )
|
23 |
+
->setMod( $this->getMod() )
|
24 |
+
->run();
|
25 |
( new Plugin\Components\PluginBadge() )
|
26 |
->setMod( $this->getMod() )
|
27 |
->run();
|
85 |
);
|
86 |
}
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
/**
|
89 |
* @return \ICWP_WPSF_Processor_Plugin_Tracking
|
90 |
*/
|
106 |
return [
|
107 |
'importexport' => 'ICWP_WPSF_Processor_Plugin_ImportExport',
|
108 |
'tracking' => 'ICWP_WPSF_Processor_Plugin_Tracking',
|
|
|
|
|
109 |
];
|
110 |
}
|
111 |
|
src/processors/plugin_importexport.php
CHANGED
@@ -84,24 +84,24 @@ class ICWP_WPSF_Processor_Plugin_ImportExport extends Shield\Modules\BaseShield\
|
|
84 |
* @return string
|
85 |
*/
|
86 |
private function createExportFileDownloadLink() {
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
}
|
92 |
|
93 |
public function runWhitelistNotify() {
|
94 |
-
/** @var ICWP_WPSF_FeatureHandler_Plugin $
|
95 |
-
$
|
96 |
$oHttpReq = Services::HttpRequest();
|
97 |
|
98 |
-
if ( $
|
99 |
|
100 |
$aQuery = [
|
101 |
'blocking' => false,
|
102 |
'body' => [ 'shield_action' => 'importexport_updatenotified' ]
|
103 |
];
|
104 |
-
foreach ( $
|
105 |
$oHttpReq->get( $sUrl, $aQuery );
|
106 |
}
|
107 |
|
84 |
* @return string
|
85 |
*/
|
86 |
private function createExportFileDownloadLink() {
|
87 |
+
return add_query_arg(
|
88 |
+
$this->getMod()->getNonceActionData( 'export_file_download' ),
|
89 |
+
$this->getMod()->getUrl_AdminPage()
|
90 |
+
);
|
91 |
}
|
92 |
|
93 |
public function runWhitelistNotify() {
|
94 |
+
/** @var ICWP_WPSF_FeatureHandler_Plugin $oMod */
|
95 |
+
$oMod = $this->getMod();
|
96 |
$oHttpReq = Services::HttpRequest();
|
97 |
|
98 |
+
if ( $oMod->hasImportExportWhitelistSites() ) {
|
99 |
|
100 |
$aQuery = [
|
101 |
'blocking' => false,
|
102 |
'body' => [ 'shield_action' => 'importexport_updatenotified' ]
|
103 |
];
|
104 |
+
foreach ( $oMod->getImportExportWhitelist() as $sUrl ) {
|
105 |
$oHttpReq->get( $sUrl, $aQuery );
|
106 |
}
|
107 |
|
src/processors/sessions.php
CHANGED
@@ -187,13 +187,4 @@ class ICWP_WPSF_Processor_Sessions extends Modules\BaseShield\ShieldProcessor {
|
|
187 |
$oSel = $oMod->getDbHandler_Sessions()->getQuerySelector();
|
188 |
return $oSel->retrieveUserSession( $sSessionId, $sUsername );
|
189 |
}
|
190 |
-
|
191 |
-
/**
|
192 |
-
* @param int $nSessionId
|
193 |
-
* @return bool
|
194 |
-
* @deprecated 8.5
|
195 |
-
*/
|
196 |
-
public function terminateSession( $nSessionId ) {
|
197 |
-
return false;
|
198 |
-
}
|
199 |
}
|
187 |
$oSel = $oMod->getDbHandler_Sessions()->getQuerySelector();
|
188 |
return $oSel->retrieveUserSession( $sSessionId, $sUsername );
|
189 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
}
|
src/processors/user_management.php
CHANGED
@@ -42,6 +42,10 @@ class ICWP_WPSF_Processor_UserManagement extends Modules\BaseShield\ShieldProces
|
|
42 |
add_action( 'user_register', function ( $nUserId ) {
|
43 |
$this->getCon()->getUserMeta( Services::WpUsers()->getUserById( $nUserId ) );
|
44 |
} );
|
|
|
|
|
|
|
|
|
45 |
}
|
46 |
|
47 |
/**
|
@@ -254,30 +258,6 @@ class ICWP_WPSF_Processor_UserManagement extends Modules\BaseShield\ShieldProces
|
|
254 |
);
|
255 |
}
|
256 |
|
257 |
-
/**
|
258 |
-
* @return ICWP_WPSF_Processor_UserManagement_Passwords|mixed
|
259 |
-
* @deprecated 8.5.2
|
260 |
-
*/
|
261 |
-
protected function getProcessorPasswords() {
|
262 |
-
return $this->getSubPro( 'passwords' );
|
263 |
-
}
|
264 |
-
|
265 |
-
/**
|
266 |
-
* @return ICWP_WPSF_Processor_UserManagement_Sessions|mixed
|
267 |
-
* @deprecated 8.5.2
|
268 |
-
*/
|
269 |
-
public function getProcessorSessions() {
|
270 |
-
return $this->getSubPro( 'sessions' );
|
271 |
-
}
|
272 |
-
|
273 |
-
/**
|
274 |
-
* @return ICWP_WPSF_Processor_UserManagement_Suspend|mixed
|
275 |
-
* @deprecated 8.5.2
|
276 |
-
*/
|
277 |
-
protected function getProcessorSuspend() {
|
278 |
-
return $this->getSubPro( 'suspend' );
|
279 |
-
}
|
280 |
-
|
281 |
/**
|
282 |
* @return array
|
283 |
*/
|
42 |
add_action( 'user_register', function ( $nUserId ) {
|
43 |
$this->getCon()->getUserMeta( Services::WpUsers()->getUserById( $nUserId ) );
|
44 |
} );
|
45 |
+
|
46 |
+
( new UserManagement\Lib\Registration\EmailValidate() )
|
47 |
+
->setMod( $this->getMod() )
|
48 |
+
->run();
|
49 |
}
|
50 |
|
51 |
/**
|
258 |
);
|
259 |
}
|
260 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
261 |
/**
|
262 |
* @return array
|
263 |
*/
|
src/processors/usermanagement_sessions.php
CHANGED
@@ -181,22 +181,4 @@ class ICWP_WPSF_Processor_UserManagement_Sessions extends Modules\BaseShield\Shi
|
|
181 |
}
|
182 |
return $oError;
|
183 |
}
|
184 |
-
|
185 |
-
/**
|
186 |
-
* @deprecated 8.5
|
187 |
-
*/
|
188 |
-
public function cleanExpiredSessions() {
|
189 |
-
}
|
190 |
-
|
191 |
-
/**
|
192 |
-
* @deprecated 8.5
|
193 |
-
*/
|
194 |
-
private function getLoginIdleExpiredBoundary() {
|
195 |
-
}
|
196 |
-
|
197 |
-
/**
|
198 |
-
* @deprecated 8.5
|
199 |
-
*/
|
200 |
-
private function getLoginExpiredBoundary() {
|
201 |
-
}
|
202 |
}
|
181 |
}
|
182 |
return $oError;
|
183 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
}
|
src/wizards/login_protect.php
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
<?php
|
2 |
|
|
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
|
5 |
/**
|
@@ -99,8 +100,8 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
99 |
* @return \FernleafSystems\Utilities\Response
|
100 |
*/
|
101 |
private function processAuthGa() {
|
102 |
-
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $
|
103 |
-
$
|
104 |
$oReq = Services::Request();
|
105 |
|
106 |
$oResponse = new \FernleafSystems\Utilities\Response();
|
@@ -116,15 +117,14 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
116 |
$sMessage = __( 'Code was empty.', 'wp-simple-firewall' );
|
117 |
}
|
118 |
else {
|
|
|
|
|
|
|
119 |
$oUser = Services::WpUsers()->getCurrentWpUser();
|
120 |
-
|
121 |
-
$oProc = $oFO->getProcessor();
|
122 |
-
$oProcGa = $oProc->getSubProIntent()
|
123 |
-
->getProcessorGoogleAuthenticator();
|
124 |
-
$bValidated = $oProcGa->validateGaCode( $oUser, $sCode );
|
125 |
|
126 |
if ( $bValidated ) {
|
127 |
-
$
|
128 |
$sMessage = 'Google Authenticator was validated.';
|
129 |
$oResponse->setSuccessful( true );
|
130 |
}
|
@@ -139,7 +139,7 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
139 |
}
|
140 |
|
141 |
if ( $bEnableGa ) {
|
142 |
-
$
|
143 |
$sMessage .= ' '.__( 'Google Authenticator was enabled for the site.', 'wp-simple-firewall' );
|
144 |
}
|
145 |
|
@@ -188,7 +188,7 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
188 |
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $oFO */
|
189 |
$oFO = $this->getMod();
|
190 |
|
191 |
-
$aStepsSlugs =
|
192 |
|
193 |
if ( !$oFO->getIfCanSendEmailVerified() || !$oFO->isEmailAuthenticationActive() ) {
|
194 |
$aStepsSlugs[] = 'authemail';
|
@@ -208,50 +208,49 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
208 |
* @return array
|
209 |
*/
|
210 |
protected function getRenderData_SlideExtra( $sStep ) {
|
211 |
-
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $
|
212 |
-
$
|
213 |
|
214 |
-
$aAdditional =
|
215 |
|
216 |
switch ( $sStep ) {
|
217 |
|
218 |
case 'authemail':
|
219 |
$oUser = Services::WpUsers()->getCurrentWpUser();
|
220 |
-
$aAdditional =
|
221 |
-
'data' =>
|
222 |
'name' => $oUser->first_name,
|
223 |
'user_email' => $oUser->user_email
|
224 |
-
|
225 |
-
|
226 |
break;
|
227 |
|
228 |
case 'authga':
|
229 |
$oUser = Services::WpUsers()->getCurrentWpUser();
|
230 |
-
/** @var
|
231 |
-
$
|
232 |
-
|
233 |
-
|
234 |
-
$
|
235 |
-
|
236 |
-
'data' => array(
|
237 |
'name' => $oUser->first_name,
|
238 |
'user_email' => $oUser->user_email
|
239 |
-
|
240 |
-
'hrefs' =>
|
241 |
'ga_chart' => $sGaUrl,
|
242 |
-
|
243 |
-
'flags' =>
|
244 |
-
'has_ga' => $
|
245 |
-
|
246 |
-
|
247 |
break;
|
248 |
|
249 |
case 'multiselect':
|
250 |
-
$aAdditional =
|
251 |
-
'flags' =>
|
252 |
-
'has_multiselect' => $
|
253 |
-
|
254 |
-
|
255 |
break;
|
256 |
|
257 |
default:
|
1 |
<?php
|
2 |
|
3 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
/**
|
100 |
* @return \FernleafSystems\Utilities\Response
|
101 |
*/
|
102 |
private function processAuthGa() {
|
103 |
+
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
104 |
+
$oMod = $this->getMod();
|
105 |
$oReq = Services::Request();
|
106 |
|
107 |
$oResponse = new \FernleafSystems\Utilities\Response();
|
117 |
$sMessage = __( 'Code was empty.', 'wp-simple-firewall' );
|
118 |
}
|
119 |
else {
|
120 |
+
/** @var TwoFactor\Provider\GoogleAuth $oGA */
|
121 |
+
$oGA = $oMod->getLoginIntentController()
|
122 |
+
->getProviders()[ TwoFactor\Provider\GoogleAuth::SLUG ];
|
123 |
$oUser = Services::WpUsers()->getCurrentWpUser();
|
124 |
+
$bValidated = $oGA->validateGaCode( $oUser, $sCode );
|
|
|
|
|
|
|
|
|
125 |
|
126 |
if ( $bValidated ) {
|
127 |
+
$oGA->setProfileValidated( $oUser, true );
|
128 |
$sMessage = 'Google Authenticator was validated.';
|
129 |
$oResponse->setSuccessful( true );
|
130 |
}
|
139 |
}
|
140 |
|
141 |
if ( $bEnableGa ) {
|
142 |
+
$oMod->setEnabled2FaGoogleAuthenticator( true );
|
143 |
$sMessage .= ' '.__( 'Google Authenticator was enabled for the site.', 'wp-simple-firewall' );
|
144 |
}
|
145 |
|
188 |
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $oFO */
|
189 |
$oFO = $this->getMod();
|
190 |
|
191 |
+
$aStepsSlugs = [ 'start' ];
|
192 |
|
193 |
if ( !$oFO->getIfCanSendEmailVerified() || !$oFO->isEmailAuthenticationActive() ) {
|
194 |
$aStepsSlugs[] = 'authemail';
|
208 |
* @return array
|
209 |
*/
|
210 |
protected function getRenderData_SlideExtra( $sStep ) {
|
211 |
+
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
212 |
+
$oMod = $this->getMod();
|
213 |
|
214 |
+
$aAdditional = [];
|
215 |
|
216 |
switch ( $sStep ) {
|
217 |
|
218 |
case 'authemail':
|
219 |
$oUser = Services::WpUsers()->getCurrentWpUser();
|
220 |
+
$aAdditional = [
|
221 |
+
'data' => [
|
222 |
'name' => $oUser->first_name,
|
223 |
'user_email' => $oUser->user_email
|
224 |
+
]
|
225 |
+
];
|
226 |
break;
|
227 |
|
228 |
case 'authga':
|
229 |
$oUser = Services::WpUsers()->getCurrentWpUser();
|
230 |
+
/** @var TwoFactor\Provider\GoogleAuth $oGA */
|
231 |
+
$oGA = $oMod->getLoginIntentController()
|
232 |
+
->getProviders()[ TwoFactor\Provider\GoogleAuth::SLUG ];
|
233 |
+
$sGaUrl = $oGA->getGaRegisterChartUrl( $oUser );
|
234 |
+
$aAdditional = [
|
235 |
+
'data' => [
|
|
|
236 |
'name' => $oUser->first_name,
|
237 |
'user_email' => $oUser->user_email
|
238 |
+
],
|
239 |
+
'hrefs' => [
|
240 |
'ga_chart' => $sGaUrl,
|
241 |
+
],
|
242 |
+
'flags' => [
|
243 |
+
'has_ga' => $oGA->hasValidatedProfile( $oUser ),
|
244 |
+
]
|
245 |
+
];
|
246 |
break;
|
247 |
|
248 |
case 'multiselect':
|
249 |
+
$aAdditional = [
|
250 |
+
'flags' => [
|
251 |
+
'has_multiselect' => $oMod->isChainedAuth(),
|
252 |
+
]
|
253 |
+
];
|
254 |
break;
|
255 |
|
256 |
default:
|
src/wizards/plugin.php
CHANGED
@@ -371,7 +371,8 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
371 |
/** @var \ICWP_WPSF_FeatureHandler_License $oModule */
|
372 |
$oModule = $this->getCon()->getModule( 'license' );
|
373 |
try {
|
374 |
-
$bSuccess = $oModule->
|
|
|
375 |
->hasValidWorkingLicense();
|
376 |
if ( $bSuccess ) {
|
377 |
$sMessage = __( 'License was found and successfully installed.', 'wp-simple-firewall' );
|
371 |
/** @var \ICWP_WPSF_FeatureHandler_License $oModule */
|
372 |
$oModule = $this->getCon()->getModule( 'license' );
|
373 |
try {
|
374 |
+
$bSuccess = $oModule->getLicenseHandler()
|
375 |
+
->verify( true )
|
376 |
->hasValidWorkingLicense();
|
377 |
if ( $bSuccess ) {
|
378 |
$sMessage = __( 'License was found and successfully installed.', 'wp-simple-firewall' );
|
templates/php/snippets/user_profile_backupcode.php
DELETED
@@ -1,47 +0,0 @@
|
|
1 |
-
<div id="shield-options-backupcode" class="shield-user-options-block">
|
2 |
-
<h3><?php echo $strings[ 'title' ]; ?>
|
3 |
-
<small>(<?php echo $strings[ 'provided_by' ]; ?>)</small>
|
4 |
-
</h3>
|
5 |
-
<table class="form-table">
|
6 |
-
<tbody>
|
7 |
-
|
8 |
-
<?php if ( $is_my_user_profile ) : ?>
|
9 |
-
<tr>
|
10 |
-
<th>
|
11 |
-
<label>
|
12 |
-
<?php echo $strings[ 'label_enter_code' ]; ?>
|
13 |
-
</label>
|
14 |
-
</th>
|
15 |
-
<td>
|
16 |
-
<?php if ( !$has_mfa ) : ?>
|
17 |
-
<?php echo $strings[ 'not_available' ]; ?>
|
18 |
-
<?php else : ?>
|
19 |
-
<a href="#" id="IcwpWpsfGenBackupLoginCode"
|
20 |
-
class="button button-primary">
|
21 |
-
<?php echo $strings[ 'button_gen_code' ]; ?>
|
22 |
-
</a>
|
23 |
-
<?php if ( $has_validated_profile ) : ?>
|
24 |
-
<a href="#" id="IcwpWpsfDelBackupLoginCode"
|
25 |
-
class="button">
|
26 |
-
<?php echo $strings[ 'button_del_code' ]; ?>
|
27 |
-
</a>
|
28 |
-
<?php endif; ?>
|
29 |
-
<p class="description">
|
30 |
-
<?php echo $strings[ 'description_code' ]; ?>
|
31 |
-
<br/><strong><?php echo $strings[ 'description_code_ext1' ]; ?></strong>
|
32 |
-
<?php if ( $has_validated_profile ) : ?>
|
33 |
-
<br /><?php echo $strings[ 'description_code_ext2' ]; ?>
|
34 |
-
<?php endif; ?>
|
35 |
-
</p>
|
36 |
-
<?php endif; ?>
|
37 |
-
</td>
|
38 |
-
</tr>
|
39 |
-
<?php else : ?>
|
40 |
-
<td>
|
41 |
-
<p class="description"><?php echo $strings[ 'cant_add_other_user' ]; ?></p>
|
42 |
-
</td>
|
43 |
-
<?php endif; ?>
|
44 |
-
|
45 |
-
</tbody>
|
46 |
-
</table>
|
47 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/php/snippets/user_profile_emailauthentication.php
DELETED
@@ -1,29 +0,0 @@
|
|
1 |
-
<div id="shield-options-email-authentication" class="shield-user-options-block">
|
2 |
-
<h3><?php echo $strings['title']; ?>
|
3 |
-
<small>(<?php echo $strings['provided_by']; ?>)</small>
|
4 |
-
</h3>
|
5 |
-
|
6 |
-
<table class="form-table">
|
7 |
-
<tbody>
|
8 |
-
|
9 |
-
<tr>
|
10 |
-
<th><label for="shield_email_authentication"><?php echo $strings['label_email_authentication']; ?></label></th>
|
11 |
-
<td>
|
12 |
-
<input
|
13 |
-
type="checkbox"
|
14 |
-
name="shield_email_authentication" id="shield_email_authentication"
|
15 |
-
value="Y"
|
16 |
-
<?php if ( $bools['checked'] ) : ?>
|
17 |
-
checked="checked"
|
18 |
-
<?php endif; ?>
|
19 |
-
<?php if ( $bools['disabled'] ) : ?>
|
20 |
-
disabled="disabled"
|
21 |
-
<?php endif; ?>
|
22 |
-
/>
|
23 |
-
<p class="description"><?php echo $strings['description_email_authentication_checkbox']; ?></p>
|
24 |
-
</td>
|
25 |
-
</tr>
|
26 |
-
|
27 |
-
</tbody>
|
28 |
-
</table>
|
29 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/php/snippets/user_profile_googleauthenticator.php
DELETED
@@ -1,89 +0,0 @@
|
|
1 |
-
<style type="text/css">
|
2 |
-
#shield_ga_secret {
|
3 |
-
letter-spacing: 5px;
|
4 |
-
font-family: monospace;
|
5 |
-
font-size: 24px;
|
6 |
-
text-shadow: 1px 1px 0 rgba(0,0,0,0.4);
|
7 |
-
border: 1px solid rgba(0,0,0,0.1);
|
8 |
-
padding: 0 7px;
|
9 |
-
background-color: whitesmoke;
|
10 |
-
}
|
11 |
-
</style>
|
12 |
-
<div id="shield-options-google-authenticator" class="shield-user-options-block">
|
13 |
-
<h3><?php echo $strings['title']; ?>
|
14 |
-
<small>(<?php echo $strings['provided_by']; ?>)</small>
|
15 |
-
</h3>
|
16 |
-
<table class="form-table">
|
17 |
-
<tbody>
|
18 |
-
|
19 |
-
<?php if ( $has_validated_profile ) : ?>
|
20 |
-
|
21 |
-
<?php if ( $is_my_user_profile || $i_am_valid_admin ) : ?>
|
22 |
-
<tr>
|
23 |
-
<th><label for="shield_turn_off_google_authenticator"><?php echo $strings['label_check_to_remove']; ?></label></th>
|
24 |
-
<td>
|
25 |
-
<input type="checkbox" name="shield_turn_off_google_authenticator" id="shield_turn_off_google_authenticator" value="Y" />
|
26 |
-
<p class="description">
|
27 |
-
<?php echo $strings['desc_remove']; ?>
|
28 |
-
</p>
|
29 |
-
</td>
|
30 |
-
</tr>
|
31 |
-
<tr>
|
32 |
-
<th><label for="<?php echo $data['otp_field_name']; ?>"><?php echo $strings['label_enter_code']; ?></label></th>
|
33 |
-
<td>
|
34 |
-
<input class="regular-text"
|
35 |
-
type="text"
|
36 |
-
id="<?php echo $data['otp_field_name']; ?>"
|
37 |
-
name="<?php echo $data['otp_field_name']; ?>"
|
38 |
-
value="" autocomplete="off" />
|
39 |
-
<p class="description"><?php echo $strings['description_otp_code']; ?></p>
|
40 |
-
</td>
|
41 |
-
</tr>
|
42 |
-
<?php else : ?>
|
43 |
-
<td>
|
44 |
-
<p class="description"><?php echo $strings['cant_remove_admins']; ?></p>
|
45 |
-
</td>
|
46 |
-
<?php endif; ?>
|
47 |
-
|
48 |
-
<?php else : ?>
|
49 |
-
|
50 |
-
<?php if ( $is_my_user_profile ) : ?>
|
51 |
-
<tr>
|
52 |
-
<th><?php echo $strings['label_scan_qr_code']; ?></th>
|
53 |
-
<td>
|
54 |
-
<img src="<?php echo $chart_url; ?>" />
|
55 |
-
<p class="description"><?php echo $strings['description_chart_url']; ?></p>
|
56 |
-
</td>
|
57 |
-
</tr>
|
58 |
-
<tr>
|
59 |
-
<th><label for="shield_ga_secret"><?php echo $strings['label_ga_secret']; ?></label></th>
|
60 |
-
<td>
|
61 |
-
<span id="shield_ga_secret"><?php echo $user_google_authenticator_secret; ?></span>
|
62 |
-
<p class="description"><?php echo $strings['description_ga_secret']; ?></p>
|
63 |
-
</td>
|
64 |
-
</tr>
|
65 |
-
<tr>
|
66 |
-
<th><label for="<?php echo $data['otp_field_name']; ?>"><?php echo $strings['label_enter_code']; ?></label></th>
|
67 |
-
<td>
|
68 |
-
<input class="regular-text"
|
69 |
-
type="text"
|
70 |
-
id="<?php echo $data['otp_field_name']; ?>"
|
71 |
-
name="<?php echo $data['otp_field_name']; ?>"
|
72 |
-
value="" autocomplete="off" />
|
73 |
-
<p class="description">
|
74 |
-
<?php echo $strings['description_otp_code']; ?>
|
75 |
-
<br/><?php echo $strings['description_otp_code_ext']; ?>
|
76 |
-
</p>
|
77 |
-
</td>
|
78 |
-
</tr>
|
79 |
-
<?php else : ?>
|
80 |
-
<td>
|
81 |
-
<p class="description"><?php echo $strings['cant_add_other_user']; ?></p>
|
82 |
-
</td>
|
83 |
-
<?php endif; ?>
|
84 |
-
|
85 |
-
<?php endif; ?>
|
86 |
-
|
87 |
-
</tbody>
|
88 |
-
</table>
|
89 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/php/snippets/user_profile_yubikey.php
DELETED
@@ -1,81 +0,0 @@
|
|
1 |
-
<style type="text/css">
|
2 |
-
#shield_ga_secret {
|
3 |
-
letter-spacing: 5px;
|
4 |
-
font-family: monospace;
|
5 |
-
font-size: 24px;
|
6 |
-
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.4);
|
7 |
-
border: 1px solid rgba(0, 0, 0, 0.1);
|
8 |
-
padding: 0 7px;
|
9 |
-
background-color: whitesmoke;
|
10 |
-
}
|
11 |
-
</style>
|
12 |
-
<div id="shield-options-google-authenticator" class="shield-user-options-block">
|
13 |
-
<h3><?php echo $strings[ 'title' ]; ?>
|
14 |
-
<small>(<?php echo $strings[ 'provided_by' ]; ?>)</small>
|
15 |
-
</h3>
|
16 |
-
<table class="form-table">
|
17 |
-
<tbody>
|
18 |
-
|
19 |
-
<?php if ( $has_validated_profile ) : ?>
|
20 |
-
|
21 |
-
<?php if ( $is_my_user_profile || $i_am_valid_admin ) : ?>
|
22 |
-
<tr>
|
23 |
-
<th><label for="yubi_code"><?php echo $strings[ 'label_enter_code' ]; ?></label></th>
|
24 |
-
<td>
|
25 |
-
<input class="regular-text" name="yubi_code" id="yubi_code"
|
26 |
-
type="text" value="<?php echo $data[ 'secret' ]; ?>" readonly />
|
27 |
-
<p class="description">
|
28 |
-
<?php echo $strings[ 'description_otp_code' ]; ?>
|
29 |
-
<br /><?php echo $strings[ 'description_otp_code_ext' ]; ?>
|
30 |
-
</p>
|
31 |
-
</td>
|
32 |
-
</tr>
|
33 |
-
|
34 |
-
<tr>
|
35 |
-
<th><label for="<?php echo $data[ 'otp_field_name' ]; ?>"><?php echo $strings[ 'label_enter_otp' ]; ?></label></th>
|
36 |
-
<td>
|
37 |
-
<input class="regular-text"
|
38 |
-
type="text"
|
39 |
-
id="<?php echo $data[ 'otp_field_name' ]; ?>"
|
40 |
-
name="<?php echo $data[ 'otp_field_name' ]; ?>"
|
41 |
-
value="" autocomplete="off" />
|
42 |
-
<p class="description"><?php echo $strings[ 'description_otp' ]; ?>
|
43 |
-
<br /><?php echo $strings[ 'description_otp_ext' ]; ?>
|
44 |
-
<br /><?php echo $strings[ 'description_otp_ext_2' ]; ?>
|
45 |
-
</p>
|
46 |
-
</td>
|
47 |
-
</tr>
|
48 |
-
<?php else : ?>
|
49 |
-
<td>
|
50 |
-
<p class="description"><?php echo $strings[ 'cant_remove_admins' ]; ?></p>
|
51 |
-
</td>
|
52 |
-
<?php endif; ?>
|
53 |
-
|
54 |
-
<?php else : ?>
|
55 |
-
|
56 |
-
<?php if ( $is_my_user_profile ) : ?>
|
57 |
-
<tr>
|
58 |
-
<th><label for="<?php echo $data[ 'otp_field_name' ]; ?>"><?php echo $strings[ 'label_enter_otp' ]; ?></label></th>
|
59 |
-
<td>
|
60 |
-
<input class="regular-text"
|
61 |
-
type="text"
|
62 |
-
id="<?php echo $data[ 'otp_field_name' ]; ?>"
|
63 |
-
name="<?php echo $data[ 'otp_field_name' ]; ?>"
|
64 |
-
value="" autocomplete="off" />
|
65 |
-
<p class="description">
|
66 |
-
<?php echo $strings[ 'description_otp' ]; ?>
|
67 |
-
<br /><?php echo $strings[ 'description_otp_ext' ]; ?>
|
68 |
-
</p>
|
69 |
-
</td>
|
70 |
-
</tr>
|
71 |
-
<?php else : ?>
|
72 |
-
<td>
|
73 |
-
<p class="description"><?php echo $strings[ 'cant_add_other_user' ]; ?></p>
|
74 |
-
</td>
|
75 |
-
<?php endif; ?>
|
76 |
-
|
77 |
-
<?php endif; ?>
|
78 |
-
|
79 |
-
</tbody>
|
80 |
-
</table>
|
81 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/notices/wphashes-token-fail.twig
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% extends "/notices/base-error.twig" %}
|
2 |
+
|
3 |
+
{% block notice_body %}
|
4 |
+
{% for msg in strings.messages %}
|
5 |
+
<p>{{ msg }}</p>
|
6 |
+
{% endfor %}
|
7 |
+
{% endblock %}
|
templates/twig/pages/login_intent/index.twig
CHANGED
@@ -6,21 +6,10 @@
|
|
6 |
body {
|
7 |
background: #ffffff;
|
8 |
}
|
9 |
-
.message {
|
10 |
-
padding: 15px;
|
11 |
-
margin-bottom: 30px;
|
12 |
-
}
|
13 |
-
.submit.form-group {
|
14 |
-
margin-top: 25px;
|
15 |
-
}
|
16 |
.input-group-addon a {
|
17 |
font-weight: bold;
|
18 |
display: block;
|
19 |
}
|
20 |
-
a.input-help {
|
21 |
-
display: inline-block;
|
22 |
-
padding: 0 0.5rem;
|
23 |
-
}
|
24 |
#countdown {
|
25 |
font-weight: bolder;
|
26 |
}
|
@@ -32,51 +21,9 @@
|
|
32 |
margin: 30px 0;
|
33 |
text-decoration: underline;
|
34 |
}
|
35 |
-
#skip_mfa {
|
36 |
-
margin: 10px 10px 5px 20px;
|
37 |
-
}
|
38 |
</style>
|
39 |
{% endblock %}
|
40 |
|
41 |
-
{% block head_inline_scripts %}
|
42 |
-
|
43 |
-
<script type="text/javascript">
|
44 |
-
// Set the date we're counting down to
|
45 |
-
var timeRemaining = {{ data.time_remaining }};
|
46 |
-
// Update the count down every 1 second
|
47 |
-
var x = setInterval( function () {
|
48 |
-
timeRemaining -= 1;
|
49 |
-
var timeRemainingText = '';
|
50 |
-
if ( timeRemaining < 0 ) {
|
51 |
-
timeRemainingText = '{{ strings.login_expired }}';
|
52 |
-
clearInterval( x );
|
53 |
-
loginExpired();
|
54 |
-
}
|
55 |
-
else {
|
56 |
-
var minutes = Math.floor( timeRemaining / 60 );
|
57 |
-
var seconds = Math.floor( timeRemaining % 60 );
|
58 |
-
if ( minutes > 0 ) {
|
59 |
-
timeRemainingText = minutes + " minutes and " + seconds
|
60 |
-
+ " {{ strings.seconds }}";
|
61 |
-
}
|
62 |
-
else {
|
63 |
-
timeRemainingText = timeRemaining.toFixed( 0 )
|
64 |
-
+ " {{ strings.seconds }}";
|
65 |
-
}
|
66 |
-
}
|
67 |
-
document.getElementById( "countdown" ).innerHTML = timeRemainingText;
|
68 |
-
},
|
69 |
-
1000
|
70 |
-
);
|
71 |
-
|
72 |
-
function loginExpired() {
|
73 |
-
document.getElementById( "mainSubmit" ).setAttribute( 'disabled', 'disabled' );
|
74 |
-
document.getElementById( "TimeRemaining" ).className = "text-center alert alert-danger";
|
75 |
-
}
|
76 |
-
</script>
|
77 |
-
{% endblock %}
|
78 |
-
|
79 |
-
|
80 |
{% block body_content_header %}
|
81 |
<div class="row">
|
82 |
<div class="col-8 offset-2 col-md-6 offset-md-3 text-center">
|
@@ -88,80 +35,7 @@
|
|
88 |
|
89 |
<div class="row">
|
90 |
<div class="col-12 col-md-8 offset-md-2 col-lg-6 offset-lg-3">
|
91 |
-
|
92 |
-
<div class="alert alert-{{ data.message_type }}" role="alert">{{ strings.message }}</div>
|
93 |
-
|
94 |
-
<form action="{{ hrefs.form_action }}" method="post" class="form-horizontal">
|
95 |
-
<input type="hidden" name="{{ data.login_intent_flag }}" value="1" />
|
96 |
-
{% if not hrefs.redirect_to is empty %}
|
97 |
-
<input type="hidden" name="redirect_to" value="{{ hrefs.redirect_to }}" />
|
98 |
-
{% endif %}
|
99 |
-
{% if not hrefs.redirect_to is empty %}
|
100 |
-
<input type="hidden" name="cancel_href" value="{{ hrefs.cancel_href }}" />
|
101 |
-
{% endif %}
|
102 |
-
|
103 |
-
{% for key_field, aField in data.login_fields %}
|
104 |
-
<div class="form-row">
|
105 |
-
<div class="form-group col">
|
106 |
-
<label for="{{ aField.name }}">{{ aField.text }}</label>
|
107 |
-
<div class="input-group">
|
108 |
-
<input type="{{ aField.type }}"
|
109 |
-
name="{{ aField.name }}"
|
110 |
-
value="{{ aField.value }}"
|
111 |
-
class="form-control"
|
112 |
-
id="{{ aField.name }}"
|
113 |
-
placeholder="{{ aField.placeholder }}"
|
114 |
-
autocomplete="off"
|
115 |
-
{% if key_field == 0 %}autofocus{% endif %}
|
116 |
-
/>
|
117 |
-
|
118 |
-
{% if flags.show_branded_links %}
|
119 |
-
<div class="input-group-append">
|
120 |
-
<div class="input-group-text">
|
121 |
-
<a href="{{ aField.help_link }}"
|
122 |
-
target="_blank" class="input-help">?</a>
|
123 |
-
</div>
|
124 |
-
</div>
|
125 |
-
{% endif %}
|
126 |
-
</div>
|
127 |
-
</div>
|
128 |
-
</div>
|
129 |
-
|
130 |
-
{% endfor %}
|
131 |
-
|
132 |
-
{% if flags.can_skip_mfa %}
|
133 |
-
<div class="form-row">
|
134 |
-
<div class="form-group mb-0">
|
135 |
-
<div class="input-group">
|
136 |
-
<label for="skip_mfa">
|
137 |
-
<input type="checkbox" value="Y" name="skip_mfa" id="skip_mfa">
|
138 |
-
{{ strings.skip_mfa }}
|
139 |
-
</label>
|
140 |
-
</div>
|
141 |
-
</div>
|
142 |
-
</div>
|
143 |
-
{% endif %}
|
144 |
-
|
145 |
-
<div class="form-group row submit">
|
146 |
-
<div class="col-6 order-2 text-right">
|
147 |
-
<button type="submit" id="mainSubmit" class="pull-right btn btn-success">
|
148 |
-
{{ strings.verify_my_login }}</button>
|
149 |
-
</div>
|
150 |
-
<div class="col-6 order-1 text-left">
|
151 |
-
<button class="btn btn-outline-danger" name="cancel" value="1">
|
152 |
-
← {{ strings.cancel }}</button>
|
153 |
-
</div>
|
154 |
-
</div>
|
155 |
-
</form>
|
156 |
-
|
157 |
-
<div class="row">
|
158 |
-
<div class="col">
|
159 |
-
<p id="TimeRemaining" class="text-center alert alert-warning">
|
160 |
-
{{ strings.time_remaining }}:
|
161 |
-
<span id="countdown">{{ strings.calculating }}</span>
|
162 |
-
</p>
|
163 |
-
</div>
|
164 |
-
</div>
|
165 |
</div>
|
166 |
</div>
|
167 |
{% endblock %}
|
6 |
body {
|
7 |
background: #ffffff;
|
8 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
.input-group-addon a {
|
10 |
font-weight: bold;
|
11 |
display: block;
|
12 |
}
|
|
|
|
|
|
|
|
|
13 |
#countdown {
|
14 |
font-weight: bolder;
|
15 |
}
|
21 |
margin: 30px 0;
|
22 |
text-decoration: underline;
|
23 |
}
|
|
|
|
|
|
|
24 |
</style>
|
25 |
{% endblock %}
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
{% block body_content_header %}
|
28 |
<div class="row">
|
29 |
<div class="col-8 offset-2 col-md-6 offset-md-3 text-center">
|
35 |
|
36 |
<div class="row">
|
37 |
<div class="col-12 col-md-8 offset-md-2 col-lg-6 offset-lg-3">
|
38 |
+
{{ content.form|raw }}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
</div>
|
40 |
</div>
|
41 |
{% endblock %}
|
templates/twig/snippets/login_intent/form.twig
ADDED
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<style>
|
2 |
+
.message {
|
3 |
+
padding: 15px;
|
4 |
+
margin-bottom: 30px;
|
5 |
+
}
|
6 |
+
.submit.form-group {
|
7 |
+
margin-top: 25px;
|
8 |
+
}
|
9 |
+
.input-group-addon a {
|
10 |
+
font-weight: bold;
|
11 |
+
display: block;
|
12 |
+
}
|
13 |
+
a.input-help {
|
14 |
+
display: inline-block;
|
15 |
+
padding: 0 0.5rem;
|
16 |
+
}
|
17 |
+
#countdown {
|
18 |
+
font-weight: bolder;
|
19 |
+
}
|
20 |
+
#TimeRemaining {
|
21 |
+
margin-top: 30px;
|
22 |
+
padding: 10px;
|
23 |
+
}
|
24 |
+
#skip_mfa {
|
25 |
+
margin: 10px 10px 5px 20px;
|
26 |
+
}
|
27 |
+
</style>
|
28 |
+
|
29 |
+
<div class="alert alert-{{ data.message_type }}" role="alert">{{ strings.message }}</div>
|
30 |
+
|
31 |
+
<form action="{{ hrefs.form_action }}" method="post" class="form-horizontal">
|
32 |
+
<input type="hidden" name="{{ data.login_intent_flag }}" value="1" />
|
33 |
+
{% if not hrefs.redirect_to is empty %}
|
34 |
+
<input type="hidden" name="redirect_to" value="{{ hrefs.redirect_to }}" />
|
35 |
+
{% endif %}
|
36 |
+
{% if not hrefs.redirect_to is empty %}
|
37 |
+
<input type="hidden" name="cancel_href" value="{{ hrefs.cancel_href }}" />
|
38 |
+
{% endif %}
|
39 |
+
|
40 |
+
{% for key_field, aField in data.login_fields %}
|
41 |
+
<div class="form-row">
|
42 |
+
<div class="form-group col">
|
43 |
+
<label for="{{ aField.name }}">{{ aField.text }}</label>
|
44 |
+
<div class="input-group">
|
45 |
+
<input type="{{ aField.type }}"
|
46 |
+
name="{{ aField.name }}"
|
47 |
+
value="{{ aField.value }}"
|
48 |
+
class="form-control"
|
49 |
+
id="{{ aField.name }}"
|
50 |
+
placeholder="{{ aField.placeholder }}"
|
51 |
+
autocomplete="off"
|
52 |
+
{% if key_field == 0 %}autofocus{% endif %}
|
53 |
+
/>
|
54 |
+
|
55 |
+
{% if flags.show_branded_links %}
|
56 |
+
<div class="input-group-append">
|
57 |
+
<div class="input-group-text">
|
58 |
+
<a href="{{ aField.help_link }}"
|
59 |
+
target="_blank" class="input-help">?</a>
|
60 |
+
</div>
|
61 |
+
</div>
|
62 |
+
{% endif %}
|
63 |
+
</div>
|
64 |
+
</div>
|
65 |
+
</div>
|
66 |
+
|
67 |
+
{% endfor %}
|
68 |
+
|
69 |
+
{% if flags.can_skip_mfa %}
|
70 |
+
<div class="form-row">
|
71 |
+
<div class="form-group mb-0">
|
72 |
+
<div class="input-group">
|
73 |
+
<label for="skip_mfa">
|
74 |
+
<input type="checkbox" value="Y" name="skip_mfa" id="skip_mfa">
|
75 |
+
{{ strings.skip_mfa }}
|
76 |
+
</label>
|
77 |
+
</div>
|
78 |
+
</div>
|
79 |
+
</div>
|
80 |
+
{% endif %}
|
81 |
+
|
82 |
+
<div class="form-group row submit">
|
83 |
+
<div class="col-6 order-2 text-right">
|
84 |
+
<button type="submit" id="mainSubmit" class="pull-right btn btn-success">
|
85 |
+
{{ strings.verify_my_login }}</button>
|
86 |
+
</div>
|
87 |
+
<div class="col-6 order-1 text-left">
|
88 |
+
<button class="btn btn-outline-danger" name="cancel" value="1">
|
89 |
+
← {{ strings.cancel }}</button>
|
90 |
+
</div>
|
91 |
+
</div>
|
92 |
+
</form>
|
93 |
+
|
94 |
+
<div class="row">
|
95 |
+
<div class="col">
|
96 |
+
<p id="TimeRemaining" class="text-center alert alert-warning">
|
97 |
+
{{ strings.time_remaining }}:
|
98 |
+
<span id="countdown">{{ strings.calculating }}</span>
|
99 |
+
</p>
|
100 |
+
</div>
|
101 |
+
</div>
|
102 |
+
|
103 |
+
<script type="text/javascript">
|
104 |
+
// Set the date we're counting down to
|
105 |
+
var timeRemaining = {{ data.time_remaining }};
|
106 |
+
// Update the count down every 1 second
|
107 |
+
var x = setInterval( function () {
|
108 |
+
timeRemaining -= 1;
|
109 |
+
var timeRemainingText = '';
|
110 |
+
if ( timeRemaining < 0 ) {
|
111 |
+
timeRemainingText = '{{ strings.login_expired }}';
|
112 |
+
clearInterval( x );
|
113 |
+
loginExpired();
|
114 |
+
}
|
115 |
+
else {
|
116 |
+
var minutes = Math.floor( timeRemaining / 60 );
|
117 |
+
var seconds = Math.floor( timeRemaining % 60 );
|
118 |
+
if ( minutes > 0 ) {
|
119 |
+
timeRemainingText = minutes + " minutes and " + seconds
|
120 |
+
+ " {{ strings.seconds }}";
|
121 |
+
}
|
122 |
+
else {
|
123 |
+
timeRemainingText = timeRemaining.toFixed( 0 )
|
124 |
+
+ " {{ strings.seconds }}";
|
125 |
+
}
|
126 |
+
}
|
127 |
+
document.getElementById( "countdown" ).innerHTML = timeRemainingText;
|
128 |
+
},
|
129 |
+
1000
|
130 |
+
);
|
131 |
+
|
132 |
+
function loginExpired() {
|
133 |
+
document.getElementById( "mainSubmit" ).setAttribute( 'disabled', 'disabled' );
|
134 |
+
document.getElementById( "TimeRemaining" ).className = "text-center alert alert-danger";
|
135 |
+
}
|
136 |
+
</script>
|
templates/twig/snippets/user/profile/mfa/mfa_backup.twig
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<th><label for="shield_backup_code">{{ strings.label_enter_code }}</label></th>
|
3 |
+
<td>
|
4 |
+
<a href="#" id="IcwpWpsfGenBackupLoginCode"
|
5 |
+
class="button button-primary">{{ strings.button_gen_code }}</a>
|
6 |
+
{% if flags.has_validated_profile %}
|
7 |
+
<a href="#" id="IcwpWpsfDelBackupLoginCode"
|
8 |
+
class="button">{{ strings.button_del_code }}</a>
|
9 |
+
{% endif %}
|
10 |
+
<p class="description">
|
11 |
+
{{ strings.description_code }}
|
12 |
+
<br /><strong>{{ strings.description_code_ext1 }}</strong>
|
13 |
+
{% if flags.has_validated_profile %}
|
14 |
+
<br />{{ strings.description_code_ext2 }}
|
15 |
+
{% endif %}
|
16 |
+
</p>
|
17 |
+
</td>
|
18 |
+
</tr>
|
templates/twig/snippets/user/profile/mfa/mfa_container.twig
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div id="shield-options-mfa-authentication" class="shield-user-options-block">
|
2 |
+
<h3>{{ strings.title }}<small style="margin-left: 10px">({{ strings.provided_by }})</small></h3>
|
3 |
+
|
4 |
+
<table class="form-table">
|
5 |
+
<tbody>
|
6 |
+
{% for mfa_slug,mfa_row in mfa_rows %}
|
7 |
+
{{ mfa_row|raw }}
|
8 |
+
{% endfor %}
|
9 |
+
</tbody>
|
10 |
+
</table>
|
11 |
+
</div>
|
templates/twig/snippets/user/profile/mfa/mfa_email.twig
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<th><label for="shield_enable_mfaemail">{{ strings.label_email_authentication }}</label></th>
|
3 |
+
<td>
|
4 |
+
<input type="checkbox" name="shield_enable_mfaemail" id="shield_enable_mfaemail" value="Y"
|
5 |
+
{% if flags.is_profile_active %}checked="checked"{% endif %}
|
6 |
+
{% if flags.is_enforced %}disabled="disabled"{% endif %}
|
7 |
+
/>
|
8 |
+
<p class="description">{{ strings.description_email_authentication_checkbox }}</p>
|
9 |
+
{% if flags.is_enforced %}
|
10 |
+
<p class="description">{{ strings.is_enforced }}</p>
|
11 |
+
{% endif %}
|
12 |
+
</td>
|
13 |
+
</tr>
|
templates/twig/snippets/user/profile/mfa/mfa_ga.twig
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<style type="text/css">
|
2 |
+
#shield_ga_secret {
|
3 |
+
letter-spacing: 5px;
|
4 |
+
font-family: monospace;
|
5 |
+
font-size: 24px;
|
6 |
+
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.4);
|
7 |
+
border: 1px solid rgba(0, 0, 0, 0.1);
|
8 |
+
padding: 0 7px;
|
9 |
+
background-color: whitesmoke;
|
10 |
+
}
|
11 |
+
</style>
|
12 |
+
|
13 |
+
{% if flags.is_profile_active %}
|
14 |
+
|
15 |
+
{% if (flags.is_my_user_profile or flags.i_am_valid_admin) %}
|
16 |
+
<tr>
|
17 |
+
<th><label for="shield_turn_off_ga">{{ strings.label_check_to_remove }}</label></th>
|
18 |
+
<td>
|
19 |
+
<input type="checkbox" name="shield_turn_off_ga" id="shield_turn_off_ga" value="Y" />
|
20 |
+
<p class="description">{{ strings.desc_remove }}</p>
|
21 |
+
</td>
|
22 |
+
</tr>
|
23 |
+
{% endif %}
|
24 |
+
|
25 |
+
{% else %}
|
26 |
+
|
27 |
+
{% if flags.is_my_user_profile %}
|
28 |
+
<tr>
|
29 |
+
<th><label for="{{ vars.otp_field_name }}">{{ strings.title }}</label></th>
|
30 |
+
<td>
|
31 |
+
<div style="width: 350px; margin-bottom: 15px">
|
32 |
+
<img src="{{ hrefs.src_chart_url }}" alt="{{ strings.description_chart_url }}"
|
33 |
+
title="{{ strings.description_chart_url }}"
|
34 |
+
style="display:block;margin:0 auto 10px" />
|
35 |
+
<div style="margin: auto;width: fit-content;text-align: center;"
|
36 |
+
id="shield_ga_secret">{{ vars.ga_secret }}</div>
|
37 |
+
</div>
|
38 |
+
|
39 |
+
<input class="regular-text"
|
40 |
+
type="text"
|
41 |
+
id="{{ vars.otp_field_name }}"
|
42 |
+
name="{{ vars.otp_field_name }}"
|
43 |
+
placeholder="{{ strings.enter_auth_app_code }}"
|
44 |
+
value="" autocomplete="off" />
|
45 |
+
<p class="description">
|
46 |
+
{{ strings.description_chart_url }}
|
47 |
+
</p>
|
48 |
+
<p class="description">
|
49 |
+
{{ strings.description_ga_secret }}
|
50 |
+
</p>
|
51 |
+
</td>
|
52 |
+
</tr>
|
53 |
+
{% endif %}
|
54 |
+
|
55 |
+
{% endif %}
|
templates/twig/snippets/user/profile/mfa/mfa_yubikey.twig
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% if (flags.is_my_user_profile or flags.i_am_valid_admin) %}
|
2 |
+
<tr>
|
3 |
+
<th><label for="{{ vars.otp_field_name }}">{{ strings.title }}</label></th>
|
4 |
+
<td>
|
5 |
+
{% if flags.is_profile_active %}
|
6 |
+
<p>{{ strings.current_yubi_ids }}</p>
|
7 |
+
<ul style=" list-style: circle inside; ">
|
8 |
+
{% for yubi_id in vars.yubi_ids %}
|
9 |
+
<li><code>{{ yubi_id }}</code></li>
|
10 |
+
{% endfor %}
|
11 |
+
</ul>
|
12 |
+
{% else %}
|
13 |
+
<p>{{ strings.no_active_yubi_ids }}</p>
|
14 |
+
{% endif %}
|
15 |
+
|
16 |
+
<p style="margin-bottom: 5px">{{ strings.enter_otp }}</p>
|
17 |
+
<input class="regular-text"
|
18 |
+
type="text"
|
19 |
+
id="{{ vars.otp_field_name }}"
|
20 |
+
name="{{ vars.otp_field_name }}"
|
21 |
+
value="" autocomplete="off" />
|
22 |
+
{% if flags.is_profile_active %}
|
23 |
+
<p class="description">
|
24 |
+
{{ strings.to_remove_device }}
|
25 |
+
</p>
|
26 |
+
{% endif %}
|
27 |
+
<p class="description">
|
28 |
+
{{ strings.multiple_for_pro }}
|
29 |
+
</p>
|
30 |
+
</td>
|
31 |
+
</tr>
|
32 |
+
{% else %}
|
33 |
+
<td>
|
34 |
+
<p class="description">{{ strings.cant_remove_admins }}</p>
|
35 |
+
</td>
|
36 |
+
{% endif %}
|
templates/twig/wpadmin_pages/insights/license/license.twig
CHANGED
@@ -40,13 +40,18 @@
|
|
40 |
<h5 class="mb-0">{{ strings.title_license_summary }}</h5>
|
41 |
</div>
|
42 |
<div class="card-body">
|
|
|
|
|
|
|
43 |
<table class="table table-hover table-sm mb-0">
|
44 |
<tbody>
|
45 |
{% for license_key, license_val in vars.license_table %}
|
46 |
-
|
47 |
-
<
|
48 |
-
|
49 |
-
|
|
|
|
|
50 |
{% endfor %}
|
51 |
</tbody>
|
52 |
</table>
|
@@ -128,7 +133,15 @@
|
|
128 |
<div id="collone" class="collapse show" aria-labelledby="headingOne"
|
129 |
data-parent="#accordion">
|
130 |
<div class="card-body">
|
|
|
|
|
131 |
<dl>
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
<dt>Plugin and Theme Vulnerability Scanner</dt>
|
133 |
<dd>Alerts to plugin/theme vulnerabilities.
|
134 |
Shield can then automatically upgrade as updates become available.
|
40 |
<h5 class="mb-0">{{ strings.title_license_summary }}</h5>
|
41 |
</div>
|
42 |
<div class="card-body">
|
43 |
+
{% if flags.has_error %}
|
44 |
+
<div class="alert alert-warning mb-0">{{ vars.error }}</div>
|
45 |
+
{% endif %}
|
46 |
<table class="table table-hover table-sm mb-0">
|
47 |
<tbody>
|
48 |
{% for license_key, license_val in vars.license_table %}
|
49 |
+
{% if license_val is not empty %}
|
50 |
+
<tr>
|
51 |
+
<th scope="row">{{ attribute(strings, license_key) }}:</th>
|
52 |
+
<td class="">{{ license_val|raw }}</td>
|
53 |
+
</tr>
|
54 |
+
{% endif %}
|
55 |
{% endfor %}
|
56 |
</tbody>
|
57 |
</table>
|
133 |
<div id="collone" class="collapse show" aria-labelledby="headingOne"
|
134 |
data-parent="#accordion">
|
135 |
<div class="card-body">
|
136 |
+
<p><a href="https://shsec.io/gp" target="_blank" class="btn btn-success">
|
137 |
+
See All PRO Features and Extras ↗</a></p>
|
138 |
<dl>
|
139 |
+
<dt>Powerful, Auto-Learning Malware Scanner</dt>
|
140 |
+
<dd>Detects common and uncommon malware patterns in PHP files and alerts you immediately.
|
141 |
+
<br/>With ShieldNET crowd-sourcing intelligence, Shield automatically hides false-positives
|
142 |
+
so you can focus on risks that matter, and can ignore the noise that wastes your time.
|
143 |
+
</dd>
|
144 |
+
|
145 |
<dt>Plugin and Theme Vulnerability Scanner</dt>
|
146 |
<dd>Alerts to plugin/theme vulnerabilities.
|
147 |
Shield can then automatically upgrade as updates become available.
|
templates/twig/wpadmin_pages/insights/traffic/index.twig
CHANGED
@@ -4,11 +4,13 @@
|
|
4 |
<div class="row ">
|
5 |
<div class="col-12 insights_section">
|
6 |
{% if flags.can_traffic %}
|
7 |
-
{% if flags.is_enabled %}
|
8 |
-
|
9 |
-
|
10 |
-
|
|
|
11 |
{% endif %}
|
|
|
12 |
{% else %}
|
13 |
{% include '/wpadmin_pages/insights/common/feature_unavailable.twig' %}
|
14 |
{% endif %}
|
4 |
<div class="row ">
|
5 |
<div class="col-12 insights_section">
|
6 |
{% if flags.can_traffic %}
|
7 |
+
{% if not flags.is_enabled %}
|
8 |
+
<div class="alert alert-info">
|
9 |
+
<h6 class="alert-heading">{{ strings.not_enabled }}</h6>
|
10 |
+
<p class="m-0"><a class="alert-link" href="{{ hrefs.please_enable }}">{{ strings.please_enable }}</a></p>
|
11 |
+
</div>
|
12 |
{% endif %}
|
13 |
+
{% include '/wpadmin_pages/insights/traffic/traffic_table.twig' %}
|
14 |
{% else %}
|
15 |
{% include '/wpadmin_pages/insights/common/feature_unavailable.twig' %}
|
16 |
{% endif %}
|