Version Description
Download this release
Release Info
Developer | paultgoodchild |
Plugin | Shield Security for WordPress |
Version | 11.5.0 |
Comparing to | |
See all releases |
Code changes from version 11.4.5 to 11.5.0
- cl.json +108 -0
- icwp-wpsf.php +1 -1
- plugin-spec.php +68 -11
- readme.txt +1 -1
- resources/css/plugin.css +35 -2
- resources/css/shield/scanners.css +0 -0
- resources/images/bootstrap/download.svg +4 -0
- resources/images/bootstrap/eye-slash-fill.svg +4 -0
- resources/images/bootstrap/file-excel.svg +4 -0
- resources/images/bootstrap/tools.svg +2 -2
- resources/images/bootstrap/x-square.svg +4 -0
- resources/js/global-plugin.js +2 -0
- resources/js/shield/scanners.js +90 -0
- resources/js/shield/scans.js +8 -8
- resources/js/shield/scantables.js +294 -0
- src/config/feature-hack_protect.php +90 -56
- src/config/feature-integrations.php +4 -0
- src/config/feature-ips.php +18 -3
- src/lib/src/Controller/Assets/Paths.php +9 -1
- src/lib/src/Controller/Assets/Urls.php +3 -11
- src/lib/src/Controller/Controller.php +10 -58
- src/lib/src/Databases/Base/BaseQuery.php +5 -5
- src/lib/src/Databases/Base/Select.php +5 -5
- src/lib/src/Databases/Events/Handler.php +15 -17
- src/lib/src/Databases/FileLocker/EntryVO.php +2 -2
- src/lib/src/Databases/ScanQueue/Select.php +46 -23
- src/lib/src/Databases/Scanner/EntryVO.php +1 -1
- src/lib/src/Databases/Scanner/Insert.php +2 -4
- src/lib/src/Databases/Scanner/Select.php +17 -0
- src/lib/src/Modules/AuditTrail/Lib/AuditWriter.php +3 -0
- src/lib/src/Modules/Autoupdates/Processor.php +6 -6
- src/lib/src/Modules/Base/Lib/Rest/Utility/RestLocker.php +1 -2
- src/lib/src/Modules/Base/ModCon.php +2 -2
- src/lib/src/Modules/Base/Options/WildCardOptions.php +123 -0
- src/lib/src/Modules/Base/UI.php +1 -0
- src/lib/src/Modules/BaseShield/ModCon.php +3 -1
- src/lib/src/Modules/CommentsFilter/ModCon.php +2 -5
- src/lib/src/Modules/Email/Processor.php +15 -5
- src/lib/src/Modules/Events/Lib/Reports/KeyStats.php +1 -4
- src/lib/src/Modules/Events/Lib/Reports/ScanRepairs.php +0 -67
- src/lib/src/Modules/Events/Lib/StatsWriter.php +8 -6
- src/lib/src/Modules/Events/Reporting.php +0 -9
- src/lib/src/Modules/Events/Strings.php +10 -15
- src/lib/src/Modules/HackGuard/AjaxHandler.php +42 -16
- src/lib/src/Modules/HackGuard/Lib/FileLocker/FileLockerController.php +0 -6
- src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/Accept.php +1 -3
- src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/Diff.php +12 -13
- src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/Restore.php +6 -10
- src/lib/src/Modules/HackGuard/Lib/Reports/FileLockerAlerts.php +16 -19
- src/lib/src/Modules/HackGuard/Lib/Reports/ScanAlerts.php +4 -7
- src/lib/src/Modules/HackGuard/Lib/Reports/ScanRepairs.php +90 -0
- src/lib/src/Modules/HackGuard/Lib/ScanTables/DelegateAjaxHandler.php +152 -0
- src/lib/src/Modules/HackGuard/Lib/ScanTables/LoadRawTableData.php +328 -0
- src/lib/src/Modules/HackGuard/Lib/ScanTables/RetrieveFileContents.php +63 -0
- src/lib/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForCrowdSource.php +5 -19
- src/lib/src/Modules/HackGuard/Lib/Snapshots/CrowdSourced/SubmitHashes.php +5 -1
- src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CleanAll.php +6 -6
- src/lib/src/Modules/HackGuard/Lib/Utility/VerifyFileByHash.php +95 -0
- src/lib/src/Modules/HackGuard/ModCon.php +37 -13
- src/lib/src/Modules/HackGuard/Options.php +36 -25
- src/lib/src/Modules/HackGuard/Processor.php +0 -12
- src/lib/src/Modules/HackGuard/Render/ScanResults/SectionBase.php +59 -0
- src/lib/src/Modules/HackGuard/Render/ScanResults/SectionLogs.php +65 -0
- src/lib/src/Modules/HackGuard/Render/ScanResults/SectionMalware.php +66 -0
- src/lib/src/Modules/HackGuard/Render/ScanResults/SectionPluginThemesBase.php +63 -0
- src/lib/src/Modules/HackGuard/Render/ScanResults/SectionPlugins.php +144 -0
- src/lib/src/Modules/HackGuard/Render/ScanResults/SectionThemes.php +149 -0
- src/lib/src/Modules/HackGuard/Render/ScanResults/SectionWordpress.php +64 -0
- src/lib/src/Modules/HackGuard/Reporting.php +2 -1
- src/lib/src/Modules/HackGuard/Scan/Controller/Base.php +66 -42
- src/lib/src/Modules/HackGuard/Scan/Controller/BaseForAssets.php +2 -2
- src/lib/src/Modules/HackGuard/Scan/Controller/Ptg.php +48 -9
- src/lib/src/Modules/HackGuard/Scan/Controller/Ufc.php +7 -3
- src/lib/src/Modules/HackGuard/Scan/Queue/CollateResults.php +22 -22
- src/lib/src/Modules/HackGuard/Scan/Queue/CompleteQueue.php +9 -9
- src/lib/src/Modules/HackGuard/Scan/Queue/Controller.php +25 -25
- src/lib/src/Modules/HackGuard/Scan/Queue/ConvertBetweenTypes.php +7 -7
- src/lib/src/Modules/HackGuard/Scan/Queue/QueueProcessor.php +9 -9
- src/lib/src/Modules/HackGuard/Scan/Queue/ScanEnqueue.php +10 -10
- src/lib/src/Modules/HackGuard/Scan/Queue/ScanExecute.php +11 -12
- src/lib/src/Modules/HackGuard/Scan/Results/ConvertBetweenTypes.php +27 -25
- src/lib/src/Modules/HackGuard/Scan/Results/ResultsDelete.php +2 -2
- src/lib/src/Modules/HackGuard/Scan/Results/ResultsRetrieve.php +1 -1
- src/lib/src/Modules/HackGuard/Scan/Results/ResultsStore.php +11 -10
- src/lib/src/Modules/HackGuard/Scan/Results/ResultsUpdate.php +26 -25
- src/lib/src/Modules/HackGuard/Scan/ScansController.php +4 -4
- src/lib/src/Modules/HackGuard/Scan/Utilities/WpvAddPluginRows.php +1 -1
- src/lib/src/Modules/HackGuard/Strings.php +38 -68
- src/lib/src/Modules/HackGuard/UI.php +53 -36
- src/lib/src/Modules/HackGuard/Upgrade.php +0 -44
- src/lib/src/Modules/IPs/AjaxHandler.php +17 -17
- src/lib/src/Modules/IPs/Components/UnblockIpByFlag.php +3 -3
- src/lib/src/Modules/IPs/Lib/BlacklistHandler.php +0 -6
- src/lib/src/Modules/IPs/Lib/Bots/BotEventListener.php +1 -1
- src/lib/src/Modules/IPs/Lib/Ops/AddIp.php +43 -35
- src/lib/src/Modules/IPs/Lib/Ops/DeleteIp.php +1 -0
- src/lib/src/Modules/IPs/ModCon.php +24 -26
- src/lib/src/Modules/IPs/Options.php +12 -25
- src/lib/src/Modules/IPs/Strings.php +12 -0
- src/lib/src/Modules/IPs/WpCli/Add.php +8 -8
- src/lib/src/Modules/IPs/WpCli/Remove.php +8 -8
- src/lib/src/Modules/Insights/Lib/SideMenuBuilder.php +1 -1
- src/lib/src/Modules/Insights/ModCon.php +3 -2
- src/lib/src/Modules/Insights/Strings.php +3 -6
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SupportCandy.php +27 -0
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/SpamController.php +1 -0
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/AntibotSetup.php +2 -2
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/AntiBot.php +1 -1
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/BaseProtectionProvider.php +2 -2
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/CoolDown.php +5 -5
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/GaspJs.php +3 -3
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/GoogleRecaptcha.php +1 -1
- src/lib/src/Modules/LoginGuard/Lib/CooldownFlagFile.php +8 -14
- src/lib/src/Modules/LoginGuard/Lib/CooldownRedirect.php +0 -63
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php +1 -1
- src/lib/src/Modules/LoginGuard/UI.php +7 -1
- src/lib/src/Modules/Plugin/Lib/TestCacheDirWrite.php +15 -17
- src/lib/src/Modules/Plugin/Options.php +0 -8
- src/lib/src/Modules/Plugin/WpCli/Export.php +19 -19
- src/lib/src/Modules/Plugin/WpCli/ForceOff.php +8 -8
- src/lib/src/Modules/Reporting/Lib/Reports/BaseReporter.php +1 -4
- src/lib/src/Modules/Reporting/Lib/Reports/Build/BaseBuilder.php +1 -1
- src/lib/src/Modules/Reporting/Lib/Reports/Build/BuilderAlerts.php +2 -2
- src/lib/src/Modules/Reporting/Lib/Reports/Build/BuilderInfo.php +2 -2
- src/lib/src/Modules/SecurityAdmin/Options.php +0 -22
- src/lib/src/Modules/Sessions/Lib/Ops/Retrieve.php +0 -38
- src/lib/src/Scans/Apc/ConvertVosToResults.php +0 -32
- src/lib/src/Scans/Apc/ResultItem.php +1 -1
- src/lib/src/Scans/Apc/ResultsSet.php +12 -105
- src/lib/src/Scans/Apc/Scan.php +1 -1
- src/lib/src/Scans/Apc/Utilities/ItemActionHandler.php +0 -6
- src/lib/src/Scans/Apc/Utilities/Repair.php +1 -1
- src/lib/src/Scans/Base/BaseBuildFileMap.php +37 -0
- src/lib/src/Scans/Base/BaseBuildScanAction.php +20 -12
- src/lib/src/Scans/Base/BaseConvertVosToResults.php +0 -30
- src/lib/src/Scans/Base/BaseFileScanActionVO.php +15 -0
- src/lib/src/Scans/Base/BaseMergeItems.php +3 -3
- src/lib/src/Scans/Base/BaseScan.php +6 -6
- src/lib/src/Scans/Base/BaseScanActionVO.php +2 -2
- src/lib/src/Scans/Base/DiffResultForStorage.php +3 -4
- src/lib/src/Scans/Base/FileResultItem.php +13 -0
- src/lib/src/Scans/Base/Files/BaseFileScanner.php +1 -1
- src/lib/src/Scans/Base/Files/BaseScanFromFileMap.php +33 -4
- src/lib/src/Scans/Base/{BaseResultItem.php → ResultItem.php} +8 -1
- src/lib/src/Scans/Base/{BaseResultsSet.php → ResultsSet.php} +14 -18
- src/lib/src/Scans/Base/Table/BaseEntryFormatter.php +2 -2
- src/lib/src/Scans/Base/Table/BaseFileEntryFormatter.php +1 -1
- src/lib/src/Scans/Base/Utilities/BaseRepair.php +7 -19
- src/lib/src/Scans/Base/Utilities/ItemActionHandler.php +50 -36
- src/lib/src/Scans/Base/Utilities/ItemActionHandlerAssets.php +3 -3
- src/lib/src/Scans/Common/ScanActionConsumer.php +3 -3
- src/lib/src/Scans/Common/ScanItemConsumer.php +8 -8
- src/lib/src/Scans/Helpers/CopyResultsSets.php +3 -3
- src/lib/src/Scans/Helpers/MergeResultsSets.php +4 -4
- src/lib/src/Scans/Helpers/WpCoreFile.php +7 -7
- src/lib/src/Scans/Mal/BuildFileMap.php +5 -24
- src/lib/src/Scans/Mal/BuildScanAction.php +8 -11
- src/lib/src/Scans/Mal/FileScanner.php +15 -18
- src/lib/src/Scans/Mal/ResultItem.php +1 -3
- src/lib/src/Scans/Mal/ResultsSet.php +1 -1
- src/lib/src/Scans/Mal/ScanActionVO.php +1 -1
- src/lib/src/Scans/Mal/Utilities/ItemActionHandler.php +10 -13
- src/lib/src/Scans/Mal/Utilities/Patterns.php +6 -4
- src/lib/src/Scans/Mal/Utilities/Repair.php +60 -78
- src/lib/src/Scans/Ptg/BuildFileMap.php +27 -35
- src/lib/src/Scans/Ptg/BuildScanAction.php +12 -17
- src/lib/src/Scans/Ptg/FileScanner.php +73 -27
- src/lib/src/Scans/Ptg/ResultItem.php +1 -3
- src/lib/src/Scans/Ptg/ResultsSet.php +9 -9
- src/lib/src/Scans/Ptg/ScanFromFileMap.php +4 -4
- src/lib/src/Scans/Ptg/Utilities/ItemActionHandler.php +15 -18
- src/lib/src/Scans/Ptg/Utilities/Repair.php +19 -37
- src/lib/src/Scans/Ufc/BuildFileMap.php +18 -22
- src/lib/src/Scans/Ufc/BuildScanAction.php +5 -4
- src/lib/src/Scans/Ufc/ConvertVosToResults.php +0 -33
- src/lib/src/Scans/Ufc/ResultItem.php +1 -7
- src/lib/src/Scans/Ufc/ResultsSet.php +1 -1
- src/lib/src/Scans/Ufc/Utilities/ItemActionHandler.php +4 -15
- src/lib/src/Scans/Ufc/Utilities/Repair.php +18 -20
- src/lib/src/Scans/Wcf/BuildFileMap.php +13 -12
- src/lib/src/Scans/Wcf/BuildScanAction.php +11 -10
- src/lib/src/Scans/Wcf/ConvertVosToResults.php +0 -33
- src/lib/src/Scans/Wcf/FileScanner.php +13 -13
- src/lib/src/Scans/Wcf/ResultItem.php +1 -3
- src/lib/src/Scans/Wcf/ResultsSet.php +6 -7
- src/lib/src/Scans/Wcf/Utilities/ItemActionHandler.php +4 -8
- src/lib/src/Scans/Wcf/Utilities/Repair.php +9 -12
- src/lib/src/Scans/Wpv/ConvertVosToResults.php +0 -32
- src/lib/src/Scans/Wpv/ResultItem.php +1 -1
- src/lib/src/Scans/Wpv/ResultsSet.php +1 -1
- src/lib/src/Scans/Wpv/Scan.php +13 -14
- src/lib/src/Scans/Wpv/Utilities/ItemActionHandler.php +1 -19
- src/lib/src/Scans/Wpv/Utilities/Repair.php +8 -11
- src/lib/src/Scans/Wpv/WpVulnDb/WpVulnVO.php +0 -43
- src/lib/src/ShieldNetApi/FileLocker/DecryptFile.php +7 -7
- src/lib/src/Tables/Build/ScanAggregate.php +4 -8
- src/lib/src/Tables/Build/ScanApc.php +4 -4
- src/lib/src/Tables/DataTables/Build/AuditTrail/ForAuditTrail.php +111 -0
- src/lib/src/Tables/DataTables/Build/Base.php +77 -0
- src/lib/src/Tables/DataTables/Build/Scans/BaseForScan.php +111 -0
- src/lib/src/Tables/DataTables/Build/Scans/ForMalware.php +50 -0
- src/lib/src/Tables/DataTables/Build/Scans/ForPluginTheme.php +9 -0
- src/lib/src/Tables/DataTables/Build/Scans/ForWordpress.php +9 -0
- src/lib/src/Tables/Render/DataTable/Base.php +0 -10
- src/lib/src/Tables/Render/DataTable/ScanBase.php +0 -9
- src/lib/src/Tables/Render/DataTable/ScanWcf.php +0 -9
- src/lib/src/Utilities/CacheDir.php +100 -0
- src/lib/src/Utilities/HumanSpam/TestContent.php +4 -4
- src/lib/src/Utilities/Resources/Dynamic.php +5 -0
- src/lib/src/Utilities/Tool/TmpFileStore.php +16 -7
- src/lib/vendor/composer/autoload_classmap.php +28 -12
- src/lib/vendor/composer/autoload_static.php +28 -12
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Fs.php +27 -32
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpBaseVo.php +3 -3
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpPluginVo.php +6 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpThemeVo.php +12 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Assets/DetectInstallationDate.php +29 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Code/AssessPhpFile.php +93 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Data.php +4 -4
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Encrypt/OpenSslEncrypt.php +96 -77
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Encrypt/OpenSslEncryptVo.php +14 -6
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/LocateStrInFile.php +23 -9
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/ReadDataFromFileEncrypted.php +15 -15
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/WriteDataToFileEncrypted.php +12 -12
- templates/twig/components/reports/mod/events/alert_scanrepairs.twig +0 -8
- templates/twig/components/reports/mod/hack_protect/alert_scanrepairs.twig +19 -0
- templates/twig/components/reports/mod/hack_protect/alert_scanresults.twig +4 -1
- templates/twig/wpadmin_pages/components/page/nav_sidebar.twig +4 -4
- templates/twig/wpadmin_pages/insights/scans/modal/code_block.twig +1 -0
- templates/twig/wpadmin_pages/insights/scans/modal/code_render.twig +20 -0
- templates/twig/wpadmin_pages/insights/scans/results/index.twig +1 -0
- templates/twig/wpadmin_pages/insights/scans/results/scan_results.twig +93 -39
- templates/twig/wpadmin_pages/insights/scans/results/section/malware/index.twig +64 -0
- templates/twig/wpadmin_pages/insights/scans/results/section/plugins/index.twig +39 -0
- templates/twig/wpadmin_pages/insights/scans/results/section/plugins/plugin_panel.twig +109 -0
- templates/twig/wpadmin_pages/insights/scans/results/section/themes/index.twig +38 -0
- templates/twig/wpadmin_pages/insights/scans/results/section/themes/theme_panel.twig +104 -0
- templates/twig/wpadmin_pages/insights/scans/results/section/wordpress/index.twig +66 -0
cl.json
CHANGED
@@ -1,4 +1,112 @@
|
|
1 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
"11.4": {
|
3 |
"version": "11.4",
|
4 |
"released_at": 1625560514,
|
1 |
{
|
2 |
+
"11.5": {
|
3 |
+
"version": "11.5",
|
4 |
+
"released_at": 1626779164,
|
5 |
+
"hrefs": {
|
6 |
+
"release": "https://shsec.io/shieldrelease115",
|
7 |
+
"upgrade": "https://shsec.io/shieldupgradeguide115"
|
8 |
+
},
|
9 |
+
"title": "Revamped Scan Results",
|
10 |
+
"description": [
|
11 |
+
],
|
12 |
+
"items": [
|
13 |
+
{
|
14 |
+
"type": "new",
|
15 |
+
"pro_only": false,
|
16 |
+
"title": "Brand New Arrangements of Scan Results",
|
17 |
+
"description": [
|
18 |
+
"To-date scan results have been presented in tabular format, by listing affected files or assets.",
|
19 |
+
"This release sees a major reorganisation to display results grouped into logical sections and areas, such as by plugin, theme, WordPress etc."
|
20 |
+
]
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"type": "new",
|
24 |
+
"pro_only": false,
|
25 |
+
"title": "View Scan File Contents In Browser",
|
26 |
+
"description": [
|
27 |
+
"We've added the ability to view the contents of any file shown in file results directly within your web browser.",
|
28 |
+
"There's no longer any need to download the files, though you still can do this of course."
|
29 |
+
]
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"type": "new",
|
33 |
+
"pro_only": false,
|
34 |
+
"title": "Remove 'Empty' PHP Files From Results",
|
35 |
+
"description": [
|
36 |
+
"A common problem is where a PHP file that has no executable code in it gets flagged in certain scans.",
|
37 |
+
"It isn't trivial to detect whether a PHP file has executable code, but we've added detection for this scenario."
|
38 |
+
]
|
39 |
+
},
|
40 |
+
{
|
41 |
+
"type": "new",
|
42 |
+
"pro_only": false,
|
43 |
+
"title": "Scan File and Folder Exclusions",
|
44 |
+
"description": [
|
45 |
+
"You can specify files and folder which will be excluded from all file scans.",
|
46 |
+
"Files can be excluded in bulk using the asterisk (*) wildcard.",
|
47 |
+
"This option is designed to completely replace the exclusions option under the Unrecognised Files Scanner."
|
48 |
+
]
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"type": "improved",
|
52 |
+
"pro_only": false,
|
53 |
+
"title": "Scan Results Management",
|
54 |
+
"description": [
|
55 |
+
"We've scrapped the 'WordPress Tables' approach to display results and instead use the powerful DataTables JS plugin.",
|
56 |
+
"This makes display, pagination, refresh and actions far smoother and completely seamless."
|
57 |
+
]
|
58 |
+
},
|
59 |
+
{
|
60 |
+
"type": "improved",
|
61 |
+
"pro_only": true,
|
62 |
+
"title": "Switch To Crowd-Sourced Plugin and Theme Hashes.",
|
63 |
+
"description": [
|
64 |
+
"When scanning plugin and theme files for modification, Shield now uses its ShieldNET crowd-source hashes system.",
|
65 |
+
"This results in more accurate and adaptive hashes accounting for edge-cases better resulting in fewer false positives in scan results."
|
66 |
+
]
|
67 |
+
},
|
68 |
+
{
|
69 |
+
"type": "improved",
|
70 |
+
"pro_only": true,
|
71 |
+
"title": "Malware Scanner Uses Crowd-Sourced Hashing Data",
|
72 |
+
"description": [
|
73 |
+
"False Positives in malware results are frustrating, so the more we can reduce them, the better.",
|
74 |
+
"Shield already removes 99% of false positives automatically from results, before you even see them.",
|
75 |
+
"To improve this, ShieldNET now draws upon Crowd-Source Hashes to eliminate false positives even further."
|
76 |
+
]
|
77 |
+
},
|
78 |
+
{
|
79 |
+
"type": "improved",
|
80 |
+
"title": "Reporting alert email now lists some repaired/deleted files.",
|
81 |
+
"description": []
|
82 |
+
},
|
83 |
+
{
|
84 |
+
"type": "improved",
|
85 |
+
"title": "WP Admin warning when 2FA by email verification isn't complete.",
|
86 |
+
"description": []
|
87 |
+
},
|
88 |
+
{
|
89 |
+
"type": "new",
|
90 |
+
"title": "Audit Trail entries for IP addresses are added and removed manually.",
|
91 |
+
"description": []
|
92 |
+
},
|
93 |
+
{
|
94 |
+
"type": "new",
|
95 |
+
"title": "Audit Trail WordPress filter to allow customisation of event logging.",
|
96 |
+
"description": []
|
97 |
+
},
|
98 |
+
{
|
99 |
+
"type": "improved",
|
100 |
+
"title": "Improved support and fixes for PHP 8 and WordPress 5.8.",
|
101 |
+
"description": []
|
102 |
+
},
|
103 |
+
{
|
104 |
+
"type": "fixed",
|
105 |
+
"title": "Sidebar navigation bugs.",
|
106 |
+
"description": []
|
107 |
+
}
|
108 |
+
]
|
109 |
+
},
|
110 |
"11.4": {
|
111 |
"version": "11.4",
|
112 |
"released_at": 1625560514,
|
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: 11.
|
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: 11.5.0
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
plugin-spec.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "11.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "202107.
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
@@ -53,7 +53,7 @@
|
|
53 |
"plugin",
|
54 |
"jquery/featherlight",
|
55 |
"introjs",
|
56 |
-
"
|
57 |
],
|
58 |
"js": [
|
59 |
"select2",
|
@@ -61,7 +61,8 @@
|
|
61 |
"jquery/featherlight",
|
62 |
"jquery/fileDownload",
|
63 |
"shield/tours",
|
64 |
-
"bootstrap-select"
|
|
|
65 |
]
|
66 |
},
|
67 |
"frontend": {
|
@@ -91,16 +92,27 @@
|
|
91 |
"plugin"
|
92 |
]
|
93 |
},
|
94 |
-
"datatables": {
|
95 |
-
"url": "https://
|
96 |
"deps": [
|
97 |
"bootstrap"
|
98 |
]
|
99 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
"global-plugin": {},
|
101 |
"plugin": {
|
102 |
"deps": [
|
103 |
-
"datatables",
|
104 |
"bootstrap",
|
105 |
"global-plugin"
|
106 |
]
|
@@ -136,7 +148,18 @@
|
|
136 |
],
|
137 |
"footer": true
|
138 |
},
|
139 |
-
"shield/mainwp": {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
},
|
141 |
"js": {
|
142 |
"bootstrap": {
|
@@ -164,12 +187,30 @@
|
|
164 |
]
|
165 |
},
|
166 |
"datatables": {
|
167 |
-
"url": "https://
|
168 |
"deps": [
|
169 |
"bootstrap",
|
170 |
"wp-jquery"
|
171 |
]
|
172 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
"global-plugin": {
|
174 |
"deps": [
|
175 |
"wp-jquery"
|
@@ -178,7 +219,7 @@
|
|
178 |
"plugin": {
|
179 |
"deps": [
|
180 |
"bootstrap",
|
181 |
-
"datatables",
|
182 |
"global-plugin",
|
183 |
"shield/navigation",
|
184 |
"base64.min",
|
@@ -249,6 +290,19 @@
|
|
249 |
"plugin"
|
250 |
]
|
251 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
252 |
"shield/tours": {
|
253 |
"deps": [
|
254 |
"plugin",
|
@@ -305,6 +359,9 @@
|
|
305 |
"async": "async",
|
306 |
"defer": "defer"
|
307 |
}
|
|
|
|
|
|
|
308 |
}
|
309 |
}
|
310 |
}
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "11.5.0",
|
4 |
+
"release_timestamp": 1627376940,
|
5 |
+
"build": "202107.2701",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
53 |
"plugin",
|
54 |
"jquery/featherlight",
|
55 |
"introjs",
|
56 |
+
"shield/scanners"
|
57 |
],
|
58 |
"js": [
|
59 |
"select2",
|
61 |
"jquery/featherlight",
|
62 |
"jquery/fileDownload",
|
63 |
"shield/tours",
|
64 |
+
"bootstrap-select",
|
65 |
+
"shield/scanners"
|
66 |
]
|
67 |
},
|
68 |
"frontend": {
|
92 |
"plugin"
|
93 |
]
|
94 |
},
|
95 |
+
"datatables-bootstrap": {
|
96 |
+
"url": "https://cdn.datatables.net/1.10.25/css/dataTables.bootstrap4.min.css",
|
97 |
"deps": [
|
98 |
"bootstrap"
|
99 |
]
|
100 |
},
|
101 |
+
"datatables-select": {
|
102 |
+
"url": "https://cdn.datatables.net/select/1.3.3/css/select.dataTables.min.css",
|
103 |
+
"deps": [
|
104 |
+
"datatables-bootstrap"
|
105 |
+
]
|
106 |
+
},
|
107 |
+
"datatables-buttons": {
|
108 |
+
"url": "https://cdn.datatables.net/buttons/1.7.1/css/buttons.dataTables.min.css",
|
109 |
+
"deps": [
|
110 |
+
"datatables-bootstrap"
|
111 |
+
]
|
112 |
+
},
|
113 |
"global-plugin": {},
|
114 |
"plugin": {
|
115 |
"deps": [
|
|
|
116 |
"bootstrap",
|
117 |
"global-plugin"
|
118 |
]
|
148 |
],
|
149 |
"footer": true
|
150 |
},
|
151 |
+
"shield/mainwp": {},
|
152 |
+
"shield/scanners": {
|
153 |
+
"deps": [
|
154 |
+
"datatables-select",
|
155 |
+
"datatables-buttons",
|
156 |
+
"datatables-bootstrap",
|
157 |
+
"tp/highlightjs"
|
158 |
+
]
|
159 |
+
},
|
160 |
+
"tp/highlightjs": {
|
161 |
+
"url": "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/styles/default.min.css"
|
162 |
+
}
|
163 |
},
|
164 |
"js": {
|
165 |
"bootstrap": {
|
187 |
]
|
188 |
},
|
189 |
"datatables": {
|
190 |
+
"url": "https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js",
|
191 |
"deps": [
|
192 |
"bootstrap",
|
193 |
"wp-jquery"
|
194 |
]
|
195 |
},
|
196 |
+
"datatables-bootstrap": {
|
197 |
+
"url": "https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js",
|
198 |
+
"deps": [
|
199 |
+
"datatables"
|
200 |
+
]
|
201 |
+
},
|
202 |
+
"datatables-select": {
|
203 |
+
"url": "https://cdn.datatables.net/select/1.3.3/js/dataTables.select.min.js",
|
204 |
+
"deps": [
|
205 |
+
"datatables"
|
206 |
+
]
|
207 |
+
},
|
208 |
+
"datatables-buttons": {
|
209 |
+
"url": "https://cdn.datatables.net/buttons/1.7.1/js/dataTables.buttons.min.js",
|
210 |
+
"deps": [
|
211 |
+
"datatables-bootstrap"
|
212 |
+
]
|
213 |
+
},
|
214 |
"global-plugin": {
|
215 |
"deps": [
|
216 |
"wp-jquery"
|
219 |
"plugin": {
|
220 |
"deps": [
|
221 |
"bootstrap",
|
222 |
+
"datatables-bootstrap",
|
223 |
"global-plugin",
|
224 |
"shield/navigation",
|
225 |
"base64.min",
|
290 |
"plugin"
|
291 |
]
|
292 |
},
|
293 |
+
"shield/scanners": {
|
294 |
+
"deps": [
|
295 |
+
"shield/scantables"
|
296 |
+
]
|
297 |
+
},
|
298 |
+
"shield/scantables": {
|
299 |
+
"deps": [
|
300 |
+
"datatables-select",
|
301 |
+
"datatables-buttons",
|
302 |
+
"datatables-bootstrap",
|
303 |
+
"tp/highlightjs"
|
304 |
+
]
|
305 |
+
},
|
306 |
"shield/tours": {
|
307 |
"deps": [
|
308 |
"plugin",
|
359 |
"async": "async",
|
360 |
"defer": "defer"
|
361 |
}
|
362 |
+
},
|
363 |
+
"tp/highlightjs": {
|
364 |
+
"url": "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/highlight.min.js"
|
365 |
}
|
366 |
}
|
367 |
}
|
readme.txt
CHANGED
@@ -8,7 +8,7 @@ Requires at least: 3.7
|
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 5.8
|
11 |
-
Stable tag: 11.
|
12 |
|
13 |
No-Nonsense Security Hardening that protects WordPress against hackers, malicious bots, and spammers (no captchas!). Now with exclusive ShieldNET Technology.
|
14 |
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 5.8
|
11 |
+
Stable tag: 11.5.0
|
12 |
|
13 |
No-Nonsense Security Hardening that protects WordPress against hackers, malicious bots, and spammers (no captchas!). Now with exclusive ShieldNET Technology.
|
14 |
|
resources/css/plugin.css
CHANGED
@@ -1105,7 +1105,6 @@ input[type=checkbox].form-check-input {
|
|
1105 |
.icwpOptionsForm .option_link_info > .dashicons {
|
1106 |
font-size: 16px;
|
1107 |
text-decoration: none;
|
1108 |
-
width: 1px;
|
1109 |
}
|
1110 |
.tooltip .arrow {
|
1111 |
display: none !important;
|
@@ -1553,7 +1552,8 @@ body.folded #FooterBannerGoPro {
|
|
1553 |
border-color: rgb(177 216 178);
|
1554 |
border-width: 1px 1px 1px 0;
|
1555 |
border-style: solid;
|
1556 |
-
min-width:
|
|
|
1557 |
}
|
1558 |
#NavSideBar a.nav-link:hover {
|
1559 |
}
|
@@ -1719,4 +1719,37 @@ body.folded #FooterBannerGoPro {
|
|
1719 |
background: -webkit-linear-gradient(top, #ffeded 0%, #fcd6d6 12%, #f9acac 88%); /* Chrome10-25,Safari5.1-6 */
|
1720 |
background: linear-gradient(to bottom, #ffeded 0%, #fcd6d6 12%, #f9acac 88%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
1721 |
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffeded', endColorstr='#f9acac', GradientType=0); /* IE6-9 */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1722 |
}
|
1105 |
.icwpOptionsForm .option_link_info > .dashicons {
|
1106 |
font-size: 16px;
|
1107 |
text-decoration: none;
|
|
|
1108 |
}
|
1109 |
.tooltip .arrow {
|
1110 |
display: none !important;
|
1552 |
border-color: rgb(177 216 178);
|
1553 |
border-width: 1px 1px 1px 0;
|
1554 |
border-style: solid;
|
1555 |
+
min-width: 130px;
|
1556 |
+
width: 130px;
|
1557 |
}
|
1558 |
#NavSideBar a.nav-link:hover {
|
1559 |
}
|
1719 |
background: -webkit-linear-gradient(top, #ffeded 0%, #fcd6d6 12%, #f9acac 88%); /* Chrome10-25,Safari5.1-6 */
|
1720 |
background: linear-gradient(to bottom, #ffeded 0%, #fcd6d6 12%, #f9acac 88%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
1721 |
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffeded', endColorstr='#f9acac', GradientType=0); /* IE6-9 */
|
1722 |
+
}
|
1723 |
+
#ScanResultsPlugins li.nav-item a.nav-link {
|
1724 |
+
/*background-color: white;*/
|
1725 |
+
border: 1px solid #c2c2c2;
|
1726 |
+
border-radius: 3px;
|
1727 |
+
margin-right: 0;
|
1728 |
+
}
|
1729 |
+
#ScanResultsTabs table td.actions {
|
1730 |
+
white-space: nowrap;
|
1731 |
+
}
|
1732 |
+
#ScanResultsTabs table td.file {
|
1733 |
+
}
|
1734 |
+
button.btn.action {
|
1735 |
+
padding: 3px 6px;
|
1736 |
+
line-height: 16px;
|
1737 |
+
}
|
1738 |
+
|
1739 |
+
#CodeRenderModal pre.icwp-code-render {
|
1740 |
+
counter-reset: line;
|
1741 |
+
}
|
1742 |
+
#CodeRenderModal pre.icwp-code-render > code {
|
1743 |
+
counter-increment: line;
|
1744 |
+
background-color: transparent;
|
1745 |
+
padding: 0;
|
1746 |
+
display: block;
|
1747 |
+
}
|
1748 |
+
#CodeRenderModal pre.icwp-code-render > code:before {
|
1749 |
+
content: counter(line);
|
1750 |
+
width: 32px;
|
1751 |
+
display: inline-block;
|
1752 |
+
}
|
1753 |
+
#CodeRenderModal pre.icwp-code-render > code:before {
|
1754 |
+
-webkit-user-select: none;
|
1755 |
}
|
resources/css/shield/scanners.css
ADDED
File without changes
|
resources/images/bootstrap/download.svg
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-download" viewBox="0 0 16 16">
|
2 |
+
<path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
|
3 |
+
<path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
|
4 |
+
</svg>
|
resources/images/bootstrap/eye-slash-fill.svg
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye-slash-fill" viewBox="0 0 16 16">
|
2 |
+
<path d="m10.79 12.912-1.614-1.615a3.5 3.5 0 0 1-4.474-4.474l-2.06-2.06C.938 6.278 0 8 0 8s3 5.5 8 5.5a7.029 7.029 0 0 0 2.79-.588zM5.21 3.088A7.028 7.028 0 0 1 8 2.5c5 0 8 5.5 8 5.5s-.939 1.721-2.641 3.238l-2.062-2.062a3.5 3.5 0 0 0-4.474-4.474L5.21 3.089z"/>
|
3 |
+
<path d="M5.525 7.646a2.5 2.5 0 0 0 2.829 2.829l-2.83-2.829zm4.95.708-2.829-2.83a2.5 2.5 0 0 1 2.829 2.829zm3.171 6-12-12 .708-.708 12 12-.708.708z"/>
|
4 |
+
</svg>
|
resources/images/bootstrap/file-excel.svg
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-excel" viewBox="0 0 16 16">
|
2 |
+
<path d="M5.18 4.616a.5.5 0 0 1 .704.064L8 7.219l2.116-2.54a.5.5 0 1 1 .768.641L8.651 8l2.233 2.68a.5.5 0 0 1-.768.64L8 8.781l-2.116 2.54a.5.5 0 0 1-.768-.641L7.349 8 5.116 5.32a.5.5 0 0 1 .064-.704z"/>
|
3 |
+
<path d="M4 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H4zm0 1h8a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1z"/>
|
4 |
+
</svg>
|
resources/images/bootstrap/tools.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-tools" viewBox="0 0 16 16">
|
2 |
-
<path d="M1 0 0 1l2.2 3.081a1 1 0 0 0 .815.419h.07a1 1 0 0 1 .708.293l2.675 2.675-2.617 2.654A3.003 3.003 0 0 0 0 13a3 3 0 1 0 5.878-.851l2.654-2.617.968.968-.305.914a1 1 0 0 0 .242 1.023l3.356 3.356a1 1 0 0 0 1.414 0l1.586-1.586a1 1 0 0 0 0-1.414l-3.356-3.356a1 1 0 0 0-1.023-.242L10.5 9.5l-.96-.96 2.68-2.643A3.005 3.005 0 0 0 16 3c0-.269-.035-.53-.102-.777l-2.14 2.141L12 4l-.364-1.757L13.777.102a3 3 0 0 0-3.675 3.68L7.462 6.46 4.793 3.793a1 1 0 0 1-.293-.707v-.071a1 1 0 0 0-.419-.814L1 0zm9.646 10.646a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708zM3 11l.471.242.529.026.287.445.445.287.026.529L5 13l-.242.471-.026.529-.445.287-.287.445-.529.026L3 15l-.471-.242L2 14.732l-.287-.445L1.268 14l-.026-.529L1 13l.242-.471.026-.529.445-.287.287-.445.529-.026L3 11z"/>
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-tools" viewBox="0 0 16 16">
|
2 |
+
<path d="M1 0 0 1l2.2 3.081a1 1 0 0 0 .815.419h.07a1 1 0 0 1 .708.293l2.675 2.675-2.617 2.654A3.003 3.003 0 0 0 0 13a3 3 0 1 0 5.878-.851l2.654-2.617.968.968-.305.914a1 1 0 0 0 .242 1.023l3.356 3.356a1 1 0 0 0 1.414 0l1.586-1.586a1 1 0 0 0 0-1.414l-3.356-3.356a1 1 0 0 0-1.023-.242L10.5 9.5l-.96-.96 2.68-2.643A3.005 3.005 0 0 0 16 3c0-.269-.035-.53-.102-.777l-2.14 2.141L12 4l-.364-1.757L13.777.102a3 3 0 0 0-3.675 3.68L7.462 6.46 4.793 3.793a1 1 0 0 1-.293-.707v-.071a1 1 0 0 0-.419-.814L1 0zm9.646 10.646a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708zM3 11l.471.242.529.026.287.445.445.287.026.529L5 13l-.242.471-.026.529-.445.287-.287.445-.529.026L3 15l-.471-.242L2 14.732l-.287-.445L1.268 14l-.026-.529L1 13l.242-.471.026-.529.445-.287.287-.445.529-.026L3 11z"/>
|
3 |
</svg>
|
resources/images/bootstrap/x-square.svg
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x-square" viewBox="0 0 16 16">
|
2 |
+
<path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h12zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
|
3 |
+
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
|
4 |
+
</svg>
|
resources/js/global-plugin.js
CHANGED
@@ -255,6 +255,7 @@ var iCWP_WPSF_BodyOverlay = new function () {
|
|
255 |
this.show = function () {
|
256 |
nOverlays++;
|
257 |
jQuery( 'div#icwp-fade-wrapper' ).fadeIn( 1000 );
|
|
|
258 |
};
|
259 |
|
260 |
this.hide = function () {
|
@@ -263,6 +264,7 @@ var iCWP_WPSF_BodyOverlay = new function () {
|
|
263 |
nOverlays = 0;
|
264 |
jQuery( 'div#icwp-fade-wrapper' ).stop().fadeOut();
|
265 |
}
|
|
|
266 |
};
|
267 |
|
268 |
this.initialise = function () {
|
255 |
this.show = function () {
|
256 |
nOverlays++;
|
257 |
jQuery( 'div#icwp-fade-wrapper' ).fadeIn( 1000 );
|
258 |
+
jQuery( 'html' ).css( 'cursor', 'wait' );
|
259 |
};
|
260 |
|
261 |
this.hide = function () {
|
264 |
nOverlays = 0;
|
265 |
jQuery( 'div#icwp-fade-wrapper' ).stop().fadeOut();
|
266 |
}
|
267 |
+
jQuery( 'html' ).css( 'cursor', 'initial' );
|
268 |
};
|
269 |
|
270 |
this.initialise = function () {
|
resources/js/shield/scanners.js
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* https://css-tricks.com/snippets/jquery/jquery-plugin-template/
|
3 |
+
*/
|
4 |
+
(function ( $, window, document, undefined ) {
|
5 |
+
|
6 |
+
$.fn.icwpWpsfScanResultsActions = function ( runtimeOptions ) {
|
7 |
+
return this.each(
|
8 |
+
function () {
|
9 |
+
new $.icwpWpsfScanResultsActions( this, runtimeOptions )
|
10 |
+
}
|
11 |
+
);
|
12 |
+
};
|
13 |
+
|
14 |
+
$.icwpWpsfScanResultsActions = function ( el, options ) {
|
15 |
+
// To avoid scope issues, use 'base' instead of 'this'
|
16 |
+
// to reference this class from internal events and functions.
|
17 |
+
var base = this;
|
18 |
+
|
19 |
+
// Access to jQuery and DOM versions of element
|
20 |
+
base.$el = $( el );
|
21 |
+
base.el = el;
|
22 |
+
|
23 |
+
// Add a reverse reference to the DOM object
|
24 |
+
base.$el.data( "icwpWpsfScanResultsActions", base );
|
25 |
+
|
26 |
+
base.init = function () {
|
27 |
+
base.options = $.extend( {}, $.icwpWpsfScanResultsActions.defaultOptions, options );
|
28 |
+
base.bindEvents();
|
29 |
+
};
|
30 |
+
|
31 |
+
base.bindEvents = function () {
|
32 |
+
|
33 |
+
base.$el.on(
|
34 |
+
'click' + '.' + base._name,
|
35 |
+
'button.action.standalone-action.ignore',
|
36 |
+
function ( evt ) {
|
37 |
+
evt.preventDefault();
|
38 |
+
base.bulkAction.call( base, 'ignore', [ $( this ).data( 'rid' ) ] );
|
39 |
+
}
|
40 |
+
);
|
41 |
+
|
42 |
+
};
|
43 |
+
|
44 |
+
base.bulkAction = function ( action, RIDs ) {
|
45 |
+
let reqData = this.getBaseAjaxData();
|
46 |
+
reqData[ 'sub_action' ] = action;
|
47 |
+
reqData[ 'rids' ] = RIDs;
|
48 |
+
this.sendReq( reqData );
|
49 |
+
};
|
50 |
+
|
51 |
+
base.sendReq = function ( reqData, ) {
|
52 |
+
|
53 |
+
$( 'html' ).css( 'cursor', 'wait' );
|
54 |
+
|
55 |
+
$.post( ajaxurl, reqData,
|
56 |
+
function ( response ) {
|
57 |
+
|
58 |
+
if ( response.success ) {
|
59 |
+
iCWP_WPSF_Toaster.showMessage( response.data.message, response.success );
|
60 |
+
if ( response.data.table_reload ) {
|
61 |
+
}
|
62 |
+
else {
|
63 |
+
iCWP_WPSF_Toaster.showMessage( response.data.message, response.success );
|
64 |
+
}
|
65 |
+
}
|
66 |
+
else {
|
67 |
+
let msg = 'Communications error with site.';
|
68 |
+
if ( response.data.message !== undefined ) {
|
69 |
+
msg = response.data.message;
|
70 |
+
}
|
71 |
+
alert( msg );
|
72 |
+
}
|
73 |
+
}
|
74 |
+
).always( function () {
|
75 |
+
$( "html" ).css( "cursor", 'initial' );
|
76 |
+
}
|
77 |
+
);
|
78 |
+
};
|
79 |
+
|
80 |
+
base.getBaseAjaxData = function () {
|
81 |
+
return JSON.parse( JSON.stringify( base.options.ajax[ 'scanresults_action' ] ) );
|
82 |
+
};
|
83 |
+
|
84 |
+
// Run initializer
|
85 |
+
base.init();
|
86 |
+
}
|
87 |
+
|
88 |
+
$.icwpWpsfScanResultsActions.defaultOptions = {};
|
89 |
+
|
90 |
+
})( jQuery );
|
resources/js/shield/scans.js
CHANGED
@@ -75,28 +75,28 @@ jQuery.fn.icwpWpsfScansCheck = function ( aOptions ) {
|
|
75 |
|
76 |
let aReqData = aOpts[ 'ajax_scans_check' ];
|
77 |
jQuery.post( ajaxurl, jQuery.extend( aReqData, aParams ),
|
78 |
-
function (
|
79 |
|
80 |
bCurrentlyRunning = false;
|
81 |
nRunningCount = 0;
|
82 |
-
if (
|
83 |
-
for ( const scankey of Object.keys(
|
84 |
-
if (
|
85 |
nRunningCount++;
|
86 |
bFoundRunning = true;
|
87 |
bCurrentlyRunning = true;
|
88 |
}
|
89 |
}
|
90 |
}
|
91 |
-
let
|
92 |
-
jQuery( '.modal-body',
|
93 |
-
|
94 |
}
|
95 |
).always( function () {
|
96 |
if ( bCurrentlyRunning ) {
|
97 |
setTimeout( function () {
|
98 |
sendReq();
|
99 |
-
},
|
100 |
}
|
101 |
else {
|
102 |
setTimeout( function () {
|
75 |
|
76 |
let aReqData = aOpts[ 'ajax_scans_check' ];
|
77 |
jQuery.post( ajaxurl, jQuery.extend( aReqData, aParams ),
|
78 |
+
function ( response ) {
|
79 |
|
80 |
bCurrentlyRunning = false;
|
81 |
nRunningCount = 0;
|
82 |
+
if ( response.data.running !== undefined ) {
|
83 |
+
for ( const scankey of Object.keys( response.data.running ) ) {
|
84 |
+
if ( response.data.running[ scankey ] ) {
|
85 |
nRunningCount++;
|
86 |
bFoundRunning = true;
|
87 |
bCurrentlyRunning = true;
|
88 |
}
|
89 |
}
|
90 |
}
|
91 |
+
let modal = jQuery( '#ScanProgressModal' );
|
92 |
+
jQuery( '.modal-body', modal ).html( response.data.vars.progress_html );
|
93 |
+
modal.modal( 'show' );
|
94 |
}
|
95 |
).always( function () {
|
96 |
if ( bCurrentlyRunning ) {
|
97 |
setTimeout( function () {
|
98 |
sendReq();
|
99 |
+
}, 3000 );
|
100 |
}
|
101 |
else {
|
102 |
setTimeout( function () {
|
resources/js/shield/scantables.js
ADDED
@@ -0,0 +1,294 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* https://css-tricks.com/snippets/jquery/jquery-plugin-template/
|
3 |
+
*/
|
4 |
+
(function ( $, window, document, undefined ) {
|
5 |
+
|
6 |
+
$.fn.icwpWpsfScanTableActions = function ( runtimeOptions ) {
|
7 |
+
return this.each(
|
8 |
+
function () {
|
9 |
+
new $.icwpWpsfScanTableActions( this, runtimeOptions )
|
10 |
+
}
|
11 |
+
);
|
12 |
+
};
|
13 |
+
|
14 |
+
$.icwpWpsfScanTableActions = function ( el, options ) {
|
15 |
+
// To avoid scope issues, use 'base' instead of 'this'
|
16 |
+
// to reference this class from internal events and functions.
|
17 |
+
const base = this;
|
18 |
+
|
19 |
+
// Access to jQuery and DOM versions of element
|
20 |
+
base.$el = $( el );
|
21 |
+
base.el = el;
|
22 |
+
|
23 |
+
// Add a reverse reference to the DOM object
|
24 |
+
base.$el.data( "icwpWpsfScanTableActions", base );
|
25 |
+
|
26 |
+
base.init = function () {
|
27 |
+
base.options = $.extend( {}, $.icwpWpsfScanTableActions.defaultOptions, options );
|
28 |
+
base.setupDatatable();
|
29 |
+
base.bindEvents();
|
30 |
+
};
|
31 |
+
|
32 |
+
base.rowSelectionChanged = function () {
|
33 |
+
if ( this.$table.rows( { selected: true } ).count() > 0 ) {
|
34 |
+
this.$table.buttons( 'selected-ignore:name, selected-repair:name' ).enable();
|
35 |
+
}
|
36 |
+
else {
|
37 |
+
this.$table.buttons( 'selected-ignore:name, selected-repair:name' ).disable();
|
38 |
+
}
|
39 |
+
};
|
40 |
+
|
41 |
+
base.bindEvents = function () {
|
42 |
+
|
43 |
+
base.$table.on( 'draw',
|
44 |
+
function ( e, dt, type, row_index ) {
|
45 |
+
base.rowSelectionChanged.call( base );
|
46 |
+
}
|
47 |
+
);
|
48 |
+
|
49 |
+
base.$table.on( 'select',
|
50 |
+
function ( e, dt, type, row_index ) {
|
51 |
+
base.rowSelectionChanged.call( base );
|
52 |
+
}
|
53 |
+
);
|
54 |
+
|
55 |
+
base.$table.on( 'deselect',
|
56 |
+
function ( e, dt, type, row_index ) {
|
57 |
+
base.rowSelectionChanged.call( base );
|
58 |
+
}
|
59 |
+
);
|
60 |
+
|
61 |
+
base.$el.on(
|
62 |
+
'click' + '.' + base._name,
|
63 |
+
'button.action.delete',
|
64 |
+
function ( evt ) {
|
65 |
+
evt.preventDefault();
|
66 |
+
if ( confirm( icwp_wpsf_vars_insights.strings.are_you_sure ) ) {
|
67 |
+
base.bulkAction.call( base, 'delete', [ $( this ).data( 'rid' ) ] );
|
68 |
+
}
|
69 |
+
}
|
70 |
+
);
|
71 |
+
|
72 |
+
base.$el.on(
|
73 |
+
'click' + '.' + base._name,
|
74 |
+
'button.action.ignore',
|
75 |
+
function ( evt ) {
|
76 |
+
evt.preventDefault();
|
77 |
+
base.bulkAction.call( base, 'ignore', [ $( this ).data( 'rid' ) ] );
|
78 |
+
}
|
79 |
+
);
|
80 |
+
|
81 |
+
base.$el.on(
|
82 |
+
'click' + '.' + base._name,
|
83 |
+
'button.action.repair',
|
84 |
+
function ( evt ) {
|
85 |
+
evt.preventDefault();
|
86 |
+
base.$table.rows().deselect();
|
87 |
+
base.bulkAction.call( base, 'repair', [ $( this ).data( 'rid' ) ] );
|
88 |
+
}
|
89 |
+
);
|
90 |
+
|
91 |
+
base.$el.on(
|
92 |
+
'click' + '.' + base._name,
|
93 |
+
'a.action.view-file',
|
94 |
+
function ( evt ) {
|
95 |
+
evt.preventDefault();
|
96 |
+
let reqData = base.getBaseAjaxData();
|
97 |
+
reqData.sub_action = 'view_file';
|
98 |
+
reqData.rid = $( this ).data( 'rid' );
|
99 |
+
$.post( ajaxurl, reqData, function ( response ) {
|
100 |
+
if ( response.success ) {
|
101 |
+
let $codeModal = jQuery( '#CodeRenderModal' );
|
102 |
+
jQuery( '.modal-title', $codeModal ).html( response.data.vars.path );
|
103 |
+
jQuery( '.modal-body', $codeModal ).html( response.data.vars.contents );
|
104 |
+
$codeModal.modal( 'show' );
|
105 |
+
$codeModal[ 0 ].querySelectorAll( 'pre.icwp-code-render code' ).forEach( ( el ) => {
|
106 |
+
hljs.highlightElement( el );
|
107 |
+
} );
|
108 |
+
}
|
109 |
+
else {
|
110 |
+
let msg = 'Communications error with site.';
|
111 |
+
if ( response.data.message !== undefined ) {
|
112 |
+
msg = response.data.message;
|
113 |
+
}
|
114 |
+
alert( msg );
|
115 |
+
}
|
116 |
+
} );
|
117 |
+
}
|
118 |
+
);
|
119 |
+
|
120 |
+
base.$el.on(
|
121 |
+
'click' + '.' + base._name,
|
122 |
+
'button.action.href-download',
|
123 |
+
function ( evt ) {
|
124 |
+
evt.preventDefault();
|
125 |
+
var button = $( this );
|
126 |
+
var href = button.data( 'href-download' );
|
127 |
+
if ( href !== undefined ) {
|
128 |
+
base.hrefDownload.call( base, href );
|
129 |
+
}
|
130 |
+
}
|
131 |
+
);
|
132 |
+
|
133 |
+
};
|
134 |
+
|
135 |
+
base.bulkAction = function ( action, RIDs = [] ) {
|
136 |
+
|
137 |
+
if ( RIDs.length === 0 ) {
|
138 |
+
this.$table.rows( { selected: true } ).every( function ( rowIdx, tableLoop, rowLoop ) {
|
139 |
+
RIDs.push( this.data()[ 'rid' ] );
|
140 |
+
} );
|
141 |
+
}
|
142 |
+
|
143 |
+
if ( RIDs.length > 0 ) {
|
144 |
+
let reqData = this.getBaseAjaxData();
|
145 |
+
reqData[ 'sub_action' ] = action;
|
146 |
+
reqData[ 'rids' ] = RIDs;
|
147 |
+
this.sendReq( reqData );
|
148 |
+
}
|
149 |
+
};
|
150 |
+
|
151 |
+
base.hrefDownload = function ( href ) {
|
152 |
+
$.fileDownload( href, {
|
153 |
+
preparingMessageHtml: icwp_wpsf_vars_plugin.strings.downloading_file,
|
154 |
+
failMessageHtml: icwp_wpsf_vars_plugin.strings.downloading_file_problem
|
155 |
+
} );
|
156 |
+
return false;
|
157 |
+
};
|
158 |
+
|
159 |
+
base.sendReq = function ( reqData, forceTableReload = false ) {
|
160 |
+
|
161 |
+
$( 'html' ).css( 'cursor', 'wait' );
|
162 |
+
|
163 |
+
$.post( ajaxurl, reqData,
|
164 |
+
function ( response ) {
|
165 |
+
|
166 |
+
if ( response.success ) {
|
167 |
+
iCWP_WPSF_Toaster.showMessage( response.data.message, response.success );
|
168 |
+
if ( response.data.table_reload ) {
|
169 |
+
}
|
170 |
+
else {
|
171 |
+
iCWP_WPSF_Toaster.showMessage( response.data.message, response.success );
|
172 |
+
}
|
173 |
+
}
|
174 |
+
else {
|
175 |
+
let msg = 'Communications error with site.';
|
176 |
+
if ( response.data.message !== undefined ) {
|
177 |
+
msg = response.data.message;
|
178 |
+
}
|
179 |
+
alert( msg );
|
180 |
+
}
|
181 |
+
|
182 |
+
if ( response.data.table_reload ) {
|
183 |
+
base.tableReload();
|
184 |
+
}
|
185 |
+
}
|
186 |
+
).always( function () {
|
187 |
+
$( "html" ).css( "cursor", 'initial' );
|
188 |
+
}
|
189 |
+
);
|
190 |
+
};
|
191 |
+
|
192 |
+
base.getBaseAjaxData = function () {
|
193 |
+
return JSON.parse( JSON.stringify( base.options.ajax[ 'scanresults_action' ] ) );
|
194 |
+
};
|
195 |
+
|
196 |
+
base.setupDatatable = function () {
|
197 |
+
|
198 |
+
this.$table = this.$el.DataTable(
|
199 |
+
$.extend( base.options.datatables_init,
|
200 |
+
{
|
201 |
+
ajax: function ( data, callback, settings ) {
|
202 |
+
let reqData = base.getBaseAjaxData();
|
203 |
+
reqData.sub_action = 'retrieve_table_data';
|
204 |
+
reqData.type = base.options.type;
|
205 |
+
reqData.file = base.options.file;
|
206 |
+
$.post( ajaxurl, reqData, function ( response ) {
|
207 |
+
if ( response.success ) {
|
208 |
+
callback( response.data.vars );
|
209 |
+
}
|
210 |
+
else {
|
211 |
+
let msg = 'Communications error with site.';
|
212 |
+
if ( response.data.message !== undefined ) {
|
213 |
+
msg = response.data.message;
|
214 |
+
}
|
215 |
+
alert( msg );
|
216 |
+
}
|
217 |
+
} );
|
218 |
+
},
|
219 |
+
deferRender: true,
|
220 |
+
select: {
|
221 |
+
style: 'multi'
|
222 |
+
},
|
223 |
+
dom: 'Bfrtip',
|
224 |
+
buttons: [
|
225 |
+
{
|
226 |
+
text: 'Reload',
|
227 |
+
name: 'table-reload',
|
228 |
+
className: 'action table-refresh',
|
229 |
+
action: function ( e, dt, node, config ) {
|
230 |
+
base.tableReload.call( base );
|
231 |
+
}
|
232 |
+
},
|
233 |
+
{
|
234 |
+
text: 'De/Select All',
|
235 |
+
name: 'all-select',
|
236 |
+
className: 'select-all',
|
237 |
+
action: function ( e, dt, node, config ) {
|
238 |
+
let total = base.$table.rows().count()
|
239 |
+
if ( base.$table.rows( { selected: true } ).count() < total ) {
|
240 |
+
base.$table.rows().select();
|
241 |
+
}
|
242 |
+
else {
|
243 |
+
base.$table.rows().deselect();
|
244 |
+
}
|
245 |
+
}
|
246 |
+
},
|
247 |
+
{
|
248 |
+
text: 'Ignore Selected',
|
249 |
+
name: 'selected-ignore',
|
250 |
+
className: 'action selected-action ignore',
|
251 |
+
action: function ( e, dt, node, config ) {
|
252 |
+
if ( confirm( icwp_wpsf_vars_insights.strings.are_you_sure ) ) {
|
253 |
+
base.bulkAction.call( base, 'ignore' );
|
254 |
+
}
|
255 |
+
}
|
256 |
+
},
|
257 |
+
{
|
258 |
+
text: 'Delete/Repair Selected',
|
259 |
+
name: 'selected-repair',
|
260 |
+
className: 'action selected-action repair',
|
261 |
+
action: function ( e, dt, node, config ) {
|
262 |
+
|
263 |
+
if ( base.$table.rows().count() > 20 ) {
|
264 |
+
alert( "Sorry, this tool isn't designed for such large repairs. We recommend completely removing and reinstalling the item." )
|
265 |
+
}
|
266 |
+
else if ( confirm( icwp_wpsf_vars_insights.strings.absolutely_sure ) ) {
|
267 |
+
base.bulkAction.call( base, 'repair-delete' );
|
268 |
+
}
|
269 |
+
}
|
270 |
+
}
|
271 |
+
],
|
272 |
+
language: {
|
273 |
+
emptyTable: "There are no items to display, or they've been set to be ignored."
|
274 |
+
}
|
275 |
+
}
|
276 |
+
) );
|
277 |
+
|
278 |
+
$( '#ScanResultsPlugins a[data-toggle="tab"]' ).on( 'shown.bs.tab', function ( e ) {
|
279 |
+
$.fn.dataTable.tables( { visible: true, api: true } ).columns.adjust();
|
280 |
+
} );
|
281 |
+
};
|
282 |
+
|
283 |
+
base.tableReload = function ( full = false ) {
|
284 |
+
this.$table.ajax.reload( null, full );
|
285 |
+
this.rowSelectionChanged();
|
286 |
+
};
|
287 |
+
|
288 |
+
// Run initializer
|
289 |
+
base.init();
|
290 |
+
}
|
291 |
+
|
292 |
+
$.icwpWpsfScanTableActions.defaultOptions = {};
|
293 |
+
|
294 |
+
})( jQuery );
|
src/config/feature-hack_protect.php
CHANGED
@@ -385,6 +385,41 @@
|
|
385 |
"summary": "Show Re-Install Links For Plugins",
|
386 |
"description": "Show links to re-install plugins and offer re-install when activating plugins."
|
387 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
{
|
389 |
"key": "snapshot_users",
|
390 |
"section": "section_non_ui",
|
@@ -427,6 +462,27 @@
|
|
427 |
}
|
428 |
],
|
429 |
"definitions": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
430 |
"db_classes": {
|
431 |
"filelocker": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\FileLocker\\Handler",
|
432 |
"scanner": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Scanner\\Handler",
|
@@ -474,21 +530,22 @@
|
|
474 |
"finished_at": "Scan Completed"
|
475 |
}
|
476 |
},
|
477 |
-
"all_scan_slugs": [
|
478 |
-
"apc",
|
479 |
-
"mal",
|
480 |
-
"ptg",
|
481 |
-
"wpv",
|
482 |
-
"wcf",
|
483 |
-
"ufc"
|
484 |
-
],
|
485 |
"table_name_filelocker": "filelocker",
|
486 |
"url_mal_sigs_simple": "https://raw.githubusercontent.com/scr34m/php-malware-scanner/master/definitions/patterns_raw.txt",
|
487 |
"url_mal_sigs_regex": "https://raw.githubusercontent.com/scr34m/php-malware-scanner/master/definitions/patterns_re.txt",
|
488 |
-
"
|
489 |
-
"wp-content/
|
490 |
-
"wp-content/
|
491 |
-
"wp-content/icwp/rollback
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
492 |
],
|
493 |
"cron_all_scans": "all-scans",
|
494 |
"wcf_exclusions": [
|
@@ -503,104 +560,81 @@
|
|
503 |
"xmlrpc.php"
|
504 |
],
|
505 |
"events": {
|
506 |
-
"apc_alert_sent":
|
507 |
},
|
508 |
-
"mal_alert_sent":
|
509 |
},
|
510 |
-
"ptg_alert_sent":
|
511 |
},
|
512 |
-
"ufc_alert_sent":
|
513 |
},
|
514 |
-
"wcf_alert_sent":
|
515 |
},
|
516 |
-
"wpv_alert_sent":
|
517 |
},
|
518 |
-
"apc_scan_run":
|
519 |
"audit": false,
|
520 |
"recent": true
|
521 |
},
|
522 |
-
"mal_scan_run":
|
523 |
"audit": false,
|
524 |
"recent": true
|
525 |
},
|
526 |
-
"ptg_scan_run":
|
527 |
"audit": false,
|
528 |
"recent": true
|
529 |
},
|
530 |
-
"ufc_scan_run":
|
531 |
"audit": false,
|
532 |
"recent": true
|
533 |
},
|
534 |
-
"wcf_scan_run":
|
535 |
"audit": false,
|
536 |
"recent": true
|
537 |
},
|
538 |
-
"wpv_scan_run":
|
539 |
"audit": false,
|
540 |
"recent": true
|
541 |
},
|
542 |
-
"apc_scan_found":
|
543 |
"cat": 2,
|
544 |
"audit_multiple": true,
|
545 |
"recent": true
|
546 |
},
|
547 |
-
"mal_scan_found":
|
548 |
"cat": 3,
|
549 |
"audit_multiple": true,
|
550 |
"recent": true
|
551 |
},
|
552 |
-
"ptg_scan_found":
|
553 |
"cat": 3,
|
554 |
"audit_multiple": true,
|
555 |
"recent": true
|
556 |
},
|
557 |
-
"ufc_scan_found":
|
558 |
"cat": 3,
|
559 |
"audit_multiple": true,
|
560 |
"recent": true
|
561 |
},
|
562 |
-
"wcf_scan_found":
|
563 |
"cat": 3,
|
564 |
"audit_multiple": true,
|
565 |
"recent": true
|
566 |
},
|
567 |
-
"wpv_scan_found":
|
568 |
"cat": 3,
|
569 |
"audit_multiple": true,
|
570 |
"recent": true
|
571 |
},
|
572 |
-
"
|
573 |
-
"audit_multiple": true
|
574 |
-
},
|
575 |
-
"apc_item_repair_fail": {
|
576 |
-
},
|
577 |
-
"mal_item_repair_success": {
|
578 |
"audit_multiple": true,
|
579 |
"recent": true
|
580 |
},
|
581 |
-
"
|
582 |
-
},
|
583 |
-
"ptg_item_repair_success": {
|
584 |
"audit_multiple": true
|
585 |
},
|
586 |
-
"
|
587 |
-
},
|
588 |
-
"ufc_item_repair_success": {
|
589 |
-
"audit_multiple": true,
|
590 |
-
"recent": true
|
591 |
-
},
|
592 |
-
"ufc_item_repair_fail": {
|
593 |
-
},
|
594 |
-
"wcf_item_repair_success": {
|
595 |
-
"audit_multiple": true,
|
596 |
-
"recent": true
|
597 |
-
},
|
598 |
-
"wcf_item_repair_fail": {
|
599 |
-
},
|
600 |
-
"wpv_item_repair_success": {
|
601 |
"audit_multiple": true
|
602 |
-
},
|
603 |
-
"wpv_item_repair_fail": {
|
604 |
}
|
605 |
}
|
606 |
}
|
385 |
"summary": "Show Re-Install Links For Plugins",
|
386 |
"description": "Show links to re-install plugins and offer re-install when activating plugins."
|
387 |
},
|
388 |
+
{
|
389 |
+
"key": "auto_filter_results",
|
390 |
+
"section": "section_scan_options",
|
391 |
+
"premium": false,
|
392 |
+
"type": "checkbox",
|
393 |
+
"default": "Y",
|
394 |
+
"link_info": "",
|
395 |
+
"link_blog": "",
|
396 |
+
"beacon_id": 439,
|
397 |
+
"name": "Auto-Filter Results",
|
398 |
+
"summary": "Automatically Filter Results Of Irrelevant Items",
|
399 |
+
"description": "Automatically remove items from results that are irrelevant."
|
400 |
+
},
|
401 |
+
{
|
402 |
+
"key": "scan_path_exclusions",
|
403 |
+
"section": "section_scan_options",
|
404 |
+
"advanced": true,
|
405 |
+
"premium": true,
|
406 |
+
"default": [
|
407 |
+
"wp-content/cache/",
|
408 |
+
"wp-content/nfwlog/",
|
409 |
+
"wp-content/wflogs/",
|
410 |
+
"*/error_log",
|
411 |
+
"*/php_error_log",
|
412 |
+
"*/mail.log",
|
413 |
+
"*/php_mail.log"
|
414 |
+
],
|
415 |
+
"type": "array",
|
416 |
+
"link_info": "",
|
417 |
+
"link_blog": "",
|
418 |
+
"beacon_id": 441,
|
419 |
+
"name": "Scan Exclusions",
|
420 |
+
"summary": "Scan File and Folder Exclusions",
|
421 |
+
"description": "Scan File and Folder Exclusions."
|
422 |
+
},
|
423 |
{
|
424 |
"key": "snapshot_users",
|
425 |
"section": "section_non_ui",
|
462 |
}
|
463 |
],
|
464 |
"definitions": {
|
465 |
+
"all_scan_slugs": [
|
466 |
+
"apc",
|
467 |
+
"mal",
|
468 |
+
"ptg",
|
469 |
+
"wpv",
|
470 |
+
"wcf",
|
471 |
+
"ufc"
|
472 |
+
],
|
473 |
+
"file_scan_extensions": [
|
474 |
+
"php",
|
475 |
+
"php5",
|
476 |
+
"php7",
|
477 |
+
"js",
|
478 |
+
"json",
|
479 |
+
"css",
|
480 |
+
"htm",
|
481 |
+
"html",
|
482 |
+
"svg",
|
483 |
+
"twig",
|
484 |
+
"hbs"
|
485 |
+
],
|
486 |
"db_classes": {
|
487 |
"filelocker": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\FileLocker\\Handler",
|
488 |
"scanner": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Scanner\\Handler",
|
530 |
"finished_at": "Scan Completed"
|
531 |
}
|
532 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
533 |
"table_name_filelocker": "filelocker",
|
534 |
"url_mal_sigs_simple": "https://raw.githubusercontent.com/scr34m/php-malware-scanner/master/definitions/patterns_raw.txt",
|
535 |
"url_mal_sigs_regex": "https://raw.githubusercontent.com/scr34m/php-malware-scanner/master/definitions/patterns_re.txt",
|
536 |
+
"default_whitelist_paths": [
|
537 |
+
"wp-content/cache/*",
|
538 |
+
"wp-content/shield/*",
|
539 |
+
"wp-content/icwp/rollback/*",
|
540 |
+
"wp-content/plugins-before-restore/*",
|
541 |
+
"wp-content/themes-before-restore/*",
|
542 |
+
"wp-content/uploads/bb-plugin/cache/*",
|
543 |
+
"wp-content/uploads/cache/wpml/twig/*",
|
544 |
+
"wp-content/cache/*",
|
545 |
+
"*/error_log",
|
546 |
+
"*/php_error_log",
|
547 |
+
"*/mail.log",
|
548 |
+
"*/php_mail.log"
|
549 |
],
|
550 |
"cron_all_scans": "all-scans",
|
551 |
"wcf_exclusions": [
|
560 |
"xmlrpc.php"
|
561 |
],
|
562 |
"events": {
|
563 |
+
"apc_alert_sent": {
|
564 |
},
|
565 |
+
"mal_alert_sent": {
|
566 |
},
|
567 |
+
"ptg_alert_sent": {
|
568 |
},
|
569 |
+
"ufc_alert_sent": {
|
570 |
},
|
571 |
+
"wcf_alert_sent": {
|
572 |
},
|
573 |
+
"wpv_alert_sent": {
|
574 |
},
|
575 |
+
"apc_scan_run": {
|
576 |
"audit": false,
|
577 |
"recent": true
|
578 |
},
|
579 |
+
"mal_scan_run": {
|
580 |
"audit": false,
|
581 |
"recent": true
|
582 |
},
|
583 |
+
"ptg_scan_run": {
|
584 |
"audit": false,
|
585 |
"recent": true
|
586 |
},
|
587 |
+
"ufc_scan_run": {
|
588 |
"audit": false,
|
589 |
"recent": true
|
590 |
},
|
591 |
+
"wcf_scan_run": {
|
592 |
"audit": false,
|
593 |
"recent": true
|
594 |
},
|
595 |
+
"wpv_scan_run": {
|
596 |
"audit": false,
|
597 |
"recent": true
|
598 |
},
|
599 |
+
"apc_scan_found": {
|
600 |
"cat": 2,
|
601 |
"audit_multiple": true,
|
602 |
"recent": true
|
603 |
},
|
604 |
+
"mal_scan_found": {
|
605 |
"cat": 3,
|
606 |
"audit_multiple": true,
|
607 |
"recent": true
|
608 |
},
|
609 |
+
"ptg_scan_found": {
|
610 |
"cat": 3,
|
611 |
"audit_multiple": true,
|
612 |
"recent": true
|
613 |
},
|
614 |
+
"ufc_scan_found": {
|
615 |
"cat": 3,
|
616 |
"audit_multiple": true,
|
617 |
"recent": true
|
618 |
},
|
619 |
+
"wcf_scan_found": {
|
620 |
"cat": 3,
|
621 |
"audit_multiple": true,
|
622 |
"recent": true
|
623 |
},
|
624 |
+
"wpv_scan_found": {
|
625 |
"cat": 3,
|
626 |
"audit_multiple": true,
|
627 |
"recent": true
|
628 |
},
|
629 |
+
"scan_item_repair_success": {
|
|
|
|
|
|
|
|
|
|
|
630 |
"audit_multiple": true,
|
631 |
"recent": true
|
632 |
},
|
633 |
+
"scan_item_repair_fail": {
|
|
|
|
|
634 |
"audit_multiple": true
|
635 |
},
|
636 |
+
"scan_item_delete_success": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
637 |
"audit_multiple": true
|
|
|
|
|
638 |
}
|
639 |
}
|
640 |
}
|
src/config/feature-integrations.php
CHANGED
@@ -107,6 +107,10 @@
|
|
107 |
"value_key": "superforms",
|
108 |
"text": "Super Forms"
|
109 |
},
|
|
|
|
|
|
|
|
|
110 |
{
|
111 |
"value_key": "wpforo",
|
112 |
"text": "wpForo"
|
107 |
"value_key": "superforms",
|
108 |
"text": "Super Forms"
|
109 |
},
|
110 |
+
{
|
111 |
+
"value_key": "supportcandy",
|
112 |
+
"text": "Support Candy"
|
113 |
+
},
|
114 |
{
|
115 |
"value_key": "wpforo",
|
116 |
"text": "wpForo"
|
src/config/feature-ips.php
CHANGED
@@ -659,10 +659,25 @@
|
|
659 |
"audit": false,
|
660 |
"stat": false
|
661 |
},
|
662 |
-
"
|
663 |
"offense": false,
|
664 |
-
"
|
665 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
666 |
},
|
667 |
"ip_unblock_flag": {
|
668 |
"cat": 1
|
659 |
"audit": false,
|
660 |
"stat": false
|
661 |
},
|
662 |
+
"ip_block_auto": {
|
663 |
"offense": false,
|
664 |
+
"stat": false,
|
665 |
+
"cat": 1
|
666 |
+
},
|
667 |
+
"ip_block_manual": {
|
668 |
+
"offense": false,
|
669 |
+
"stat": false,
|
670 |
+
"cat": 1
|
671 |
+
},
|
672 |
+
"ip_bypass_add": {
|
673 |
+
"offense": false,
|
674 |
+
"stat": false,
|
675 |
+
"cat": 1
|
676 |
+
},
|
677 |
+
"ip_bypass_remove": {
|
678 |
+
"offense": false,
|
679 |
+
"stat": false,
|
680 |
+
"cat": 1
|
681 |
},
|
682 |
"ip_unblock_flag": {
|
683 |
"cat": 1
|
src/lib/src/Controller/Assets/Paths.php
CHANGED
@@ -35,4 +35,12 @@ class Paths {
|
|
35 |
public function forTemplate( string $item = '' ) :string {
|
36 |
return $this->forPluginItem( $this->getCon()->cfg->paths[ 'templates' ].'/'.ltrim( $item, '/' ) );
|
37 |
}
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
public function forTemplate( string $item = '' ) :string {
|
36 |
return $this->forPluginItem( $this->getCon()->cfg->paths[ 'templates' ].'/'.ltrim( $item, '/' ) );
|
37 |
}
|
38 |
+
|
39 |
+
public function cacheDir() :string {
|
40 |
+
return path_join( WP_CONTENT_DIR, $this->getCon()->cfg->paths[ 'cache' ] );
|
41 |
+
}
|
42 |
+
|
43 |
+
public function forCacheItem( string $item = '' ) :string {
|
44 |
+
return path_join( $this->cacheDir(), $item );
|
45 |
+
}
|
46 |
+
}
|
src/lib/src/Controller/Assets/Urls.php
CHANGED
@@ -3,7 +3,6 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Controller\Assets;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Resources\Dynamic;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
class Urls {
|
@@ -24,14 +23,7 @@ class Urls {
|
|
24 |
public function forJs( string $asset ) :string {
|
25 |
$url = $this->lookupAssetUrlInSpec( $asset, 'js' );
|
26 |
if ( empty( $url ) ) {
|
27 |
-
|
28 |
-
$url = ( new Dynamic() )
|
29 |
-
->setCon( $this->getCon() )
|
30 |
-
->getResourceUrl( Services::Data()->addExtensionToFilePath( $asset, 'js' ) );
|
31 |
-
}
|
32 |
-
else {
|
33 |
-
$url = $this->forAsset( 'js/'.Services::Data()->addExtensionToFilePath( $asset, 'js' ) );
|
34 |
-
}
|
35 |
}
|
36 |
return $url;
|
37 |
}
|
@@ -54,10 +46,10 @@ class Urls {
|
|
54 |
* @param string $asset
|
55 |
* @param string $type
|
56 |
* @return mixed|null
|
|
|
57 |
*/
|
58 |
protected function isAssetDynamic( string $asset, string $type ) :bool {
|
59 |
-
|
60 |
-
return !empty( $asset[ 'dynamic' ] );
|
61 |
}
|
62 |
|
63 |
/**
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Controller\Assets;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
|
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
class Urls {
|
23 |
public function forJs( string $asset ) :string {
|
24 |
$url = $this->lookupAssetUrlInSpec( $asset, 'js' );
|
25 |
if ( empty( $url ) ) {
|
26 |
+
$url = $this->forAsset( 'js/'.Services::Data()->addExtensionToFilePath( $asset, 'js' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
return $url;
|
29 |
}
|
46 |
* @param string $asset
|
47 |
* @param string $type
|
48 |
* @return mixed|null
|
49 |
+
* @deprecated 11.4
|
50 |
*/
|
51 |
protected function isAssetDynamic( string $asset, string $type ) :bool {
|
52 |
+
return false;
|
|
|
53 |
}
|
54 |
|
55 |
/**
|
src/lib/src/Controller/Controller.php
CHANGED
@@ -321,72 +321,24 @@ class Controller extends DynPropertiesClass {
|
|
321 |
}
|
322 |
}
|
323 |
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
$path = false;
|
330 |
-
if ( $this->hasCacheDir() ) {
|
331 |
-
try {
|
332 |
-
// Never throws an exception if "hasCacheDir" == true
|
333 |
-
$path = $this->buildPluginCacheDir();
|
334 |
-
if ( !empty( $cachePath ) ) {
|
335 |
-
$path = path_join( $path, $cachePath );
|
336 |
-
}
|
337 |
-
}
|
338 |
-
catch ( \Exception $e ) {
|
339 |
-
}
|
340 |
-
}
|
341 |
-
return $path;
|
342 |
}
|
343 |
|
344 |
public function hasCacheDir() :bool {
|
345 |
-
|
346 |
-
$this->buildPluginCacheDir();
|
347 |
-
}
|
348 |
-
catch ( \Exception $e ) {
|
349 |
-
}
|
350 |
-
return $this->cache_dir_ready;
|
351 |
}
|
352 |
|
353 |
/**
|
354 |
-
* @
|
355 |
-
* @throws \Exception
|
356 |
*/
|
357 |
private function buildPluginCacheDir() :string {
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
if ( empty( $cacheDirBasename ) ) {
|
362 |
-
$this->cache_dir_ready = false;
|
363 |
-
throw new \Exception( 'No slug for cache dir' );
|
364 |
-
}
|
365 |
-
|
366 |
-
$cacheDir = path_join( WP_CONTENT_DIR, $cacheDirBasename );
|
367 |
-
if ( empty( $this->cache_dir_ready ) && $FS->mkdir( $cacheDir ) ) {
|
368 |
-
$htFile = path_join( $cacheDir, '.htaccess' );
|
369 |
-
$htContent = implode( "\n", [
|
370 |
-
"# BEGIN SHIELD",
|
371 |
-
"Options -Indexes",
|
372 |
-
"Order allow,deny",
|
373 |
-
"Deny from all",
|
374 |
-
'<FilesMatch "^.*\.(css|js)$">',
|
375 |
-
" Allow from all",
|
376 |
-
'</FilesMatch>',
|
377 |
-
"# END SHIELD"
|
378 |
-
] );
|
379 |
-
if ( !$FS->exists( $htFile ) || ( md5_file( $htFile ) !== md5( $htContent ) ) ) {
|
380 |
-
$FS->putFileContent( $htFile, $htContent );
|
381 |
-
}
|
382 |
-
$index = path_join( $cacheDir, 'index.php' );
|
383 |
-
$indexContent = "<?php\nhttp_response_code(404);";
|
384 |
-
if ( !$FS->exists( $index ) || ( md5_file( $index ) !== md5( $indexContent ) ) ) {
|
385 |
-
$FS->putFileContent( $index, $indexContent );
|
386 |
-
}
|
387 |
-
$this->cache_dir_ready = true;
|
388 |
-
}
|
389 |
-
return $cacheDir;
|
390 |
}
|
391 |
|
392 |
protected function doRegisterHooks() {
|
321 |
}
|
322 |
}
|
323 |
|
324 |
+
public function getPluginCachePath( $cachePath = '' ) :string {
|
325 |
+
$cacheDir = ( new Shield\Utilities\CacheDir() )
|
326 |
+
->setCon( $this )
|
327 |
+
->build();
|
328 |
+
return empty( $cacheDir ) ? '' : path_join( $cacheDir, $cachePath );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
329 |
}
|
330 |
|
331 |
public function hasCacheDir() :bool {
|
332 |
+
return !empty( $this->getPluginCachePath() );
|
|
|
|
|
|
|
|
|
|
|
333 |
}
|
334 |
|
335 |
/**
|
336 |
+
* @deprecated 11.4
|
|
|
337 |
*/
|
338 |
private function buildPluginCacheDir() :string {
|
339 |
+
return ( new Shield\Utilities\CacheDir() )
|
340 |
+
->setCon( $this )
|
341 |
+
->build();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
342 |
}
|
343 |
|
344 |
protected function doRegisterHooks() {
|
src/lib/src/Databases/Base/BaseQuery.php
CHANGED
@@ -263,13 +263,13 @@ abstract class BaseQuery {
|
|
263 |
}
|
264 |
|
265 |
/**
|
266 |
-
* @param int $
|
267 |
-
* @param int $
|
268 |
* @return $this
|
269 |
*/
|
270 |
-
public function filterByBoundary( $
|
271 |
-
return $this->filterByCreatedAt( $
|
272 |
-
->filterByCreatedAt( $
|
273 |
}
|
274 |
|
275 |
/**
|
263 |
}
|
264 |
|
265 |
/**
|
266 |
+
* @param int $startTS
|
267 |
+
* @param int $endTS
|
268 |
* @return $this
|
269 |
*/
|
270 |
+
public function filterByBoundary( $startTS, $endTS ) {
|
271 |
+
return $this->filterByCreatedAt( $endTS, '<=' )
|
272 |
+
->filterByCreatedAt( $startTS, '>=' );
|
273 |
}
|
274 |
|
275 |
/**
|
src/lib/src/Databases/Base/Select.php
CHANGED
@@ -63,10 +63,10 @@ class Select extends BaseQuery {
|
|
63 |
* @return \stdClass
|
64 |
*/
|
65 |
public function byId( $nId ) {
|
66 |
-
$
|
67 |
-
|
68 |
-
|
69 |
-
return array_shift( $
|
70 |
}
|
71 |
|
72 |
/**
|
@@ -188,7 +188,7 @@ class Select extends BaseQuery {
|
|
188 |
|
189 |
/**
|
190 |
* Handle COUNT, DISTINCT, & normal SELECT
|
191 |
-
* @return int|string[]|array[]|EntryVO[]|mixed
|
192 |
*/
|
193 |
public function query() {
|
194 |
if ( $this->isCount() || $this->isSum() ) {
|
63 |
* @return \stdClass
|
64 |
*/
|
65 |
public function byId( $nId ) {
|
66 |
+
$items = $this->reset()
|
67 |
+
->addWhereEquals( 'id', $nId )
|
68 |
+
->query();
|
69 |
+
return array_shift( $items );
|
70 |
}
|
71 |
|
72 |
/**
|
188 |
|
189 |
/**
|
190 |
* Handle COUNT, DISTINCT, & normal SELECT
|
191 |
+
* @return int|string[]|array[]|EntryVO[]|\stdClass[]|mixed
|
192 |
*/
|
193 |
public function query() {
|
194 |
if ( $this->isCount() || $this->isSum() ) {
|
src/lib/src/Databases/Events/Handler.php
CHANGED
@@ -8,32 +8,30 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
/**
|
11 |
-
* @param $
|
12 |
*/
|
13 |
-
public function commitEvents( $
|
14 |
-
foreach ( $
|
15 |
-
$this->commitEvent( $
|
16 |
}
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
* @param string $evt
|
21 |
-
* @param
|
22 |
-
* @param int $nCount
|
23 |
* @return bool
|
24 |
*/
|
25 |
-
public function commitEvent( string $evt, $
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
$
|
33 |
-
$
|
34 |
-
$oEvt->created_at = max( 1, $nTs );
|
35 |
/** @var Insert $QI */
|
36 |
$QI = $this->getQueryInserter();
|
37 |
-
return $QI->insert( $
|
38 |
}
|
39 |
}
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
/**
|
11 |
+
* @param $events - array of events: key event slug, value created_at timestamp
|
12 |
*/
|
13 |
+
public function commitEvents( array $events ) {
|
14 |
+
foreach ( $events as $event => $count ) {
|
15 |
+
$this->commitEvent( $event, $count );
|
16 |
}
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
* @param string $evt
|
21 |
+
* @param int $count
|
|
|
22 |
* @return bool
|
23 |
*/
|
24 |
+
public function commitEvent( string $evt, int $count = 1 ) {
|
25 |
+
/** @var EntryVO $entry */
|
26 |
+
$entry = $this->getVo();
|
27 |
+
$entry->event = $evt;
|
28 |
+
/**
|
29 |
+
* @deprecated 11.5
|
30 |
+
*/
|
31 |
+
$entry->count = min( max( 1, $count ), 1627310000 );
|
32 |
+
$entry->created_at = Services::Request()->ts();
|
|
|
33 |
/** @var Insert $QI */
|
34 |
$QI = $this->getQueryInserter();
|
35 |
+
return $QI->insert( $entry );
|
36 |
}
|
37 |
}
|
src/lib/src/Databases/FileLocker/EntryVO.php
CHANGED
@@ -26,7 +26,7 @@ class EntryVO extends Base\EntryVO {
|
|
26 |
switch ( $key ) {
|
27 |
case 'content':
|
28 |
case 'file':
|
29 |
-
$value = base64_decode( $value );
|
30 |
break;
|
31 |
|
32 |
default:
|
@@ -42,7 +42,7 @@ class EntryVO extends Base\EntryVO {
|
|
42 |
switch ( $key ) {
|
43 |
case 'content':
|
44 |
case 'file':
|
45 |
-
$value = base64_encode( $value);
|
46 |
break;
|
47 |
|
48 |
default:
|
26 |
switch ( $key ) {
|
27 |
case 'content':
|
28 |
case 'file':
|
29 |
+
$value = (string)base64_decode( $value );
|
30 |
break;
|
31 |
|
32 |
default:
|
42 |
switch ( $key ) {
|
43 |
case 'content':
|
44 |
case 'file':
|
45 |
+
$value = base64_encode( $value );
|
46 |
break;
|
47 |
|
48 |
default:
|
src/lib/src/Databases/ScanQueue/Select.php
CHANGED
@@ -8,16 +8,48 @@ class Select extends Base\Select {
|
|
8 |
|
9 |
use Common;
|
10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
/**
|
12 |
-
*
|
13 |
*/
|
14 |
-
public function getCurrentScan() {
|
15 |
-
return $this->reset()
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
->queryVar();
|
21 |
}
|
22 |
|
23 |
/**
|
@@ -27,21 +59,12 @@ class Select extends Base\Select {
|
|
27 |
return $this->getDistinctForColumn( 'scan' );
|
28 |
}
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
->setColumnsToSelect( [ 'scan' ] )
|
37 |
-
->filterByNotFinished()
|
38 |
-
->query();
|
39 |
-
$scans = [];
|
40 |
-
/** @var EntryVO $entry */
|
41 |
-
foreach ( $aResults as $entry ) {
|
42 |
-
$scans[ $entry->scan ] = 1;
|
43 |
-
}
|
44 |
-
return array_keys( $scans );
|
45 |
}
|
46 |
|
47 |
public function countForScan( string $scan ) :int {
|
8 |
|
9 |
use Common;
|
10 |
|
11 |
+
public function countAllForEachScan() :array {
|
12 |
+
/** @var array[] $res */
|
13 |
+
$res = $this->setCustomSelect( '`scan`,COUNT(*) as count' )
|
14 |
+
->setGroupBy( 'scan' )
|
15 |
+
->setResultsAsVo( false )
|
16 |
+
->setSelectResultsFormat( ARRAY_A )
|
17 |
+
->query();
|
18 |
+
$counts = [];
|
19 |
+
if ( is_array( $res ) ) {
|
20 |
+
foreach ( $res as $entry ) {
|
21 |
+
$counts[ $entry[ 'scan' ] ] = $entry[ 'count' ];
|
22 |
+
}
|
23 |
+
}
|
24 |
+
return $counts;
|
25 |
+
}
|
26 |
+
|
27 |
+
public function countUnfinishedForEachScan() :array {
|
28 |
+
/** @var array[] $res */
|
29 |
+
$res = $this->setCustomSelect( '`scan`,COUNT(*) as count' )
|
30 |
+
->filterByNotFinished()
|
31 |
+
->setGroupBy( 'scan' )
|
32 |
+
->setResultsAsVo( false )
|
33 |
+
->setSelectResultsFormat( ARRAY_A )
|
34 |
+
->query();
|
35 |
+
$counts = [];
|
36 |
+
if ( is_array( $res ) ) {
|
37 |
+
foreach ( $res as $entry ) {
|
38 |
+
$counts[ $entry[ 'scan' ] ] = $entry[ 'count' ];
|
39 |
+
}
|
40 |
+
}
|
41 |
+
return $counts;
|
42 |
+
}
|
43 |
+
|
44 |
/**
|
45 |
+
* Not quite right. it'll only get the latest finished_at, not the currently processing item
|
46 |
*/
|
47 |
+
public function getCurrentScan() :string {
|
48 |
+
return (string)$this->reset()
|
49 |
+
->setColumnsToSelect( [ 'scan' ] )
|
50 |
+
->setOrderBy( 'finished_at', 'desc' )
|
51 |
+
->setLimit( 1 )
|
52 |
+
->queryVar();
|
|
|
53 |
}
|
54 |
|
55 |
/**
|
59 |
return $this->getDistinctForColumn( 'scan' );
|
60 |
}
|
61 |
|
62 |
+
public function getUnfinishedScans() :array {
|
63 |
+
return $this->reset()
|
64 |
+
->filterByNotFinished()
|
65 |
+
->addColumnToSelect( 'scan' )
|
66 |
+
->setIsDistinct( true )
|
67 |
+
->query();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
}
|
69 |
|
70 |
public function countForScan( string $scan ) :int {
|
src/lib/src/Databases/Scanner/EntryVO.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner;
|
4 |
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner;
|
4 |
|
src/lib/src/Databases/Scanner/Insert.php
CHANGED
@@ -1,9 +1,7 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner;
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
class Insert extends Base\Insert {
|
8 |
|
9 |
}
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner;
|
4 |
|
5 |
+
class Insert extends \FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\Insert {
|
|
|
|
|
6 |
|
7 |
}
|
src/lib/src/Databases/Scanner/Select.php
CHANGED
@@ -8,6 +8,23 @@ class Select extends Base\Select {
|
|
8 |
|
9 |
use Common;
|
10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
public function countForScan( string $scan ) :int {
|
12 |
return $this->reset()
|
13 |
->filterByNotIgnored()
|
8 |
|
9 |
use Common;
|
10 |
|
11 |
+
public function countForEachScan() :array {
|
12 |
+
/** @var array[] $res */
|
13 |
+
$res = $this->setCustomSelect( '`scan`,COUNT(*) as count' )
|
14 |
+
->setGroupBy( 'scan' )
|
15 |
+
->setResultsAsVo( false )
|
16 |
+
->setSelectResultsFormat( ARRAY_A )
|
17 |
+
->filterByNotIgnored()
|
18 |
+
->query();
|
19 |
+
$counts = [];
|
20 |
+
if ( is_array( $res ) ) {
|
21 |
+
foreach ( $res as $entry ) {
|
22 |
+
$counts[ $entry[ 'scan' ] ] = $entry[ 'count' ];
|
23 |
+
}
|
24 |
+
}
|
25 |
+
return $counts;
|
26 |
+
}
|
27 |
+
|
28 |
public function countForScan( string $scan ) :int {
|
29 |
return $this->reset()
|
30 |
->filterByNotIgnored()
|
src/lib/src/Modules/AuditTrail/Lib/AuditWriter.php
CHANGED
@@ -23,6 +23,9 @@ class AuditWriter extends EventsListener {
|
|
23 |
*/
|
24 |
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
25 |
$con = $this->getCon();
|
|
|
|
|
|
|
26 |
if ( $def[ 'audit' ] && empty( $meta[ 'suppress_audit' ] ) ) { // only audit if it's an auditable event
|
27 |
$entry = new AuditTrail\EntryVO();
|
28 |
$entry->rid = $con->getShortRequestId();
|
23 |
*/
|
24 |
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
25 |
$con = $this->getCon();
|
26 |
+
|
27 |
+
$meta = apply_filters( 'shield/audit_event_meta', $meta, $evt );
|
28 |
+
|
29 |
if ( $def[ 'audit' ] && empty( $meta[ 'suppress_audit' ] ) ) { // only audit if it's an auditable event
|
30 |
$entry = new AuditTrail\EntryVO();
|
31 |
$entry->rid = $con->getShortRequestId();
|
src/lib/src/Modules/Autoupdates/Processor.php
CHANGED
@@ -71,13 +71,13 @@ class Processor extends BaseShield\Processor {
|
|
71 |
private function trackAssetsVersions() {
|
72 |
$aAssVers = $this->getTrackedAssetsVersions();
|
73 |
|
74 |
-
$
|
75 |
-
foreach ( array_keys( $
|
76 |
-
$aAssVers[ 'plugins' ][ $
|
77 |
}
|
78 |
-
$
|
79 |
-
foreach ( array_keys( $
|
80 |
-
$aAssVers[ 'themes' ][ $
|
81 |
}
|
82 |
$this->assetsVersions = $aAssVers;
|
83 |
}
|
71 |
private function trackAssetsVersions() {
|
72 |
$aAssVers = $this->getTrackedAssetsVersions();
|
73 |
|
74 |
+
$WPP = Services::WpPlugins();
|
75 |
+
foreach ( array_keys( $WPP->getUpdates() ) as $file ) {
|
76 |
+
$aAssVers[ 'plugins' ][ $file ] = $WPP->getPluginAsVo( $file )->Version;
|
77 |
}
|
78 |
+
$WPT = Services::WpThemes();
|
79 |
+
foreach ( array_keys( $WPT->getUpdates() ) as $file ) {
|
80 |
+
$aAssVers[ 'themes' ][ $file ] = $WPT->getTheme( $file )->get( 'Version' );
|
81 |
}
|
82 |
$this->assetsVersions = $aAssVers;
|
83 |
}
|
src/lib/src/Modules/Base/Lib/Rest/Utility/RestLocker.php
CHANGED
@@ -54,8 +54,7 @@ class RestLocker {
|
|
54 |
*/
|
55 |
private function getLockFile() {
|
56 |
try {
|
57 |
-
$
|
58 |
-
$file = path_join( $sBase, 'rest_process.lock' );
|
59 |
}
|
60 |
catch ( \Exception $e ) {
|
61 |
$file = false;
|
54 |
*/
|
55 |
private function getLockFile() {
|
56 |
try {
|
57 |
+
$file = path_join( $this->getRestRoute()->getWorkingDir(), 'rest_process.lock' );
|
|
|
58 |
}
|
59 |
catch ( \Exception $e ) {
|
60 |
$file = false;
|
src/lib/src/Modules/Base/ModCon.php
CHANGED
@@ -270,8 +270,8 @@ abstract class ModCon {
|
|
270 |
$this->loadProcessor();
|
271 |
}
|
272 |
try {
|
273 |
-
$
|
274 |
-
if ( !$
|
275 |
$this->doExecuteProcessor();
|
276 |
}
|
277 |
}
|
270 |
$this->loadProcessor();
|
271 |
}
|
272 |
try {
|
273 |
+
$skip = (bool)$opts->getFeatureProperty( 'skip_processor' );
|
274 |
+
if ( !$skip && !$this->isUpgrading() && $this->isModuleEnabled() && $this->isReadyToExecute() ) {
|
275 |
$this->doExecuteProcessor();
|
276 |
}
|
277 |
}
|
src/lib/src/Modules/Base/Options/WildCardOptions.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Options;
|
4 |
+
|
5 |
+
use function path_join;
|
6 |
+
|
7 |
+
class WildCardOptions {
|
8 |
+
|
9 |
+
const FILE_PATH_REL = 0;
|
10 |
+
const URL_PATH = 1;
|
11 |
+
|
12 |
+
public function clean( array $optValues, array $checks, int $dataType ) :array {
|
13 |
+
|
14 |
+
$optValues = $this->basicCleanValues( $optValues, $dataType );
|
15 |
+
$checks = $this->preProcessChecks( $checks, $dataType );
|
16 |
+
|
17 |
+
$cleanedValues = [];
|
18 |
+
foreach ( $optValues as $value ) {
|
19 |
+
|
20 |
+
$cleanedValues[ $value ] = $value;
|
21 |
+
|
22 |
+
$valueRegEx = $this->buildFullRegexValue( $value, $dataType );
|
23 |
+
foreach ( $checks as $check ) {
|
24 |
+
if ( preg_match( $valueRegEx, $check ) ) {
|
25 |
+
$cleanedValues[ $value ] = false;
|
26 |
+
break;
|
27 |
+
}
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
return array_values( array_filter( $cleanedValues ) );
|
32 |
+
}
|
33 |
+
|
34 |
+
protected function preProcessChecks( array $checks, int $type ) :array {
|
35 |
+
|
36 |
+
switch ( $type ) {
|
37 |
+
|
38 |
+
case self::FILE_PATH_REL:
|
39 |
+
$checks = array_merge( $checks, array_map( 'untrailingslashit', $checks ) );
|
40 |
+
break;
|
41 |
+
|
42 |
+
case self::URL_PATH:
|
43 |
+
$checks = array_map( function ( $path ) {
|
44 |
+
$path = '/'.ltrim( $path, '/' );
|
45 |
+
return '/'.trim( $path, '/' );
|
46 |
+
}, $checks );
|
47 |
+
$checks = array_merge( $checks, array_map( 'trailingslashit', $checks ) );
|
48 |
+
break;
|
49 |
+
|
50 |
+
default:
|
51 |
+
break;
|
52 |
+
}
|
53 |
+
|
54 |
+
return array_unique( $checks );
|
55 |
+
}
|
56 |
+
|
57 |
+
protected function basicCleanValues( array $optValues, int $type ) :array {
|
58 |
+
|
59 |
+
$optValues = array_filter( array_map( function ( $value ) {
|
60 |
+
return strtolower( trim( $value ) );
|
61 |
+
}, $optValues ) );
|
62 |
+
|
63 |
+
switch ( $type ) {
|
64 |
+
|
65 |
+
case self::FILE_PATH_REL:
|
66 |
+
$optValues = array_map( function ( string $relPath ) {
|
67 |
+
$relPath = wp_normalize_path( $relPath );
|
68 |
+
if ( strpos( $relPath, wp_normalize_path( ABSPATH ) ) === 0 ) {
|
69 |
+
$relPath = str_replace( wp_normalize_path( ABSPATH ), '', $relPath );
|
70 |
+
}
|
71 |
+
return ltrim( $relPath, '/' );
|
72 |
+
}, $optValues );
|
73 |
+
break;
|
74 |
+
|
75 |
+
case self::URL_PATH:
|
76 |
+
$optValues = array_map( function ( $path ) {
|
77 |
+
if ( strpos( $path, '*' ) !== 0 ) {
|
78 |
+
$path = '/'.ltrim( $path, '/' );
|
79 |
+
}
|
80 |
+
return $path;
|
81 |
+
}, $optValues );
|
82 |
+
break;
|
83 |
+
|
84 |
+
default:
|
85 |
+
break;
|
86 |
+
}
|
87 |
+
|
88 |
+
return array_unique( $optValues );
|
89 |
+
}
|
90 |
+
|
91 |
+
public function buildFullRegexValue( string $value, int $type ) :string {
|
92 |
+
$valueRegEx = $this->convertValueToRegEx( $value, $type );
|
93 |
+
|
94 |
+
switch ( $type ) {
|
95 |
+
case self::FILE_PATH_REL:
|
96 |
+
$fullValue = path_join( ABSPATH, $valueRegEx );
|
97 |
+
break;
|
98 |
+
|
99 |
+
case self::URL_PATH:
|
100 |
+
default:
|
101 |
+
$fullValue = $valueRegEx;
|
102 |
+
break;
|
103 |
+
}
|
104 |
+
|
105 |
+
return sprintf( '#^%s$#i', $fullValue );
|
106 |
+
}
|
107 |
+
|
108 |
+
protected function convertValueToRegEx( string $value, int $type ) :string {
|
109 |
+
|
110 |
+
switch ( $type ) {
|
111 |
+
case self::FILE_PATH_REL:
|
112 |
+
if ( preg_match( '#/$#', $value ) ) {
|
113 |
+
$value .= '*';
|
114 |
+
}
|
115 |
+
break;
|
116 |
+
|
117 |
+
case self::URL_PATH:
|
118 |
+
default:
|
119 |
+
break;
|
120 |
+
}
|
121 |
+
return str_replace( 'WILDCARDSTAR', '.*', preg_quote( str_replace( '*', 'WILDCARDSTAR', $value ), '#' ) );
|
122 |
+
}
|
123 |
+
}
|
src/lib/src/Modules/Base/UI.php
CHANGED
@@ -251,6 +251,7 @@ class UI {
|
|
251 |
],
|
252 |
'imgs' => [
|
253 |
'svgs' => [
|
|
|
254 |
'triangle' => $con->svgs->raw( 'bootstrap/triangle-fill.svg' ),
|
255 |
],
|
256 |
'favicon' => $urlBuilder->forImage( 'pluginlogo_24x24.png' ),
|
251 |
],
|
252 |
'imgs' => [
|
253 |
'svgs' => [
|
254 |
+
'ignore' => $con->svgs->raw( 'bootstrap/eye-slash-fill.svg' ),
|
255 |
'triangle' => $con->svgs->raw( 'bootstrap/triangle-fill.svg' ),
|
256 |
],
|
257 |
'favicon' => $urlBuilder->forImage( 'pluginlogo_24x24.png' ),
|
src/lib/src/Modules/BaseShield/ModCon.php
CHANGED
@@ -5,7 +5,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
8 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin;
|
9 |
use FernleafSystems\Wordpress\Services\Services;
|
10 |
use FernleafSystems\Wordpress\Services\Utilities;
|
11 |
|
@@ -21,6 +20,9 @@ class ModCon extends Base\ModCon {
|
|
21 |
*/
|
22 |
private static $bVisitorIsWhitelisted;
|
23 |
|
|
|
|
|
|
|
24 |
public function canCacheDirWrite() :bool {
|
25 |
return ( new Shield\Modules\Plugin\Lib\TestCacheDirWrite() )
|
26 |
->setMod( $this->getCon()->getModule_Plugin() )
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
|
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
9 |
use FernleafSystems\Wordpress\Services\Utilities;
|
10 |
|
20 |
*/
|
21 |
private static $bVisitorIsWhitelisted;
|
22 |
|
23 |
+
/**
|
24 |
+
* @deprecated 11.4
|
25 |
+
*/
|
26 |
public function canCacheDirWrite() :bool {
|
27 |
return ( new Shield\Modules\Plugin\Lib\TestCacheDirWrite() )
|
28 |
->setMod( $this->getCon()->getModule_Plugin() )
|
src/lib/src/Modules/CommentsFilter/ModCon.php
CHANGED
@@ -91,10 +91,7 @@ class ModCon extends BaseShield\ModCon {
|
|
91 |
$this->getOptions()->setOpt( 'enable_antibot_check', $enabled ? 'Y' : 'N' );
|
92 |
}
|
93 |
|
94 |
-
|
95 |
-
|
96 |
-
*/
|
97 |
-
public function getSpamBlacklistFile() {
|
98 |
-
return $this->getCon()->getPluginCachePath( 'spamblacklist.txt' );
|
99 |
}
|
100 |
}
|
91 |
$this->getOptions()->setOpt( 'enable_antibot_check', $enabled ? 'Y' : 'N' );
|
92 |
}
|
93 |
|
94 |
+
public function getSpamBlacklistFile() :string {
|
95 |
+
return $this->getCon()->paths->forCacheItem( 'spamblacklist.txt' );
|
|
|
|
|
|
|
96 |
}
|
97 |
}
|
src/lib/src/Modules/Email/Processor.php
CHANGED
@@ -153,16 +153,22 @@ class Processor extends BaseShield\Processor {
|
|
153 |
*/
|
154 |
public function setMailFrom( $from ) {
|
155 |
$DP = Services::Data();
|
156 |
-
|
|
|
|
|
|
|
|
|
|
|
157 |
if ( $DP->validEmail( $proposed ) ) {
|
158 |
$from = $proposed;
|
159 |
}
|
|
|
160 |
// We help out by trying to correct any funky "from" addresses
|
161 |
// So, at the very least, we don't fail on this for our emails.
|
162 |
if ( !$DP->validEmail( $from ) ) {
|
163 |
-
$
|
164 |
-
if ( !empty( $
|
165 |
-
$proposed = 'wordpress@'.$
|
166 |
if ( $DP->validEmail( $proposed ) ) {
|
167 |
$from = $proposed;
|
168 |
}
|
@@ -176,7 +182,11 @@ class Processor extends BaseShield\Processor {
|
|
176 |
* @return string
|
177 |
*/
|
178 |
public function setMailFromName( $name ) :string {
|
179 |
-
$proposed = apply_filters(
|
|
|
|
|
|
|
|
|
180 |
if ( !empty( $proposed ) ) {
|
181 |
$name = $proposed;
|
182 |
}
|
153 |
*/
|
154 |
public function setMailFrom( $from ) {
|
155 |
$DP = Services::Data();
|
156 |
+
|
157 |
+
$proposed = trim( (string)apply_filters(
|
158 |
+
'shield/email_from',
|
159 |
+
apply_filters( 'icwp_shield_from_email', $from )
|
160 |
+
) );
|
161 |
+
|
162 |
if ( $DP->validEmail( $proposed ) ) {
|
163 |
$from = $proposed;
|
164 |
}
|
165 |
+
|
166 |
// We help out by trying to correct any funky "from" addresses
|
167 |
// So, at the very least, we don't fail on this for our emails.
|
168 |
if ( !$DP->validEmail( $from ) ) {
|
169 |
+
$host = @parse_url( Services::WpGeneral()->getWpUrl(), PHP_URL_HOST );
|
170 |
+
if ( !empty( $host ) ) {
|
171 |
+
$proposed = 'wordpress@'.$host;
|
172 |
if ( $DP->validEmail( $proposed ) ) {
|
173 |
$from = $proposed;
|
174 |
}
|
182 |
* @return string
|
183 |
*/
|
184 |
public function setMailFromName( $name ) :string {
|
185 |
+
$proposed = apply_filters(
|
186 |
+
'shield/email_from_name',
|
187 |
+
apply_filters( 'icwp_shield_from_email_name', '' )
|
188 |
+
);
|
189 |
+
|
190 |
if ( !empty( $proposed ) ) {
|
191 |
$name = $proposed;
|
192 |
}
|
src/lib/src/Modules/Events/Lib/Reports/KeyStats.php
CHANGED
@@ -8,10 +8,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Reporting\Lib\Reports\BaseRe
|
|
8 |
|
9 |
class KeyStats extends BaseReporter {
|
10 |
|
11 |
-
|
12 |
-
* @inheritDoc
|
13 |
-
*/
|
14 |
-
public function build() {
|
15 |
$alerts = [];
|
16 |
|
17 |
/** @var Events\ModCon $mod */
|
8 |
|
9 |
class KeyStats extends BaseReporter {
|
10 |
|
11 |
+
public function build() :array {
|
|
|
|
|
|
|
12 |
$alerts = [];
|
13 |
|
14 |
/** @var Events\ModCon $mod */
|
src/lib/src/Modules/Events/Lib/Reports/ScanRepairs.php
DELETED
@@ -1,67 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Events\Lib\Reports;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Events as DBEvents;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Events;
|
7 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Options;
|
8 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Reporting\Lib\Reports\BaseReporter;
|
9 |
-
|
10 |
-
class ScanRepairs extends BaseReporter {
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @inheritDoc
|
14 |
-
*/
|
15 |
-
public function build() {
|
16 |
-
$aAlerts = [];
|
17 |
-
|
18 |
-
/** @var Events\ModCon $mod */
|
19 |
-
$mod = $this->getMod();
|
20 |
-
/** @var DBEvents\Select $selectorEvents */
|
21 |
-
$selectorEvents = $mod->getDbHandler_Events()->getQuerySelector();
|
22 |
-
/** @var Events\Strings $strings */
|
23 |
-
$strings = $mod->getStrings();
|
24 |
-
|
25 |
-
$report = $this->getReport();
|
26 |
-
|
27 |
-
$counts = [];
|
28 |
-
|
29 |
-
/** @var Options $oHGOptions */
|
30 |
-
$oHGOptions = $this->getCon()->getModule_HackGuard()->getOptions();
|
31 |
-
foreach ( $oHGOptions->getScanSlugs() as $scan ) {
|
32 |
-
try {
|
33 |
-
$event = $scan.'_item_repair_success';
|
34 |
-
$count = $selectorEvents
|
35 |
-
->filterByEvent( $event )
|
36 |
-
->filterByBoundary( $report->interval_start_at, $report->interval_end_at )
|
37 |
-
->count();
|
38 |
-
if ( $count > 0 ) {
|
39 |
-
$counts[ $scan ] = [
|
40 |
-
'count' => $count,
|
41 |
-
'name' => $strings->getEventName( $event ),
|
42 |
-
];
|
43 |
-
}
|
44 |
-
}
|
45 |
-
catch ( \Exception $e ) {
|
46 |
-
}
|
47 |
-
}
|
48 |
-
|
49 |
-
if ( count( $counts ) > 0 ) {
|
50 |
-
$aAlerts[] = $this->getMod()->renderTemplate(
|
51 |
-
'/components/reports/mod/events/info_keystats.twig',
|
52 |
-
[
|
53 |
-
'vars' => [
|
54 |
-
'counts' => $counts
|
55 |
-
],
|
56 |
-
'strings' => [
|
57 |
-
'title' => __( 'Scanner Repairs', 'wp-simple-firewall' ),
|
58 |
-
],
|
59 |
-
'hrefs' => [
|
60 |
-
],
|
61 |
-
]
|
62 |
-
);
|
63 |
-
}
|
64 |
-
|
65 |
-
return $aAlerts;
|
66 |
-
}
|
67 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Modules/Events/Lib/StatsWriter.php
CHANGED
@@ -4,7 +4,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Events\Lib;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\HandlerConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Events\Handler;
|
7 |
-
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
class StatsWriter extends EventsListener {
|
10 |
|
@@ -23,7 +22,10 @@ class StatsWriter extends EventsListener {
|
|
23 |
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
24 |
if ( !empty( $def[ 'stat' ] ) ) {
|
25 |
$stats = $this->getEventStats();
|
26 |
-
$stats[ $evt ]
|
|
|
|
|
|
|
27 |
$this->setEventStats( $stats );
|
28 |
}
|
29 |
}
|
@@ -40,16 +42,16 @@ class StatsWriter extends EventsListener {
|
|
40 |
/**
|
41 |
* @return int[]
|
42 |
*/
|
43 |
-
public function getEventStats() {
|
44 |
return is_array( $this->aEventStats ) ? $this->aEventStats : [];
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
-
* @param int[] $
|
49 |
* @return $this
|
50 |
*/
|
51 |
-
public function setEventStats( $
|
52 |
-
$this->aEventStats = $
|
53 |
return $this;
|
54 |
}
|
55 |
}
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\HandlerConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Events\Handler;
|
|
|
7 |
|
8 |
class StatsWriter extends EventsListener {
|
9 |
|
22 |
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
23 |
if ( !empty( $def[ 'stat' ] ) ) {
|
24 |
$stats = $this->getEventStats();
|
25 |
+
if ( !isset( $stats[ $evt ] ) ) {
|
26 |
+
$stats[ $evt ] = 0;
|
27 |
+
}
|
28 |
+
$stats[ $evt ]++;
|
29 |
$this->setEventStats( $stats );
|
30 |
}
|
31 |
}
|
42 |
/**
|
43 |
* @return int[]
|
44 |
*/
|
45 |
+
public function getEventStats() :array {
|
46 |
return is_array( $this->aEventStats ) ? $this->aEventStats : [];
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
+
* @param int[] $stats
|
51 |
* @return $this
|
52 |
*/
|
53 |
+
public function setEventStats( array $stats = [] ) {
|
54 |
+
$this->aEventStats = $stats;
|
55 |
return $this;
|
56 |
}
|
57 |
}
|
src/lib/src/Modules/Events/Reporting.php
CHANGED
@@ -7,15 +7,6 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Events\Lib\Reports;
|
|
7 |
|
8 |
class Reporting extends Base\Reporting {
|
9 |
|
10 |
-
/**
|
11 |
-
* @inheritDoc
|
12 |
-
*/
|
13 |
-
protected function enumAlertReporters() :array {
|
14 |
-
return [
|
15 |
-
new Reports\ScanRepairs(),
|
16 |
-
];
|
17 |
-
}
|
18 |
-
|
19 |
/**
|
20 |
* @inheritDoc
|
21 |
*/
|
7 |
|
8 |
class Reporting extends Base\Reporting {
|
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
/**
|
11 |
* @inheritDoc
|
12 |
*/
|
src/lib/src/Modules/Events/Strings.php
CHANGED
@@ -15,10 +15,10 @@ class Strings extends Base\Strings {
|
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
-
* @param bool $
|
19 |
* @return string[]
|
20 |
*/
|
21 |
-
public function getEventNames( $
|
22 |
$names = [
|
23 |
'test_cron_run' => __( 'Test Cron Run', 'wp-simple-firewall' ),
|
24 |
'import_notify_sent' => __( 'Import Notify Sent', 'wp-simple-firewall' ),
|
@@ -37,6 +37,10 @@ class Strings extends Base\Strings {
|
|
37 |
'ip_offense' => __( 'Offense Triggered', 'wp-simple-firewall' ),
|
38 |
'ip_blocked' => __( 'IP Blocked', 'wp-simple-firewall' ),
|
39 |
'ip_unblock_flag' => __( 'IP Unblocked Using Flag File', 'wp-simple-firewall' ),
|
|
|
|
|
|
|
|
|
40 |
'antibot_fail' => __( 'Fail AntiBot Test', 'wp-simple-firewall' ),
|
41 |
'antibot_pass' => __( 'Pass AntiBot Test', 'wp-simple-firewall' ),
|
42 |
'bottrack_404' => sprintf( '%s: %s',
|
@@ -143,18 +147,9 @@ class Strings extends Base\Strings {
|
|
143 |
__( 'Scan Item Discovered', 'wp-simple-firewall' ),
|
144 |
__( 'Vulnerabilities', 'wp-simple-firewall' )
|
145 |
),
|
146 |
-
'
|
147 |
-
'
|
148 |
-
'
|
149 |
-
'mal_item_repair_fail' => __( 'Malware File Repair Failure', 'wp-simple-firewall' ),
|
150 |
-
'ptg_item_repair_success' => __( 'Plugin/Theme File Repair Success', 'wp-simple-firewall' ),
|
151 |
-
'ptg_item_repair_fail' => __( 'Plugin/Theme File Repair Failure', 'wp-simple-firewall' ),
|
152 |
-
'ufc_item_repair_success' => __( 'Unrecognised File Deleted Success', 'wp-simple-firewall' ),
|
153 |
-
'ufc_item_repair_fail' => __( 'Unrecognised File Deleted Failure', 'wp-simple-firewall' ),
|
154 |
-
'wcf_item_repair_success' => __( 'WordPress Core File Repair Success', 'wp-simple-firewall' ),
|
155 |
-
'wcf_item_repair_fail' => __( 'WordPress Core File Repair Failure', 'wp-simple-firewall' ),
|
156 |
-
'wpv_item_repair_success' => __( 'Vulnerable WordPress Plugin Repair Success', 'wp-simple-firewall' ),
|
157 |
-
'wpv_item_repair_fail' => __( 'Vulnerable WordPress Plugin Repair Failure', 'wp-simple-firewall' ),
|
158 |
'2fa_backupcode_verified' => __( '', 'wp-simple-firewall' ),
|
159 |
'2fa_backupcode_fail' => __( '', 'wp-simple-firewall' ),
|
160 |
'2fa_email_verified' => __( '', 'wp-simple-firewall' ),
|
@@ -271,7 +266,7 @@ class Strings extends Base\Strings {
|
|
271 |
'lic_fail_deactivate' => __( 'License Deactivated', 'wp-simple-firewall' ),
|
272 |
];
|
273 |
|
274 |
-
if ( $
|
275 |
foreach ( $names as $key => $name ) {
|
276 |
if ( empty( $name ) ) {
|
277 |
$names[ $key ] = ucwords( str_replace( '_', ' ', $key ) );
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
+
* @param bool $auto
|
19 |
* @return string[]
|
20 |
*/
|
21 |
+
public function getEventNames( bool $auto = true ) :array {
|
22 |
$names = [
|
23 |
'test_cron_run' => __( 'Test Cron Run', 'wp-simple-firewall' ),
|
24 |
'import_notify_sent' => __( 'Import Notify Sent', 'wp-simple-firewall' ),
|
37 |
'ip_offense' => __( 'Offense Triggered', 'wp-simple-firewall' ),
|
38 |
'ip_blocked' => __( 'IP Blocked', 'wp-simple-firewall' ),
|
39 |
'ip_unblock_flag' => __( 'IP Unblocked Using Flag File', 'wp-simple-firewall' ),
|
40 |
+
'ip_block_auto' => __( 'IP Block Add Auto', 'wp-simple-firewall' ),
|
41 |
+
'ip_block_manual' => __( 'IP Block Add Manual', 'wp-simple-firewall' ),
|
42 |
+
'ip_bypass_add' => __( 'IP Bypass Add', 'wp-simple-firewall' ),
|
43 |
+
'ip_bypass_remove' => __( 'IP Bypass Remove', 'wp-simple-firewall' ),
|
44 |
'antibot_fail' => __( 'Fail AntiBot Test', 'wp-simple-firewall' ),
|
45 |
'antibot_pass' => __( 'Pass AntiBot Test', 'wp-simple-firewall' ),
|
46 |
'bottrack_404' => sprintf( '%s: %s',
|
147 |
__( 'Scan Item Discovered', 'wp-simple-firewall' ),
|
148 |
__( 'Vulnerabilities', 'wp-simple-firewall' )
|
149 |
),
|
150 |
+
'scan_item_delete_success' => __( 'Scan Item Delete Success', 'wp-simple-firewall' ),
|
151 |
+
'scan_item_repair_success' => __( 'Scan Item Repair Success', 'wp-simple-firewall' ),
|
152 |
+
'scan_item_repair_fail' => __( 'Scan Item Repair Failure', 'wp-simple-firewall' ),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
'2fa_backupcode_verified' => __( '', 'wp-simple-firewall' ),
|
154 |
'2fa_backupcode_fail' => __( '', 'wp-simple-firewall' ),
|
155 |
'2fa_email_verified' => __( '', 'wp-simple-firewall' ),
|
266 |
'lic_fail_deactivate' => __( 'License Deactivated', 'wp-simple-firewall' ),
|
267 |
];
|
268 |
|
269 |
+
if ( $auto ) {
|
270 |
foreach ( $names as $key => $name ) {
|
271 |
if ( empty( $name ) ) {
|
272 |
$names[ $key ] = ucwords( str_replace( '_', ' ', $key ) );
|
src/lib/src/Modules/HackGuard/AjaxHandler.php
CHANGED
@@ -16,6 +16,10 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
16 |
$req = Services::Request();
|
17 |
switch ( $action ) {
|
18 |
|
|
|
|
|
|
|
|
|
19 |
case 'scans_start':
|
20 |
$response = $this->ajaxExec_StartScans();
|
21 |
break;
|
@@ -351,33 +355,40 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
351 |
private function ajaxExec_CheckScans() :array {
|
352 |
/** @var ModCon $mod */
|
353 |
$mod = $this->getMod();
|
354 |
-
/** @var Strings $
|
355 |
-
$
|
356 |
-
/** @var Shield\Databases\ScanQueue\Select $
|
357 |
-
$
|
358 |
-
|
359 |
-
$
|
360 |
-
$
|
361 |
-
$
|
362 |
-
if ( $
|
363 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
364 |
}
|
365 |
else {
|
366 |
-
$
|
|
|
367 |
}
|
368 |
|
369 |
return [
|
370 |
'success' => true,
|
371 |
-
'running' => $
|
372 |
'vars' => [
|
373 |
'progress_html' => $mod->renderTemplate(
|
374 |
'/wpadmin_pages/insights/scans/modal/progress_snippet.twig',
|
375 |
[
|
376 |
'current_scan' => __( 'Current Scan', 'wp-simple-firewall' ),
|
377 |
-
'scan' => $
|
378 |
-
'remaining_scans' =>
|
379 |
-
|
380 |
-
'progress' => 100*$oQueCon->getScanJobProgress(),
|
381 |
'patience_1' => __( 'Please be patient.', 'wp-simple-firewall' ),
|
382 |
'patience_2' => __( 'Some scans can take quite a while to complete.', 'wp-simple-firewall' ),
|
383 |
'completed' => __( 'Scans completed.', 'wp-simple-firewall' ).' '.__( 'Reloading page', 'wp-simple-firewall' ).'...'
|
@@ -442,4 +453,19 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
442 |
'message' => $msg,
|
443 |
];
|
444 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
445 |
}
|
16 |
$req = Services::Request();
|
17 |
switch ( $action ) {
|
18 |
|
19 |
+
case 'scanresults_action':
|
20 |
+
$response = $this->ajaxExec_ScanTableAction();
|
21 |
+
break;
|
22 |
+
|
23 |
case 'scans_start':
|
24 |
$response = $this->ajaxExec_StartScans();
|
25 |
break;
|
355 |
private function ajaxExec_CheckScans() :array {
|
356 |
/** @var ModCon $mod */
|
357 |
$mod = $this->getMod();
|
358 |
+
/** @var Strings $strings */
|
359 |
+
$strings = $mod->getStrings();
|
360 |
+
/** @var Shield\Databases\ScanQueue\Select $selector */
|
361 |
+
$selector = $mod->getDbHandler_ScanQueue()->getQuerySelector();
|
362 |
+
|
363 |
+
$queueCon = $mod->getScanQueueController();
|
364 |
+
$current = $selector->getCurrentScan();
|
365 |
+
$hasCurrent = !empty( $current );
|
366 |
+
if ( $hasCurrent ) {
|
367 |
+
$currentScan = $strings->getScanName( $current );
|
368 |
+
}
|
369 |
+
else {
|
370 |
+
$currentScan = __( 'No scan running.', 'wp-simple-firewall' );
|
371 |
+
}
|
372 |
+
|
373 |
+
if ( count( $selector->getInitiatedScans() ) === 0 ) {
|
374 |
+
$remainingScans = __( 'No scans remaining.', 'wp-simple-firewall' );
|
375 |
}
|
376 |
else {
|
377 |
+
$remainingScans = sprintf( __( '%s of %s scans remaining.', 'wp-simple-firewall' ),
|
378 |
+
count( $selector->getUnfinishedScans() ), count( $selector->getInitiatedScans() ) );
|
379 |
}
|
380 |
|
381 |
return [
|
382 |
'success' => true,
|
383 |
+
'running' => $queueCon->getScansRunningStates(),
|
384 |
'vars' => [
|
385 |
'progress_html' => $mod->renderTemplate(
|
386 |
'/wpadmin_pages/insights/scans/modal/progress_snippet.twig',
|
387 |
[
|
388 |
'current_scan' => __( 'Current Scan', 'wp-simple-firewall' ),
|
389 |
+
'scan' => $currentScan,
|
390 |
+
'remaining_scans' => $remainingScans,
|
391 |
+
'progress' => 100*$queueCon->getScanJobProgress(),
|
|
|
392 |
'patience_1' => __( 'Please be patient.', 'wp-simple-firewall' ),
|
393 |
'patience_2' => __( 'Some scans can take quite a while to complete.', 'wp-simple-firewall' ),
|
394 |
'completed' => __( 'Scans completed.', 'wp-simple-firewall' ).' '.__( 'Reloading page', 'wp-simple-firewall' ).'...'
|
453 |
'message' => $msg,
|
454 |
];
|
455 |
}
|
456 |
+
|
457 |
+
private function ajaxExec_ScanTableAction() :array {
|
458 |
+
try {
|
459 |
+
return ( new Lib\ScanTables\DelegateAjaxHandler() )
|
460 |
+
->setMod( $this->getMod() )
|
461 |
+
->processAjaxAction();
|
462 |
+
}
|
463 |
+
catch ( \Exception $e ) {
|
464 |
+
return [
|
465 |
+
'success' => false,
|
466 |
+
'page_reload' => true,
|
467 |
+
'message' => $e->getMessage(),
|
468 |
+
];
|
469 |
+
}
|
470 |
+
}
|
471 |
}
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/FileLockerController.php
CHANGED
@@ -244,10 +244,4 @@ class FileLockerController {
|
|
244 |
protected function setState( array $state ) {
|
245 |
$this->getOptions()->setOpt( 'filelocker_state', $state );
|
246 |
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* @deprecated 11.4
|
250 |
-
*/
|
251 |
-
public function processFileLocks() {
|
252 |
-
}
|
253 |
}
|
244 |
protected function setState( array $state ) {
|
245 |
$this->getOptions()->setOpt( 'filelocker_state', $state );
|
246 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
}
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/Accept.php
CHANGED
@@ -13,11 +13,9 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
13 |
class Accept extends BaseOps {
|
14 |
|
15 |
/**
|
16 |
-
* @param FileLocker\EntryVO $lock
|
17 |
-
* @return bool
|
18 |
* @throws \ErrorException
|
19 |
*/
|
20 |
-
public function run( $lock ) {
|
21 |
/** @var ModCon $mod */
|
22 |
$mod = $this->getMod();
|
23 |
|
13 |
class Accept extends BaseOps {
|
14 |
|
15 |
/**
|
|
|
|
|
16 |
* @throws \ErrorException
|
17 |
*/
|
18 |
+
public function run( FileLocker\EntryVO $lock ) :bool {
|
19 |
/** @var ModCon $mod */
|
20 |
$mod = $this->getMod();
|
21 |
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/Diff.php
CHANGED
@@ -14,18 +14,17 @@ class Diff extends BaseOps {
|
|
14 |
|
15 |
/**
|
16 |
* @param FileLocker\EntryVO $lock
|
17 |
-
* @return
|
18 |
* @throws \Exception
|
19 |
*/
|
20 |
-
public function run( $lock ) {
|
21 |
-
|
22 |
-
$oFS = Services::WpFs();
|
23 |
|
24 |
-
if ( !$
|
25 |
throw new \Exception( __( 'File is missing or could not be read.', 'wp-simple-firewall' ) );
|
26 |
}
|
27 |
|
28 |
-
$current =
|
29 |
if ( empty( $current ) ) {
|
30 |
throw new \Exception( __( 'File is empty or could not be read.', 'wp-simple-firewall' ) );
|
31 |
}
|
@@ -48,21 +47,21 @@ class Diff extends BaseOps {
|
|
48 |
}
|
49 |
|
50 |
/**
|
51 |
-
* @param string $
|
52 |
-
* @param string $
|
53 |
* @return string
|
54 |
* @throws \Exception
|
55 |
*/
|
56 |
-
private function useWpHashes( $
|
57 |
-
$
|
58 |
-
if ( !is_array( $
|
59 |
throw new \Exception( 'Could not get a valid diff for this file.' );
|
60 |
}
|
61 |
return sprintf( '<style>%s</style>%s',
|
62 |
'table.diff.diff-wrapper tbody tr td:nth-child(2){ width:auto;}'.
|
63 |
'table.diff.diff-wrapper { table-layout: auto;}'.
|
64 |
-
base64_decode( $
|
65 |
-
base64_decode( $
|
66 |
);
|
67 |
}
|
68 |
|
14 |
|
15 |
/**
|
16 |
* @param FileLocker\EntryVO $lock
|
17 |
+
* @return string
|
18 |
* @throws \Exception
|
19 |
*/
|
20 |
+
public function run( FileLocker\EntryVO $lock ) {
|
21 |
+
$FS = Services::WpFs();
|
|
|
22 |
|
23 |
+
if ( !$FS->isFile( $lock->file ) ) {
|
24 |
throw new \Exception( __( 'File is missing or could not be read.', 'wp-simple-firewall' ) );
|
25 |
}
|
26 |
|
27 |
+
$current = $FS->getFileContent( $lock->file );
|
28 |
if ( empty( $current ) ) {
|
29 |
throw new \Exception( __( 'File is empty or could not be read.', 'wp-simple-firewall' ) );
|
30 |
}
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
+
* @param string $original
|
51 |
+
* @param string $current
|
52 |
* @return string
|
53 |
* @throws \Exception
|
54 |
*/
|
55 |
+
private function useWpHashes( $original, $current ) :string {
|
56 |
+
$res = ( new WpHashes\Util\Diff() )->getDiff( $original, $current );
|
57 |
+
if ( !is_array( $res ) || empty( $res[ 'html' ] ) ) {
|
58 |
throw new \Exception( 'Could not get a valid diff for this file.' );
|
59 |
}
|
60 |
return sprintf( '<style>%s</style>%s',
|
61 |
'table.diff.diff-wrapper tbody tr td:nth-child(2){ width:auto;}'.
|
62 |
'table.diff.diff-wrapper { table-layout: auto;}'.
|
63 |
+
base64_decode( $res[ 'html' ][ 'css_default' ] ),
|
64 |
+
base64_decode( $res[ 'html' ][ 'content' ] )
|
65 |
);
|
66 |
}
|
67 |
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/Restore.php
CHANGED
@@ -12,23 +12,19 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
12 |
*/
|
13 |
class Restore extends BaseOps {
|
14 |
|
15 |
-
|
16 |
-
* @param Databases\FileLocker\EntryVO $oRecord
|
17 |
-
* @return mixed
|
18 |
-
*/
|
19 |
-
public function run( $oRecord ) {
|
20 |
$bReverted = Services::WpFs()->putFileContent(
|
21 |
-
$
|
22 |
( new ReadOriginalFileContent() )
|
23 |
->setMod( $this->getMod() )
|
24 |
-
->run( $
|
25 |
);
|
26 |
if ( $bReverted ) {
|
27 |
/** @var ModCon $mod */
|
28 |
$mod = $this->getMod();
|
29 |
-
/** @var Databases\FileLocker\Update $
|
30 |
-
$
|
31 |
-
$
|
32 |
$this->clearFileLocksCache();
|
33 |
}
|
34 |
return $bReverted;
|
12 |
*/
|
13 |
class Restore extends BaseOps {
|
14 |
|
15 |
+
public function run( Databases\FileLocker\EntryVO $record ) :bool {
|
|
|
|
|
|
|
|
|
16 |
$bReverted = Services::WpFs()->putFileContent(
|
17 |
+
$record->file,
|
18 |
( new ReadOriginalFileContent() )
|
19 |
->setMod( $this->getMod() )
|
20 |
+
->run( $record )
|
21 |
);
|
22 |
if ( $bReverted ) {
|
23 |
/** @var ModCon $mod */
|
24 |
$mod = $this->getMod();
|
25 |
+
/** @var Databases\FileLocker\Update $update */
|
26 |
+
$update = $mod->getDbHandler_FileLocker()->getQueryUpdater();
|
27 |
+
$update->markReverted( $record );
|
28 |
$this->clearFileLocksCache();
|
29 |
}
|
30 |
return $bReverted;
|
src/lib/src/Modules/HackGuard/Lib/Reports/FileLockerAlerts.php
CHANGED
@@ -8,21 +8,18 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Reporting\Lib\Reports\BaseRe
|
|
8 |
|
9 |
class FileLockerAlerts extends BaseReporter {
|
10 |
|
11 |
-
|
12 |
-
|
13 |
-
*/
|
14 |
-
public function build() {
|
15 |
-
$aAlerts = [];
|
16 |
|
17 |
/** @var HackGuard\ModCon $mod */
|
18 |
$mod = $this->getMod();
|
19 |
|
20 |
-
$
|
21 |
->setMod( $this->getMod() );
|
22 |
-
$
|
23 |
|
24 |
-
if ( count( $
|
25 |
-
$
|
26 |
'/components/reports/mod/hack_protect/alert_filelocker.twig',
|
27 |
[
|
28 |
'vars' => [
|
@@ -31,7 +28,7 @@ class FileLockerAlerts extends BaseReporter {
|
|
31 |
'strings' => [
|
32 |
'title' => __( 'File Locker Changes Detected', 'wp-simple-firewall' ),
|
33 |
'file_changed' => __( 'Changes have been detected in the contents of critical files.', 'wp-simple-firewall' ),
|
34 |
-
'total_files' => sprintf( '%s: %s', __( 'Total Changed Files', 'wp-simple-firewall' ), count( $
|
35 |
'view_results' => __( 'Click Here To View File Locker Results', 'wp-simple-firewall' ),
|
36 |
],
|
37 |
'hrefs' => [
|
@@ -39,23 +36,23 @@ class FileLockerAlerts extends BaseReporter {
|
|
39 |
],
|
40 |
]
|
41 |
);
|
42 |
-
$this->markAlertsAsNotified( $
|
43 |
-
$
|
44 |
}
|
45 |
|
46 |
-
return $
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
-
* @param FileLocker\EntryVO[] $
|
51 |
*/
|
52 |
-
private function markAlertsAsNotified( $
|
53 |
/** @var HackGuard\ModCon $mod */
|
54 |
$mod = $this->getMod();
|
55 |
-
/** @var FileLocker\Update $
|
56 |
-
$
|
57 |
-
foreach ( $
|
58 |
-
$
|
59 |
}
|
60 |
}
|
61 |
}
|
8 |
|
9 |
class FileLockerAlerts extends BaseReporter {
|
10 |
|
11 |
+
public function build() :array {
|
12 |
+
$alerts = [];
|
|
|
|
|
|
|
13 |
|
14 |
/** @var HackGuard\ModCon $mod */
|
15 |
$mod = $this->getMod();
|
16 |
|
17 |
+
$lockOps = ( new HackGuard\Lib\FileLocker\Ops\LoadFileLocks() )
|
18 |
->setMod( $this->getMod() );
|
19 |
+
$notNotified = $lockOps->withProblemsNotNotified();
|
20 |
|
21 |
+
if ( count( $notNotified ) > 0 ) {
|
22 |
+
$alerts[] = $this->getMod()->renderTemplate(
|
23 |
'/components/reports/mod/hack_protect/alert_filelocker.twig',
|
24 |
[
|
25 |
'vars' => [
|
28 |
'strings' => [
|
29 |
'title' => __( 'File Locker Changes Detected', 'wp-simple-firewall' ),
|
30 |
'file_changed' => __( 'Changes have been detected in the contents of critical files.', 'wp-simple-firewall' ),
|
31 |
+
'total_files' => sprintf( '%s: %s', __( 'Total Changed Files', 'wp-simple-firewall' ), count( $notNotified ) ),
|
32 |
'view_results' => __( 'Click Here To View File Locker Results', 'wp-simple-firewall' ),
|
33 |
],
|
34 |
'hrefs' => [
|
36 |
],
|
37 |
]
|
38 |
);
|
39 |
+
$this->markAlertsAsNotified( $notNotified );
|
40 |
+
$lockOps->clearLocksCache();
|
41 |
}
|
42 |
|
43 |
+
return $alerts;
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
+
* @param FileLocker\EntryVO[] $setNotified
|
48 |
*/
|
49 |
+
private function markAlertsAsNotified( $setNotified ) {
|
50 |
/** @var HackGuard\ModCon $mod */
|
51 |
$mod = $this->getMod();
|
52 |
+
/** @var FileLocker\Update $updater */
|
53 |
+
$updater = $mod->getDbHandler_FileLocker()->getQueryUpdater();
|
54 |
+
foreach ( $setNotified as $entry ) {
|
55 |
+
$updater->markNotified( $entry );
|
56 |
}
|
57 |
}
|
58 |
}
|
src/lib/src/Modules/HackGuard/Lib/Reports/ScanAlerts.php
CHANGED
@@ -9,13 +9,7 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
9 |
|
10 |
class ScanAlerts extends BaseReporter {
|
11 |
|
12 |
-
|
13 |
-
* @inheritDoc
|
14 |
-
*/
|
15 |
-
public function build() {
|
16 |
-
/** @var HackGuard\ModCon $mod */
|
17 |
-
$mod = $this->getMod();
|
18 |
-
|
19 |
$alerts = [];
|
20 |
|
21 |
/** @var HackGuard\Strings $strings */
|
@@ -44,6 +38,9 @@ class ScanAlerts extends BaseReporter {
|
|
44 |
'strings' => [
|
45 |
'title' => __( 'New Scan Results', 'wp-simple-firewall' ),
|
46 |
'view_results' => __( 'Click Here To View Scan Results Details', 'wp-simple-firewall' ),
|
|
|
|
|
|
|
47 |
],
|
48 |
'hrefs' => [
|
49 |
'view_results' => $this->getCon()
|
9 |
|
10 |
class ScanAlerts extends BaseReporter {
|
11 |
|
12 |
+
public function build() :array {
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
$alerts = [];
|
14 |
|
15 |
/** @var HackGuard\Strings $strings */
|
38 |
'strings' => [
|
39 |
'title' => __( 'New Scan Results', 'wp-simple-firewall' ),
|
40 |
'view_results' => __( 'Click Here To View Scan Results Details', 'wp-simple-firewall' ),
|
41 |
+
'note_changes' => sprintf( '%s: %s', __( 'Note', 'wp-simple-firewall' ),
|
42 |
+
__( 'Depending on previous actions taken on the site or file system changes, these results may no longer be available to view.', 'wp-simple-firewall' ) ),
|
43 |
+
|
44 |
],
|
45 |
'hrefs' => [
|
46 |
'view_results' => $this->getCon()
|
src/lib/src/Modules/HackGuard/Lib/Reports/ScanRepairs.php
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Reports;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\AuditTrail as DBAudit;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Events as DBEvents;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Events;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Reporting\Lib\Reports\BaseReporter;
|
9 |
+
|
10 |
+
class ScanRepairs extends BaseReporter {
|
11 |
+
|
12 |
+
public function build() :array {
|
13 |
+
$alerts = [];
|
14 |
+
|
15 |
+
$modEvents = $this->getCon()->getModule_Events();
|
16 |
+
/** @var DBEvents\Select $selectorEvents */
|
17 |
+
$selectorEvents = $this->getCon()
|
18 |
+
->getModule_Events()
|
19 |
+
->getDbHandler_Events()
|
20 |
+
->getQuerySelector();
|
21 |
+
/** @var Events\Strings $strings */
|
22 |
+
$strings = $modEvents->getStrings();
|
23 |
+
|
24 |
+
$report = $this->getReport();
|
25 |
+
|
26 |
+
$repairs = [];
|
27 |
+
$repairEvents = [
|
28 |
+
'scan_item_repair_success',
|
29 |
+
'scan_item_repair_fail',
|
30 |
+
'scan_item_delete_success',
|
31 |
+
];
|
32 |
+
|
33 |
+
$total = 0;
|
34 |
+
foreach ( $repairEvents as $event ) {
|
35 |
+
$eventTotal = $selectorEvents
|
36 |
+
->filterByBoundary( $report->interval_start_at, $report->interval_end_at )
|
37 |
+
->sumEvent( $event );
|
38 |
+
$total += $eventTotal;
|
39 |
+
|
40 |
+
if ( $eventTotal > 0 ) {
|
41 |
+
/** @var DBAudit\Select $auditSelector */
|
42 |
+
$auditSelector = $this->getCon()
|
43 |
+
->getModule_AuditTrail()
|
44 |
+
->getDbHandler_AuditTrail()
|
45 |
+
->getQuerySelector();
|
46 |
+
/** @var DBAudit\EntryVO[] $audits */
|
47 |
+
$audits = $auditSelector->filterByEvent( $event )
|
48 |
+
->filterByBoundary( $report->interval_start_at, $report->interval_end_at )
|
49 |
+
->setLimit( 10 )
|
50 |
+
->query();
|
51 |
+
|
52 |
+
$repairs[] = [
|
53 |
+
'count' => $eventTotal,
|
54 |
+
'name' => $strings->getEventName( $event ),
|
55 |
+
'repairs' => array_filter( array_map( function ( $entry ) {
|
56 |
+
// see Base ItemActionHandler for audit event data
|
57 |
+
$fragment = $entry->meta[ 'path_full' ] ?? ( $entry->meta[ 'fragment' ] ?? false );
|
58 |
+
if ( !empty( $fragment ) ) {
|
59 |
+
$fragment = str_replace( wp_normalize_path( ABSPATH ), '', $fragment );
|
60 |
+
}
|
61 |
+
return $fragment;
|
62 |
+
}, $audits ) ),
|
63 |
+
];
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
if ( !empty( $repairs ) ) {
|
68 |
+
$alerts[] = $this->getMod()->renderTemplate(
|
69 |
+
'/components/reports/mod/hack_protect/alert_scanrepairs.twig',
|
70 |
+
[
|
71 |
+
'vars' => [
|
72 |
+
'total' => $total,
|
73 |
+
'repairs' => $repairs,
|
74 |
+
],
|
75 |
+
'strings' => [
|
76 |
+
'title' => \__( 'Scanner Repairs', 'wp-simple-firewall' ),
|
77 |
+
'audit_trail' => \__( 'View all repairs and file deletions in the Audit Trail', 'wp-simple-firewall' ),
|
78 |
+
],
|
79 |
+
'hrefs' => [
|
80 |
+
'audit_trail' => $this->getCon()
|
81 |
+
->getModule_Insights()
|
82 |
+
->getUrl_SubInsightsPage( 'audit' ),
|
83 |
+
],
|
84 |
+
]
|
85 |
+
);
|
86 |
+
}
|
87 |
+
|
88 |
+
return $alerts;
|
89 |
+
}
|
90 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/DelegateAjaxHandler.php
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
8 |
+
use FernleafSystems\Wordpress\Services\Services;
|
9 |
+
|
10 |
+
class DelegateAjaxHandler {
|
11 |
+
|
12 |
+
use Shield\Modules\ModConsumer;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return array
|
16 |
+
* @throws \Exception
|
17 |
+
*/
|
18 |
+
public function processAjaxAction() :array {
|
19 |
+
$action = Services::Request()->post( 'sub_action' );
|
20 |
+
switch ( $action ) {
|
21 |
+
|
22 |
+
case 'retrieve_table_data':
|
23 |
+
$response = $this->retrieveTableData();
|
24 |
+
break;
|
25 |
+
|
26 |
+
case 'delete':
|
27 |
+
case 'ignore':
|
28 |
+
case 'repair':
|
29 |
+
case 'repair-delete':
|
30 |
+
$response = $this->doAction( $action );
|
31 |
+
break;
|
32 |
+
|
33 |
+
case 'view_file':
|
34 |
+
$response = $this->viewFile();
|
35 |
+
break;
|
36 |
+
|
37 |
+
default:
|
38 |
+
throw new \Exception( 'Not a supported scan tables sub_action: '.$action );
|
39 |
+
}
|
40 |
+
return $response;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param string $action
|
45 |
+
* @return array
|
46 |
+
* @throws \Exception
|
47 |
+
*/
|
48 |
+
private function doAction( string $action ) :array {
|
49 |
+
/** @var HackGuard\ModCon $mod */
|
50 |
+
$mod = $this->getMod();
|
51 |
+
|
52 |
+
$success = false;
|
53 |
+
|
54 |
+
$items = $this->getItemIDs();
|
55 |
+
|
56 |
+
$resultIT = $mod->getDbHandler_ScanResults()->getIterator();
|
57 |
+
$resultIT->setSelector(
|
58 |
+
$resultIT->getSelector()->addWhereIn( 'id', $items )
|
59 |
+
);
|
60 |
+
|
61 |
+
$scanSlugs = [];
|
62 |
+
$successfulItems = [];
|
63 |
+
|
64 |
+
/** @var Databases\Scanner\EntryVO $entry */
|
65 |
+
foreach ( $resultIT as $entry ) {
|
66 |
+
$scanSlugs[ $entry->scan ] = 1;
|
67 |
+
if ( $mod->getScanCon( $entry->scan )->executeEntryAction( $entry, $action ) ) {
|
68 |
+
$successfulItems[] = $entry->id;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
$scanSlugs = array_keys( $scanSlugs );
|
73 |
+
|
74 |
+
foreach ( $scanSlugs as $slug ) {
|
75 |
+
$mod->getScanCon( $slug )->cleanStalesResults();
|
76 |
+
}
|
77 |
+
|
78 |
+
if ( count( $successfulItems ) === count( $items ) ) {
|
79 |
+
$success = true;
|
80 |
+
$msg = __( 'Action successful.' );
|
81 |
+
}
|
82 |
+
else {
|
83 |
+
$msg = __( 'An error occurred.' ).' '.__( 'Some items may not have been processed.' );
|
84 |
+
}
|
85 |
+
|
86 |
+
// We don't rescan for ignores or malware
|
87 |
+
$rescanSlugs = array_diff( $scanSlugs, [ HackGuard\Scan\Controller\Mal::SCAN_SLUG ] );
|
88 |
+
if ( !empty( $rescanSlugs ) && !in_array( $action, [ 'ignore' ] ) ) {
|
89 |
+
$mod->getScanQueueController()->startScans( $rescanSlugs );
|
90 |
+
}
|
91 |
+
|
92 |
+
return [
|
93 |
+
'success' => $success,
|
94 |
+
'page_reload' => false,
|
95 |
+
'table_reload' => in_array( $action, [ 'ignore', 'repair', 'delete', 'repair-delete' ] ),
|
96 |
+
'message' => $msg,
|
97 |
+
];
|
98 |
+
}
|
99 |
+
|
100 |
+
private function getItemIDs() :array {
|
101 |
+
$items = Services::Request()->post( 'rids' );
|
102 |
+
if ( empty( $items ) || !is_array( $items ) ) {
|
103 |
+
throw new \Exception( 'No items selected.' );
|
104 |
+
}
|
105 |
+
return array_filter(
|
106 |
+
array_map(
|
107 |
+
function ( $rid ) {
|
108 |
+
return is_numeric( $rid ) ? intval( $rid ) : null;
|
109 |
+
},
|
110 |
+
$items
|
111 |
+
),
|
112 |
+
function ( $rid ) {
|
113 |
+
return !is_null( $rid );
|
114 |
+
}
|
115 |
+
);
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* @return array
|
120 |
+
* @throws \Exception
|
121 |
+
*/
|
122 |
+
private function viewFile() :array {
|
123 |
+
$req = Services::Request();
|
124 |
+
$rid = $req->post( 'rid' );
|
125 |
+
if ( !is_numeric( $rid ) ) {
|
126 |
+
throw new \Exception( 'Not a valid file to view' );
|
127 |
+
}
|
128 |
+
|
129 |
+
return [
|
130 |
+
'success' => true,
|
131 |
+
'vars' => ( new RetrieveFileContents() )
|
132 |
+
->setMod( $this->getMod() )
|
133 |
+
->retrieve( (int)$rid ),
|
134 |
+
];
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* @return array
|
139 |
+
* @throws \Exception
|
140 |
+
*/
|
141 |
+
private function retrieveTableData() :array {
|
142 |
+
$req = Services::Request();
|
143 |
+
return [
|
144 |
+
'success' => true,
|
145 |
+
'vars' => [
|
146 |
+
'data' => ( new LoadRawTableData() )
|
147 |
+
->setMod( $this->getMod() )
|
148 |
+
->loadFor( $req->post( 'type' ), $req->post( 'file' ) )
|
149 |
+
],
|
150 |
+
];
|
151 |
+
}
|
152 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/LoadRawTableData.php
ADDED
@@ -0,0 +1,328 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Tool\FormatBytes;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller\{
|
8 |
+
Mal,
|
9 |
+
Ptg,
|
10 |
+
Ufc,
|
11 |
+
Wcf
|
12 |
+
};
|
13 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
14 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
15 |
+
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
|
16 |
+
WpPluginVo,
|
17 |
+
WpThemeVo
|
18 |
+
};
|
19 |
+
use FernleafSystems\Wordpress\Services\Services;
|
20 |
+
|
21 |
+
class LoadRawTableData {
|
22 |
+
|
23 |
+
use ModConsumer;
|
24 |
+
|
25 |
+
private static $GuardFiles;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @param string $type
|
29 |
+
* @param string $file
|
30 |
+
* @return array
|
31 |
+
* @throws \Exception
|
32 |
+
*/
|
33 |
+
public function loadFor( string $type, string $file ) :array {
|
34 |
+
|
35 |
+
switch ( $type ) {
|
36 |
+
|
37 |
+
case 'plugin':
|
38 |
+
$item = Services::WpPlugins()->getPluginAsVo( $file );
|
39 |
+
if ( empty( $item ) ) {
|
40 |
+
throw new \Exception( '[LoadRawTableData] Unsupported slug: '.$file );
|
41 |
+
}
|
42 |
+
$data = $this->loadForPlugin( $item );
|
43 |
+
break;
|
44 |
+
|
45 |
+
case 'theme':
|
46 |
+
$item = Services::WpThemes()->getThemeAsVo( $file );
|
47 |
+
if ( empty( $item ) ) {
|
48 |
+
throw new \Exception( '[LoadRawTableData] Unsupported slug: '.$file );
|
49 |
+
}
|
50 |
+
$data = $this->loadForTheme( $item );
|
51 |
+
break;
|
52 |
+
|
53 |
+
case 'wordpress':
|
54 |
+
$data = $this->loadForWordPress();
|
55 |
+
break;
|
56 |
+
|
57 |
+
case 'malware':
|
58 |
+
$data = $this->loadForMalware();
|
59 |
+
break;
|
60 |
+
|
61 |
+
default:
|
62 |
+
throw new \Exception( '[LoadRawTableData] Unsupported type: '.$type );
|
63 |
+
}
|
64 |
+
|
65 |
+
return $data;
|
66 |
+
}
|
67 |
+
|
68 |
+
public function loadForMalware() :array {
|
69 |
+
/** @var ModCon $mod */
|
70 |
+
$mod = $this->getMod();
|
71 |
+
try {
|
72 |
+
$files = array_map(
|
73 |
+
function ( $item ) {
|
74 |
+
/** @var Scans\Mal\ResultItem $item */
|
75 |
+
$data = $item->getRawData();
|
76 |
+
|
77 |
+
$data[ 'rid' ] = $item->VO->id;
|
78 |
+
$data[ 'file' ] = $item->path_fragment;
|
79 |
+
$data[ 'detected_at' ] = $item->VO->created_at;
|
80 |
+
$data[ 'detected_since' ] = Services::Request()
|
81 |
+
->carbon( true )
|
82 |
+
->setTimestamp( $item->VO->created_at )
|
83 |
+
->diffForHumans();
|
84 |
+
|
85 |
+
$data[ 'file_as_href' ] = $this->getColumnContent_File( $item );
|
86 |
+
|
87 |
+
$data[ 'status_slug' ] = 'malware';
|
88 |
+
$data[ 'status' ] = $this->getColumnContent_FileStatus( $item, __( 'Malware', 'wp-simple-firewall' ) );
|
89 |
+
|
90 |
+
$data[ 'line_numbers' ] = implode( ', ', array_map(
|
91 |
+
function ( $line ) {
|
92 |
+
return $line + 1;
|
93 |
+
},
|
94 |
+
$item->file_lines // because lines start at ZERO
|
95 |
+
) );
|
96 |
+
$data[ 'mal_sig' ] = sprintf( '<code style="white-space: nowrap">%s</code>', esc_html( base64_decode( $item->mal_sig ) ) );
|
97 |
+
|
98 |
+
$data[ 'file_type' ] = strtoupper( Services::Data()->getExtension( $item->path_full ) );
|
99 |
+
$data[ 'actions' ] = implode( ' ', $this->getActions( $data[ 'status_slug' ], $item ) );
|
100 |
+
return $data;
|
101 |
+
},
|
102 |
+
array_merge(
|
103 |
+
$mod->getScanCon( Mal::SCAN_SLUG )->getAllResults()->getItems()
|
104 |
+
)
|
105 |
+
);
|
106 |
+
}
|
107 |
+
catch ( \Exception $e ) {
|
108 |
+
$files = [];
|
109 |
+
}
|
110 |
+
|
111 |
+
return $files;
|
112 |
+
}
|
113 |
+
|
114 |
+
public function loadForPlugin( WpPluginVo $plugin ) :array {
|
115 |
+
return $this->getGuardFilesDataFor( $plugin );
|
116 |
+
}
|
117 |
+
|
118 |
+
public function loadForTheme( WpThemeVo $theme ) :array {
|
119 |
+
return $this->getGuardFilesDataFor( $theme );
|
120 |
+
}
|
121 |
+
|
122 |
+
public function loadForWordPress() :array {
|
123 |
+
/** @var ModCon $mod */
|
124 |
+
$mod = $this->getMod();
|
125 |
+
try {
|
126 |
+
$files = array_map(
|
127 |
+
function ( $item ) {
|
128 |
+
/** @var Scans\Wcf\ResultItem|Scans\Ufc\ResultItem $item */
|
129 |
+
$data = $item->getRawData();
|
130 |
+
$data[ 'rid' ] = $item->VO->id;
|
131 |
+
$data[ 'file' ] = $item->path_fragment;
|
132 |
+
$data[ 'detected_at' ] = $item->VO->created_at;
|
133 |
+
$data[ 'detected_since' ] = Services::Request()
|
134 |
+
->carbon( true )
|
135 |
+
->setTimestamp( $item->VO->created_at )
|
136 |
+
->diffForHumans();
|
137 |
+
|
138 |
+
if ( !$item->is_missing ) {
|
139 |
+
$data[ 'file_as_href' ] = $this->getColumnContent_File( $item );
|
140 |
+
}
|
141 |
+
else {
|
142 |
+
$data[ 'file_as_href' ] = $item->path_fragment;
|
143 |
+
}
|
144 |
+
|
145 |
+
if ( $item->is_checksumfail ) {
|
146 |
+
$data[ 'status_slug' ] = 'modified';
|
147 |
+
$data[ 'status' ] = __( 'Modified', 'wp-simple-firewall' );
|
148 |
+
}
|
149 |
+
elseif ( $item->is_missing ) {
|
150 |
+
$data[ 'status_slug' ] = 'missing';
|
151 |
+
$data[ 'status' ] = __( 'Missing', 'wp-simple-firewall' );
|
152 |
+
}
|
153 |
+
else {
|
154 |
+
$data[ 'status_slug' ] = 'unrecognised';
|
155 |
+
$data[ 'status' ] = __( 'Unrecognised', 'wp-simple-firewall' );
|
156 |
+
}
|
157 |
+
$data[ 'status' ] = $this->getColumnContent_FileStatus( $item, $data[ 'status' ] );
|
158 |
+
|
159 |
+
$data[ 'file_type' ] = strtoupper( Services::Data()->getExtension( $item->path_full ) );
|
160 |
+
$data[ 'actions' ] = implode( ' ', $this->getActions( $data[ 'status_slug' ], $item ) );
|
161 |
+
return $data;
|
162 |
+
},
|
163 |
+
array_merge(
|
164 |
+
$mod->getScanCon( Wcf::SCAN_SLUG )->getAllResults()->getItems(),
|
165 |
+
$mod->getScanCon( Ufc::SCAN_SLUG )->getAllResults()->getItems()
|
166 |
+
)
|
167 |
+
);
|
168 |
+
}
|
169 |
+
catch ( \Exception $e ) {
|
170 |
+
$files = [];
|
171 |
+
}
|
172 |
+
|
173 |
+
return $files;
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* @param WpPluginVo|WpThemeVo $item
|
178 |
+
* @return array
|
179 |
+
*/
|
180 |
+
private function getGuardFilesDataFor( $item ) :array {
|
181 |
+
return array_map(
|
182 |
+
function ( $item ) {
|
183 |
+
|
184 |
+
$data = $item->getRawData();
|
185 |
+
$data[ 'rid' ] = $item->VO->id;
|
186 |
+
$data[ 'file' ] = $item->path_fragment;
|
187 |
+
$data[ 'detected_at' ] = $item->VO->created_at;
|
188 |
+
$data[ 'detected_since' ] = Services::Request()
|
189 |
+
->carbon( true )
|
190 |
+
->setTimestamp( $item->VO->created_at )
|
191 |
+
->diffForHumans();
|
192 |
+
|
193 |
+
if ( $item->is_different ) {
|
194 |
+
$data[ 'status_slug' ] = 'modified';
|
195 |
+
$data[ 'status' ] = __( 'Modified', 'wp-simple-firewall' );
|
196 |
+
}
|
197 |
+
elseif ( $item->is_missing ) {
|
198 |
+
$data[ 'status_slug' ] = 'missing';
|
199 |
+
$data[ 'status' ] = __( 'Missing', 'wp-simple-firewall' );
|
200 |
+
}
|
201 |
+
else {
|
202 |
+
$data[ 'status_slug' ] = 'unrecognised';
|
203 |
+
$data[ 'status' ] = __( 'Unrecognised', 'wp-simple-firewall' );
|
204 |
+
}
|
205 |
+
$data[ 'status' ] = $this->getColumnContent_FileStatus( $item, $data[ 'status' ] );
|
206 |
+
|
207 |
+
if ( !$item->is_missing ) {
|
208 |
+
$data[ 'file_as_href' ] = $this->getColumnContent_File( $item );
|
209 |
+
}
|
210 |
+
else {
|
211 |
+
$data[ 'file_as_href' ] = $item->path_fragment;
|
212 |
+
}
|
213 |
+
|
214 |
+
$data[ 'file_type' ] = strtoupper( Services::Data()->getExtension( $item->path_full ) );
|
215 |
+
$data[ 'actions' ] = implode( ' ', $this->getActions( $data[ 'status_slug' ], $item ) );
|
216 |
+
return $data;
|
217 |
+
},
|
218 |
+
$this->getGuardFiles()->getItemsForSlug( $item->asset_type === 'plugin' ? $item->file : $item->stylesheet )
|
219 |
+
);
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* @param string $status
|
224 |
+
* @param Scans\Base\ResultItem $item
|
225 |
+
* @return array
|
226 |
+
*/
|
227 |
+
private function getActions( string $status, $item ) :array {
|
228 |
+
$con = $this->getCon();
|
229 |
+
/** @var ModCon $mod */
|
230 |
+
$mod = $this->getMod();
|
231 |
+
$itemActionHandler = $mod->getScanCon( $item->VO->scan )
|
232 |
+
->getItemActionHandler()
|
233 |
+
->setScanItem( $item );
|
234 |
+
|
235 |
+
$actions = [];
|
236 |
+
|
237 |
+
$defaultButtonClasses = [
|
238 |
+
'btn',
|
239 |
+
'action',
|
240 |
+
];
|
241 |
+
|
242 |
+
if ( in_array( $status, [ 'unrecognised', 'malware' ] ) ) {
|
243 |
+
$actions[] = sprintf( '<button class="btn-danger delete %s" title="%s" data-rid="%s">%s</button>',
|
244 |
+
implode( ' ', $defaultButtonClasses ),
|
245 |
+
__( 'Delete', 'wp-simple-firewall' ),
|
246 |
+
$item->VO->id,
|
247 |
+
$con->svgs->raw( 'bootstrap/x-square.svg' )
|
248 |
+
);
|
249 |
+
}
|
250 |
+
|
251 |
+
if ( in_array( $status, [ 'modified', 'missing', 'malware' ] ) && $itemActionHandler->getRepairer()
|
252 |
+
->canRepair() ) {
|
253 |
+
$actions[] = sprintf( '<button class="btn-warning repair %s" title="%s" data-rid="%s">%s</button>',
|
254 |
+
implode( ' ', $defaultButtonClasses ),
|
255 |
+
__( 'Repair', 'wp-simple-firewall' ),
|
256 |
+
$item->VO->id,
|
257 |
+
$con->svgs->raw( 'bootstrap/tools.svg' )
|
258 |
+
);
|
259 |
+
}
|
260 |
+
|
261 |
+
if ( in_array( $status, [ 'modified', 'unrecognised', 'malware' ] ) ) {
|
262 |
+
$actions[] = sprintf( '<button class="btn-dark href-download %s" title="%s" data-href-download="%s">%s</button>',
|
263 |
+
implode( ' ', $defaultButtonClasses ),
|
264 |
+
__( 'Download', 'wp-simple-firewall' ),
|
265 |
+
$mod->getScanCon( $item->VO->scan )->createFileDownloadLink( $item->VO->id ),
|
266 |
+
$con->svgs->raw( 'bootstrap/download.svg' )
|
267 |
+
);
|
268 |
+
}
|
269 |
+
|
270 |
+
$actions[] = sprintf( '<button class="btn-light ignore %s" title="%s" data-rid="%s">%s</button>',
|
271 |
+
implode( ' ', $defaultButtonClasses ),
|
272 |
+
__( 'Ignore', 'wp-simple-firewall' ),
|
273 |
+
$item->VO->id,
|
274 |
+
$con->svgs->raw( 'bootstrap/eye-slash-fill.svg' )
|
275 |
+
);
|
276 |
+
|
277 |
+
return $actions;
|
278 |
+
}
|
279 |
+
|
280 |
+
private function getGuardFiles() :Scans\Ptg\ResultsSet {
|
281 |
+
/** @var ModCon $mod */
|
282 |
+
$mod = $this->getMod();
|
283 |
+
if ( !isset( self::$GuardFiles ) ) {
|
284 |
+
try {
|
285 |
+
self::$GuardFiles = $mod->getScanCon( Ptg::SCAN_SLUG )->getAllResults();
|
286 |
+
}
|
287 |
+
catch ( \Exception $e ) {
|
288 |
+
self::$GuardFiles = new Scans\Ptg\ResultsSet();
|
289 |
+
}
|
290 |
+
}
|
291 |
+
return self::$GuardFiles;
|
292 |
+
}
|
293 |
+
|
294 |
+
private function getColumnContent_File( Scans\Base\FileResultItem $item ) :string {
|
295 |
+
return sprintf( '<div>%s</div>', $this->getColumnContent_FileAsHref( $item ) );
|
296 |
+
}
|
297 |
+
|
298 |
+
private function getColumnContent_FileStatus( Scans\Base\FileResultItem $item, string $status ) :string {
|
299 |
+
$content = $status;
|
300 |
+
|
301 |
+
$FS = Services::WpFs();
|
302 |
+
if ( $FS->isFile( $item->path_full ) ) {
|
303 |
+
$carbon = Services::Request()->carbon( true );
|
304 |
+
$content = sprintf( '%s<ul style="list-style: square inside"><li>%s</li></ul>',
|
305 |
+
$status,
|
306 |
+
implode( '</li><li>', [
|
307 |
+
sprintf( '%s: %s', __( 'Modified', 'wp-simple-firewall' ),
|
308 |
+
$carbon->setTimestamp( $FS->getModifiedTime( $item->path_full ) )
|
309 |
+
->diffForHumans()
|
310 |
+
),
|
311 |
+
sprintf( '%s: %s', __( 'Size', 'wp-simple-firewall' ),
|
312 |
+
FormatBytes::Format( $FS->getFileSize( $item->path_full ) )
|
313 |
+
)
|
314 |
+
] )
|
315 |
+
);
|
316 |
+
}
|
317 |
+
|
318 |
+
return $content;
|
319 |
+
}
|
320 |
+
|
321 |
+
private function getColumnContent_FileAsHref( Scans\Base\FileResultItem $item ) :string {
|
322 |
+
return sprintf( '<a href="#" title="%s" class="action view-file" data-rid="%s">%s</a>',
|
323 |
+
__( 'View File Contents', 'wp-simple-firewall' ),
|
324 |
+
$item->VO->id,
|
325 |
+
$item->path_fragment
|
326 |
+
);
|
327 |
+
}
|
328 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/RetrieveFileContents.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Results\ConvertBetweenTypes;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
9 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
10 |
+
use FernleafSystems\Wordpress\Services\Services;
|
11 |
+
|
12 |
+
class RetrieveFileContents {
|
13 |
+
|
14 |
+
use ModConsumer;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param int $rid
|
18 |
+
* @param bool $raw
|
19 |
+
* @return array
|
20 |
+
* @throws \Exception
|
21 |
+
*/
|
22 |
+
public function retrieve( int $rid, bool $raw = false ) :array {
|
23 |
+
/** @var ModCon $mod */
|
24 |
+
$mod = $this->getMod();
|
25 |
+
|
26 |
+
/** @var EntryVO $record */
|
27 |
+
$record = $mod->getDbHandler_ScanResults()
|
28 |
+
->getQuerySelector()
|
29 |
+
->byId( $rid );
|
30 |
+
if ( empty( $record ) ) {
|
31 |
+
throw new \Exception( 'Not a valid file record' );
|
32 |
+
}
|
33 |
+
$item = ( new ConvertBetweenTypes() )
|
34 |
+
->setScanController( $mod->getScanCon( $record->scan ) )
|
35 |
+
->convertVoToResultItem( $record );
|
36 |
+
$path = $item->path_full;
|
37 |
+
if ( empty( $path ) ) {
|
38 |
+
throw new \Exception( 'There is no path associated with this record' );
|
39 |
+
}
|
40 |
+
$FS = Services::WpFs();
|
41 |
+
if ( !$FS->isFile( $path ) ) {
|
42 |
+
throw new \Exception( 'File does not exist.' );
|
43 |
+
}
|
44 |
+
$contents = $FS->getFileContent( $path );
|
45 |
+
if ( empty( $contents ) ) {
|
46 |
+
throw new \Exception( 'File is empty or could not be read.' );
|
47 |
+
}
|
48 |
+
if ( !$raw ) {
|
49 |
+
$modContents = Services::DataManipulation()->convertLineEndingsDosToLinux( $path );
|
50 |
+
$contents = $this->getMod()
|
51 |
+
->renderTemplate(
|
52 |
+
'/wpadmin_pages/insights/scans/modal/code_block.twig',
|
53 |
+
[
|
54 |
+
'lines' => explode( "\n", str_replace( "\t", " ", $modContents ) ),
|
55 |
+
]
|
56 |
+
);
|
57 |
+
}
|
58 |
+
return [
|
59 |
+
'contents' => $contents,
|
60 |
+
'path' => esc_html( $item->path_fragment ),
|
61 |
+
];
|
62 |
+
}
|
63 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForCrowdSource.php
CHANGED
@@ -16,17 +16,19 @@ class BuildHashesForCrowdSource {
|
|
16 |
* @param WpPluginVo|WpThemeVo $asset
|
17 |
* @return string[]
|
18 |
*/
|
19 |
-
public function build( $asset ) :array {
|
20 |
$hashes = [];
|
21 |
$DM = Services::DataManipulation();
|
22 |
$dir = wp_normalize_path( $asset->getInstallDir() );
|
23 |
try {
|
24 |
-
$exts
|
|
|
|
|
25 |
foreach ( StandardDirectoryIterator::create( $dir, 0, [] ) as $file ) {
|
26 |
/** @var \SplFileInfo $file */
|
27 |
if ( in_array( strtolower( $file->getExtension() ), $exts ) ) {
|
28 |
$fullPath = $file->getPathname();
|
29 |
-
$key = str_replace( $dir, '', wp_normalize_path( $fullPath ) );
|
30 |
$hashes[ $key ] = hash( 'sha1', $DM->convertLineEndingsDosToLinux( $fullPath ) );
|
31 |
}
|
32 |
}
|
@@ -37,20 +39,4 @@ class BuildHashesForCrowdSource {
|
|
37 |
}
|
38 |
return $hashes;
|
39 |
}
|
40 |
-
|
41 |
-
private function getExtensions() :array {
|
42 |
-
return [
|
43 |
-
'php',
|
44 |
-
'php5',
|
45 |
-
'php7',
|
46 |
-
'js',
|
47 |
-
'json',
|
48 |
-
'css',
|
49 |
-
'htm',
|
50 |
-
'html',
|
51 |
-
'svg',
|
52 |
-
'twig',
|
53 |
-
'hbs',
|
54 |
-
];
|
55 |
-
}
|
56 |
}
|
16 |
* @param WpPluginVo|WpThemeVo $asset
|
17 |
* @return string[]
|
18 |
*/
|
19 |
+
public function build( $asset, array $exts ) :array {
|
20 |
$hashes = [];
|
21 |
$DM = Services::DataManipulation();
|
22 |
$dir = wp_normalize_path( $asset->getInstallDir() );
|
23 |
try {
|
24 |
+
if ( empty( $exts ) ) {
|
25 |
+
throw new \Exception( 'File extensions are empty' );
|
26 |
+
}
|
27 |
foreach ( StandardDirectoryIterator::create( $dir, 0, [] ) as $file ) {
|
28 |
/** @var \SplFileInfo $file */
|
29 |
if ( in_array( strtolower( $file->getExtension() ), $exts ) ) {
|
30 |
$fullPath = $file->getPathname();
|
31 |
+
$key = strtolower( str_replace( $dir, '', wp_normalize_path( $fullPath ) ) );
|
32 |
$hashes[ $key ] = hash( 'sha1', $DM->convertLineEndingsDosToLinux( $fullPath ) );
|
33 |
}
|
34 |
}
|
39 |
}
|
40 |
return $hashes;
|
41 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
}
|
src/lib/src/Modules/HackGuard/Lib/Snapshots/CrowdSourced/SubmitHashes.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\CrowdSourced;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\Build;
|
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
|
8 |
WpPluginVo,
|
@@ -32,11 +33,14 @@ class SubmitHashes {
|
|
32 |
* @param WpPluginVo|WpThemeVo $asset
|
33 |
*/
|
34 |
public function run( $asset ) {
|
|
|
|
|
|
|
35 |
$this->asset = $asset;
|
36 |
|
37 |
if ( $this->canSubmitAsset() ) {
|
38 |
$this->hashes = ( new Build\BuildHashesForCrowdSource() )
|
39 |
-
->build( $asset );
|
40 |
|
41 |
if ( !empty( $this->hashes ) && $this->isSubmitRequired() ) {
|
42 |
$this->submit();
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\CrowdSourced;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\Build;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Options;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
|
9 |
WpPluginVo,
|
33 |
* @param WpPluginVo|WpThemeVo $asset
|
34 |
*/
|
35 |
public function run( $asset ) {
|
36 |
+
/** @var Options $opts */
|
37 |
+
$opts = $this->getOptions();
|
38 |
+
|
39 |
$this->asset = $asset;
|
40 |
|
41 |
if ( $this->canSubmitAsset() ) {
|
42 |
$this->hashes = ( new Build\BuildHashesForCrowdSource() )
|
43 |
+
->build( $asset, $opts->getDef( 'file_scan_extensions' ) );
|
44 |
|
45 |
if ( !empty( $this->hashes ) && $this->isSubmitRequired() ) {
|
46 |
$this->submit();
|
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CleanAll.php
CHANGED
@@ -12,14 +12,14 @@ class CleanAll extends BaseBulk {
|
|
12 |
/** @var ModCon $mod */
|
13 |
$mod = $this->getMod();
|
14 |
try {
|
15 |
-
$
|
16 |
->carbon()
|
17 |
->subDay()->timestamp;
|
18 |
-
$
|
19 |
-
foreach ( $
|
20 |
-
/** @var \SplFileInfo $
|
21 |
-
if ( $
|
22 |
-
Services::WpFs()->deleteFile( $
|
23 |
}
|
24 |
}
|
25 |
}
|
12 |
/** @var ModCon $mod */
|
13 |
$mod = $this->getMod();
|
14 |
try {
|
15 |
+
$boundary = Services::Request()
|
16 |
->carbon()
|
17 |
->subDay()->timestamp;
|
18 |
+
$IT = StandardDirectoryIterator::create( $mod->getPtgSnapsBaseDir() );
|
19 |
+
foreach ( $IT as $file ) {
|
20 |
+
/** @var \SplFileInfo $file */
|
21 |
+
if ( $boundary > $file->getMTime() ) {
|
22 |
+
Services::WpFs()->deleteFile( $file->getPathname() );
|
23 |
}
|
24 |
}
|
25 |
}
|
src/lib/src/Modules/HackGuard/Lib/Utility/VerifyFileByHash.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Utility;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Core\CoreFileHashes;
|
7 |
+
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
|
8 |
+
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpThemeVo;
|
9 |
+
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Query;
|
10 |
+
use FernleafSystems\Wordpress\Services\Utilities\WpOrg\{
|
11 |
+
Plugin,
|
12 |
+
Theme
|
13 |
+
};
|
14 |
+
|
15 |
+
class VerifyFileByHash {
|
16 |
+
|
17 |
+
use ModConsumer;
|
18 |
+
|
19 |
+
private $fullPath;
|
20 |
+
|
21 |
+
private $coreFileHashes;
|
22 |
+
|
23 |
+
private $tmpItem;
|
24 |
+
|
25 |
+
private $tmpItemHashes;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* TODO
|
29 |
+
*/
|
30 |
+
public function verify( string $fullPath ) :bool {
|
31 |
+
$this->fullPath = wp_normalize_path( $fullPath );
|
32 |
+
|
33 |
+
return $this->isValidCoreFile();
|
34 |
+
|
35 |
+
/*
|
36 |
+
$verified = false;
|
37 |
+
|
38 |
+
if ( $this->isValidCoreFile() ) {
|
39 |
+
$verified = true;
|
40 |
+
}
|
41 |
+
elseif ( $this->isInCoreDir() ) {
|
42 |
+
$verified = false;
|
43 |
+
}
|
44 |
+
elseif ( false && $this->isInPluginsDir() ) {
|
45 |
+
}
|
46 |
+
elseif ( false && $this->isInThemesDir() ) {
|
47 |
+
}
|
48 |
+
|
49 |
+
return $verified;
|
50 |
+
*/
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @param WpPluginVo|WpThemeVo $asset
|
55 |
+
*/
|
56 |
+
private function getAssetHashes( $asset ) :array {
|
57 |
+
if ( empty( $this->tmpItem ) || $this->tmpItem !== $asset->unique_id ) {
|
58 |
+
$this->tmpItem = null;
|
59 |
+
$this->tmpItemHashes = null;
|
60 |
+
}
|
61 |
+
|
62 |
+
if ( !is_array( $this->tmpItemHashes ) ) {
|
63 |
+
$hashes = ( $asset->asset_type === 'plugin' ? new Query\Plugin() : new Query\Theme() )
|
64 |
+
->getHashesFromVO( $asset );
|
65 |
+
$this->tmpItem = $asset->unique_id;
|
66 |
+
$this->tmpItemHashes = is_array( $hashes ) ? $hashes : [];
|
67 |
+
}
|
68 |
+
|
69 |
+
return $this->tmpItemHashes;
|
70 |
+
}
|
71 |
+
|
72 |
+
private function isValidCoreFile() :bool {
|
73 |
+
return $this->getCoreFileHashes()->isCoreFileHashValid( $this->fullPath );
|
74 |
+
}
|
75 |
+
|
76 |
+
private function isInCoreDir() :bool {
|
77 |
+
return strpos( $this->fullPath, wp_normalize_path( path_join( ABSPATH, 'wp-admin' ) ) ) === 0
|
78 |
+
|| strpos( $this->fullPath, wp_normalize_path( path_join( ABSPATH, 'wp-includes' ) ) ) === 0;
|
79 |
+
}
|
80 |
+
|
81 |
+
private function isInPluginsDir() :bool {
|
82 |
+
return strpos( $this->fullPath, wp_normalize_path( WP_PLUGIN_DIR ) ) === 0;
|
83 |
+
}
|
84 |
+
|
85 |
+
private function isInThemesDir() :bool {
|
86 |
+
return strpos( $this->fullPath, wp_normalize_path( path_join( WP_CONTENT_DIR, 'themes' ) ) ) === 0;
|
87 |
+
}
|
88 |
+
|
89 |
+
private function getCoreFileHashes() :CoreFileHashes {
|
90 |
+
if ( empty( $this->coreFileHashes ) ) {
|
91 |
+
$this->coreFileHashes = new CoreFileHashes();
|
92 |
+
}
|
93 |
+
return $this->coreFileHashes;
|
94 |
+
}
|
95 |
+
}
|
src/lib/src/Modules/HackGuard/ModCon.php
CHANGED
@@ -5,6 +5,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
|
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
9 |
|
10 |
class ModCon extends BaseShield\ModCon {
|
@@ -116,6 +117,31 @@ class ModCon extends BaseShield\ModCon {
|
|
116 |
$con->purge();
|
117 |
}
|
118 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
}
|
120 |
|
121 |
/**
|
@@ -169,26 +195,24 @@ class ModCon extends BaseShield\ModCon {
|
|
169 |
return $this->isModuleEnabled() && $this->isPremium()
|
170 |
&& $opts->isOpt( 'ptg_enable', 'enabled' )
|
171 |
&& $opts->isOptReqsMet( 'ptg_enable' )
|
172 |
-
&& $this->
|
|
|
173 |
}
|
174 |
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
return $this->getCon()->getPluginCachePath( 'ptguard/' );
|
180 |
}
|
181 |
|
182 |
public function hasWizard() :bool {
|
183 |
return false;
|
184 |
}
|
185 |
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
$dir = $this->getCon()->getPluginCachePath( 'scans' );
|
191 |
-
return Services::WpFs()->mkdir( $dir ) ? $dir : false;
|
192 |
}
|
193 |
|
194 |
public function getDbHandler_FileLocker() :Databases\FileLocker\Handler {
|
@@ -211,7 +235,7 @@ class ModCon extends BaseShield\ModCon {
|
|
211 |
return ( $this->getDbHandler_ScanQueue() instanceof Databases\ScanQueue\Handler )
|
212 |
&& $this->getDbHandler_ScanQueue()->isReady()
|
213 |
&& ( $this->getDbHandler_ScanResults() instanceof Databases\Scanner\Handler )
|
214 |
-
&& $this->
|
215 |
&& parent::isReadyToExecute();
|
216 |
}
|
217 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\CacheDir;
|
9 |
use FernleafSystems\Wordpress\Services\Services;
|
10 |
|
11 |
class ModCon extends BaseShield\ModCon {
|
117 |
$con->purge();
|
118 |
}
|
119 |
}
|
120 |
+
|
121 |
+
$this->cleanScanExclusions();
|
122 |
+
}
|
123 |
+
|
124 |
+
private function cleanScanExclusions() {
|
125 |
+
/** @var Options $opts */
|
126 |
+
$opts = $this->getOptions();
|
127 |
+
|
128 |
+
$specialDirs = array_map( 'trailingslashit', [
|
129 |
+
ABSPATH,
|
130 |
+
path_join( ABSPATH, 'wp-admin' ),
|
131 |
+
path_join( ABSPATH, 'wp-includes' ),
|
132 |
+
untrailingslashit( WP_CONTENT_DIR ),
|
133 |
+
path_join( WP_CONTENT_DIR, 'plugins' ),
|
134 |
+
path_join( WP_CONTENT_DIR, 'themes' ),
|
135 |
+
] );
|
136 |
+
|
137 |
+
$values = $opts->getOpt( 'scan_path_exclusions', [] );
|
138 |
+
$opts->setOpt( 'scan_path_exclusions',
|
139 |
+
( new Shield\Modules\Base\Options\WildCardOptions() )->clean(
|
140 |
+
is_array( $values ) ? $values : [],
|
141 |
+
$specialDirs,
|
142 |
+
Shield\Modules\Base\Options\WildCardOptions::FILE_PATH_REL
|
143 |
+
)
|
144 |
+
);
|
145 |
}
|
146 |
|
147 |
/**
|
195 |
return $this->isModuleEnabled() && $this->isPremium()
|
196 |
&& $opts->isOpt( 'ptg_enable', 'enabled' )
|
197 |
&& $opts->isOptReqsMet( 'ptg_enable' )
|
198 |
+
&& $this->getCon()->hasCacheDir()
|
199 |
+
&& !empty( $this->getPtgSnapsBaseDir() );
|
200 |
}
|
201 |
|
202 |
+
public function getPtgSnapsBaseDir() :string {
|
203 |
+
return ( new CacheDir() )
|
204 |
+
->setCon( $this->getCon() )
|
205 |
+
->buildSubDir( 'ptguard' );
|
|
|
206 |
}
|
207 |
|
208 |
public function hasWizard() :bool {
|
209 |
return false;
|
210 |
}
|
211 |
|
212 |
+
public function getScansTempDir() :string {
|
213 |
+
return ( new CacheDir() )
|
214 |
+
->setCon( $this->getCon() )
|
215 |
+
->buildSubDir( 'scans' );
|
|
|
|
|
216 |
}
|
217 |
|
218 |
public function getDbHandler_FileLocker() :Databases\FileLocker\Handler {
|
235 |
return ( $this->getDbHandler_ScanQueue() instanceof Databases\ScanQueue\Handler )
|
236 |
&& $this->getDbHandler_ScanQueue()->isReady()
|
237 |
&& ( $this->getDbHandler_ScanResults() instanceof Databases\Scanner\Handler )
|
238 |
+
&& $this->getDbHandler_ScanResults()->isReady()
|
239 |
&& parent::isReadyToExecute();
|
240 |
}
|
241 |
|
src/lib/src/Modules/HackGuard/Options.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
class Options extends BaseShield\Options {
|
@@ -16,6 +17,28 @@ class Options extends BaseShield\Options {
|
|
16 |
return is_array( $this->getOpt( 'file_repair_areas' ) ) ? $this->getOpt( 'file_repair_areas' ) : [];
|
17 |
}
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
/**
|
20 |
* @return int[] - keys are the unique report hash
|
21 |
*/
|
@@ -32,23 +55,6 @@ class Options extends BaseShield\Options {
|
|
32 |
return (int)apply_filters( 'shield/fp_confidence_boundary', 65 );
|
33 |
}
|
34 |
|
35 |
-
/**
|
36 |
-
* We do some WP Content dir replacement as there may be custom wp-content dir defines
|
37 |
-
* @return string[]
|
38 |
-
*/
|
39 |
-
public function getMalWhitelistPaths() {
|
40 |
-
return array_map(
|
41 |
-
function ( $sFragment ) {
|
42 |
-
return str_replace(
|
43 |
-
wp_normalize_path( ABSPATH.'wp-content' ),
|
44 |
-
rtrim( wp_normalize_path( WP_CONTENT_DIR ), '/' ),
|
45 |
-
wp_normalize_path( path_join( ABSPATH, ltrim( $sFragment, '/' ) ) )
|
46 |
-
);
|
47 |
-
},
|
48 |
-
apply_filters( 'icwp_shield_malware_whitelist_paths', $this->getDef( 'malware_whitelist_paths' ) )
|
49 |
-
);
|
50 |
-
}
|
51 |
-
|
52 |
/**
|
53 |
* @return int
|
54 |
*/
|
@@ -59,14 +65,14 @@ class Options extends BaseShield\Options {
|
|
59 |
/**
|
60 |
* @return string[]
|
61 |
*/
|
62 |
-
public function getMalSignaturesSimple() {
|
63 |
return $this->getMalSignatures( 'malsigs_simple.txt', $this->getDef( 'url_mal_sigs_simple' ) );
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
* @return string[]
|
68 |
*/
|
69 |
-
public function getMalSignaturesRegex() {
|
70 |
return $this->getMalSignatures( 'malsigs_regex.txt', $this->getDef( 'url_mal_sigs_regex' ) );
|
71 |
}
|
72 |
|
@@ -75,10 +81,10 @@ class Options extends BaseShield\Options {
|
|
75 |
* @param string $url
|
76 |
* @return string[]
|
77 |
*/
|
78 |
-
|
79 |
$FS = Services::WpFs();
|
80 |
-
$file = $this->getCon()->
|
81 |
-
if ( $FS->exists( $file ) ) {
|
82 |
$sigs = explode( "\n", $FS->getFileContent( $file, true ) );
|
83 |
}
|
84 |
else {
|
@@ -87,15 +93,16 @@ class Options extends BaseShield\Options {
|
|
87 |
explode( "\n", Services::HttpRequest()->getContent( $url ) )
|
88 |
),
|
89 |
function ( $line ) {
|
90 |
-
return (
|
91 |
}
|
92 |
);
|
93 |
|
94 |
-
if ( !empty( $sigs ) ) {
|
95 |
$FS->putFileContent( $file, implode( "\n", $sigs ), true );
|
96 |
}
|
97 |
}
|
98 |
-
|
|
|
99 |
}
|
100 |
|
101 |
public function isMalAutoRepairSurgical() :bool {
|
@@ -106,6 +113,10 @@ class Options extends BaseShield\Options {
|
|
106 |
return $this->getMalConfidenceBoundary() > 0;
|
107 |
}
|
108 |
|
|
|
|
|
|
|
|
|
109 |
public function isPtgReinstallLinks() :bool {
|
110 |
return $this->isOpt( 'ptg_reinstall_links', 'Y' ) && $this->isPremium();
|
111 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Options\WildCardOptions;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
class Options extends BaseShield\Options {
|
17 |
return is_array( $this->getOpt( 'file_repair_areas' ) ) ? $this->getOpt( 'file_repair_areas' ) : [];
|
18 |
}
|
19 |
|
20 |
+
/**
|
21 |
+
* @return string[] - precise REGEX patterns to match against PATH.
|
22 |
+
*/
|
23 |
+
public function getWhitelistedPathsAsRegex() :array {
|
24 |
+
if ( $this->isPremium() ) {
|
25 |
+
$paths = array_merge(
|
26 |
+
$this->getOpt( 'scan_path_exclusions', [] ),
|
27 |
+
$this->getDef( 'default_whitelist_paths' )
|
28 |
+
);
|
29 |
+
}
|
30 |
+
else {
|
31 |
+
$paths = [];
|
32 |
+
}
|
33 |
+
|
34 |
+
return array_map(
|
35 |
+
function ( $value ) {
|
36 |
+
return ( new WildCardOptions() )->buildFullRegexValue( $value, WildCardOptions::FILE_PATH_REL );
|
37 |
+
},
|
38 |
+
is_array( $paths ) ? $paths : []
|
39 |
+
);
|
40 |
+
}
|
41 |
+
|
42 |
/**
|
43 |
* @return int[] - keys are the unique report hash
|
44 |
*/
|
55 |
return (int)apply_filters( 'shield/fp_confidence_boundary', 65 );
|
56 |
}
|
57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
/**
|
59 |
* @return int
|
60 |
*/
|
65 |
/**
|
66 |
* @return string[]
|
67 |
*/
|
68 |
+
public function getMalSignaturesSimple() :array {
|
69 |
return $this->getMalSignatures( 'malsigs_simple.txt', $this->getDef( 'url_mal_sigs_simple' ) );
|
70 |
}
|
71 |
|
72 |
/**
|
73 |
* @return string[]
|
74 |
*/
|
75 |
+
public function getMalSignaturesRegex() :array {
|
76 |
return $this->getMalSignatures( 'malsigs_regex.txt', $this->getDef( 'url_mal_sigs_regex' ) );
|
77 |
}
|
78 |
|
81 |
* @param string $url
|
82 |
* @return string[]
|
83 |
*/
|
84 |
+
private function getMalSignatures( string $fileName, string $url ) :array {
|
85 |
$FS = Services::WpFs();
|
86 |
+
$file = $this->getCon()->paths->forCacheItem( $fileName );
|
87 |
+
if ( !empty( $file ) && $FS->exists( $file ) ) {
|
88 |
$sigs = explode( "\n", $FS->getFileContent( $file, true ) );
|
89 |
}
|
90 |
else {
|
93 |
explode( "\n", Services::HttpRequest()->getContent( $url ) )
|
94 |
),
|
95 |
function ( $line ) {
|
96 |
+
return ( strpos( $line, '#' ) !== 0 ) && strlen( $line ) > 0;
|
97 |
}
|
98 |
);
|
99 |
|
100 |
+
if ( !empty( $file ) && !empty( $sigs ) ) {
|
101 |
$FS->putFileContent( $file, implode( "\n", $sigs ), true );
|
102 |
}
|
103 |
}
|
104 |
+
|
105 |
+
return is_array( $sigs ) ? $sigs : [];
|
106 |
}
|
107 |
|
108 |
public function isMalAutoRepairSurgical() :bool {
|
113 |
return $this->getMalConfidenceBoundary() > 0;
|
114 |
}
|
115 |
|
116 |
+
public function isAutoFilterResults() :bool {
|
117 |
+
return $this->isOpt( 'auto_filter_results', 'Y' );
|
118 |
+
}
|
119 |
+
|
120 |
public function isPtgReinstallLinks() :bool {
|
121 |
return $this->isOpt( 'ptg_reinstall_links', 'Y' ) && $this->isPremium();
|
122 |
}
|
src/lib/src/Modules/HackGuard/Processor.php
CHANGED
@@ -20,26 +20,14 @@ class Processor extends BaseShield\Processor {
|
|
20 |
}
|
21 |
|
22 |
public function runHourlyCron() {
|
23 |
-
( new Lib\Snapshots\StoreAction\TouchAll() )
|
24 |
-
->setMod( $this->getMod() )
|
25 |
-
->run();
|
26 |
}
|
27 |
|
28 |
public function runDailyCron() {
|
29 |
-
( new Lib\Snapshots\StoreAction\CleanAll() )
|
30 |
-
->setMod( $this->getMod() )
|
31 |
-
->run();
|
32 |
}
|
33 |
|
34 |
public function onWpLoaded() {
|
35 |
-
( new Lib\Snapshots\StoreAction\ScheduleBuildAll() )
|
36 |
-
->setMod( $this->getMod() )
|
37 |
-
->hookBuild();
|
38 |
}
|
39 |
|
40 |
public function onModuleShutdown() {
|
41 |
-
( new Lib\Snapshots\StoreAction\ScheduleBuildAll() )
|
42 |
-
->setMod( $this->getMod() )
|
43 |
-
->schedule();
|
44 |
}
|
45 |
}
|
20 |
}
|
21 |
|
22 |
public function runHourlyCron() {
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
public function runDailyCron() {
|
|
|
|
|
|
|
26 |
}
|
27 |
|
28 |
public function onWpLoaded() {
|
|
|
|
|
|
|
29 |
}
|
30 |
|
31 |
public function onModuleShutdown() {
|
|
|
|
|
|
|
32 |
}
|
33 |
}
|
src/lib/src/Modules/HackGuard/Render/ScanResults/SectionBase.php
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class SectionBase {
|
9 |
+
|
10 |
+
use ModConsumer;
|
11 |
+
|
12 |
+
protected $renderData = [];
|
13 |
+
|
14 |
+
protected function buildRenderData() :array {
|
15 |
+
return [];
|
16 |
+
}
|
17 |
+
|
18 |
+
public function getRenderData() :array {
|
19 |
+
if ( empty( $this->renderData ) ) {
|
20 |
+
$this->renderData = $this->buildRenderData();
|
21 |
+
}
|
22 |
+
return $this->renderData;
|
23 |
+
}
|
24 |
+
|
25 |
+
protected function getCommonRenderData() :array {
|
26 |
+
return Services::DataManipulation()
|
27 |
+
->mergeArraysRecursive(
|
28 |
+
$this->getMod()->getUIHandler()->getBaseDisplayData(),
|
29 |
+
[
|
30 |
+
'ajax' => [
|
31 |
+
'scanresults_action' => $this->getMod()
|
32 |
+
->getAjaxActionData( 'scanresults_action', true ),
|
33 |
+
],
|
34 |
+
'strings' => [
|
35 |
+
'author' => __( 'Author' ),
|
36 |
+
'version' => __( 'Version' ),
|
37 |
+
'name' => __( 'Name' ),
|
38 |
+
'install_dir' => __( 'Installation Directory', 'wp-simple-firewall' ),
|
39 |
+
'file_integrity' => __( 'File Integrity', 'wp-simple-firewall' ),
|
40 |
+
'status_good' => __( 'Good', 'wp-simple-firewall' ),
|
41 |
+
'status_warning' => __( 'Warning', 'wp-simple-firewall' ),
|
42 |
+
'abandoned' => __( 'Abandoned', 'wp-simple-firewall' ),
|
43 |
+
'vulnerable' => __( 'Vulnerable', 'wp-simple-firewall' ),
|
44 |
+
'vulnerable_known' => __( 'Known vulnerabilities discovered.', 'wp-simple-firewall' ),
|
45 |
+
'vulnerable_update' => __( "You should upgrade to the latest version or remove it if no updates are available.", 'wp-simple-firewall' ),
|
46 |
+
'update_available' => __( 'Update Available', 'wp-simple-firewall' ),
|
47 |
+
'installed_at' => __( 'Installed', 'wp-simple-firewall' ),
|
48 |
+
'estimated' => __( 'estimated', 'wp-simple-firewall' ),
|
49 |
+
'rel_to_abspath' => __( 'relative to WordPress install dir', 'wp-simple-firewall' ),
|
50 |
+
'child_theme' => __( 'Linked To Child Theme', 'wp-simple-firewall' ),
|
51 |
+
'parent_theme' => __( 'Linked To Parent Theme', 'wp-simple-firewall' ),
|
52 |
+
],
|
53 |
+
'hrefs' => [
|
54 |
+
'upgrade' => Services::WpGeneral()->getAdminUrl_Updates()
|
55 |
+
],
|
56 |
+
]
|
57 |
+
);
|
58 |
+
}
|
59 |
+
}
|
src/lib/src/Modules/HackGuard/Render/ScanResults/SectionLogs.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\{
|
6 |
+
Lib\ScanTables\LoadRawTableData,
|
7 |
+
ModCon,
|
8 |
+
Scan\Controller\Mal
|
9 |
+
};
|
10 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
11 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Scans\ForMalware;
|
12 |
+
use FernleafSystems\Wordpress\Services\Services;
|
13 |
+
|
14 |
+
class SectionLogs extends SectionBase {
|
15 |
+
|
16 |
+
public function render() :string {
|
17 |
+
return $this->getMod()
|
18 |
+
->renderTemplate(
|
19 |
+
'/wpadmin_pages/insights/scans/results/section/logs/index.twig',
|
20 |
+
$this->buildRenderData()
|
21 |
+
);
|
22 |
+
}
|
23 |
+
|
24 |
+
protected function buildRenderData() :array {
|
25 |
+
/** @var ModCon $mod */
|
26 |
+
$mod = $this->getMod();
|
27 |
+
$data = $this->buildMalwareData();
|
28 |
+
return Services::DataManipulation()
|
29 |
+
->mergeArraysRecursive( $this->getCommonRenderData(), [
|
30 |
+
'strings' => [
|
31 |
+
'no_files' => __( "Previous scans didn't detect any files suspected of being malware.", 'wp-simple-firewall' ),
|
32 |
+
'files_found' => __( "Previous scans detected 1 or more files suspected of being malware.", 'wp-simple-firewall' ),
|
33 |
+
'mal_restricted' => __( 'The Malware File Scanner is only available with ShieldPRO.', 'wp-simple-firewall' ),
|
34 |
+
],
|
35 |
+
'flags' => [
|
36 |
+
'mal_is_restricted' => $mod->getScanCon( Mal::SCAN_SLUG )->isRestricted(),
|
37 |
+
],
|
38 |
+
'vars' => [
|
39 |
+
'count_items' => $data[ 'vars' ][ 'count_items' ],
|
40 |
+
'malware' => $data,
|
41 |
+
'datatables_init' => ( new ForMalware() )
|
42 |
+
->setMod( $this->getMod() )
|
43 |
+
->build()
|
44 |
+
]
|
45 |
+
] );
|
46 |
+
}
|
47 |
+
|
48 |
+
private function buildMalwareData() :array {
|
49 |
+
|
50 |
+
$filesData = ( new LoadRawTableData() )
|
51 |
+
->setMod( $this->getMod() )
|
52 |
+
->loadForMalware();
|
53 |
+
|
54 |
+
$data = [
|
55 |
+
'flags' => [
|
56 |
+
'has_malware' => !empty( $filesData ),
|
57 |
+
],
|
58 |
+
'vars' => [
|
59 |
+
'count_items' => count( $filesData )
|
60 |
+
]
|
61 |
+
];
|
62 |
+
$data[ 'flags' ][ 'has_issue' ] = $data[ 'flags' ][ 'has_malware' ];
|
63 |
+
return $data;
|
64 |
+
}
|
65 |
+
}
|
src/lib/src/Modules/HackGuard/Render/ScanResults/SectionMalware.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\{
|
6 |
+
Lib\ScanTables\LoadRawTableData,
|
7 |
+
ModCon,
|
8 |
+
Scan\Controller\Mal
|
9 |
+
};
|
10 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
11 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Scans\ForMalware;
|
12 |
+
use FernleafSystems\Wordpress\Services\Services;
|
13 |
+
|
14 |
+
class SectionMalware extends SectionBase {
|
15 |
+
|
16 |
+
public function render() :string {
|
17 |
+
return $this->getMod()
|
18 |
+
->renderTemplate(
|
19 |
+
'/wpadmin_pages/insights/scans/results/section/malware/index.twig',
|
20 |
+
$this->buildRenderData()
|
21 |
+
);
|
22 |
+
}
|
23 |
+
|
24 |
+
protected function buildRenderData() :array {
|
25 |
+
/** @var ModCon $mod */
|
26 |
+
$mod = $this->getMod();
|
27 |
+
$data = $this->buildMalwareData();
|
28 |
+
return Services::DataManipulation()
|
29 |
+
->mergeArraysRecursive( $this->getCommonRenderData(), [
|
30 |
+
'strings' => [
|
31 |
+
'no_files' => __( "Previous scans didn't detect any files suspected of being malware.", 'wp-simple-firewall' ),
|
32 |
+
'files_found' => __( "Previous scans detected 1 or more files suspected of being malware.", 'wp-simple-firewall' ),
|
33 |
+
'mal_restricted' => __( 'The Malware File Scanner is only available with ShieldPRO.', 'wp-simple-firewall' ),
|
34 |
+
],
|
35 |
+
'flags' => [
|
36 |
+
'mal_is_restricted' => $mod->getScanCon( Mal::SCAN_SLUG )->isRestricted(),
|
37 |
+
],
|
38 |
+
'vars' => [
|
39 |
+
'count_items' => $data[ 'vars' ][ 'count_items' ],
|
40 |
+
'malware' => $data,
|
41 |
+
'datatables_init' => ( new ForMalware() )
|
42 |
+
->setMod( $this->getMod() )
|
43 |
+
->build(),
|
44 |
+
'beacon_help_id' => 443
|
45 |
+
]
|
46 |
+
] );
|
47 |
+
}
|
48 |
+
|
49 |
+
private function buildMalwareData() :array {
|
50 |
+
|
51 |
+
$filesData = ( new LoadRawTableData() )
|
52 |
+
->setMod( $this->getMod() )
|
53 |
+
->loadForMalware();
|
54 |
+
|
55 |
+
$data = [
|
56 |
+
'flags' => [
|
57 |
+
'has_malware' => !empty( $filesData ),
|
58 |
+
],
|
59 |
+
'vars' => [
|
60 |
+
'count_items' => count( $filesData )
|
61 |
+
]
|
62 |
+
];
|
63 |
+
$data[ 'flags' ][ 'has_issue' ] = $data[ 'flags' ][ 'has_malware' ];
|
64 |
+
return $data;
|
65 |
+
}
|
66 |
+
}
|
src/lib/src/Modules/HackGuard/Render/ScanResults/SectionPluginThemesBase.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller\Apc;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller\Ptg;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller\Wpv;
|
9 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
10 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Scans\ForPluginTheme;
|
11 |
+
use FernleafSystems\Wordpress\Services\Services;
|
12 |
+
|
13 |
+
class SectionPluginThemesBase extends SectionBase {
|
14 |
+
|
15 |
+
protected function getCommonRenderData() :array {
|
16 |
+
/** @var ModCon $mod */
|
17 |
+
$mod = $this->getMod();
|
18 |
+
|
19 |
+
return Services::DataManipulation()
|
20 |
+
->mergeArraysRecursive( parent::getCommonRenderData(), [
|
21 |
+
'strings' => [
|
22 |
+
'ptg_name' => __( 'Plugin/Theme Guard', 'wp-simple-firewall' ),
|
23 |
+
'ptg_not_available' => __( 'The Plugin & Theme File Guard Scanner is only available with ShieldPRO.', 'wp-simple-firewall' ),
|
24 |
+
],
|
25 |
+
'flags' => [
|
26 |
+
'ptg_is_restricted' => $mod->getScanCon( Ptg::SCAN_SLUG )->isRestricted(),
|
27 |
+
],
|
28 |
+
'vars' => [
|
29 |
+
'datatables_init' => ( new ForPluginTheme() )
|
30 |
+
->setMod( $this->getMod() )
|
31 |
+
->build()
|
32 |
+
]
|
33 |
+
] );
|
34 |
+
}
|
35 |
+
|
36 |
+
protected function getVulnerabilities() :Scans\Wpv\ResultsSet {
|
37 |
+
if ( !isset( $this->vulnerable ) ) {
|
38 |
+
/** @var ModCon $mod */
|
39 |
+
$mod = $this->getMod();
|
40 |
+
try {
|
41 |
+
$this->vulnerable = $mod->getScanCon( Wpv::SCAN_SLUG )->getAllResults();
|
42 |
+
}
|
43 |
+
catch ( \Exception $e ) {
|
44 |
+
$this->vulnerable = new Scans\Wpv\ResultsSet();
|
45 |
+
}
|
46 |
+
}
|
47 |
+
return $this->vulnerable;
|
48 |
+
}
|
49 |
+
|
50 |
+
protected function getAbandoned() :Scans\Apc\ResultsSet {
|
51 |
+
if ( !isset( $this->abandoned ) ) {
|
52 |
+
/** @var ModCon $mod */
|
53 |
+
$mod = $this->getMod();
|
54 |
+
try {
|
55 |
+
$this->abandoned = $mod->getScanCon( Apc::SCAN_SLUG )->getAllResults();
|
56 |
+
}
|
57 |
+
catch ( \Exception $e ) {
|
58 |
+
$this->abandoned = new Scans\Apc\ResultsSet();
|
59 |
+
}
|
60 |
+
}
|
61 |
+
return $this->abandoned;
|
62 |
+
}
|
63 |
+
}
|
src/lib/src/Modules/HackGuard/Render/ScanResults/SectionPlugins.php
ADDED
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\LoadRawTableData;
|
6 |
+
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
use FernleafSystems\Wordpress\Services\Utilities\Assets\DetectInstallationDate;
|
9 |
+
|
10 |
+
class SectionPlugins extends SectionPluginThemesBase {
|
11 |
+
|
12 |
+
public function render() :string {
|
13 |
+
return $this->getMod()
|
14 |
+
->renderTemplate(
|
15 |
+
'/wpadmin_pages/insights/scans/results/section/plugins/index.twig',
|
16 |
+
$this->buildRenderData()
|
17 |
+
);
|
18 |
+
}
|
19 |
+
|
20 |
+
protected function buildRenderData() :array {
|
21 |
+
$items = $this->buildPluginsData();
|
22 |
+
ksort( $items );
|
23 |
+
|
24 |
+
$hashes = [];
|
25 |
+
$abandoned = [];
|
26 |
+
$vulnerable = [];
|
27 |
+
$problems = [];
|
28 |
+
$inactive = [];
|
29 |
+
$warning = [];
|
30 |
+
foreach ( $items as $key => $item ) {
|
31 |
+
if ( $item[ 'flags' ][ 'has_guard_files' ] ) {
|
32 |
+
unset( $items[ $key ] );
|
33 |
+
$hashes[] = $item;
|
34 |
+
}
|
35 |
+
elseif ( $item[ 'flags' ][ 'is_vulnerable' ] ) {
|
36 |
+
unset( $items[ $key ] );
|
37 |
+
$vulnerable[] = $item;
|
38 |
+
}
|
39 |
+
elseif ( $item[ 'flags' ][ 'is_abandoned' ] ) {
|
40 |
+
unset( $items[ $key ] );
|
41 |
+
$abandoned[] = $item;
|
42 |
+
}
|
43 |
+
elseif ( $item[ 'flags' ][ 'has_issue' ] ) {
|
44 |
+
unset( $items[ $key ] );
|
45 |
+
$problems[] = $item;
|
46 |
+
}
|
47 |
+
elseif ( $item[ 'flags' ][ 'has_warning' ] ) {
|
48 |
+
unset( $items[ $key ] );
|
49 |
+
$warning[] = $item;
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
$items = array_merge( $vulnerable, $hashes, $abandoned, $problems, $warning, $inactive, $items );
|
54 |
+
|
55 |
+
return Services::DataManipulation()
|
56 |
+
->mergeArraysRecursive( $this->getCommonRenderData(), [
|
57 |
+
'strings' => [
|
58 |
+
'no_items' => __( "Previous scans didn't detect any modified or missing files in any plugin directories.", 'wp-simple-firewall' ),
|
59 |
+
'no_files' => __( "Previous scans didn't detect any modified or missing files in the plugin directory.", 'wp-simple-firewall' ),
|
60 |
+
'files_found' => __( "Previous scans detected 1 or more modified or missing files in the plugin directory.", 'wp-simple-firewall' ),
|
61 |
+
'not_active' => __( "This plugin isn't active and should be uninstalled.", 'wp-simple-firewall' ),
|
62 |
+
'go_to_plugins' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Plugins' ) ),
|
63 |
+
],
|
64 |
+
'hrefs' => [
|
65 |
+
'page_plugins' => Services::WpGeneral()->getAdminUrl_Plugins()
|
66 |
+
],
|
67 |
+
'vars' => [
|
68 |
+
'count_items' => count( $vulnerable ) + count( $hashes )
|
69 |
+
+ count( $abandoned ) + count( $problems ),
|
70 |
+
'plugins' => array_values( $items ),
|
71 |
+
]
|
72 |
+
] );
|
73 |
+
}
|
74 |
+
|
75 |
+
private function buildPluginsData() :array {
|
76 |
+
return array_map(
|
77 |
+
function ( $plugin ) {
|
78 |
+
return $this->buildPluginData( $plugin );
|
79 |
+
},
|
80 |
+
Services::WpPlugins()->getPluginsAsVo()
|
81 |
+
);
|
82 |
+
}
|
83 |
+
|
84 |
+
private function buildPluginData( WpPluginVo $plugin ) :array {
|
85 |
+
$carbon = Services::Request()->carbon();
|
86 |
+
|
87 |
+
$abandoned = $this->getAbandoned()->getItemForSlug( $plugin->file );
|
88 |
+
$guardFilesData = ( new LoadRawTableData() )
|
89 |
+
->setMod( $this->getMod() )
|
90 |
+
->loadForPlugin( $plugin );
|
91 |
+
|
92 |
+
$vulnerabilities = $this->getVulnerabilities()->getItemsForSlug( $plugin->file );
|
93 |
+
|
94 |
+
$data = [
|
95 |
+
'info' => [
|
96 |
+
'type' => 'plugin',
|
97 |
+
'name' => $plugin->Title,
|
98 |
+
'slug' => $plugin->slug,
|
99 |
+
'description' => $plugin->Description,
|
100 |
+
'version' => $plugin->Version,
|
101 |
+
'author' => $plugin->AuthorName,
|
102 |
+
'author_url' => $plugin->AuthorURI,
|
103 |
+
'file' => $plugin->file,
|
104 |
+
'installed_at' => $carbon->setTimestamp( ( new DetectInstallationDate() )->plugin( $plugin ) )
|
105 |
+
->diffForHumans(),
|
106 |
+
'dir' => '/'.str_replace( wp_normalize_path( ABSPATH ), '', wp_normalize_path( $plugin->getInstallDir() ) ),
|
107 |
+
'abandoned_at' => empty( $abandoned ) ? 0
|
108 |
+
: $carbon->setTimestamp( $abandoned->last_updated_at )->diffForHumans(),
|
109 |
+
],
|
110 |
+
'hrefs' => [
|
111 |
+
'vul_info' => add_query_arg(
|
112 |
+
[
|
113 |
+
'type' => $plugin->asset_type,
|
114 |
+
'slug' => $plugin->slug,
|
115 |
+
'version' => $plugin->Version,
|
116 |
+
],
|
117 |
+
'https://shsec.io/shieldvulnerabilitylookup'
|
118 |
+
),
|
119 |
+
],
|
120 |
+
'flags' => [
|
121 |
+
'has_update' => $plugin->hasUpdate(),
|
122 |
+
'has_guard_files' => !empty( $guardFilesData ),
|
123 |
+
'is_abandoned' => !empty( $abandoned ),
|
124 |
+
'is_active' => $plugin->active,
|
125 |
+
'is_vulnerable' => !empty( $vulnerabilities ),
|
126 |
+
'is_wporg' => $plugin->isWpOrg(),
|
127 |
+
],
|
128 |
+
'vars' => [
|
129 |
+
'abandoned_rid' => empty( $abandoned ) ? -1 : $abandoned->VO->id,
|
130 |
+
'count_items' => count( $guardFilesData ) + count( $vulnerabilities )
|
131 |
+
+ ( empty( $abandoned ) ? 0 : 1 )
|
132 |
+
],
|
133 |
+
];
|
134 |
+
$data[ 'flags' ][ 'has_issue' ] = $data[ 'flags' ][ 'is_abandoned' ]
|
135 |
+
|| $data[ 'flags' ][ 'has_guard_files' ]
|
136 |
+
|| $data[ 'flags' ][ 'is_vulnerable' ];
|
137 |
+
$data[ 'flags' ][ 'has_warning' ] = !$data[ 'flags' ][ 'has_issue' ]
|
138 |
+
&& (
|
139 |
+
!$data[ 'flags' ][ 'is_active' ]
|
140 |
+
|| $data[ 'flags' ][ 'has_update' ]
|
141 |
+
);
|
142 |
+
return $data;
|
143 |
+
}
|
144 |
+
}
|
src/lib/src/Modules/HackGuard/Render/ScanResults/SectionThemes.php
ADDED
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\LoadRawTableData;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
+
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpThemeVo;
|
8 |
+
use FernleafSystems\Wordpress\Services\Services;
|
9 |
+
use FernleafSystems\Wordpress\Services\Utilities\Assets\DetectInstallationDate;
|
10 |
+
|
11 |
+
class SectionThemes extends SectionPluginThemesBase {
|
12 |
+
|
13 |
+
public function render() :string {
|
14 |
+
$renderData = $this->buildRenderData();
|
15 |
+
return $this->getMod()
|
16 |
+
->renderTemplate(
|
17 |
+
'/wpadmin_pages/insights/scans/results/section/themes/index.twig',
|
18 |
+
$renderData
|
19 |
+
);
|
20 |
+
}
|
21 |
+
|
22 |
+
protected function buildRenderData() :array {
|
23 |
+
$items = $this->buildThemesData();
|
24 |
+
ksort( $items );
|
25 |
+
|
26 |
+
$hashes = [];
|
27 |
+
$abandoned = [];
|
28 |
+
$vulnerable = [];
|
29 |
+
$problems = [];
|
30 |
+
$inactive = [];
|
31 |
+
$warning = [];
|
32 |
+
foreach ( $items as $key => $item ) {
|
33 |
+
if ( $item[ 'flags' ][ 'has_guard_files' ] ) {
|
34 |
+
unset( $items[ $key ] );
|
35 |
+
$hashes[] = $item;
|
36 |
+
}
|
37 |
+
elseif ( $item[ 'flags' ][ 'is_vulnerable' ] ) {
|
38 |
+
unset( $items[ $key ] );
|
39 |
+
$vulnerable[] = $item;
|
40 |
+
}
|
41 |
+
elseif ( $item[ 'flags' ][ 'is_abandoned' ] ) {
|
42 |
+
unset( $items[ $key ] );
|
43 |
+
$abandoned[] = $item;
|
44 |
+
}
|
45 |
+
elseif ( $item[ 'flags' ][ 'has_issue' ] ) {
|
46 |
+
unset( $items[ $key ] );
|
47 |
+
$problems[] = $item;
|
48 |
+
}
|
49 |
+
elseif ( $item[ 'flags' ][ 'has_warning' ] ) {
|
50 |
+
unset( $items[ $key ] );
|
51 |
+
$warning[] = $item;
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
$items = array_merge( $vulnerable, $hashes, $abandoned, $problems, $warning, $inactive, $items );
|
56 |
+
|
57 |
+
return Services::DataManipulation()
|
58 |
+
->mergeArraysRecursive( $this->getCommonRenderData(), [
|
59 |
+
'strings' => [
|
60 |
+
'no_items' => __( "Previous scans didn't detect any modified or missing files in any Theme directories.", 'wp-simple-firewall' ),
|
61 |
+
'no_files' => __( "Previous scans didn't detect any modified or missing files in the Theme directories.", 'wp-simple-firewall' ),
|
62 |
+
'files_found' => __( "Previous scans detected 1 or more modified or missing files in the theme directory.", 'wp-simple-firewall' ),
|
63 |
+
'not_active' => __( "This theme isn't active and should be uninstalled.", 'wp-simple-firewall' ),
|
64 |
+
'go_to_themes' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Themes' ) ),
|
65 |
+
],
|
66 |
+
'hrefs' => [
|
67 |
+
'page_themes' => Services::WpGeneral()->getAdminUrl_Themes()
|
68 |
+
],
|
69 |
+
'vars' => [
|
70 |
+
'count_items' => count( $vulnerable ) + count( $hashes )
|
71 |
+
+ count( $abandoned ) + count( $problems ),
|
72 |
+
'themes' => array_values( $items ),
|
73 |
+
]
|
74 |
+
] );
|
75 |
+
}
|
76 |
+
|
77 |
+
private function buildThemesData() :array {
|
78 |
+
return array_map(
|
79 |
+
function ( $item ) {
|
80 |
+
return $this->buildThemeData( $item );
|
81 |
+
},
|
82 |
+
Services::WpThemes()->getThemesAsVo()
|
83 |
+
);
|
84 |
+
}
|
85 |
+
|
86 |
+
private function buildThemeData( WpThemeVo $theme ) :array {
|
87 |
+
$carbon = Services::Request()->carbon();
|
88 |
+
|
89 |
+
$abandoned = $this->getAbandoned()->getItemForSlug( $theme->stylesheet );
|
90 |
+
$guardFilesData = ( new LoadRawTableData() )
|
91 |
+
->setMod( $this->getMod() )
|
92 |
+
->loadForTheme( $theme );
|
93 |
+
|
94 |
+
$vulnerabilities = $this->getVulnerabilities()->getItemsForSlug( $theme->file );
|
95 |
+
|
96 |
+
$data = [
|
97 |
+
'info' => [
|
98 |
+
'type' => 'theme',
|
99 |
+
'name' => $theme->Name,
|
100 |
+
'slug' => $theme->slug,
|
101 |
+
'description' => $theme->Description,
|
102 |
+
'version' => $theme->Version,
|
103 |
+
'author' => $theme->Author,
|
104 |
+
'author_url' => $theme->AuthorURI,
|
105 |
+
'file' => $theme->stylesheet,
|
106 |
+
'dir' => '/'.str_replace( wp_normalize_path( ABSPATH ), '', wp_normalize_path( $theme->getInstallDir() ) ),
|
107 |
+
'abandoned_at' => empty( $abandoned ) ? 0
|
108 |
+
: $carbon->setTimestamp( $abandoned->last_updated_at )->diffForHumans(),
|
109 |
+
'installed_at' => $carbon->setTimestamp( ( new DetectInstallationDate() )->theme( $theme ) )
|
110 |
+
->diffForHumans(),
|
111 |
+
'child_theme' => $theme->is_parent ? $theme->child_theme->Name : '',
|
112 |
+
'parent_theme' => $theme->is_child ? $theme->parent_theme->Name : '',
|
113 |
+
],
|
114 |
+
'hrefs' => [
|
115 |
+
'vul_info' => add_query_arg(
|
116 |
+
[
|
117 |
+
'type' => $theme->asset_type,
|
118 |
+
'slug' => $theme->stylesheet,
|
119 |
+
'version' => $theme->Version,
|
120 |
+
],
|
121 |
+
'https://shsec.io/shieldvulnerabilitylookup'
|
122 |
+
),
|
123 |
+
],
|
124 |
+
'flags' => [
|
125 |
+
'has_update' => $theme->hasUpdate(),
|
126 |
+
'is_abandoned' => !empty( $abandoned ),
|
127 |
+
'has_guard_files' => !empty( $guardFilesData ),
|
128 |
+
'is_active' => $theme->active || $theme->is_parent,
|
129 |
+
'is_vulnerable' => !empty( $vulnerabilities ),
|
130 |
+
'is_wporg' => $theme->isWpOrg(),
|
131 |
+
'is_child' => $theme->is_child,
|
132 |
+
'is_parent' => $theme->is_parent,
|
133 |
+
],
|
134 |
+
'vars' => [
|
135 |
+
'count_items' => count( $guardFilesData ) + count( $vulnerabilities )
|
136 |
+
+ ( empty( $abandoned ) ? 0 : 1 )
|
137 |
+
],
|
138 |
+
];
|
139 |
+
$data[ 'flags' ][ 'has_issue' ] = $data[ 'flags' ][ 'is_abandoned' ]
|
140 |
+
|| $data[ 'flags' ][ 'has_guard_files' ]
|
141 |
+
|| $data[ 'flags' ][ 'is_vulnerable' ];
|
142 |
+
$data[ 'flags' ][ 'has_warning' ] = !$data[ 'flags' ][ 'has_issue' ]
|
143 |
+
&& (
|
144 |
+
!$data[ 'flags' ][ 'is_active' ]
|
145 |
+
|| $data[ 'flags' ][ 'has_update' ]
|
146 |
+
);
|
147 |
+
return $data;
|
148 |
+
}
|
149 |
+
}
|
src/lib/src/Modules/HackGuard/Render/ScanResults/SectionWordpress.php
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\LoadRawTableData;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Scans\ForWordpress;
|
8 |
+
use FernleafSystems\Wordpress\Services\Services;
|
9 |
+
|
10 |
+
class SectionWordpress extends SectionBase {
|
11 |
+
|
12 |
+
public function render() :string {
|
13 |
+
return $this->getMod()
|
14 |
+
->renderTemplate(
|
15 |
+
'/wpadmin_pages/insights/scans/results/section/wordpress/index.twig',
|
16 |
+
$this->buildRenderData()
|
17 |
+
);
|
18 |
+
}
|
19 |
+
|
20 |
+
protected function buildRenderData() :array {
|
21 |
+
$wpData = $this->buildWordpressData();
|
22 |
+
return Services::DataManipulation()
|
23 |
+
->mergeArraysRecursive( $this->getCommonRenderData(), [
|
24 |
+
'strings' => [
|
25 |
+
'no_files' => __( "Previous scans didn't detect any modified, missing or unrecognised files in the WordPress core directories.", 'wp-simple-firewall' ),
|
26 |
+
'files_found' => __( "Previous scans detected 1 or more modified, missing or unrecognised files in the WordPress core directories.", 'wp-simple-firewall' ),
|
27 |
+
],
|
28 |
+
'vars' => [
|
29 |
+
'count_items' => $wpData[ 'vars' ][ 'count_items' ],
|
30 |
+
'wordpress' => $wpData,
|
31 |
+
'datatables_init' => ( new ForWordpress() )
|
32 |
+
->setMod( $this->getMod() )
|
33 |
+
->build()
|
34 |
+
]
|
35 |
+
] );
|
36 |
+
}
|
37 |
+
|
38 |
+
private function buildWordpressData() :array {
|
39 |
+
|
40 |
+
$coreFilesData = ( new LoadRawTableData() )
|
41 |
+
->setMod( $this->getMod() )
|
42 |
+
->loadForWordPress();
|
43 |
+
|
44 |
+
$WP = Services::WpGeneral();
|
45 |
+
$data = [
|
46 |
+
'info' => [
|
47 |
+
'type' => 'theme',
|
48 |
+
'version' => $WP->getVersion(),
|
49 |
+
'dir' => wp_normalize_path( ABSPATH ),
|
50 |
+
],
|
51 |
+
'flags' => [
|
52 |
+
'has_update' => $WP->hasCoreUpdate(),
|
53 |
+
'has_core_files' => !empty( $coreFilesData ),
|
54 |
+
'is_vulnerable' => false,
|
55 |
+
],
|
56 |
+
'vars' => [
|
57 |
+
'count_items' => count( $coreFilesData )
|
58 |
+
]
|
59 |
+
];
|
60 |
+
$data[ 'flags' ][ 'has_issue' ] = $data[ 'flags' ][ 'has_core_files' ]
|
61 |
+
|| $data[ 'flags' ][ 'is_vulnerable' ];
|
62 |
+
return $data;
|
63 |
+
}
|
64 |
+
}
|
src/lib/src/Modules/HackGuard/Reporting.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
4 |
|
@@ -13,6 +13,7 @@ class Reporting extends Base\Reporting {
|
|
13 |
protected function enumAlertReporters() :array {
|
14 |
return [
|
15 |
new Reports\ScanAlerts(),
|
|
|
16 |
new Reports\FileLockerAlerts(),
|
17 |
];
|
18 |
}
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
4 |
|
13 |
protected function enumAlertReporters() :array {
|
14 |
return [
|
15 |
new Reports\ScanAlerts(),
|
16 |
+
new Reports\ScanRepairs(),
|
17 |
new Reports\FileLockerAlerts(),
|
18 |
];
|
19 |
}
|
src/lib/src/Modules/HackGuard/Scan/Controller/Base.php
CHANGED
@@ -2,13 +2,14 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
|
9 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
10 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\
|
11 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\
|
12 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO;
|
13 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Table\BaseEntryFormatter;
|
14 |
use FernleafSystems\Wordpress\Services\Services;
|
@@ -16,16 +17,15 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
16 |
abstract class Base extends ExecOnceModConsumer {
|
17 |
|
18 |
const SCAN_SLUG = '';
|
|
|
19 |
|
20 |
/**
|
21 |
* @var BaseScanActionVO
|
22 |
*/
|
23 |
private $scanActionVO;
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
* see dynamic constructors: features/hack_protect.php
|
28 |
-
*/
|
29 |
public function __construct() {
|
30 |
}
|
31 |
|
@@ -42,6 +42,21 @@ abstract class Base extends ExecOnceModConsumer {
|
|
42 |
$mod->getScanQueueController()->startScans( [ $this->getSlug() ] );
|
43 |
}
|
44 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
}
|
46 |
|
47 |
public function cleanStalesResults() {
|
@@ -58,8 +73,8 @@ abstract class Base extends ExecOnceModConsumer {
|
|
58 |
->delete( $results );
|
59 |
}
|
60 |
|
61 |
-
public function createFileDownloadLink(
|
62 |
-
return $this->getMod()->createFileDownloadLink( 'scan_file', [ 'rid' => $
|
63 |
}
|
64 |
|
65 |
public function getLastScanAt() :int {
|
@@ -72,53 +87,57 @@ abstract class Base extends ExecOnceModConsumer {
|
|
72 |
return ( $entry instanceof Databases\Events\EntryVO ) ? (int)$entry->created_at : 0;
|
73 |
}
|
74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
public function getScanHasProblem() :bool {
|
76 |
-
|
77 |
-
$mod = $this->getMod();
|
78 |
-
/** @var Databases\Scanner\Select $sel */
|
79 |
-
$sel = $mod->getDbHandler_ScanResults()->getQuerySelector();
|
80 |
-
return $sel->filterByNotIgnored()
|
81 |
-
->filterByScan( $this->getSlug() )
|
82 |
-
->count() > 0;
|
83 |
}
|
84 |
|
85 |
/**
|
86 |
-
* @param
|
87 |
* @return bool
|
88 |
*/
|
89 |
abstract protected function isResultItemStale( $item ) :bool;
|
90 |
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
|
|
|
|
|
|
|
|
|
|
97 |
$success = false;
|
98 |
|
99 |
-
if ( is_numeric( $
|
100 |
/** @var Databases\Scanner\EntryVO $entry */
|
101 |
$entry = $this->getScanResultsDbHandler()
|
102 |
->getQuerySelector()
|
103 |
-
->byId( $
|
104 |
if ( empty( $entry ) ) {
|
105 |
throw new \Exception( 'Item could not be found.' );
|
106 |
}
|
107 |
|
108 |
-
$
|
109 |
-
->setScanController( $this )
|
110 |
-
->convertVoToResultItem( $entry );
|
111 |
-
|
112 |
-
$success = $this->getItemActionHandler()
|
113 |
-
->setScanItem( $entry )
|
114 |
-
->process( $action );
|
115 |
}
|
116 |
|
117 |
return $success;
|
118 |
}
|
119 |
|
120 |
/**
|
121 |
-
* @return Scans\Base\
|
122 |
*/
|
123 |
protected function getItemsToAutoRepair() {
|
124 |
/** @var Databases\Scanner\Select $sel */
|
@@ -140,25 +159,26 @@ abstract class Base extends ExecOnceModConsumer {
|
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
-
* @param bool $
|
144 |
-
* @return Scans\Base\
|
145 |
*/
|
146 |
-
public function getAllResults( $
|
147 |
/** @var Databases\Scanner\Select $sel */
|
148 |
$sel = $this->getScanResultsDbHandler()->getQuerySelector();
|
149 |
$sel->filterByScan( $this->getSlug() );
|
150 |
-
if ( !$
|
151 |
$sel->filterByNotIgnored();
|
152 |
}
|
|
|
153 |
return ( new HackGuard\Scan\Results\ConvertBetweenTypes() )
|
154 |
->setScanController( $this )
|
155 |
-
->fromVOsToResultsSet( $
|
156 |
}
|
157 |
|
158 |
/**
|
159 |
* @return Scans\Base\Utilities\ItemActionHandler
|
160 |
*/
|
161 |
-
|
162 |
return $this->newItemActionHandler()
|
163 |
->setMod( $this->getMod() )
|
164 |
->setScanController( $this );
|
@@ -189,6 +209,10 @@ abstract class Base extends ExecOnceModConsumer {
|
|
189 |
return false;
|
190 |
}
|
191 |
|
|
|
|
|
|
|
|
|
192 |
abstract public function isEnabled() :bool;
|
193 |
|
194 |
protected function isPremiumOnly() :bool {
|
@@ -235,7 +259,7 @@ abstract class Base extends ExecOnceModConsumer {
|
|
235 |
try {
|
236 |
$this->getItemActionHandler()
|
237 |
->setScanItem( $item )
|
238 |
-
->repair();
|
239 |
}
|
240 |
catch ( \Exception $e ) {
|
241 |
}
|
@@ -264,14 +288,14 @@ abstract class Base extends ExecOnceModConsumer {
|
|
264 |
try {
|
265 |
$slug = strtolower( ( new \ReflectionClass( $this ) )->getShortName() );
|
266 |
}
|
267 |
-
catch ( \
|
268 |
$slug = '';
|
269 |
}
|
270 |
return $slug;
|
271 |
}
|
272 |
|
273 |
/**
|
274 |
-
* @return
|
275 |
*/
|
276 |
public function getNewResultItem() {
|
277 |
$class = $this->getScanNamespace().'ResultItem';
|
@@ -279,7 +303,7 @@ abstract class Base extends ExecOnceModConsumer {
|
|
279 |
}
|
280 |
|
281 |
/**
|
282 |
-
* @return
|
283 |
*/
|
284 |
public function getNewResultsSet() {
|
285 |
$class = $this->getScanNamespace().'ResultsSet';
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Crons\PluginCronsConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
9 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
|
10 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
11 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultItem;
|
12 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultsSet;
|
13 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO;
|
14 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Table\BaseEntryFormatter;
|
15 |
use FernleafSystems\Wordpress\Services\Services;
|
17 |
abstract class Base extends ExecOnceModConsumer {
|
18 |
|
19 |
const SCAN_SLUG = '';
|
20 |
+
use PluginCronsConsumer;
|
21 |
|
22 |
/**
|
23 |
* @var BaseScanActionVO
|
24 |
*/
|
25 |
private $scanActionVO;
|
26 |
|
27 |
+
private static $resultsCounts;
|
28 |
+
|
|
|
|
|
29 |
public function __construct() {
|
30 |
}
|
31 |
|
42 |
$mod->getScanQueueController()->startScans( [ $this->getSlug() ] );
|
43 |
}
|
44 |
);
|
45 |
+
add_filter( $this->getCon()->prefix( 'admin_bar_menu_items' ), [ $this, 'addAdminMenuBarItem' ], 100 );
|
46 |
+
}
|
47 |
+
|
48 |
+
public function addAdminMenuBarItem( array $items ) :array {
|
49 |
+
$problems = $this->countScanProblems();
|
50 |
+
if ( $problems > 0 ) {
|
51 |
+
$items[] = [
|
52 |
+
'id' => $this->getCon()->prefix( 'problems-'.$this->getSlug() ),
|
53 |
+
'title' => $this->getScanName()
|
54 |
+
.sprintf( '<div class="wp-core-ui wp-ui-notification shield-counter"><span aria-hidden="true">%s</span></div>', $problems ),
|
55 |
+
'href' => $this->getCon()->getModule_Insights()->getUrl_ScansResults(),
|
56 |
+
'warnings' => $problems
|
57 |
+
];
|
58 |
+
}
|
59 |
+
return $items;
|
60 |
}
|
61 |
|
62 |
public function cleanStalesResults() {
|
73 |
->delete( $results );
|
74 |
}
|
75 |
|
76 |
+
public function createFileDownloadLink( int $recordID ) :string {
|
77 |
+
return $this->getMod()->createFileDownloadLink( 'scan_file', [ 'rid' => $recordID ] );
|
78 |
}
|
79 |
|
80 |
public function getLastScanAt() :int {
|
87 |
return ( $entry instanceof Databases\Events\EntryVO ) ? (int)$entry->created_at : 0;
|
88 |
}
|
89 |
|
90 |
+
public function countScanProblems() :int {
|
91 |
+
if ( !isset( self::$resultsCounts ) ) {
|
92 |
+
/** @var ModCon $mod */
|
93 |
+
$mod = $this->getMod();
|
94 |
+
/** @var Databases\Scanner\Select $sel */
|
95 |
+
$sel = $mod->getDbHandler_ScanResults()->getQuerySelector();
|
96 |
+
self::$resultsCounts = $sel->countForEachScan();
|
97 |
+
}
|
98 |
+
return self::$resultsCounts[ static::SCAN_SLUG ] ?? 0;
|
99 |
+
}
|
100 |
+
|
101 |
public function getScanHasProblem() :bool {
|
102 |
+
return $this->countScanProblems() > 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
}
|
104 |
|
105 |
/**
|
106 |
+
* @param ResultItem|mixed $item
|
107 |
* @return bool
|
108 |
*/
|
109 |
abstract protected function isResultItemStale( $item ) :bool;
|
110 |
|
111 |
+
public function executeEntryAction( Databases\Scanner\EntryVO $entry, string $action ) :bool {
|
112 |
+
$item = ( new HackGuard\Scan\Results\ConvertBetweenTypes() )
|
113 |
+
->setScanController( $this )
|
114 |
+
->convertVoToResultItem( $entry );
|
115 |
+
|
116 |
+
return $this->getItemActionHandler()
|
117 |
+
->setScanItem( $item )
|
118 |
+
->process( $action );
|
119 |
+
}
|
120 |
+
|
121 |
+
public function executeItemAction( int $recordID, string $action ) :bool {
|
122 |
$success = false;
|
123 |
|
124 |
+
if ( is_numeric( $recordID ) ) {
|
125 |
/** @var Databases\Scanner\EntryVO $entry */
|
126 |
$entry = $this->getScanResultsDbHandler()
|
127 |
->getQuerySelector()
|
128 |
+
->byId( $recordID );
|
129 |
if ( empty( $entry ) ) {
|
130 |
throw new \Exception( 'Item could not be found.' );
|
131 |
}
|
132 |
|
133 |
+
$success = $this->executeEntryAction( $entry, $action );
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
}
|
135 |
|
136 |
return $success;
|
137 |
}
|
138 |
|
139 |
/**
|
140 |
+
* @return Scans\Base\ResultsSet|mixed
|
141 |
*/
|
142 |
protected function getItemsToAutoRepair() {
|
143 |
/** @var Databases\Scanner\Select $sel */
|
159 |
}
|
160 |
|
161 |
/**
|
162 |
+
* @param bool $includeIgnored
|
163 |
+
* @return Scans\Base\ResultsSet|mixed
|
164 |
*/
|
165 |
+
public function getAllResults( $includeIgnored = false ) {
|
166 |
/** @var Databases\Scanner\Select $sel */
|
167 |
$sel = $this->getScanResultsDbHandler()->getQuerySelector();
|
168 |
$sel->filterByScan( $this->getSlug() );
|
169 |
+
if ( !$includeIgnored ) {
|
170 |
$sel->filterByNotIgnored();
|
171 |
}
|
172 |
+
$raw = $this->isRestricted() ? [] : $sel->query();
|
173 |
return ( new HackGuard\Scan\Results\ConvertBetweenTypes() )
|
174 |
->setScanController( $this )
|
175 |
+
->fromVOsToResultsSet( $raw );
|
176 |
}
|
177 |
|
178 |
/**
|
179 |
* @return Scans\Base\Utilities\ItemActionHandler
|
180 |
*/
|
181 |
+
public function getItemActionHandler() {
|
182 |
return $this->newItemActionHandler()
|
183 |
->setMod( $this->getMod() )
|
184 |
->setScanController( $this );
|
209 |
return false;
|
210 |
}
|
211 |
|
212 |
+
public function canCronAutoDelete() :bool {
|
213 |
+
return false;
|
214 |
+
}
|
215 |
+
|
216 |
abstract public function isEnabled() :bool;
|
217 |
|
218 |
protected function isPremiumOnly() :bool {
|
259 |
try {
|
260 |
$this->getItemActionHandler()
|
261 |
->setScanItem( $item )
|
262 |
+
->repair( $this->canCronAutoDelete() );
|
263 |
}
|
264 |
catch ( \Exception $e ) {
|
265 |
}
|
288 |
try {
|
289 |
$slug = strtolower( ( new \ReflectionClass( $this ) )->getShortName() );
|
290 |
}
|
291 |
+
catch ( \Exception $e ) {
|
292 |
$slug = '';
|
293 |
}
|
294 |
return $slug;
|
295 |
}
|
296 |
|
297 |
/**
|
298 |
+
* @return ResultItem|mixed
|
299 |
*/
|
300 |
public function getNewResultItem() {
|
301 |
$class = $this->getScanNamespace().'ResultItem';
|
303 |
}
|
304 |
|
305 |
/**
|
306 |
+
* @return ResultsSet|mixed
|
307 |
*/
|
308 |
public function getNewResultsSet() {
|
309 |
$class = $this->getScanNamespace().'ResultsSet';
|
src/lib/src/Modules/HackGuard/Scan/Controller/BaseForAssets.php
CHANGED
@@ -14,11 +14,11 @@ abstract class BaseForAssets extends Base {
|
|
14 |
protected function isResultItemStale( $item ) :bool {
|
15 |
if ( $item->context == 'plugins' ) {
|
16 |
$asset = Services::WpPlugins()->getPluginAsVo( $item->slug );
|
17 |
-
$stale = empty( $asset )
|
18 |
}
|
19 |
else {
|
20 |
$asset = Services::WpThemes()->getThemeAsVo( $item->slug );
|
21 |
-
$stale = empty( $asset )
|
22 |
}
|
23 |
return $stale;
|
24 |
}
|
14 |
protected function isResultItemStale( $item ) :bool {
|
15 |
if ( $item->context == 'plugins' ) {
|
16 |
$asset = Services::WpPlugins()->getPluginAsVo( $item->slug );
|
17 |
+
$stale = empty( $asset );
|
18 |
}
|
19 |
else {
|
20 |
$asset = Services::WpThemes()->getThemeAsVo( $item->slug );
|
21 |
+
$stale = empty( $asset );
|
22 |
}
|
23 |
return $stale;
|
24 |
}
|
src/lib/src/Modules/HackGuard/Scan/Controller/Ptg.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
use FernleafSystems\Wordpress\Services\Utilities\WpOrg;
|
@@ -16,6 +17,31 @@ class Ptg extends BaseForAssets {
|
|
16 |
( new HackGuard\Scan\Utilities\PtgAddReinstallLinks() )
|
17 |
->setScanController( $this )
|
18 |
->execute();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
}
|
20 |
|
21 |
/**
|
@@ -35,6 +61,13 @@ class Ptg extends BaseForAssets {
|
|
35 |
elseif ( $opts->isRepairFilePlugin() ) {
|
36 |
$results = $results->getResultsForPluginsContext();
|
37 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
}
|
39 |
|
40 |
return $results;
|
@@ -47,15 +80,23 @@ class Ptg extends BaseForAssets {
|
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
-
* @param Scans\
|
51 |
* @return bool
|
52 |
*/
|
53 |
protected function isResultItemStale( $item ) :bool {
|
54 |
-
$
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
58 |
-
|
|
|
59 |
}
|
60 |
|
61 |
/**
|
@@ -84,13 +125,11 @@ class Ptg extends BaseForAssets {
|
|
84 |
}
|
85 |
|
86 |
public function isEnabled() :bool {
|
87 |
-
return $this->getOptions()->isOpt( 'ptg_enable', 'Y' )
|
88 |
}
|
89 |
|
90 |
public function isReady() :bool {
|
91 |
-
return parent::isReady()
|
92 |
-
&& $this->getOptions()->isOptReqsMet( 'ptg_enable' )
|
93 |
-
&& $this->getMod()->canCacheDirWrite();
|
94 |
}
|
95 |
|
96 |
/**
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
9 |
use FernleafSystems\Wordpress\Services\Utilities\WpOrg;
|
17 |
( new HackGuard\Scan\Utilities\PtgAddReinstallLinks() )
|
18 |
->setScanController( $this )
|
19 |
->execute();
|
20 |
+
|
21 |
+
$this->setupCronHooks();
|
22 |
+
add_action( 'wp_loaded', [ $this, 'onWpLoaded' ] );
|
23 |
+
add_action( $this->getCon()->prefix( 'plugin_shutdown' ), [ $this, 'onModuleShutdown' ] );
|
24 |
+
}
|
25 |
+
|
26 |
+
public function onWpLoaded() {
|
27 |
+
( new StoreAction\ScheduleBuildAll() )
|
28 |
+
->setMod( $this->getMod() )
|
29 |
+
->hookBuild();
|
30 |
+
}
|
31 |
+
|
32 |
+
public function onModuleShutdown() {
|
33 |
+
( new StoreAction\ScheduleBuildAll() )
|
34 |
+
->setMod( $this->getMod() )
|
35 |
+
->schedule();
|
36 |
+
}
|
37 |
+
|
38 |
+
public function runHourlyCron() {
|
39 |
+
( new StoreAction\TouchAll() )
|
40 |
+
->setMod( $this->getMod() )
|
41 |
+
->run();
|
42 |
+
( new StoreAction\CleanAll() )
|
43 |
+
->setMod( $this->getMod() )
|
44 |
+
->run();
|
45 |
}
|
46 |
|
47 |
/**
|
61 |
elseif ( $opts->isRepairFilePlugin() ) {
|
62 |
$results = $results->getResultsForPluginsContext();
|
63 |
}
|
64 |
+
|
65 |
+
/** @var Scans\Ptg\ResultItem $item */
|
66 |
+
foreach ( $results->getItems() as $item ) {
|
67 |
+
if ( $item->is_unrecognised ) {
|
68 |
+
$results->removeItem( $item );
|
69 |
+
}
|
70 |
+
}
|
71 |
}
|
72 |
|
73 |
return $results;
|
80 |
}
|
81 |
|
82 |
/**
|
83 |
+
* @param Scans\Ptg\ResultItem $item
|
84 |
* @return bool
|
85 |
*/
|
86 |
protected function isResultItemStale( $item ) :bool {
|
87 |
+
$FS = Services::WPFS();
|
88 |
+
$stale = parent::isResultItemStale( $item )
|
89 |
+
|| ( ( $item->is_unrecognised || $item->is_different ) && !$FS->isFile( $item->path_full ) );
|
90 |
+
|
91 |
+
if ( !$stale ) {
|
92 |
+
$asset = ( new WpOrg\Plugin\Files() )->findPluginFromFile( $item->path_full );
|
93 |
+
if ( empty( $asset ) ) {
|
94 |
+
$asset = ( new WpOrg\Theme\Files() )->findThemeFromFile( $item->path_full );
|
95 |
+
}
|
96 |
+
$stale = empty( $asset );
|
97 |
}
|
98 |
+
|
99 |
+
return $stale;
|
100 |
}
|
101 |
|
102 |
/**
|
125 |
}
|
126 |
|
127 |
public function isEnabled() :bool {
|
128 |
+
return $this->getOptions()->isOpt( 'ptg_enable', 'Y' );
|
129 |
}
|
130 |
|
131 |
public function isReady() :bool {
|
132 |
+
return parent::isReady() && $this->getCon()->hasCacheDir();
|
|
|
|
|
133 |
}
|
134 |
|
135 |
/**
|
src/lib/src/Modules/HackGuard/Scan/Controller/Ufc.php
CHANGED
@@ -17,6 +17,10 @@ class Ufc extends Base {
|
|
17 |
return new Scans\Ufc\Utilities\ItemActionHandler();
|
18 |
}
|
19 |
|
|
|
|
|
|
|
|
|
20 |
/**
|
21 |
* @param Scans\Mal\ResultItem $item
|
22 |
* @return bool
|
@@ -26,9 +30,9 @@ class Ufc extends Base {
|
|
26 |
}
|
27 |
|
28 |
public function isCronAutoRepair() :bool {
|
29 |
-
/** @var HackGuard\Options $
|
30 |
-
$
|
31 |
-
return $
|
32 |
}
|
33 |
|
34 |
public function isEnabled() :bool {
|
17 |
return new Scans\Ufc\Utilities\ItemActionHandler();
|
18 |
}
|
19 |
|
20 |
+
public function canCronAutoDelete() :bool {
|
21 |
+
return $this->isCronAutoRepair();
|
22 |
+
}
|
23 |
+
|
24 |
/**
|
25 |
* @param Scans\Mal\ResultItem $item
|
26 |
* @return bool
|
30 |
}
|
31 |
|
32 |
public function isCronAutoRepair() :bool {
|
33 |
+
/** @var HackGuard\Options $opts */
|
34 |
+
$opts = $this->getOptions();
|
35 |
+
return $opts->isUfsDeleteFiles();
|
36 |
}
|
37 |
|
38 |
public function isEnabled() :bool {
|
src/lib/src/Modules/HackGuard/Scan/Queue/CollateResults.php
CHANGED
@@ -17,35 +17,35 @@ class CollateResults {
|
|
17 |
|
18 |
/**
|
19 |
* @param string $sScanSlug
|
20 |
-
* @return Scans\Base\
|
21 |
*/
|
22 |
public function collate( $sScanSlug ) {
|
23 |
-
/** @var Databases\ScanQueue\Handler $
|
24 |
-
$
|
25 |
-
/** @var Databases\ScanQueue\Select $
|
26 |
-
$
|
27 |
-
$
|
28 |
-
|
29 |
-
$
|
30 |
-
|
31 |
-
$
|
32 |
-
/** @var Databases\ScanQueue\EntryVO $
|
33 |
-
foreach ( $
|
34 |
-
$
|
35 |
-
->setDbHandler( $
|
36 |
-
->fromDbEntryToAction( $
|
37 |
-
|
38 |
-
if ( empty( $
|
39 |
-
$
|
40 |
}
|
41 |
|
42 |
-
foreach ( $
|
43 |
-
$
|
44 |
-
$
|
45 |
);
|
46 |
}
|
47 |
}
|
48 |
|
49 |
-
return $
|
50 |
}
|
51 |
}
|
17 |
|
18 |
/**
|
19 |
* @param string $sScanSlug
|
20 |
+
* @return Scans\Base\ResultsSet|mixed|null
|
21 |
*/
|
22 |
public function collate( $sScanSlug ) {
|
23 |
+
/** @var Databases\ScanQueue\Handler $dbh */
|
24 |
+
$dbh = $this->getDbHandler();
|
25 |
+
/** @var Databases\ScanQueue\Select $selector */
|
26 |
+
$selector = $dbh->getQuerySelector();
|
27 |
+
$selector->filterByScan( $sScanSlug )
|
28 |
+
->setResultsAsVo( true );
|
29 |
+
$scanCon = $this->getScanController();
|
30 |
+
|
31 |
+
$resultsSet = null;
|
32 |
+
/** @var Databases\ScanQueue\EntryVO $entry */
|
33 |
+
foreach ( $selector->query() as $entry ) {
|
34 |
+
$action = ( new ConvertBetweenTypes() )
|
35 |
+
->setDbHandler( $dbh )
|
36 |
+
->fromDbEntryToAction( $entry );
|
37 |
+
|
38 |
+
if ( empty( $resultsSet ) ) {
|
39 |
+
$resultsSet = $scanCon->getNewResultsSet();
|
40 |
}
|
41 |
|
42 |
+
foreach ( $action->results as $aResItemData ) {
|
43 |
+
$resultsSet->addItem(
|
44 |
+
$action->getNewResultItem()->applyFromArray( $aResItemData )
|
45 |
);
|
46 |
}
|
47 |
}
|
48 |
|
49 |
+
return $resultsSet;
|
50 |
}
|
51 |
}
|
src/lib/src/Modules/HackGuard/Scan/Queue/CompleteQueue.php
CHANGED
@@ -27,25 +27,25 @@ class CompleteQueue {
|
|
27 |
$con = $this->getCon();
|
28 |
/** @var Databases\ScanQueue\Handler $dbh */
|
29 |
$dbh = $this->getDbHandler();
|
30 |
-
$
|
31 |
|
32 |
-
foreach ( $
|
33 |
|
34 |
-
$
|
35 |
|
36 |
-
$
|
37 |
-
->setScanController( $
|
38 |
->setDbHandler( $dbh )
|
39 |
->collate( $scanSlug );
|
40 |
|
41 |
$con->fireEvent( $scanSlug.'_scan_run' );
|
42 |
|
43 |
-
if ( $
|
44 |
( new HackGuard\Scan\Results\ResultsUpdate() )
|
45 |
-
->setScanController( $
|
46 |
-
->update( $
|
47 |
|
48 |
-
if ( $
|
49 |
$con->fireEvent( $scanSlug.'_scan_found' );
|
50 |
}
|
51 |
}
|
27 |
$con = $this->getCon();
|
28 |
/** @var Databases\ScanQueue\Handler $dbh */
|
29 |
$dbh = $this->getDbHandler();
|
30 |
+
$selector = $dbh->getQuerySelector();
|
31 |
|
32 |
+
foreach ( $selector->getDistinctForColumn( 'scan' ) as $scanSlug ) {
|
33 |
|
34 |
+
$scanCon = $mod->getScanCon( $scanSlug );
|
35 |
|
36 |
+
$resultsSet = ( new CollateResults() )
|
37 |
+
->setScanController( $scanCon )
|
38 |
->setDbHandler( $dbh )
|
39 |
->collate( $scanSlug );
|
40 |
|
41 |
$con->fireEvent( $scanSlug.'_scan_run' );
|
42 |
|
43 |
+
if ( $resultsSet instanceof Scans\Base\ResultsSet ) {
|
44 |
( new HackGuard\Scan\Results\ResultsUpdate() )
|
45 |
+
->setScanController( $scanCon )
|
46 |
+
->update( $resultsSet );
|
47 |
|
48 |
+
if ( $resultsSet->countItems() > 0 ) {
|
49 |
$con->fireEvent( $scanSlug.'_scan_found' );
|
50 |
}
|
51 |
}
|
src/lib/src/Modules/HackGuard/Scan/Queue/Controller.php
CHANGED
@@ -37,7 +37,7 @@ class Controller {
|
|
37 |
/**
|
38 |
* @return bool[]
|
39 |
*/
|
40 |
-
public function getScansRunningStates() {
|
41 |
/** @var HackGuard\ModCon $mod */
|
42 |
$mod = $this->getMod();
|
43 |
/** @var HackGuard\Options $opts */
|
@@ -48,11 +48,11 @@ class Controller {
|
|
48 |
// First clean the queue:
|
49 |
$this->cleanExpiredFromQueue();
|
50 |
|
51 |
-
$
|
52 |
foreach ( $sel->getInitiatedScans() as $sInitScan ) {
|
53 |
-
$
|
54 |
}
|
55 |
-
return $
|
56 |
}
|
57 |
|
58 |
/**
|
@@ -66,16 +66,16 @@ class Controller {
|
|
66 |
$nExpiredBoundary = Services::Request()
|
67 |
->carbon()
|
68 |
->subSeconds( $opts->getMalQueueExpirationInterval() )->timestamp;
|
69 |
-
/** @var ScanQueue\Delete $
|
70 |
-
$
|
71 |
-
return $
|
72 |
-
|
73 |
}
|
74 |
|
75 |
/**
|
76 |
* @return string[]
|
77 |
*/
|
78 |
-
public function getRunningScans() {
|
79 |
return array_keys( array_filter( $this->getScansRunningStates() ) );
|
80 |
}
|
81 |
|
@@ -88,27 +88,27 @@ class Controller {
|
|
88 |
/** @var ScanQueue\Select $sel */
|
89 |
$sel = $mod->getDbHandler_ScanQueue()->getQuerySelector();
|
90 |
|
91 |
-
$
|
92 |
-
$
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
$nProgress = 1 - ( count( $aUnfinished )/count( $sel->getInitiatedScans() ) );
|
97 |
-
}
|
98 |
}
|
99 |
else {
|
100 |
-
$
|
|
|
|
|
|
|
|
|
101 |
}
|
102 |
-
|
|
|
103 |
}
|
104 |
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
/** @var HackGuard\Options $oOpts */
|
110 |
-
$oOpts = $this->getOptions();
|
111 |
-
return count( $this->getRunningScans() ) > 0 || count( $oOpts->getScansToBuild() ) > 0;
|
112 |
}
|
113 |
|
114 |
/**
|
37 |
/**
|
38 |
* @return bool[]
|
39 |
*/
|
40 |
+
public function getScansRunningStates() :array {
|
41 |
/** @var HackGuard\ModCon $mod */
|
42 |
$mod = $this->getMod();
|
43 |
/** @var HackGuard\Options $opts */
|
48 |
// First clean the queue:
|
49 |
$this->cleanExpiredFromQueue();
|
50 |
|
51 |
+
$scans = array_fill_keys( $opts->getScanSlugs(), false );
|
52 |
foreach ( $sel->getInitiatedScans() as $sInitScan ) {
|
53 |
+
$scans[ $sInitScan ] = true;
|
54 |
}
|
55 |
+
return $scans;
|
56 |
}
|
57 |
|
58 |
/**
|
66 |
$nExpiredBoundary = Services::Request()
|
67 |
->carbon()
|
68 |
->subSeconds( $opts->getMalQueueExpirationInterval() )->timestamp;
|
69 |
+
/** @var ScanQueue\Delete $deleter */
|
70 |
+
$deleter = $mod->getDbHandler_ScanQueue()->getQueryDeleter();
|
71 |
+
return $deleter->addWhereOlderThan( $nExpiredBoundary )
|
72 |
+
->query();
|
73 |
}
|
74 |
|
75 |
/**
|
76 |
* @return string[]
|
77 |
*/
|
78 |
+
public function getRunningScans() :array {
|
79 |
return array_keys( array_filter( $this->getScansRunningStates() ) );
|
80 |
}
|
81 |
|
88 |
/** @var ScanQueue\Select $sel */
|
89 |
$sel = $mod->getDbHandler_ScanQueue()->getQuerySelector();
|
90 |
|
91 |
+
$countsAll = $sel->countAllForEachScan();
|
92 |
+
$countsUnfinished = $sel->countUnfinishedForEachScan();
|
93 |
+
|
94 |
+
if ( empty( $countsAll ) || empty( $countsUnfinished ) ) {
|
95 |
+
$progress = 1;
|
|
|
|
|
96 |
}
|
97 |
else {
|
98 |
+
$progress = 0;
|
99 |
+
$eachScanWeight = 1/count( $countsAll );
|
100 |
+
foreach ( array_keys( $countsAll ) as $scan ) {
|
101 |
+
$progress += $eachScanWeight*( 1 - ( ( $countsUnfinished[ $scan ] ?? 0 )/$countsAll[ $scan ] ) );
|
102 |
+
}
|
103 |
}
|
104 |
+
|
105 |
+
return $progress;
|
106 |
}
|
107 |
|
108 |
+
public function hasRunningScans() :bool {
|
109 |
+
/** @var HackGuard\Options $opts */
|
110 |
+
$opts = $this->getOptions();
|
111 |
+
return count( $this->getRunningScans() ) > 0 || count( $opts->getScansToBuild() ) > 0;
|
|
|
|
|
|
|
112 |
}
|
113 |
|
114 |
/**
|
src/lib/src/Modules/HackGuard/Scan/Queue/ConvertBetweenTypes.php
CHANGED
@@ -15,15 +15,15 @@ class ConvertBetweenTypes {
|
|
15 |
use Databases\Base\HandlerConsumer;
|
16 |
|
17 |
/**
|
18 |
-
* @param Databases\ScanQueue\EntryVO $
|
19 |
* @return Scans\Base\BaseScanActionVO|mixed
|
20 |
*/
|
21 |
-
public function fromDbEntryToAction( $
|
22 |
-
$
|
23 |
-
$
|
24 |
-
$
|
25 |
-
$
|
26 |
-
return $
|
27 |
}
|
28 |
|
29 |
/**
|
15 |
use Databases\Base\HandlerConsumer;
|
16 |
|
17 |
/**
|
18 |
+
* @param Databases\ScanQueue\EntryVO $entry
|
19 |
* @return Scans\Base\BaseScanActionVO|mixed
|
20 |
*/
|
21 |
+
public function fromDbEntryToAction( $entry ) {
|
22 |
+
$action = ScanActionFromSlug::GetAction( $entry->scan );
|
23 |
+
$action->applyFromArray( $entry->meta );
|
24 |
+
$action->items = $entry->items;
|
25 |
+
$action->results = $entry->results;
|
26 |
+
return $action;
|
27 |
}
|
28 |
|
29 |
/**
|
src/lib/src/Modules/HackGuard/Scan/Queue/QueueProcessor.php
CHANGED
@@ -40,26 +40,26 @@ class QueueProcessor extends Utilities\BackgroundProcessing\BackgroundProcess {
|
|
40 |
* in the next pass through. Or, return false to remove the
|
41 |
* item from the queue.
|
42 |
*
|
43 |
-
* @param ScanQueue\EntryVO $
|
44 |
* @return mixed
|
45 |
*/
|
46 |
-
protected function task( $
|
47 |
-
$
|
48 |
-
/** @var ScanQueue\Update $
|
49 |
-
$
|
50 |
-
$
|
51 |
|
52 |
try {
|
53 |
( new ScanExecute() )
|
54 |
->setMod( $this->getMod() )
|
55 |
-
->execute( $
|
56 |
}
|
57 |
catch ( \Exception $e ) {
|
58 |
// error_log( $e->getMessage() );
|
59 |
}
|
60 |
|
61 |
-
$
|
62 |
-
return $
|
63 |
}
|
64 |
|
65 |
/**
|
40 |
* in the next pass through. Or, return false to remove the
|
41 |
* item from the queue.
|
42 |
*
|
43 |
+
* @param ScanQueue\EntryVO $entry Queue item to iterate over.
|
44 |
* @return mixed
|
45 |
*/
|
46 |
+
protected function task( $entry ) {
|
47 |
+
$entry->started_at = Services::Request()->ts();
|
48 |
+
/** @var ScanQueue\Update $updater */
|
49 |
+
$updater = $this->getDbHandler()->getQueryUpdater();
|
50 |
+
$updater->setStarted( $entry );
|
51 |
|
52 |
try {
|
53 |
( new ScanExecute() )
|
54 |
->setMod( $this->getMod() )
|
55 |
+
->execute( $entry );
|
56 |
}
|
57 |
catch ( \Exception $e ) {
|
58 |
// error_log( $e->getMessage() );
|
59 |
}
|
60 |
|
61 |
+
$updater->setFinished( $entry );
|
62 |
+
return $entry;
|
63 |
}
|
64 |
|
65 |
/**
|
src/lib/src/Modules/HackGuard/Scan/Queue/ScanEnqueue.php
CHANGED
@@ -19,14 +19,14 @@ class ScanEnqueue {
|
|
19 |
* @throws \Exception
|
20 |
*/
|
21 |
public function enqueue() {
|
22 |
-
$
|
23 |
-
$aAllItems = (array)$
|
24 |
-
unset( $
|
25 |
|
26 |
-
$nSliceSize = $
|
27 |
|
28 |
do {
|
29 |
-
$oCurrent = clone $
|
30 |
$oCurrent->items = array_slice( $aAllItems, 0, $nSliceSize );
|
31 |
$this->pushActionToQueue( $oCurrent );
|
32 |
$aAllItems = array_slice( $aAllItems, $nSliceSize );
|
@@ -36,12 +36,12 @@ class ScanEnqueue {
|
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
-
* @param Scans\Base\BaseScanActionVO $
|
40 |
*/
|
41 |
-
protected function pushActionToQueue( $
|
42 |
-
$
|
43 |
->setDbHandler( $this->getDbHandler() )
|
44 |
-
->fromActionToDbEntry( $
|
45 |
-
$this->getQueueProcessor()->push_to_queue( $
|
46 |
}
|
47 |
}
|
19 |
* @throws \Exception
|
20 |
*/
|
21 |
public function enqueue() {
|
22 |
+
$action = $this->getScanActionVO();
|
23 |
+
$aAllItems = (array)$action->items;
|
24 |
+
unset( $action->items );
|
25 |
|
26 |
+
$nSliceSize = $action::QUEUE_GROUP_SIZE_LIMIT;
|
27 |
|
28 |
do {
|
29 |
+
$oCurrent = clone $action;
|
30 |
$oCurrent->items = array_slice( $aAllItems, 0, $nSliceSize );
|
31 |
$this->pushActionToQueue( $oCurrent );
|
32 |
$aAllItems = array_slice( $aAllItems, $nSliceSize );
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
+
* @param Scans\Base\BaseScanActionVO $action
|
40 |
*/
|
41 |
+
protected function pushActionToQueue( $action ) {
|
42 |
+
$entry = ( new ConvertBetweenTypes() )
|
43 |
->setDbHandler( $this->getDbHandler() )
|
44 |
+
->fromActionToDbEntry( $action );
|
45 |
+
$this->getQueueProcessor()->push_to_queue( $entry );
|
46 |
}
|
47 |
}
|
src/lib/src/Modules/HackGuard/Scan/Queue/ScanExecute.php
CHANGED
@@ -14,30 +14,29 @@ class ScanExecute {
|
|
14 |
use Shield\Modules\ModConsumer;
|
15 |
|
16 |
/**
|
17 |
-
* @param ScanQueue\EntryVO $
|
18 |
* @return ScanQueue\EntryVO
|
19 |
* @throws \Exception
|
20 |
*/
|
21 |
-
public function execute( $
|
22 |
/** @var Shield\Modules\HackGuard\ModCon $mod */
|
23 |
$mod = $this->getMod();
|
24 |
-
$oDbH = $mod->getDbHandler_ScanQueue();
|
25 |
-
$oTypeConverter = ( new ConvertBetweenTypes() )->setDbHandler( $oDbH );
|
26 |
|
27 |
-
$
|
|
|
|
|
28 |
|
29 |
-
$this->getScanner( $
|
30 |
-
->setScanActionVO( $
|
31 |
->setMod( $mod )
|
32 |
->run();
|
33 |
|
34 |
-
if ( $
|
35 |
-
usleep( $
|
36 |
}
|
37 |
|
38 |
-
$
|
39 |
-
|
40 |
-
return $oEntry;
|
41 |
}
|
42 |
|
43 |
/**
|
14 |
use Shield\Modules\ModConsumer;
|
15 |
|
16 |
/**
|
17 |
+
* @param ScanQueue\EntryVO $entry
|
18 |
* @return ScanQueue\EntryVO
|
19 |
* @throws \Exception
|
20 |
*/
|
21 |
+
public function execute( $entry ) {
|
22 |
/** @var Shield\Modules\HackGuard\ModCon $mod */
|
23 |
$mod = $this->getMod();
|
|
|
|
|
24 |
|
25 |
+
$action = ( new ConvertBetweenTypes() )
|
26 |
+
->setDbHandler( $mod->getDbHandler_ScanQueue() )
|
27 |
+
->fromDbEntryToAction( $entry );
|
28 |
|
29 |
+
$this->getScanner( $action )
|
30 |
+
->setScanActionVO( $action )
|
31 |
->setMod( $mod )
|
32 |
->run();
|
33 |
|
34 |
+
if ( $action->usleep > 0 ) {
|
35 |
+
usleep( $action->usleep );
|
36 |
}
|
37 |
|
38 |
+
$entry->results = $action->results;
|
39 |
+
return $entry;
|
|
|
40 |
}
|
41 |
|
42 |
/**
|
src/lib/src/Modules/HackGuard/Scan/Results/ConvertBetweenTypes.php
CHANGED
@@ -15,49 +15,51 @@ class ConvertBetweenTypes {
|
|
15 |
use ScanControllerConsumer;
|
16 |
|
17 |
/**
|
18 |
-
* @param Scans\Base\
|
19 |
* @return Databases\Scanner\EntryVO[]|mixed
|
20 |
*/
|
21 |
-
public function fromResultsToVOs( $
|
22 |
$vos = [];
|
23 |
-
foreach ( $
|
24 |
-
/** @var Scans\Base\
|
25 |
$vos[ $item->generateHash() ] = $this->convertResultItemToVO( $item );
|
26 |
}
|
27 |
return $vos;
|
28 |
}
|
29 |
|
30 |
/**
|
31 |
-
* @param Databases\Scanner\EntryVO[] $
|
32 |
-
* @return Scans\Base\
|
33 |
*/
|
34 |
-
public function fromVOsToResultsSet( $
|
35 |
-
$
|
36 |
-
foreach ( $
|
37 |
-
$
|
38 |
}
|
39 |
-
return $
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
-
* @param Databases\Scanner\EntryVO $
|
44 |
-
* @return Scans\Base\
|
45 |
*/
|
46 |
-
public function convertVoToResultItem( $
|
47 |
-
|
48 |
-
|
49 |
-
|
|
|
|
|
50 |
}
|
51 |
|
52 |
/**
|
53 |
-
* @param Scans\Base\
|
54 |
* @return Databases\Scanner\EntryVO
|
55 |
*/
|
56 |
-
private function convertResultItemToVO( $
|
57 |
-
$
|
58 |
-
$
|
59 |
-
$
|
60 |
-
$
|
61 |
-
return $
|
62 |
}
|
63 |
-
}
|
15 |
use ScanControllerConsumer;
|
16 |
|
17 |
/**
|
18 |
+
* @param Scans\Base\ResultsSet $resultsSet
|
19 |
* @return Databases\Scanner\EntryVO[]|mixed
|
20 |
*/
|
21 |
+
public function fromResultsToVOs( $resultsSet ) {
|
22 |
$vos = [];
|
23 |
+
foreach ( $resultsSet->getAllItems() as $item ) {
|
24 |
+
/** @var Scans\Base\ResultItem $item */
|
25 |
$vos[ $item->generateHash() ] = $this->convertResultItemToVO( $item );
|
26 |
}
|
27 |
return $vos;
|
28 |
}
|
29 |
|
30 |
/**
|
31 |
+
* @param Databases\Scanner\EntryVO[] $VOs
|
32 |
+
* @return Scans\Base\ResultsSet|mixed
|
33 |
*/
|
34 |
+
public function fromVOsToResultsSet( $VOs ) {
|
35 |
+
$results = $this->getScanController()->getNewResultsSet();
|
36 |
+
foreach ( $VOs as $VO ) {
|
37 |
+
$results->addItem( $this->convertVoToResultItem( $VO ) );
|
38 |
}
|
39 |
+
return $results;
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
+
* @param Databases\Scanner\EntryVO $VO
|
44 |
+
* @return Scans\Base\ResultItem
|
45 |
*/
|
46 |
+
public function convertVoToResultItem( Databases\Scanner\EntryVO $VO ) {
|
47 |
+
$item = $this->getScanController()
|
48 |
+
->getNewResultItem()
|
49 |
+
->applyFromArray( $VO->meta );
|
50 |
+
$item->VO = $VO;
|
51 |
+
return $item;
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
+
* @param Scans\Base\ResultItem $item
|
56 |
* @return Databases\Scanner\EntryVO
|
57 |
*/
|
58 |
+
private function convertResultItemToVO( $item ) {
|
59 |
+
$vo = new Databases\Scanner\EntryVO();
|
60 |
+
$vo->hash = $item->hash;
|
61 |
+
$vo->meta = $item->getData();
|
62 |
+
$vo->scan = $this->getScanController()->getSlug();
|
63 |
+
return $vo;
|
64 |
}
|
65 |
+
}
|
src/lib/src/Modules/HackGuard/Scan/Results/ResultsDelete.php
CHANGED
@@ -15,13 +15,13 @@ class ResultsDelete {
|
|
15 |
use ScanControllerConsumer;
|
16 |
|
17 |
/**
|
18 |
-
* @param Scans\Base\
|
19 |
* @return bool
|
20 |
*/
|
21 |
public function delete( $oResultsToDelete ) {
|
22 |
$aHashes = array_map(
|
23 |
function ( $oItem ) {
|
24 |
-
/** @var Scans\Base\
|
25 |
return $oItem->hash;
|
26 |
},
|
27 |
$oResultsToDelete->getAllItems()
|
15 |
use ScanControllerConsumer;
|
16 |
|
17 |
/**
|
18 |
+
* @param Scans\Base\ResultsSet $oResultsToDelete
|
19 |
* @return bool
|
20 |
*/
|
21 |
public function delete( $oResultsToDelete ) {
|
22 |
$aHashes = array_map(
|
23 |
function ( $oItem ) {
|
24 |
+
/** @var Scans\Base\ResultItem $oItem */
|
25 |
return $oItem->hash;
|
26 |
},
|
27 |
$oResultsToDelete->getAllItems()
|
src/lib/src/Modules/HackGuard/Scan/Results/ResultsRetrieve.php
CHANGED
@@ -15,7 +15,7 @@ class ResultsRetrieve {
|
|
15 |
use ScanControllerConsumer;
|
16 |
|
17 |
/**
|
18 |
-
* @return Scans\Base\
|
19 |
*/
|
20 |
public function retrieve() {
|
21 |
$oSCon = $this->getScanController();
|
15 |
use ScanControllerConsumer;
|
16 |
|
17 |
/**
|
18 |
+
* @return Scans\Base\ResultsSet|mixed
|
19 |
*/
|
20 |
public function retrieve() {
|
21 |
$oSCon = $this->getScanController();
|
src/lib/src/Modules/HackGuard/Scan/Results/ResultsStore.php
CHANGED
@@ -15,17 +15,18 @@ class ResultsStore {
|
|
15 |
use ScanControllerConsumer;
|
16 |
|
17 |
/**
|
18 |
-
* @param Scans\Base\
|
19 |
*/
|
20 |
-
public function store( $
|
21 |
-
$
|
22 |
-
$
|
23 |
-
|
24 |
-
$
|
25 |
-
->setScanController( $
|
26 |
-
->fromResultsToVOs( $
|
27 |
-
|
28 |
-
|
|
|
29 |
}
|
30 |
}
|
31 |
}
|
15 |
use ScanControllerConsumer;
|
16 |
|
17 |
/**
|
18 |
+
* @param Scans\Base\ResultsSet $resultsToStore
|
19 |
*/
|
20 |
+
public function store( $resultsToStore ) {
|
21 |
+
$scanCon = $this->getScanController();
|
22 |
+
$inserter = $scanCon->getScanResultsDbHandler()
|
23 |
+
->getQueryInserter();
|
24 |
+
$VOs = ( new ConvertBetweenTypes() )
|
25 |
+
->setScanController( $scanCon )
|
26 |
+
->fromResultsToVOs( $resultsToStore );
|
27 |
+
|
28 |
+
foreach ( $VOs as $vo ) {
|
29 |
+
$inserter->insert( $vo );
|
30 |
}
|
31 |
}
|
32 |
}
|
src/lib/src/Modules/HackGuard/Scan/Results/ResultsUpdate.php
CHANGED
@@ -15,38 +15,39 @@ class ResultsUpdate {
|
|
15 |
use ScanControllerConsumer;
|
16 |
|
17 |
/**
|
18 |
-
* @param Scans\Base\
|
19 |
*/
|
20 |
-
public function update( $
|
21 |
-
$
|
22 |
-
$
|
23 |
|
24 |
-
$
|
25 |
-
->setScanController( $
|
26 |
->retrieve();
|
27 |
|
28 |
-
$
|
|
|
29 |
( new ResultsDelete() )
|
30 |
-
->setScanController( $
|
31 |
-
->delete( $
|
32 |
|
33 |
( new ResultsStore() )
|
34 |
-
->setScanController( $
|
35 |
-
->store( $
|
36 |
-
|
37 |
-
$
|
38 |
-
/** @var Databases\Scanner\EntryVO $
|
39 |
-
$
|
40 |
-
foreach ( $
|
41 |
-
$
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
}
|
51 |
}
|
52 |
}
|
15 |
use ScanControllerConsumer;
|
16 |
|
17 |
/**
|
18 |
+
* @param Scans\Base\ResultsSet $newResults
|
19 |
*/
|
20 |
+
public function update( $newResults ) {
|
21 |
+
$scanCon = $this->getScanController();
|
22 |
+
$newCopy = clone $newResults; // so we don't modify these for later use.
|
23 |
|
24 |
+
$existing = ( new ResultsRetrieve() )
|
25 |
+
->setScanController( $scanCon )
|
26 |
->retrieve();
|
27 |
|
28 |
+
$itemsToDelete = ( new Scans\Base\DiffResultForStorage() )->diff( $existing, $newCopy );
|
29 |
+
|
30 |
( new ResultsDelete() )
|
31 |
+
->setScanController( $scanCon )
|
32 |
+
->delete( $itemsToDelete );
|
33 |
|
34 |
( new ResultsStore() )
|
35 |
+
->setScanController( $scanCon )
|
36 |
+
->store( $newCopy );
|
37 |
+
|
38 |
+
$updater = $scanCon->getScanResultsDbHandler()->getQueryUpdater();
|
39 |
+
/** @var Databases\Scanner\EntryVO $vo */
|
40 |
+
$converter = ( new ConvertBetweenTypes() )->setScanController( $scanCon );
|
41 |
+
foreach ( $converter->fromResultsToVOs( $existing ) as $vo ) {
|
42 |
+
$updater->reset()
|
43 |
+
->setUpdateData( $vo->getRawData() )
|
44 |
+
->setUpdateWheres(
|
45 |
+
[
|
46 |
+
'scan' => $scanCon->getSlug(),
|
47 |
+
'hash' => $vo->hash,
|
48 |
+
]
|
49 |
+
)
|
50 |
+
->query();
|
51 |
}
|
52 |
}
|
53 |
}
|
src/lib/src/Modules/HackGuard/Scan/ScansController.php
CHANGED
@@ -74,10 +74,10 @@ class ScansController extends ExecOnceModConsumer {
|
|
74 |
$mod = $this->getMod();
|
75 |
/** @var HackGuard\Options $opts */
|
76 |
$opts = $this->getOptions();
|
77 |
-
foreach ( $opts->getScanSlugs() as $
|
78 |
-
$
|
79 |
-
if ( $
|
80 |
-
$
|
81 |
}
|
82 |
}
|
83 |
}
|
74 |
$mod = $this->getMod();
|
75 |
/** @var HackGuard\Options $opts */
|
76 |
$opts = $this->getOptions();
|
77 |
+
foreach ( $opts->getScanSlugs() as $slug ) {
|
78 |
+
$scanCon = $mod->getScanCon( $slug );
|
79 |
+
if ( $scanCon->isCronAutoRepair() ) {
|
80 |
+
$scanCon->runCronAutoRepair();
|
81 |
}
|
82 |
}
|
83 |
}
|
src/lib/src/Modules/HackGuard/Scan/Utilities/WpvAddPluginRows.php
CHANGED
@@ -33,7 +33,7 @@ class WpvAddPluginRows {
|
|
33 |
private function isWpvulnPluginsHighlightEnabled() :bool {
|
34 |
$scanCon = $this->getScanController();
|
35 |
if ( $scanCon->isEnabled() ) {
|
36 |
-
$opt = apply_filters( '
|
37 |
}
|
38 |
else {
|
39 |
$opt = 'disabled';
|
33 |
private function isWpvulnPluginsHighlightEnabled() :bool {
|
34 |
$scanCon = $this->getScanController();
|
35 |
if ( $scanCon->isEnabled() ) {
|
36 |
+
$opt = apply_filters( 'shield/wpvuln_scan_display', 'securityadmin' );
|
37 |
}
|
38 |
else {
|
39 |
$opt = 'disabled';
|
src/lib/src/Modules/HackGuard/Strings.php
CHANGED
@@ -43,6 +43,18 @@ class Strings extends Base\Strings {
|
|
43 |
__( "These items wont display in results if you've previously marked them as ignored.", 'wp-simple-firewall' )
|
44 |
)
|
45 |
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
$messages[ $slug.'_item_repair_success' ] = [
|
47 |
sprintf( __( '%s scan repaired a item found in the scan.', 'wp-simple-firewall' ), $scanName )
|
48 |
.' '.__( 'Item repaired: "%s"', 'wp-simple-firewall' ),
|
@@ -242,7 +254,7 @@ class Strings extends Base\Strings {
|
|
242 |
sprintf( '%s - %s', __( 'Important', 'wp-simple-firewall' ), __( "Doesn't currently detect missing files.", 'wp-simple-firewall' ) ),
|
243 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), __( 'Keep this feature turned on, at all times.', 'wp-simple-firewall' ) )
|
244 |
];
|
245 |
-
if ( !$
|
246 |
$desc[] = sprintf( __( 'Sorry, this feature is not available because we cannot write to disk at this location: %s', 'wp-simple-firewall' ),
|
247 |
'<code>'.$mod->getPtgSnapsBaseDir().'</code>' );
|
248 |
}
|
@@ -331,22 +343,35 @@ class Strings extends Base\Strings {
|
|
331 |
$desc = __( "Show links to re-install plugins and offer re-install when activating plugins.", 'wp-simple-firewall' );
|
332 |
break;
|
333 |
|
334 |
-
case '
|
335 |
-
$name = __( '
|
336 |
-
$summary = __( '
|
337 |
-
$desc =
|
|
|
|
|
|
|
338 |
break;
|
339 |
|
340 |
-
case '
|
341 |
-
$name = __( '
|
342 |
-
$summary = __( '
|
343 |
-
$desc =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
344 |
break;
|
345 |
|
346 |
-
case '
|
347 |
-
$name = __( '
|
348 |
-
$summary = __( '
|
349 |
-
$desc = __( "
|
350 |
break;
|
351 |
|
352 |
case 'mal_autorepair_surgical' :
|
@@ -357,61 +382,6 @@ class Strings extends Base\Strings {
|
|
357 |
.'<br />'.sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( "Only applies to files that don't fall under the other categories for automatic repair.", 'wp-simple-firewall' ) );
|
358 |
break;
|
359 |
|
360 |
-
// REMOVED:
|
361 |
-
case 'mal_autorepair_plugins' :
|
362 |
-
$name = __( 'Auto-Repair WP Plugins', 'wp-simple-firewall' );
|
363 |
-
$summary = __( 'Automatically Repair WordPress.org Plugins', 'wp-simple-firewall' );
|
364 |
-
$desc = __( "Automatically repair any plugin files found to have potential malware.", 'wp-simple-firewall' )
|
365 |
-
.'<br />'.sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( 'Only compatible with plugins installed from WordPress.org.', 'wp-simple-firewall' ) )
|
366 |
-
.'<br />'.sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( "Also deletes suspected files if they weren't originally distributed with the plugin.", 'wp-simple-firewall' ) );
|
367 |
-
break;
|
368 |
-
case 'autorepair_themes' :
|
369 |
-
$name = __( 'Auto-Repair WP Themes', 'wp-simple-firewall' );
|
370 |
-
$summary = __( 'Automatically Repair WordPress.org Themes', 'wp-simple-firewall' );
|
371 |
-
$desc = __( "Automatically repair any theme files found to have potential malware.", 'wp-simple-firewall' )
|
372 |
-
.'<br />'.sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( 'Only compatible with themes installed from WordPress.org.', 'wp-simple-firewall' ) )
|
373 |
-
.'<br />'.sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( "Also deletes suspected files if they weren't originally distributed with the theme.", 'wp-simple-firewall' ) );
|
374 |
-
break;
|
375 |
-
case 'wpvuln_scan_display' :
|
376 |
-
$name = __( 'Highlight Plugins', 'wp-simple-firewall' );
|
377 |
-
$summary = __( 'Highlight Vulnerable Plugins Upon Display', 'wp-simple-firewall' );
|
378 |
-
$desc = __( 'Vulnerable plugins will be highlighted on the main plugins page.', 'wp-simple-firewall' );
|
379 |
-
break;
|
380 |
-
case 'email_files_list' :
|
381 |
-
$name = __( 'Email Files List', 'wp-simple-firewall' );
|
382 |
-
$summary = __( 'Scan Notification Emails Should Include Full Listing Of Files', 'wp-simple-firewall' );
|
383 |
-
$desc = __( 'Scanner notification emails will include a summary list of all affected files.', 'wp-simple-firewall' );
|
384 |
-
break;
|
385 |
-
case 'mal_fp_confidence' :
|
386 |
-
$name = __( 'Ignore False Positives Threshold', 'wp-simple-firewall' );
|
387 |
-
$summary = __( 'Ignore False Positives In Scan Results Automatically', 'wp-simple-firewall' );
|
388 |
-
$desc = __( "You can choose to ignore files with potential malware, depending on whether the confidence that it's a 'false positive' meets your minimum threshold.", 'wp-simple-firewall' )
|
389 |
-
.'<br />'.__( "A false positive happens when a file appears to contain malware and shows up in scan results, but it's actually clean.", 'wp-simple-firewall' )
|
390 |
-
.' ('.__( "A false positive is similar to when an anti-virus alerts to a file that doesnt have a virus.", 'wp-simple-firewall' ).')'
|
391 |
-
.'<br />'.__( "The higher the confidence level, the more likely a result is a false positive.", 'wp-simple-firewall' )
|
392 |
-
.' '.__( "A low level means it's less likely to be a false positive.", 'wp-simple-firewall' )
|
393 |
-
.'<br />'.__( "The scan will automatically ignore results whose 'false positive' confidence level is greater than your chosen threshold.", 'wp-simple-firewall' )
|
394 |
-
.'<br />'.__( "The higher the confidence threshold you select, the more likely that 'false positives' will appears in your scan results.", 'wp-simple-firewall' )
|
395 |
-
.'<br />'.__( "Disabling network intelligence turns off 'false positive confidence' levels.", 'wp-simple-firewall' )
|
396 |
-
.' '.__( 'You will no longer benefit from the intelligence gathered from the entire network.', 'wp-simple-firewall' )
|
397 |
-
.' '.__( 'All data shared is completely anonymous.', 'wp-simple-firewall' )
|
398 |
-
.' '.' [<a href="https://shsec.io/moreinfomalnetwork">'.__( 'More Info', 'wp-simple-firewall' ).'</a>]'
|
399 |
-
.'<br />'.__( 'The more sites that share this information, the stronger and smarter the network becomes.', 'wp-simple-firewall' );
|
400 |
-
break;
|
401 |
-
case 'notification_interval' :
|
402 |
-
$name = __( 'Repeat Notifications', 'wp-simple-firewall' );
|
403 |
-
$summary = __( 'Item Repeat Notifications Suppression Interval', 'wp-simple-firewall' );
|
404 |
-
$desc = __( 'How long the automated scans should wait before repeating a notification about an item.', 'wp-simple-firewall' )
|
405 |
-
.'<br/>'.__( 'Specify the number of days to suppress repeat notifications.', 'wp-simple-firewall' )
|
406 |
-
.'<br/>'.sprintf( '%s: %s', __( 'Note', 'wp-simple-firewall' ), __( 'This is per discovered item or file, not per scan.', 'wp-simple-firewall' ) );
|
407 |
-
break;
|
408 |
-
case 'ptg_extensions' :
|
409 |
-
$name = __( 'Included File Types', 'wp-simple-firewall' );
|
410 |
-
$summary = __( 'The File Types (by File Extension) Included In The Scan', 'wp-simple-firewall' );
|
411 |
-
$desc = __( 'Take a new line for each file extension.', 'wp-simple-firewall' )
|
412 |
-
.'<br/>'.__( 'No commas(,) or periods(.) necessary.', 'wp-simple-firewall' )
|
413 |
-
.'<br/>'.__( 'Remove all extensions to scan all file type (not recommended).', 'wp-simple-firewall' );
|
414 |
-
break;
|
415 |
default:
|
416 |
return parent::getOptionStrings( $key );
|
417 |
}
|
43 |
__( "These items wont display in results if you've previously marked them as ignored.", 'wp-simple-firewall' )
|
44 |
)
|
45 |
];
|
46 |
+
$messages[ 'scan_item_delete_success' ] = [
|
47 |
+
__( 'Deleted item found in the scan.', 'wp-simple-firewall' )
|
48 |
+
.' '.__( 'Item deleted: "%s"', 'wp-simple-firewall' ),
|
49 |
+
];
|
50 |
+
$messages[ 'scan_item_repair_success' ] = [
|
51 |
+
__( 'Repaired item found in the scan.', 'wp-simple-firewall' )
|
52 |
+
.' '.__( 'Item repaired: "%s"', 'wp-simple-firewall' ),
|
53 |
+
];
|
54 |
+
$messages[ 'scan_item_repair_fail' ] = [
|
55 |
+
__( 'Failed to repair scan item.', 'wp-simple-firewall' )
|
56 |
+
.' '.__( 'Failed item: "%s"', 'wp-simple-firewall' ),
|
57 |
+
];
|
58 |
$messages[ $slug.'_item_repair_success' ] = [
|
59 |
sprintf( __( '%s scan repaired a item found in the scan.', 'wp-simple-firewall' ), $scanName )
|
60 |
.' '.__( 'Item repaired: "%s"', 'wp-simple-firewall' ),
|
254 |
sprintf( '%s - %s', __( 'Important', 'wp-simple-firewall' ), __( "Doesn't currently detect missing files.", 'wp-simple-firewall' ) ),
|
255 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), __( 'Keep this feature turned on, at all times.', 'wp-simple-firewall' ) )
|
256 |
];
|
257 |
+
if ( !$this->getCon()->hasCacheDir() ) {
|
258 |
$desc[] = sprintf( __( 'Sorry, this feature is not available because we cannot write to disk at this location: %s', 'wp-simple-firewall' ),
|
259 |
'<code>'.$mod->getPtgSnapsBaseDir().'</code>' );
|
260 |
}
|
343 |
$desc = __( "Show links to re-install plugins and offer re-install when activating plugins.", 'wp-simple-firewall' );
|
344 |
break;
|
345 |
|
346 |
+
case 'auto_filter_results' :
|
347 |
+
$name = __( 'Auto-Filter Results', 'wp-simple-firewall' );
|
348 |
+
$summary = __( 'Automatically Filter Results Of Irrelevant Items', 'wp-simple-firewall' );
|
349 |
+
$desc = [
|
350 |
+
__( 'Automatically remove items from results that are irrelevant.', 'wp-simple-firewall' ),
|
351 |
+
__( "An example of this is filtering out results for PHP files that don't have any executable code.", 'wp-simple-firewall' ),
|
352 |
+
];
|
353 |
break;
|
354 |
|
355 |
+
case 'scan_path_exclusions' :
|
356 |
+
$name = __( 'Scan Exclusions', 'wp-simple-firewall' );
|
357 |
+
$summary = __( 'Scan File And Folder Exclusions', 'wp-simple-firewall' );
|
358 |
+
$desc = [
|
359 |
+
__( 'A list of file/folder paths that will never be scanned.', 'wp-simple-firewall' ),
|
360 |
+
__( 'All paths are relative to your WordPress installation directory.', 'wp-simple-firewall' ),
|
361 |
+
__( 'This is an advanced option and should be used with great care.', 'wp-simple-firewall' ),
|
362 |
+
__( 'Take a new line for each whitelisted path.', 'wp-simple-firewall' ),
|
363 |
+
__( 'All characters will be treated as case-insensitive.', 'wp-simple-firewall' ),
|
364 |
+
__( 'Directories should be provided with a trailing slash (/).', 'wp-simple-firewall' ),
|
365 |
+
__( "If a path matches any core WordPress directories, it'll be removed automatically.", 'wp-simple-firewall' ),
|
366 |
+
__( "These aren't regular expression, but you can use asterisk (*) as a wildcard.", 'wp-simple-firewall' ),
|
367 |
+
sprintf( '%s: <code>%s</code>', __( 'WordPress Installation Directory', 'wp-simple-firewall' ), ABSPATH ),
|
368 |
+
];
|
369 |
break;
|
370 |
|
371 |
+
case 'enabled_scan_apc' :
|
372 |
+
$name = __( 'Abandoned Plugin Scanner', 'wp-simple-firewall' );
|
373 |
+
$summary = __( 'Enable The Abandoned Plugin Scanner', 'wp-simple-firewall' );
|
374 |
+
$desc = __( "Scan your WordPress.org assets for whether they've been abandoned.", 'wp-simple-firewall' );
|
375 |
break;
|
376 |
|
377 |
case 'mal_autorepair_surgical' :
|
382 |
.'<br />'.sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( "Only applies to files that don't fall under the other categories for automatic repair.", 'wp-simple-firewall' ) );
|
383 |
break;
|
384 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
385 |
default:
|
386 |
return parent::getOptionStrings( $key );
|
387 |
}
|
src/lib/src/Modules/HackGuard/UI.php
CHANGED
@@ -19,6 +19,16 @@ class UI extends BaseShield\UI {
|
|
19 |
$uiTrack[ 'selected_scans' ] = $opts->getScanSlugs();
|
20 |
}
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
// Can Scan Checks:
|
23 |
$reasonsCantScan = $mod->getScansCon()->getReasonsScansCantExecute();
|
24 |
|
@@ -72,31 +82,37 @@ class UI extends BaseShield\UI {
|
|
72 |
'vars' => [
|
73 |
'initial_check' => $mod->getScanQueueController()->hasRunningScans(),
|
74 |
'cannot_scan_reasons' => $reasonsCantScan,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
],
|
76 |
'hrefs' => [
|
77 |
-
'scanner_mod_config' => $mod->getUrl_DirectLinkToSection('section_enable_plugin_feature_hack_protection_tools'),
|
78 |
'scans_results' => $this->getCon()
|
79 |
->getModule_Insights()
|
80 |
->getUrl_ScansResults(),
|
81 |
],
|
82 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
],
|
84 |
-
'
|
85 |
-
'flags' => [
|
86 |
-
'has_items' => true,
|
87 |
-
],
|
88 |
-
'hrefs' => [
|
89 |
-
'options' => $mod->getUrl_DirectLinkToSection( 'section_scan_options' )
|
90 |
-
],
|
91 |
-
'vars' => [
|
92 |
-
],
|
93 |
-
'strings' => [
|
94 |
-
'title' => __( 'File Scan', 'wp-simple-firewall' ),
|
95 |
-
'subtitle' => __( "Results of all file scans", 'wp-simple-firewall' )
|
96 |
-
],
|
97 |
-
'count' => $selector->filterByScans( [ 'ptg', 'mal', 'wcf', 'ufc' ] )
|
98 |
-
->filterByNotIgnored()
|
99 |
-
->count()
|
100 |
],
|
101 |
'file_locker' => $this->getFileLockerVars(),
|
102 |
'scans' => [
|
@@ -121,7 +137,7 @@ class UI extends BaseShield\UI {
|
|
121 |
'apc' => [
|
122 |
'flags' => [
|
123 |
'has_items' => true,
|
124 |
-
'show_table' =>
|
125 |
],
|
126 |
'hrefs' => [],
|
127 |
'vars' => [],
|
@@ -155,7 +171,7 @@ class UI extends BaseShield\UI {
|
|
155 |
'wpv' => [
|
156 |
'flags' => [
|
157 |
'has_items' => true,
|
158 |
-
'show_table' =>
|
159 |
],
|
160 |
'hrefs' => [],
|
161 |
'vars' => [],
|
@@ -213,17 +229,14 @@ class UI extends BaseShield\UI {
|
|
213 |
return $aOptParams;
|
214 |
}
|
215 |
|
216 |
-
|
217 |
-
* @return array
|
218 |
-
*/
|
219 |
-
protected function getFileLockerVars() {
|
220 |
/** @var ModCon $mod */
|
221 |
$mod = $this->getMod();
|
222 |
|
223 |
-
$
|
224 |
-
$
|
225 |
-
$
|
226 |
-
$
|
227 |
|
228 |
return [
|
229 |
'ajax' => [
|
@@ -231,7 +244,7 @@ class UI extends BaseShield\UI {
|
|
231 |
'filelocker_fileaction' => $mod->getAjaxActionData( 'filelocker_fileaction', true ),
|
232 |
],
|
233 |
'flags' => [
|
234 |
-
'is_enabled' => $
|
235 |
'is_restricted' => !$this->getCon()->isPremiumActive(),
|
236 |
],
|
237 |
'hrefs' => [
|
@@ -240,8 +253,9 @@ class UI extends BaseShield\UI {
|
|
240 |
],
|
241 |
'vars' => [
|
242 |
'file_locks' => [
|
243 |
-
'good'
|
244 |
-
'bad'
|
|
|
245 |
],
|
246 |
],
|
247 |
'strings' => [
|
@@ -249,7 +263,7 @@ class UI extends BaseShield\UI {
|
|
249 |
'subtitle' => __( 'Results of file locker monitoring', 'wp-simple-firewall' ),
|
250 |
'please_select' => __( 'Please select a file to review.', 'wp-simple-firewall' ),
|
251 |
],
|
252 |
-
'count' => count( $
|
253 |
];
|
254 |
}
|
255 |
|
@@ -267,7 +281,7 @@ class UI extends BaseShield\UI {
|
|
267 |
|
268 |
return [
|
269 |
'flags' => [
|
270 |
-
'has_items' => $mod->isPtgEnabled()
|
271 |
'has_plugins' => !empty( $aPlugins ),
|
272 |
'has_themes' => !empty( $aThemes ),
|
273 |
'show_table' => false,
|
@@ -294,12 +308,15 @@ class UI extends BaseShield\UI {
|
|
294 |
|
295 |
case 'section_realtime':
|
296 |
$canHandshake = $this->getCon()
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
if ( !$canHandshake ) {
|
301 |
$warnings[] = sprintf( __( 'Not available as your site cannot handshake with ShieldNET API.', 'wp-simple-firewall' ), 'OpenSSL' );
|
302 |
}
|
|
|
|
|
|
|
303 |
// if ( !Services::Encrypt()->isSupportedOpenSslDataEncryption() ) {
|
304 |
// $warnings[] = sprintf( __( 'Not available because the %s extension is not available.', 'wp-simple-firewall' ), 'OpenSSL' );
|
305 |
// }
|
19 |
$uiTrack[ 'selected_scans' ] = $opts->getScanSlugs();
|
20 |
}
|
21 |
|
22 |
+
foreach ( $opts->getScanSlugs() as $scan ) {
|
23 |
+
$mod->getScanCon( $scan )->cleanStalesResults();
|
24 |
+
}
|
25 |
+
|
26 |
+
$sectionBuilderPlugins = ( new Render\ScanResults\SectionPlugins() )->setMod( $this->getMod() );
|
27 |
+
$sectionBuilderThemes = ( new Render\ScanResults\SectionThemes() )->setMod( $this->getMod() );
|
28 |
+
$sectionBuilderWordpress = ( new Render\ScanResults\SectionWordpress() )->setMod( $this->getMod() );
|
29 |
+
$sectionBuilderMalware = ( new Render\ScanResults\SectionMalware() )->setMod( $this->getMod() );
|
30 |
+
// $sectionBuilderLog = ( new Render\ScanResults\SectionMalware() )->setMod( $this->getMod() );
|
31 |
+
|
32 |
// Can Scan Checks:
|
33 |
$reasonsCantScan = $mod->getScansCon()->getReasonsScansCantExecute();
|
34 |
|
82 |
'vars' => [
|
83 |
'initial_check' => $mod->getScanQueueController()->hasRunningScans(),
|
84 |
'cannot_scan_reasons' => $reasonsCantScan,
|
85 |
+
'sections' => [
|
86 |
+
'plugins' => [
|
87 |
+
'count' => $sectionBuilderPlugins->getRenderData()[ 'vars' ][ 'count_items' ]
|
88 |
+
],
|
89 |
+
'themes' => [
|
90 |
+
'count' => $sectionBuilderThemes->getRenderData()[ 'vars' ][ 'count_items' ]
|
91 |
+
],
|
92 |
+
'wordpress' => [
|
93 |
+
'count' => $sectionBuilderWordpress->getRenderData()[ 'vars' ][ 'count_items' ]
|
94 |
+
],
|
95 |
+
'malware' => [
|
96 |
+
'count' => $sectionBuilderMalware->getRenderData()[ 'vars' ][ 'count_items' ]
|
97 |
+
],
|
98 |
+
]
|
99 |
],
|
100 |
'hrefs' => [
|
101 |
+
'scanner_mod_config' => $mod->getUrl_DirectLinkToSection( 'section_enable_plugin_feature_hack_protection_tools' ),
|
102 |
'scans_results' => $this->getCon()
|
103 |
->getModule_Insights()
|
104 |
->getUrl_ScansResults(),
|
105 |
],
|
106 |
+
'content' => [
|
107 |
+
'section' => [
|
108 |
+
'plugins' => $sectionBuilderPlugins->render(),
|
109 |
+
'themes' => $sectionBuilderThemes->render(),
|
110 |
+
'wordpress' => $sectionBuilderWordpress->render(),
|
111 |
+
'malware' => $sectionBuilderMalware->render(),
|
112 |
+
'logs' => 'logs todo',
|
113 |
+
]
|
114 |
],
|
115 |
+
'scan_results' => [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
],
|
117 |
'file_locker' => $this->getFileLockerVars(),
|
118 |
'scans' => [
|
137 |
'apc' => [
|
138 |
'flags' => [
|
139 |
'has_items' => true,
|
140 |
+
'show_table' => false,
|
141 |
],
|
142 |
'hrefs' => [],
|
143 |
'vars' => [],
|
171 |
'wpv' => [
|
172 |
'flags' => [
|
173 |
'has_items' => true,
|
174 |
+
'show_table' => false,
|
175 |
],
|
176 |
'hrefs' => [],
|
177 |
'vars' => [],
|
229 |
return $aOptParams;
|
230 |
}
|
231 |
|
232 |
+
protected function getFileLockerVars() :array {
|
|
|
|
|
|
|
233 |
/** @var ModCon $mod */
|
234 |
$mod = $this->getMod();
|
235 |
|
236 |
+
$lockerCon = $mod->getFileLocker();
|
237 |
+
$lockLoader = ( new Lib\FileLocker\Ops\LoadFileLocks() )->setMod( $mod );
|
238 |
+
$problemLocks = $lockLoader->withProblems();
|
239 |
+
$goodLocks = $lockLoader->withoutProblems();
|
240 |
|
241 |
return [
|
242 |
'ajax' => [
|
244 |
'filelocker_fileaction' => $mod->getAjaxActionData( 'filelocker_fileaction', true ),
|
245 |
],
|
246 |
'flags' => [
|
247 |
+
'is_enabled' => $lockerCon->isEnabled(),
|
248 |
'is_restricted' => !$this->getCon()->isPremiumActive(),
|
249 |
],
|
250 |
'hrefs' => [
|
253 |
],
|
254 |
'vars' => [
|
255 |
'file_locks' => [
|
256 |
+
'good' => $goodLocks,
|
257 |
+
'bad' => $problemLocks,
|
258 |
+
'count_items' => count( $problemLocks ),
|
259 |
],
|
260 |
],
|
261 |
'strings' => [
|
263 |
'subtitle' => __( 'Results of file locker monitoring', 'wp-simple-firewall' ),
|
264 |
'please_select' => __( 'Please select a file to review.', 'wp-simple-firewall' ),
|
265 |
],
|
266 |
+
'count' => count( $problemLocks )
|
267 |
];
|
268 |
}
|
269 |
|
281 |
|
282 |
return [
|
283 |
'flags' => [
|
284 |
+
'has_items' => $mod->isPtgEnabled() && !empty( $aPtgResults ),
|
285 |
'has_plugins' => !empty( $aPlugins ),
|
286 |
'has_themes' => !empty( $aThemes ),
|
287 |
'show_table' => false,
|
308 |
|
309 |
case 'section_realtime':
|
310 |
$canHandshake = $this->getCon()
|
311 |
+
->getModule_Plugin()
|
312 |
+
->getShieldNetApiController()
|
313 |
+
->canHandshake();
|
314 |
if ( !$canHandshake ) {
|
315 |
$warnings[] = sprintf( __( 'Not available as your site cannot handshake with ShieldNET API.', 'wp-simple-firewall' ), 'OpenSSL' );
|
316 |
}
|
317 |
+
if ( !$this->getCon()->hasCacheDir() ) {
|
318 |
+
$warnings[] = __( "Certain scanners are unavailable because we couldn't create a temporary directory to store files.", 'wp-simple-firewall' );
|
319 |
+
}
|
320 |
// if ( !Services::Encrypt()->isSupportedOpenSslDataEncryption() ) {
|
321 |
// $warnings[] = sprintf( __( 'Not available because the %s extension is not available.', 'wp-simple-firewall' ), 'OpenSSL' );
|
322 |
// }
|
src/lib/src/Modules/HackGuard/Upgrade.php
CHANGED
@@ -16,48 +16,4 @@ class Upgrade extends Base\Upgrade {
|
|
16 |
$schema->table, 'content', $schema->enumerateColumns()[ 'content' ] )
|
17 |
);
|
18 |
}
|
19 |
-
|
20 |
-
protected function upgrade_900() {
|
21 |
-
/** @var Options $opts */
|
22 |
-
$opts = $this->getOptions();
|
23 |
-
if ( $opts->getOpt( 'ptg_enable' ) === 'enabled' ) {
|
24 |
-
$opts->setOpt( 'ptg_enable', 'Y' );
|
25 |
-
}
|
26 |
-
elseif ( $opts->getOpt( 'ptg_enable' ) === 'disabled' ) {
|
27 |
-
$opts->setOpt( 'ptg_enable', 'N' );
|
28 |
-
}
|
29 |
-
|
30 |
-
$aRepairAreas = $opts->getRepairAreas();
|
31 |
-
$aMap = [
|
32 |
-
'attempt_auto_file_repair' => 'wp',
|
33 |
-
'mal_autorepair_plugins' => 'plugin',
|
34 |
-
];
|
35 |
-
foreach ( $aMap as $sOld => $sNew ) {
|
36 |
-
if ( $opts->getOpt( $sOld ) !== false ) {
|
37 |
-
$bWasEnabled = $opts->isOpt( $sOld, 'Y' );
|
38 |
-
$nIsEnabled = array_search( $sNew, $aRepairAreas );
|
39 |
-
if ( $bWasEnabled && ( $nIsEnabled === false ) ) {
|
40 |
-
$aRepairAreas[] = $sNew;
|
41 |
-
}
|
42 |
-
elseif ( !$bWasEnabled && ( $nIsEnabled !== false ) ) {
|
43 |
-
unset( $aRepairAreas[ $nIsEnabled ] );
|
44 |
-
}
|
45 |
-
}
|
46 |
-
}
|
47 |
-
$opts->setOpt( 'file_repair_areas', $aRepairAreas );
|
48 |
-
|
49 |
-
{ // migrate old scan options
|
50 |
-
if ( $opts->getOpt( 'enable_unrecognised_file_cleaner_scan' ) == 'enabled_delete_report' ) {
|
51 |
-
$opts->setOpt( 'enable_unrecognised_file_cleaner_scan', 'enabled_delete_only' );
|
52 |
-
}
|
53 |
-
$sApcOpt = $opts->getOpt( 'enabled_scan_apc' );
|
54 |
-
if ( strlen( $sApcOpt ) > 1 ) {
|
55 |
-
$opts->setOpt( 'enabled_scan_apc', $sApcOpt == 'disabled' ? 'N' : 'Y' );
|
56 |
-
}
|
57 |
-
$sWpvOpt = $opts->getOpt( 'enable_wpvuln_scan' );
|
58 |
-
if ( strlen( $sWpvOpt ) > 1 ) {
|
59 |
-
$opts->setOpt( 'enable_wpvuln_scan', $sWpvOpt == 'disabled' ? 'N' : 'Y' );
|
60 |
-
}
|
61 |
-
}
|
62 |
-
}
|
63 |
}
|
16 |
$schema->table, 'content', $schema->enumerateColumns()[ 'content' ] )
|
17 |
);
|
18 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
}
|
src/lib/src/Modules/IPs/AjaxHandler.php
CHANGED
@@ -70,48 +70,48 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
70 |
private function ajaxExec_AddIp() :array {
|
71 |
/** @var ModCon $mod */
|
72 |
$mod = $this->getMod();
|
73 |
-
$
|
74 |
|
75 |
$formParams = FormParams::Retrieve();
|
76 |
|
77 |
$success = false;
|
78 |
$msg = __( "IP address wasn't added to the list", 'wp-simple-firewall' );
|
79 |
|
80 |
-
$ip = preg_replace( '#[^/:.a-f\d]#i', '', (
|
81 |
-
$
|
82 |
|
83 |
-
$
|
84 |
-
|| $
|
85 |
-
|| $
|
86 |
|
87 |
-
$
|
88 |
|
89 |
// TODO: Bring this IP verification out of here and make it more accessible
|
90 |
if ( empty( $ip ) ) {
|
91 |
$msg = __( "IP address not provided", 'wp-simple-firewall' );
|
92 |
}
|
93 |
-
elseif ( empty( $
|
94 |
$msg = __( "IP list not provided", 'wp-simple-firewall' );
|
95 |
}
|
96 |
-
elseif ( !$
|
97 |
$msg = __( "IP address isn't either a valid IP or a CIDR range", 'wp-simple-firewall' );
|
98 |
}
|
99 |
-
elseif ( $
|
100 |
$msg = __( "Please upgrade to Pro if you'd like to add IPs to the black list manually.", 'wp-simple-firewall' );
|
101 |
}
|
102 |
-
elseif ( $
|
103 |
$msg = __( "Manually black listing your current IP address is not supported.", 'wp-simple-firewall' );
|
104 |
}
|
105 |
-
elseif ( $
|
106 |
$msg = __( "This IP is reserved and can't be blacklisted.", 'wp-simple-firewall' );
|
107 |
}
|
108 |
else {
|
109 |
$label = $formParams[ 'label' ] ?? '';
|
110 |
-
$
|
111 |
-
switch ( $
|
112 |
case $mod::LIST_MANUAL_WHITE:
|
113 |
try {
|
114 |
-
$
|
115 |
->setMod( $mod )
|
116 |
->setIP( $ip )
|
117 |
->toManualWhitelist( (string)$label );
|
@@ -122,7 +122,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
122 |
|
123 |
case $mod::LIST_MANUAL_BLACK:
|
124 |
try {
|
125 |
-
$
|
126 |
->setMod( $mod )
|
127 |
->setIP( $ip )
|
128 |
->toManualBlacklist( (string)$label );
|
@@ -135,7 +135,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
135 |
break;
|
136 |
}
|
137 |
|
138 |
-
if ( !empty( $
|
139 |
$msg = __( 'IP address added successfully', 'wp-simple-firewall' );
|
140 |
$success = true;
|
141 |
}
|
70 |
private function ajaxExec_AddIp() :array {
|
71 |
/** @var ModCon $mod */
|
72 |
$mod = $this->getMod();
|
73 |
+
$srvIP = Services::IP();
|
74 |
|
75 |
$formParams = FormParams::Retrieve();
|
76 |
|
77 |
$success = false;
|
78 |
$msg = __( "IP address wasn't added to the list", 'wp-simple-firewall' );
|
79 |
|
80 |
+
$ip = preg_replace( '#[^/:.a-f\d]#i', '', ( $formParams[ 'ip' ] ?? '' ) );
|
81 |
+
$list = $formParams[ 'list' ] ?? '';
|
82 |
|
83 |
+
$acceptableIP = $srvIP->isValidIp( $ip )
|
84 |
+
|| $srvIP->isValidIp4Range( $ip )
|
85 |
+
|| $srvIP->isValidIp6Range( $ip );
|
86 |
|
87 |
+
$isBlackList = $list != $mod::LIST_MANUAL_WHITE;
|
88 |
|
89 |
// TODO: Bring this IP verification out of here and make it more accessible
|
90 |
if ( empty( $ip ) ) {
|
91 |
$msg = __( "IP address not provided", 'wp-simple-firewall' );
|
92 |
}
|
93 |
+
elseif ( empty( $list ) ) {
|
94 |
$msg = __( "IP list not provided", 'wp-simple-firewall' );
|
95 |
}
|
96 |
+
elseif ( !$acceptableIP ) {
|
97 |
$msg = __( "IP address isn't either a valid IP or a CIDR range", 'wp-simple-firewall' );
|
98 |
}
|
99 |
+
elseif ( $isBlackList && !$mod->isPremium() ) {
|
100 |
$msg = __( "Please upgrade to Pro if you'd like to add IPs to the black list manually.", 'wp-simple-firewall' );
|
101 |
}
|
102 |
+
elseif ( $isBlackList && $srvIP->checkIp( $srvIP->getRequestIp(), $ip ) ) {
|
103 |
$msg = __( "Manually black listing your current IP address is not supported.", 'wp-simple-firewall' );
|
104 |
}
|
105 |
+
elseif ( $isBlackList && in_array( $ip, Services::IP()->getServerPublicIPs() ) ) {
|
106 |
$msg = __( "This IP is reserved and can't be blacklisted.", 'wp-simple-firewall' );
|
107 |
}
|
108 |
else {
|
109 |
$label = $formParams[ 'label' ] ?? '';
|
110 |
+
$IP = null;
|
111 |
+
switch ( $list ) {
|
112 |
case $mod::LIST_MANUAL_WHITE:
|
113 |
try {
|
114 |
+
$IP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
115 |
->setMod( $mod )
|
116 |
->setIP( $ip )
|
117 |
->toManualWhitelist( (string)$label );
|
122 |
|
123 |
case $mod::LIST_MANUAL_BLACK:
|
124 |
try {
|
125 |
+
$IP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
126 |
->setMod( $mod )
|
127 |
->setIP( $ip )
|
128 |
->toManualBlacklist( (string)$label );
|
135 |
break;
|
136 |
}
|
137 |
|
138 |
+
if ( !empty( $IP ) ) {
|
139 |
$msg = __( 'IP address added successfully', 'wp-simple-firewall' );
|
140 |
$success = true;
|
141 |
}
|
src/lib/src/Modules/IPs/Components/UnblockIpByFlag.php
CHANGED
@@ -20,13 +20,13 @@ class UnblockIpByFlag {
|
|
20 |
$content = $FS->getFileContent( $path );
|
21 |
if ( !empty( $content ) ) {
|
22 |
|
23 |
-
foreach ( array_map( 'trim', explode( "\n", $content ) ) as $
|
24 |
$removed = ( new IPs\Lib\Ops\DeleteIp() )
|
25 |
->setMod( $mod )
|
26 |
-
->setIP( $
|
27 |
->fromBlacklist();
|
28 |
if ( $removed ) {
|
29 |
-
$this->getCon()->fireEvent( 'ip_unblock_flag', [ 'audit' => [ 'ip' => $
|
30 |
}
|
31 |
}
|
32 |
}
|
20 |
$content = $FS->getFileContent( $path );
|
21 |
if ( !empty( $content ) ) {
|
22 |
|
23 |
+
foreach ( array_map( 'trim', explode( "\n", $content ) ) as $ip ) {
|
24 |
$removed = ( new IPs\Lib\Ops\DeleteIp() )
|
25 |
->setMod( $mod )
|
26 |
+
->setIP( $ip )
|
27 |
->fromBlacklist();
|
28 |
if ( $removed ) {
|
29 |
+
$this->getCon()->fireEvent( 'ip_unblock_flag', [ 'audit' => [ 'ip' => $ip ] ] );
|
30 |
}
|
31 |
}
|
32 |
}
|
src/lib/src/Modules/IPs/Lib/BlacklistHandler.php
CHANGED
@@ -44,12 +44,6 @@ class BlacklistHandler extends Modules\Base\Common\ExecOnceModConsumer {
|
|
44 |
}
|
45 |
}
|
46 |
|
47 |
-
/**
|
48 |
-
* @deprecated 11.3
|
49 |
-
*/
|
50 |
-
public function loadBotDetectors() {
|
51 |
-
}
|
52 |
-
|
53 |
private function isRequestWhitelisted() :bool {
|
54 |
/** @var IPs\Options $opts */
|
55 |
$opts = $this->getOptions();
|
44 |
}
|
45 |
}
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
private function isRequestWhitelisted() :bool {
|
48 |
/** @var IPs\Options $opts */
|
49 |
$opts = $this->getOptions();
|
src/lib/src/Modules/IPs/Lib/Bots/BotEventListener.php
CHANGED
@@ -66,7 +66,7 @@ class BotEventListener extends ExecOnceModConsumer {
|
|
66 |
'ip_offense' => 'offense',
|
67 |
'ip_blocked' => 'blocked',
|
68 |
'ip_unblock' => 'unblocked',
|
69 |
-
'
|
70 |
'login_success' => 'auth',
|
71 |
]
|
72 |
);
|
66 |
'ip_offense' => 'offense',
|
67 |
'ip_blocked' => 'blocked',
|
68 |
'ip_unblock' => 'unblocked',
|
69 |
+
'ip_bypass_add' => 'bypass',
|
70 |
'login_success' => 'auth',
|
71 |
]
|
72 |
);
|
src/lib/src/Modules/IPs/Lib/Ops/AddIp.php
CHANGED
@@ -40,6 +40,9 @@ class AddIp {
|
|
40 |
->lookup( false );
|
41 |
if ( !$IP instanceof Databases\IPs\EntryVO ) {
|
42 |
$IP = $this->add( $mod::LIST_AUTO_BLACK, 'auto', $req->ts() );
|
|
|
|
|
|
|
43 |
}
|
44 |
|
45 |
// Edge-case: the IP is on the list but the last access long-enough passed
|
@@ -59,38 +62,41 @@ class AddIp {
|
|
59 |
}
|
60 |
|
61 |
/**
|
62 |
-
* @param string $
|
63 |
* @return Databases\IPs\EntryVO|null
|
64 |
* @throws \Exception
|
65 |
*/
|
66 |
-
public function toManualBlacklist( $
|
67 |
/** @var ModCon $mod */
|
68 |
$mod = $this->getMod();
|
69 |
-
$
|
70 |
|
71 |
-
$
|
72 |
-
if ( !$
|
73 |
throw new \Exception( "IP address isn't valid." );
|
74 |
}
|
75 |
|
76 |
$IP = null;
|
77 |
-
if ( !in_array( $
|
78 |
|
79 |
-
if ( $
|
80 |
( new DeleteIp() )
|
81 |
->setMod( $mod )
|
82 |
-
->setIP( $
|
83 |
->fromBlacklist();
|
84 |
}
|
85 |
|
86 |
$IP = ( new LookupIpOnList() )
|
87 |
->setDbHandler( $mod->getDbHandler_IPs() )
|
88 |
->setListTypeBlock()
|
89 |
-
->setIP( $
|
90 |
->lookup( false );
|
91 |
|
92 |
if ( !$IP instanceof Databases\IPs\EntryVO ) {
|
93 |
-
$IP = $this->add( $mod::LIST_MANUAL_BLACK, $
|
|
|
|
|
|
|
94 |
}
|
95 |
|
96 |
$updateData = [
|
@@ -100,8 +106,8 @@ class AddIp {
|
|
100 |
if ( $IP->list != $mod::LIST_MANUAL_BLACK ) {
|
101 |
$updateData[ 'list' ] = $mod::LIST_MANUAL_BLACK;
|
102 |
}
|
103 |
-
if ( $IP->label != $
|
104 |
-
$updateData[ 'label' ] = $
|
105 |
}
|
106 |
if ( $IP->blocked_at == 0 ) {
|
107 |
$updateData[ 'blocked_at' ] = Services::Request()->ts();
|
@@ -123,14 +129,14 @@ class AddIp {
|
|
123 |
public function toManualWhitelist( $label = '' ) {
|
124 |
/** @var ModCon $mod */
|
125 |
$mod = $this->getMod();
|
126 |
-
$
|
127 |
|
128 |
$ip = $this->getIP();
|
129 |
-
if ( !$
|
130 |
throw new \Exception( "IP address isn't valid." );
|
131 |
}
|
132 |
|
133 |
-
if ( $
|
134 |
( new DeleteIp() )
|
135 |
->setMod( $mod )
|
136 |
->setIP( $ip )
|
@@ -142,8 +148,10 @@ class AddIp {
|
|
142 |
->setIP( $this->getIP() )
|
143 |
->lookup( false );
|
144 |
if ( !$IP instanceof Databases\IPs\EntryVO ) {
|
145 |
-
$this->getCon()->fireEvent( 'ip_bypass' );
|
146 |
$IP = $this->add( $mod::LIST_MANUAL_WHITE, $label );
|
|
|
|
|
|
|
147 |
}
|
148 |
|
149 |
$updateData = [];
|
@@ -171,40 +179,40 @@ class AddIp {
|
|
171 |
|
172 |
/**
|
173 |
* @param string $list
|
174 |
-
* @param string $
|
175 |
-
* @param int|null $
|
176 |
* @return Databases\IPs\EntryVO|null
|
177 |
* @throws \Exception
|
178 |
*/
|
179 |
-
private function add( string $list, $
|
180 |
-
$
|
181 |
|
182 |
/** @var ModCon $mod */
|
183 |
$mod = $this->getMod();
|
184 |
|
185 |
// Never add a reserved IP to any black list
|
186 |
-
$
|
187 |
|
188 |
-
/** @var Databases\IPs\EntryVO $
|
189 |
-
$
|
190 |
-
$
|
191 |
-
$
|
192 |
-
$
|
193 |
-
if ( is_numeric( $
|
194 |
-
$
|
195 |
}
|
196 |
|
197 |
-
if ( $
|
198 |
-
/** @var Databases\IPs\EntryVO $
|
199 |
-
$
|
200 |
-
|
201 |
-
|
202 |
}
|
203 |
|
204 |
-
if ( !$
|
205 |
throw new \Exception( "IP couldn't be added to the database." );
|
206 |
}
|
207 |
|
208 |
-
return $
|
209 |
}
|
210 |
}
|
40 |
->lookup( false );
|
41 |
if ( !$IP instanceof Databases\IPs\EntryVO ) {
|
42 |
$IP = $this->add( $mod::LIST_AUTO_BLACK, 'auto', $req->ts() );
|
43 |
+
if ( !empty( $IP ) ) {
|
44 |
+
$this->getCon()->fireEvent( 'ip_block_auto', [ 'audit' => [ 'ip' => $this->getIP() ] ] );
|
45 |
+
}
|
46 |
}
|
47 |
|
48 |
// Edge-case: the IP is on the list but the last access long-enough passed
|
62 |
}
|
63 |
|
64 |
/**
|
65 |
+
* @param string $label
|
66 |
* @return Databases\IPs\EntryVO|null
|
67 |
* @throws \Exception
|
68 |
*/
|
69 |
+
public function toManualBlacklist( $label = '' ) {
|
70 |
/** @var ModCon $mod */
|
71 |
$mod = $this->getMod();
|
72 |
+
$srvIP = Services::IP();
|
73 |
|
74 |
+
$ip = $this->getIP();
|
75 |
+
if ( !$srvIP->isValidIp( $ip ) && !$srvIP->isValidIpRange( $ip ) ) {
|
76 |
throw new \Exception( "IP address isn't valid." );
|
77 |
}
|
78 |
|
79 |
$IP = null;
|
80 |
+
if ( !in_array( $ip, $srvIP->getServerPublicIPs() ) ) {
|
81 |
|
82 |
+
if ( $srvIP->isValidIpRange( $ip ) ) {
|
83 |
( new DeleteIp() )
|
84 |
->setMod( $mod )
|
85 |
+
->setIP( $ip )
|
86 |
->fromBlacklist();
|
87 |
}
|
88 |
|
89 |
$IP = ( new LookupIpOnList() )
|
90 |
->setDbHandler( $mod->getDbHandler_IPs() )
|
91 |
->setListTypeBlock()
|
92 |
+
->setIP( $ip )
|
93 |
->lookup( false );
|
94 |
|
95 |
if ( !$IP instanceof Databases\IPs\EntryVO ) {
|
96 |
+
$IP = $this->add( $mod::LIST_MANUAL_BLACK, $label );
|
97 |
+
if ( !empty( $IP ) ) {
|
98 |
+
$this->getCon()->fireEvent( 'ip_block_manual', [ 'audit' => [ 'ip' => $this->getIP() ] ] );
|
99 |
+
}
|
100 |
}
|
101 |
|
102 |
$updateData = [
|
106 |
if ( $IP->list != $mod::LIST_MANUAL_BLACK ) {
|
107 |
$updateData[ 'list' ] = $mod::LIST_MANUAL_BLACK;
|
108 |
}
|
109 |
+
if ( $IP->label != $label ) {
|
110 |
+
$updateData[ 'label' ] = $label;
|
111 |
}
|
112 |
if ( $IP->blocked_at == 0 ) {
|
113 |
$updateData[ 'blocked_at' ] = Services::Request()->ts();
|
129 |
public function toManualWhitelist( $label = '' ) {
|
130 |
/** @var ModCon $mod */
|
131 |
$mod = $this->getMod();
|
132 |
+
$srvIP = Services::IP();
|
133 |
|
134 |
$ip = $this->getIP();
|
135 |
+
if ( !$srvIP->isValidIp( $ip ) && !$srvIP->isValidIpRange( $ip ) ) {
|
136 |
throw new \Exception( "IP address isn't valid." );
|
137 |
}
|
138 |
|
139 |
+
if ( $srvIP->isValidIpRange( $ip ) ) {
|
140 |
( new DeleteIp() )
|
141 |
->setMod( $mod )
|
142 |
->setIP( $ip )
|
148 |
->setIP( $this->getIP() )
|
149 |
->lookup( false );
|
150 |
if ( !$IP instanceof Databases\IPs\EntryVO ) {
|
|
|
151 |
$IP = $this->add( $mod::LIST_MANUAL_WHITE, $label );
|
152 |
+
if ( !empty( $IP ) ) {
|
153 |
+
$this->getCon()->fireEvent( 'ip_bypass_add', [ 'audit' => [ 'ip' => $this->getIP() ] ] );
|
154 |
+
}
|
155 |
}
|
156 |
|
157 |
$updateData = [];
|
179 |
|
180 |
/**
|
181 |
* @param string $list
|
182 |
+
* @param string $label
|
183 |
+
* @param int|null $lastAccess
|
184 |
* @return Databases\IPs\EntryVO|null
|
185 |
* @throws \Exception
|
186 |
*/
|
187 |
+
private function add( string $list, $label = '', $lastAccess = null ) {
|
188 |
+
$IP = null;
|
189 |
|
190 |
/** @var ModCon $mod */
|
191 |
$mod = $this->getMod();
|
192 |
|
193 |
// Never add a reserved IP to any black list
|
194 |
+
$dbh = $mod->getDbHandler_IPs();
|
195 |
|
196 |
+
/** @var Databases\IPs\EntryVO $tmp */
|
197 |
+
$tmp = $dbh->getVo();
|
198 |
+
$tmp->ip = $this->getIP();
|
199 |
+
$tmp->list = $list;
|
200 |
+
$tmp->label = empty( $label ) ? __( 'No Label', 'wp-simple-firewall' ) : trim( $label );
|
201 |
+
if ( is_numeric( $lastAccess ) && $lastAccess > 0 ) {
|
202 |
+
$tmp->last_access_at = $lastAccess;
|
203 |
}
|
204 |
|
205 |
+
if ( $dbh->getQueryInserter()->insert( $tmp ) ) {
|
206 |
+
/** @var Databases\IPs\EntryVO $IP */
|
207 |
+
$IP = $dbh->getQuerySelector()
|
208 |
+
->setWheresFromVo( $tmp )
|
209 |
+
->first();
|
210 |
}
|
211 |
|
212 |
+
if ( !$IP instanceof Databases\IPs\EntryVO ) {
|
213 |
throw new \Exception( "IP couldn't be added to the database." );
|
214 |
}
|
215 |
|
216 |
+
return $IP;
|
217 |
}
|
218 |
}
|
src/lib/src/Modules/IPs/Lib/Ops/DeleteIp.php
CHANGED
@@ -19,6 +19,7 @@ class DeleteIp {
|
|
19 |
}
|
20 |
|
21 |
public function fromWhiteList() :bool {
|
|
|
22 |
return (bool)$this->getDeleter()
|
23 |
->filterByWhitelist()
|
24 |
->query();
|
19 |
}
|
20 |
|
21 |
public function fromWhiteList() :bool {
|
22 |
+
$this->getCon()->fireEvent( 'ip_bypass_remove', [ 'audit' => [ 'ip' => $this->getIP() ] ] );
|
23 |
return (bool)$this->getDeleter()
|
24 |
->filterByWhitelist()
|
25 |
->query();
|
src/lib/src/Modules/IPs/ModCon.php
CHANGED
@@ -88,6 +88,30 @@ class ModCon extends BaseShield\ModCon {
|
|
88 |
$this->cleanPathWhitelist();
|
89 |
}
|
90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
public function canLinkCheese() :bool {
|
92 |
$FS = Services::WpFs();
|
93 |
$WP = Services::WpGeneral();
|
@@ -97,32 +121,6 @@ class ModCon extends BaseShield\ModCon {
|
|
97 |
&& ( !$isSplit || !$FS->exists( path_join( dirname( ABSPATH ), 'robots.txt' ) ) );
|
98 |
}
|
99 |
|
100 |
-
private function cleanPathWhitelist() {
|
101 |
-
/** @var Options $opts */
|
102 |
-
$opts = $this->getOptions();
|
103 |
-
$opts->setOpt( 'request_whitelist', array_unique( array_filter( array_map(
|
104 |
-
function ( $rule ) {
|
105 |
-
$rule = strtolower( trim( $rule ) );
|
106 |
-
if ( !empty( $rule ) ) {
|
107 |
-
$toCheck = array_unique( [
|
108 |
-
(string)parse_url( Services::WpGeneral()->getHomeUrl(), PHP_URL_PATH ),
|
109 |
-
(string)parse_url( Services::WpGeneral()->getWpUrl(), PHP_URL_PATH ),
|
110 |
-
] );
|
111 |
-
$regEx = sprintf( '#^%s$#i', str_replace( 'STAR', '.*', preg_quote( str_replace( '*', 'STAR', $rule ), '#' ) ) );
|
112 |
-
foreach ( $toCheck as $path ) {
|
113 |
-
$slashPath = rtrim( $path, '/' ).'/';
|
114 |
-
if ( preg_match( $regEx, $path ) || preg_match( $regEx, $slashPath ) ) {
|
115 |
-
$rule = false;
|
116 |
-
break;
|
117 |
-
}
|
118 |
-
}
|
119 |
-
}
|
120 |
-
return $rule;
|
121 |
-
},
|
122 |
-
$opts->getOpt( 'request_whitelist', [] ) // do not use Options getter as it formats into regex
|
123 |
-
) ) ) );
|
124 |
-
}
|
125 |
-
|
126 |
public function loadOffenseTracker() :Lib\OffenseTracker {
|
127 |
if ( !isset( $this->oOffenseTracker ) ) {
|
128 |
$this->oOffenseTracker = new Lib\OffenseTracker( $this->getCon() );
|
88 |
$this->cleanPathWhitelist();
|
89 |
}
|
90 |
|
91 |
+
private function cleanPathWhitelist() {
|
92 |
+
/** @var Options $opts */
|
93 |
+
$opts = $this->getOptions();
|
94 |
+
|
95 |
+
$specialPaths = array_map(
|
96 |
+
function ( $url ) {
|
97 |
+
return (string)parse_url( $url, PHP_URL_PATH );
|
98 |
+
},
|
99 |
+
[
|
100 |
+
Services::WpGeneral()->getHomeUrl(),
|
101 |
+
Services::WpGeneral()->getWpUrl(),
|
102 |
+
]
|
103 |
+
);
|
104 |
+
|
105 |
+
$values = $opts->getOpt( 'request_whitelist', [] );
|
106 |
+
$opts->setOpt( 'request_whitelist',
|
107 |
+
( new Shield\Modules\Base\Options\WildCardOptions() )->clean(
|
108 |
+
is_array( $values ) ? $values : [],
|
109 |
+
$specialPaths,
|
110 |
+
Shield\Modules\Base\Options\WildCardOptions::URL_PATH
|
111 |
+
)
|
112 |
+
);
|
113 |
+
}
|
114 |
+
|
115 |
public function canLinkCheese() :bool {
|
116 |
$FS = Services::WpFs();
|
117 |
$WP = Services::WpGeneral();
|
121 |
&& ( !$isSplit || !$FS->exists( path_join( dirname( ABSPATH ), 'robots.txt' ) ) );
|
122 |
}
|
123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
public function loadOffenseTracker() :Lib\OffenseTracker {
|
125 |
if ( !isset( $this->oOffenseTracker ) ) {
|
126 |
$this->oOffenseTracker = new Lib\OffenseTracker( $this->getCon() );
|
src/lib/src/Modules/IPs/Options.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
class Options extends BaseShield\Options {
|
@@ -27,13 +28,13 @@ class Options extends BaseShield\Options {
|
|
27 |
public function getCanIpRequestAutoUnblock( string $ip ) :bool {
|
28 |
$existing = $this->getAutoUnblockIps();
|
29 |
return !array_key_exists( $ip, $existing )
|
30 |
-
|| ( Services::Request()->carbon()->
|
31 |
}
|
32 |
|
33 |
public function getCanRequestAutoUnblockEmailLink( \WP_User $user ) :bool {
|
34 |
$existing = $this->getAutoUnblockEmailIDs();
|
35 |
return !array_key_exists( $user->ID, $existing )
|
36 |
-
|| ( Services::Request()->carbon()->
|
37 |
}
|
38 |
|
39 |
public function getOffenseLimit() :int {
|
@@ -43,12 +44,13 @@ class Options extends BaseShield\Options {
|
|
43 |
/**
|
44 |
* @return string[] - precise REGEX patterns to match against PATH.
|
45 |
*/
|
46 |
-
public function getRequestWhitelistAsRegex() {
|
|
|
47 |
return array_map(
|
48 |
-
function ( $
|
49 |
-
return
|
50 |
},
|
51 |
-
$
|
52 |
);
|
53 |
}
|
54 |
|
@@ -100,34 +102,19 @@ class Options extends BaseShield\Options {
|
|
100 |
return $this->isSelectOptionEnabled( 'track_linkcheese' );
|
101 |
}
|
102 |
|
103 |
-
|
104 |
-
* @return bool
|
105 |
-
*/
|
106 |
-
public function isEnabledTrackXmlRpc() {
|
107 |
return $this->isSelectOptionEnabled( 'track_xmlrpc' );
|
108 |
}
|
109 |
|
110 |
-
|
111 |
-
* @param string $key
|
112 |
-
* @return bool
|
113 |
-
*/
|
114 |
-
public function isTrackOptTransgression( $key ) {
|
115 |
return strpos( $this->getOpt( $key ), 'transgression' ) !== false;
|
116 |
}
|
117 |
|
118 |
-
|
119 |
-
* @param string $key
|
120 |
-
* @return bool
|
121 |
-
*/
|
122 |
-
public function isTrackOptDoubleTransgression( $key ) {
|
123 |
return $this->isOpt( $key, 'transgression-double' );
|
124 |
}
|
125 |
|
126 |
-
|
127 |
-
* @param string $key
|
128 |
-
* @return bool
|
129 |
-
*/
|
130 |
-
public function isTrackOptImmediateBlock( $key ) :bool {
|
131 |
return $this->isOpt( $key, 'block' );
|
132 |
}
|
133 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Options\WildCardOptions;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
class Options extends BaseShield\Options {
|
28 |
public function getCanIpRequestAutoUnblock( string $ip ) :bool {
|
29 |
$existing = $this->getAutoUnblockIps();
|
30 |
return !array_key_exists( $ip, $existing )
|
31 |
+
|| ( Services::Request()->carbon()->subHours( 1 )->timestamp > $existing[ $ip ] );
|
32 |
}
|
33 |
|
34 |
public function getCanRequestAutoUnblockEmailLink( \WP_User $user ) :bool {
|
35 |
$existing = $this->getAutoUnblockEmailIDs();
|
36 |
return !array_key_exists( $user->ID, $existing )
|
37 |
+
|| ( Services::Request()->carbon()->subHours( 1 )->timestamp > $existing[ $user->ID ] );
|
38 |
}
|
39 |
|
40 |
public function getOffenseLimit() :int {
|
44 |
/**
|
45 |
* @return string[] - precise REGEX patterns to match against PATH.
|
46 |
*/
|
47 |
+
public function getRequestWhitelistAsRegex() :array {
|
48 |
+
$paths = $this->isPremium() ? $this->getOpt( 'request_whitelist', [] ) : [];
|
49 |
return array_map(
|
50 |
+
function ( $value ) {
|
51 |
+
return ( new WildCardOptions() )->buildFullRegexValue( $value, WildCardOptions::URL_PATH );
|
52 |
},
|
53 |
+
is_array( $paths ) ? $paths : []
|
54 |
);
|
55 |
}
|
56 |
|
102 |
return $this->isSelectOptionEnabled( 'track_linkcheese' );
|
103 |
}
|
104 |
|
105 |
+
public function isEnabledTrackXmlRpc() :bool {
|
|
|
|
|
|
|
106 |
return $this->isSelectOptionEnabled( 'track_xmlrpc' );
|
107 |
}
|
108 |
|
109 |
+
public function isTrackOptTransgression( string $key ) :bool {
|
|
|
|
|
|
|
|
|
110 |
return strpos( $this->getOpt( $key ), 'transgression' ) !== false;
|
111 |
}
|
112 |
|
113 |
+
public function isTrackOptDoubleTransgression( string $key ) :bool {
|
|
|
|
|
|
|
|
|
114 |
return $this->isOpt( $key, 'transgression-double' );
|
115 |
}
|
116 |
|
117 |
+
public function isTrackOptImmediateBlock( string $key ) :bool {
|
|
|
|
|
|
|
|
|
118 |
return $this->isOpt( $key, 'block' );
|
119 |
}
|
120 |
|
src/lib/src/Modules/IPs/Strings.php
CHANGED
@@ -325,6 +325,18 @@ class Strings extends Base\Strings {
|
|
325 |
'ip_blocked' => [
|
326 |
__( 'IP blocked after incrementing offenses from %s to %s.', 'wp-simple-firewall' )
|
327 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
'ip_unblock_flag' => [
|
329 |
__( "IP address '%s' removed from blacklist using 'unblock' file flag.", 'wp-simple-firewall' )
|
330 |
],
|
325 |
'ip_blocked' => [
|
326 |
__( 'IP blocked after incrementing offenses from %s to %s.', 'wp-simple-firewall' )
|
327 |
],
|
328 |
+
'ip_block_auto' => [
|
329 |
+
__( "IP address '%s' automatically added to block list.", 'wp-simple-firewall' )
|
330 |
+
],
|
331 |
+
'ip_block_manual' => [
|
332 |
+
__( "IP address '%s' manually added to block list.", 'wp-simple-firewall' )
|
333 |
+
],
|
334 |
+
'ip_bypass_add' => [
|
335 |
+
__( "IP address '%s' manually added to bypass list.", 'wp-simple-firewall' )
|
336 |
+
],
|
337 |
+
'ip_bypass_remove' => [
|
338 |
+
__( "IP address '%s' manually removed from the bypass list.", 'wp-simple-firewall' )
|
339 |
+
],
|
340 |
'ip_unblock_flag' => [
|
341 |
__( "IP address '%s' removed from blacklist using 'unblock' file flag.", 'wp-simple-firewall' )
|
342 |
],
|
src/lib/src/Modules/IPs/WpCli/Add.php
CHANGED
@@ -29,22 +29,22 @@ class Add extends BaseAddRemove {
|
|
29 |
|
30 |
/**
|
31 |
* @param array $null
|
32 |
-
* @param array $
|
33 |
* @throws WP_CLI\ExitException
|
34 |
*/
|
35 |
-
public function cmdIpAdd( array $null, array $
|
36 |
|
37 |
-
$label = $
|
38 |
|
39 |
-
$
|
40 |
->setMod( $this->getMod() )
|
41 |
-
->setIP( $
|
42 |
try {
|
43 |
-
if ( $
|
44 |
-
$
|
45 |
}
|
46 |
else {
|
47 |
-
$
|
48 |
}
|
49 |
}
|
50 |
catch ( \Exception $e ) {
|
29 |
|
30 |
/**
|
31 |
* @param array $null
|
32 |
+
* @param array $args
|
33 |
* @throws WP_CLI\ExitException
|
34 |
*/
|
35 |
+
public function cmdIpAdd( array $null, array $args ) {
|
36 |
|
37 |
+
$label = $args[ 'label' ] ?? 'none';
|
38 |
|
39 |
+
$adder = ( new Ops\AddIp() )
|
40 |
->setMod( $this->getMod() )
|
41 |
+
->setIP( $args[ 'ip' ] );
|
42 |
try {
|
43 |
+
if ( $args[ 'list' ] === 'white' ) {
|
44 |
+
$adder->toManualWhitelist( $label );
|
45 |
}
|
46 |
else {
|
47 |
+
$adder->toManualBlacklist( $label );
|
48 |
}
|
49 |
}
|
50 |
catch ( \Exception $e ) {
|
src/lib/src/Modules/IPs/WpCli/Remove.php
CHANGED
@@ -21,24 +21,24 @@ class Remove extends BaseAddRemove {
|
|
21 |
|
22 |
/**
|
23 |
* @param array $null
|
24 |
-
* @param array $
|
25 |
* @throws WP_CLI\ExitException
|
26 |
*/
|
27 |
-
public function cmdIpRemove( array $null, array $
|
28 |
/** @var IPs\ModCon $mod */
|
29 |
$mod = $this->getMod();
|
30 |
|
31 |
-
$
|
32 |
->setMod( $mod )
|
33 |
-
->setIP( $
|
34 |
-
if ( $
|
35 |
-
$
|
36 |
}
|
37 |
else {
|
38 |
-
$
|
39 |
}
|
40 |
|
41 |
-
$
|
42 |
WP_CLI::success( __( 'IP address removed successfully.', 'wp-simple-firewall' ) )
|
43 |
: WP_CLI::error( __( "IP address couldn't be removed. (It may not be on this list)", 'wp-simple-firewall' ) );
|
44 |
}
|
21 |
|
22 |
/**
|
23 |
* @param array $null
|
24 |
+
* @param array $args
|
25 |
* @throws WP_CLI\ExitException
|
26 |
*/
|
27 |
+
public function cmdIpRemove( array $null, array $args ) {
|
28 |
/** @var IPs\ModCon $mod */
|
29 |
$mod = $this->getMod();
|
30 |
|
31 |
+
$deleter = ( new IPs\Lib\Ops\DeleteIp() )
|
32 |
->setMod( $mod )
|
33 |
+
->setIP( $args[ 'ip' ] );
|
34 |
+
if ( $args[ 'list' ] === 'white' ) {
|
35 |
+
$success = $deleter->fromWhiteList();
|
36 |
}
|
37 |
else {
|
38 |
+
$success = $deleter->fromBlacklist();
|
39 |
}
|
40 |
|
41 |
+
$success ?
|
42 |
WP_CLI::success( __( 'IP address removed successfully.', 'wp-simple-firewall' ) )
|
43 |
: WP_CLI::error( __( "IP address couldn't be removed. (It may not be on this list)", 'wp-simple-firewall' ) );
|
44 |
}
|
src/lib/src/Modules/Insights/Lib/SideMenuBuilder.php
CHANGED
@@ -31,7 +31,7 @@ class SideMenuBuilder {
|
|
31 |
$item = Services::DataManipulation()->mergeArraysRecursive( [
|
32 |
'slug' => 'no-slug',
|
33 |
'title' => __( 'NO TITLE', 'wp-simple-firewall' ),
|
34 |
-
'href' => '
|
35 |
'classes' => [],
|
36 |
'id' => '',
|
37 |
'active' => $this->getInav() === $item[ 'slug' ],
|
31 |
$item = Services::DataManipulation()->mergeArraysRecursive( [
|
32 |
'slug' => 'no-slug',
|
33 |
'title' => __( 'NO TITLE', 'wp-simple-firewall' ),
|
34 |
+
'href' => 'javascript:{}',
|
35 |
'classes' => [],
|
36 |
'id' => '',
|
37 |
'active' => $this->getInav() === $item[ 'slug' ],
|
src/lib/src/Modules/Insights/ModCon.php
CHANGED
@@ -67,8 +67,9 @@ class ModCon extends BaseShield\ModCon {
|
|
67 |
'icwp_wpsf_vars_insights',
|
68 |
[
|
69 |
'strings' => [
|
70 |
-
'select_action'
|
71 |
-
'are_you_sure'
|
|
|
72 |
],
|
73 |
]
|
74 |
];
|
67 |
'icwp_wpsf_vars_insights',
|
68 |
[
|
69 |
'strings' => [
|
70 |
+
'select_action' => __( 'Please select an action to perform.', 'wp-simple-firewall' ),
|
71 |
+
'are_you_sure' => __( 'Are you sure?', 'wp-simple-firewall' ),
|
72 |
+
'absolutely_sure' => __( 'Are you absolutely sure?', 'wp-simple-firewall' ),
|
73 |
],
|
74 |
]
|
75 |
];
|
src/lib/src/Modules/Insights/Strings.php
CHANGED
@@ -26,12 +26,9 @@ class Strings extends Base\Strings {
|
|
26 |
'ptg_scan_found' => __( 'Found altered plugin/themes file', 'wp-simple-firewall' ),
|
27 |
'ufc_scan_found' => __( 'Found unrecognised file', 'wp-simple-firewall' ),
|
28 |
'wpv_scan_found' => __( 'Found vulnerable item', 'wp-simple-firewall' ),
|
29 |
-
'
|
30 |
-
'
|
31 |
-
'
|
32 |
-
'ufc_item_repair_success' => __( 'Repaired/Deleted unrecognised file', 'wp-simple-firewall' ),
|
33 |
-
'wcf_item_repair_success' => __( 'Repaired Core file', 'wp-simple-firewall' ),
|
34 |
-
'wpv_item_repair_success' => __( 'Repaired vulnerable item', 'wp-simple-firewall' ),
|
35 |
'session_terminate' => __( 'User session terminated and forced to re-login', 'wp-simple-firewall' ),
|
36 |
'conn_kill' => __( 'Connection killed for blocked IP address', 'wp-simple-firewall' ),
|
37 |
'ip_offense' => __( 'Offense registered against IP address', 'wp-simple-firewall' ),
|
26 |
'ptg_scan_found' => __( 'Found altered plugin/themes file', 'wp-simple-firewall' ),
|
27 |
'ufc_scan_found' => __( 'Found unrecognised file', 'wp-simple-firewall' ),
|
28 |
'wpv_scan_found' => __( 'Found vulnerable item', 'wp-simple-firewall' ),
|
29 |
+
'scan_item_repair_success' => __( 'Scan item successfully repaired', 'wp-simple-firewall' ),
|
30 |
+
'scan_item_repair_fail' => __( 'Scan item repair failed', 'wp-simple-firewall' ),
|
31 |
+
'scan_item_delete_success' => __( 'Scan item successfully deleted', 'wp-simple-firewall' ),
|
|
|
|
|
|
|
32 |
'session_terminate' => __( 'User session terminated and forced to re-login', 'wp-simple-firewall' ),
|
33 |
'conn_kill' => __( 'Connection killed for blocked IP address', 'wp-simple-firewall' ),
|
34 |
'ip_offense' => __( 'Offense registered against IP address', 'wp-simple-firewall' ),
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SupportCandy.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Spam\Handlers;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
+
class SupportCandy extends Base {
|
8 |
+
|
9 |
+
protected function run() {
|
10 |
+
add_filter( 'wpsc_before_create_ticket_args', function ( $args ) {
|
11 |
+
if ( $this->isSpam() ) {
|
12 |
+
Services::WpGeneral()->wpDie( sprintf( "Sorry, your request failed %s Bot checking.",
|
13 |
+
$this->getCon()->getHumanName() ) );
|
14 |
+
}
|
15 |
+
return $args;
|
16 |
+
}, 1000 );
|
17 |
+
}
|
18 |
+
|
19 |
+
protected function getProviderName() :string {
|
20 |
+
return 'SupportCandy';
|
21 |
+
}
|
22 |
+
|
23 |
+
public static function IsProviderInstalled() :bool {
|
24 |
+
return @class_exists( 'Support_Candy' )
|
25 |
+
&& defined( 'WPSC_VERSION' ) && version_compare( WPSC_VERSION, '2.2.3', '>=' );
|
26 |
+
}
|
27 |
+
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/SpamController.php
CHANGED
@@ -25,6 +25,7 @@ class SpamController extends BaseBotDetectionController {
|
|
25 |
new Handlers\KaliForms(),
|
26 |
new Handlers\NinjaForms(),
|
27 |
new Handlers\SuperForms(),
|
|
|
28 |
new Handlers\WPForms(),
|
29 |
new Handlers\WpForo(),
|
30 |
];
|
25 |
new Handlers\KaliForms(),
|
26 |
new Handlers\NinjaForms(),
|
27 |
new Handlers\SuperForms(),
|
28 |
+
new Handlers\SupportCandy(),
|
29 |
new Handlers\WPForms(),
|
30 |
new Handlers\WpForo(),
|
31 |
];
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/AntibotSetup.php
CHANGED
@@ -21,7 +21,7 @@ class AntibotSetup extends ExecOnceModConsumer {
|
|
21 |
$opts = $this->getOptions();
|
22 |
|
23 |
$providers = [];
|
24 |
-
if ( $opts->isEnabledCooldown() && $
|
25 |
$providers[] = ( new AntiBot\ProtectionProviders\CoolDown() )
|
26 |
->setMod( $mod );
|
27 |
}
|
@@ -91,4 +91,4 @@ class AntibotSetup extends ExecOnceModConsumer {
|
|
91 |
}
|
92 |
}
|
93 |
}
|
94 |
-
}
|
21 |
$opts = $this->getOptions();
|
22 |
|
23 |
$providers = [];
|
24 |
+
if ( $opts->isEnabledCooldown() && $this->getCon()->hasCacheDir() ) {
|
25 |
$providers[] = ( new AntiBot\ProtectionProviders\CoolDown() )
|
26 |
->setMod( $mod );
|
27 |
}
|
91 |
}
|
92 |
}
|
93 |
}
|
94 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/AntiBot.php
CHANGED
@@ -9,7 +9,7 @@ class AntiBot extends BaseProtectionProvider {
|
|
9 |
/**
|
10 |
* @inheritDoc
|
11 |
*/
|
12 |
-
public function performCheck( $
|
13 |
if ( $this->isFactorTested() ) {
|
14 |
return;
|
15 |
}
|
9 |
/**
|
10 |
* @inheritDoc
|
11 |
*/
|
12 |
+
public function performCheck( $form ) {
|
13 |
if ( $this->isFactorTested() ) {
|
14 |
return;
|
15 |
}
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/BaseProtectionProvider.php
CHANGED
@@ -42,10 +42,10 @@ abstract class BaseProtectionProvider {
|
|
42 |
}
|
43 |
|
44 |
/**
|
45 |
-
* @param LoginGuard\Lib\AntiBot\FormProviders\BaseFormProvider $
|
46 |
* @throws \Exception
|
47 |
*/
|
48 |
-
abstract public function performCheck( $
|
49 |
|
50 |
/**
|
51 |
* @param bool $tested
|
42 |
}
|
43 |
|
44 |
/**
|
45 |
+
* @param LoginGuard\Lib\AntiBot\FormProviders\BaseFormProvider $form
|
46 |
* @throws \Exception
|
47 |
*/
|
48 |
+
abstract public function performCheck( $form );
|
49 |
|
50 |
/**
|
51 |
* @param bool $tested
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/CoolDown.php
CHANGED
@@ -9,19 +9,19 @@ class CoolDown extends BaseProtectionProvider {
|
|
9 |
/**
|
10 |
* @inheritDoc
|
11 |
*/
|
12 |
-
public function performCheck( $
|
13 |
if ( !$this->isFactorTested() ) {
|
14 |
$this->setFactorTested( true );
|
15 |
|
16 |
// At this point someone has attempted to login within the previous login wait interval
|
17 |
// So we remove WordPress's authentication filter and our own user check authentication
|
18 |
// And finally return a WP_Error which will be reflected back to the user.
|
19 |
-
$
|
20 |
-
if ( $
|
21 |
$sErrorString = __( "Request Cooldown in effect.", 'wp-simple-firewall' ).' '
|
22 |
.sprintf(
|
23 |
__( "You must wait %s seconds before attempting this action again.", 'wp-simple-firewall' ),
|
24 |
-
$
|
25 |
);
|
26 |
|
27 |
$this->getCon()->fireEvent( 'cooldown_fail' );
|
@@ -29,7 +29,7 @@ class CoolDown extends BaseProtectionProvider {
|
|
29 |
throw new \Exception( $sErrorString );
|
30 |
}
|
31 |
|
32 |
-
$
|
33 |
}
|
34 |
}
|
35 |
|
9 |
/**
|
10 |
* @inheritDoc
|
11 |
*/
|
12 |
+
public function performCheck( $form ) {
|
13 |
if ( !$this->isFactorTested() ) {
|
14 |
$this->setFactorTested( true );
|
15 |
|
16 |
// At this point someone has attempted to login within the previous login wait interval
|
17 |
// So we remove WordPress's authentication filter and our own user check authentication
|
18 |
// And finally return a WP_Error which will be reflected back to the user.
|
19 |
+
$cooldown = ( new CooldownFlagFile() )->setMod( $this->getMod() );
|
20 |
+
if ( $cooldown->isWithinCooldownPeriod() ) {
|
21 |
$sErrorString = __( "Request Cooldown in effect.", 'wp-simple-firewall' ).' '
|
22 |
.sprintf(
|
23 |
__( "You must wait %s seconds before attempting this action again.", 'wp-simple-firewall' ),
|
24 |
+
$cooldown->getCooldownRemaining()
|
25 |
);
|
26 |
|
27 |
$this->getCon()->fireEvent( 'cooldown_fail' );
|
29 |
throw new \Exception( $sErrorString );
|
30 |
}
|
31 |
|
32 |
+
$cooldown->updateCooldownFlag();
|
33 |
}
|
34 |
}
|
35 |
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/GaspJs.php
CHANGED
@@ -58,7 +58,7 @@ class GaspJs extends BaseProtectionProvider {
|
|
58 |
/**
|
59 |
* @inheritDoc
|
60 |
*/
|
61 |
-
public function performCheck( $
|
62 |
if ( $this->isFactorTested() ) {
|
63 |
return;
|
64 |
}
|
@@ -71,8 +71,8 @@ class GaspJs extends BaseProtectionProvider {
|
|
71 |
|
72 |
$gasp = $req->post( $mod->getGaspKey() );
|
73 |
|
74 |
-
$username = $
|
75 |
-
$action = $
|
76 |
|
77 |
$valid = false;
|
78 |
$errorMsg = '';
|
58 |
/**
|
59 |
* @inheritDoc
|
60 |
*/
|
61 |
+
public function performCheck( $form ) {
|
62 |
if ( $this->isFactorTested() ) {
|
63 |
return;
|
64 |
}
|
71 |
|
72 |
$gasp = $req->post( $mod->getGaspKey() );
|
73 |
|
74 |
+
$username = $form->getUserToAudit();
|
75 |
+
$action = $form->getActionToAudit();
|
76 |
|
77 |
$valid = false;
|
78 |
$errorMsg = '';
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/GoogleRecaptcha.php
CHANGED
@@ -18,7 +18,7 @@ class GoogleRecaptcha extends BaseProtectionProvider {
|
|
18 |
/**
|
19 |
* @inheritDoc
|
20 |
*/
|
21 |
-
public function performCheck( $
|
22 |
if ( !$this->isFactorTested() ) {
|
23 |
$this->setFactorTested( true );
|
24 |
try {
|
18 |
/**
|
19 |
* @inheritDoc
|
20 |
*/
|
21 |
+
public function performCheck( $form ) {
|
22 |
if ( !$this->isFactorTested() ) {
|
23 |
$this->setFactorTested( true );
|
24 |
try {
|
src/lib/src/Modules/LoginGuard/Lib/CooldownFlagFile.php
CHANGED
@@ -9,10 +9,7 @@ class CooldownFlagFile {
|
|
9 |
|
10 |
use Modules\ModConsumer;
|
11 |
|
12 |
-
|
13 |
-
* @return bool
|
14 |
-
*/
|
15 |
-
public function isWithinCooldownPeriod() {
|
16 |
return $this->getCooldownRemaining() > 0;
|
17 |
}
|
18 |
|
@@ -20,16 +17,13 @@ class CooldownFlagFile {
|
|
20 |
* @return int
|
21 |
*/
|
22 |
public function getCooldownRemaining() {
|
23 |
-
/** @var Modules\LoginGuard\Options $
|
24 |
-
$
|
25 |
-
return max( 0, $
|
26 |
}
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
*/
|
31 |
-
public function getFlagFilePath() {
|
32 |
-
return $this->getCon()->getPluginCachePath( 'mode.login_throttled' );
|
33 |
}
|
34 |
|
35 |
/**
|
@@ -38,8 +32,8 @@ class CooldownFlagFile {
|
|
38 |
public function getSecondsSinceLastLogin() {
|
39 |
$FS = Services::WpFs();
|
40 |
$file = $this->getFlagFilePath();
|
41 |
-
$
|
42 |
-
return
|
43 |
}
|
44 |
|
45 |
/**
|
9 |
|
10 |
use Modules\ModConsumer;
|
11 |
|
12 |
+
public function isWithinCooldownPeriod() :bool {
|
|
|
|
|
|
|
13 |
return $this->getCooldownRemaining() > 0;
|
14 |
}
|
15 |
|
17 |
* @return int
|
18 |
*/
|
19 |
public function getCooldownRemaining() {
|
20 |
+
/** @var Modules\LoginGuard\Options $opts */
|
21 |
+
$opts = $this->getOptions();
|
22 |
+
return max( 0, $opts->getCooldownInterval() - $this->getSecondsSinceLastLogin() );
|
23 |
}
|
24 |
|
25 |
+
public function getFlagFilePath() :string {
|
26 |
+
return $this->getCon()->paths->forCacheItem( 'mode.login_throttled' );
|
|
|
|
|
|
|
27 |
}
|
28 |
|
29 |
/**
|
32 |
public function getSecondsSinceLastLogin() {
|
33 |
$FS = Services::WpFs();
|
34 |
$file = $this->getFlagFilePath();
|
35 |
+
$lastLogin = $FS->exists( $file ) ? $FS->getModifiedTime( $file ) : 0;
|
36 |
+
return Services::Request()->ts() - $lastLogin;
|
37 |
}
|
38 |
|
39 |
/**
|
src/lib/src/Modules/LoginGuard/Lib/CooldownRedirect.php
DELETED
@@ -1,63 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
|
7 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
8 |
-
use FernleafSystems\Wordpress\Services\Services;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Class CooldownRedirect
|
12 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard
|
13 |
-
*/
|
14 |
-
class CooldownRedirect {
|
15 |
-
|
16 |
-
use Modules\ModConsumer;
|
17 |
-
|
18 |
-
public function run() {
|
19 |
-
add_action( 'wp_loaded', [ $this, 'onWpLoaded' ] );
|
20 |
-
}
|
21 |
-
|
22 |
-
public function onWpLoaded() {
|
23 |
-
$oReq = Services::Request();
|
24 |
-
$oCooldownFile = ( new LoginGuard\Lib\CooldownFlagFile() )->setMod( $this->getMod() );
|
25 |
-
if ( !$oReq->isPost() && Services::WpGeneral()->isLoginUrl()
|
26 |
-
&& $oCooldownFile->isWithinCooldownPeriod()
|
27 |
-
&& !Services::WpUsers()->isUserLoggedIn()
|
28 |
-
&& $oReq->query( 'cooldown_bypass' ) != 1 ) {
|
29 |
-
$this->renderCooldownPage();
|
30 |
-
}
|
31 |
-
}
|
32 |
-
|
33 |
-
private function renderCooldownPage() {
|
34 |
-
/** @var ModCon $mod */
|
35 |
-
$mod = $this->getMod();
|
36 |
-
$nTimeRemaining = ( new LoginGuard\Lib\CooldownFlagFile() )
|
37 |
-
->setMod( $mod )
|
38 |
-
->getCooldownRemaining();
|
39 |
-
$aData = [
|
40 |
-
'strings' => [
|
41 |
-
'title' => __( "The login page is protected against too many login attempts.", 'wp-simple-firewall' ),
|
42 |
-
'lines' => [
|
43 |
-
__( 'If you attempt to login again too quickly you may be blocked from accessing this site entirely.', 'wp-simple-firewall' ),
|
44 |
-
__( 'If you share this website with others, you may also block their access to the site.', 'wp-simple-firewall' ),
|
45 |
-
__( 'To ignore this message and return to the login page, please check the box and click continue.', 'wp-simple-firewall' ),
|
46 |
-
],
|
47 |
-
'understand' => __( 'I understand I may block my access to the site.', 'wp-simple-firewall' ),
|
48 |
-
'time_remaining' => __( 'Seconds remaining', 'wp-simple-firewall' ),
|
49 |
-
'button' => __( 'Proceed To Login Page', 'wp-simple-firewall' ),
|
50 |
-
],
|
51 |
-
'vars' => [
|
52 |
-
'remaining' => $nTimeRemaining,
|
53 |
-
'login_url' => Services::WpGeneral()->getLoginUrl(),
|
54 |
-
],
|
55 |
-
'flags' => [
|
56 |
-
],
|
57 |
-
];
|
58 |
-
Services::WpGeneral()
|
59 |
-
->wpDie(
|
60 |
-
$mod->renderTemplate( '/snippets/cooldown_login_block.twig', $aData, true )
|
61 |
-
);
|
62 |
-
}
|
63 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php
CHANGED
@@ -276,7 +276,7 @@ class MfaController {
|
|
276 |
if ( !$canSkip && $this->getCon()->isPremiumActive() && @class_exists( 'WC_Social_Login' ) ) {
|
277 |
// custom support for WooCommerce Social login
|
278 |
$meta = $this->getCon()->getUserMeta( $user );
|
279 |
-
$canSkip =
|
280 |
}
|
281 |
|
282 |
return (bool)apply_filters( 'icwp_shield_2fa_skip',
|
276 |
if ( !$canSkip && $this->getCon()->isPremiumActive() && @class_exists( 'WC_Social_Login' ) ) {
|
277 |
// custom support for WooCommerce Social login
|
278 |
$meta = $this->getCon()->getUserMeta( $user );
|
279 |
+
$canSkip = $meta->wc_social_login_valid ?? false;
|
280 |
}
|
281 |
|
282 |
return (bool)apply_filters( 'icwp_shield_2fa_skip',
|
src/lib/src/Modules/LoginGuard/UI.php
CHANGED
@@ -51,10 +51,16 @@ class UI extends BaseShield\UI {
|
|
51 |
}
|
52 |
|
53 |
if ( $section == 'section_2fa_email' ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
$warnings[] =
|
55 |
__( '2FA by email demands that your WP site is properly configured to send email.', 'wp-simple-firewall' )
|
56 |
.'<br/>'.__( 'This is a common problem and you may get locked out in the future if you ignore this.', 'wp-simple-firewall' )
|
57 |
-
.' '.sprintf( '<a href="%s" target="_blank" class="alert-link">%s</a>', 'https://shsec.io/dd', __( 'Learn More.', 'wp-simple-firewall' ) );
|
58 |
}
|
59 |
|
60 |
return $warnings;
|
51 |
}
|
52 |
|
53 |
if ( $section == 'section_2fa_email' ) {
|
54 |
+
|
55 |
+
if ( $opts->isEnabledEmailAuth() && !$opts->getIfCanSendEmailVerified() ) {
|
56 |
+
$warnings[] = __( "The ability of this site to send email hasn't been verified.", 'wp-simple-firewall' )
|
57 |
+
.'<br/>'.__( 'Please click to re-save your settings to trigger another verification email.', 'wp-simple-firewall' );
|
58 |
+
}
|
59 |
+
|
60 |
$warnings[] =
|
61 |
__( '2FA by email demands that your WP site is properly configured to send email.', 'wp-simple-firewall' )
|
62 |
.'<br/>'.__( 'This is a common problem and you may get locked out in the future if you ignore this.', 'wp-simple-firewall' )
|
63 |
+
.' '.sprintf( '<a href="%s" target="_blank" class="alert-link">%s</a>', 'https://shsec.io/dd', trim( __( 'Learn More.', 'wp-simple-firewall' ), '.' ) );
|
64 |
}
|
65 |
|
66 |
return $warnings;
|
src/lib/src/Modules/Plugin/Lib/TestCacheDirWrite.php
CHANGED
@@ -20,11 +20,12 @@ class TestCacheDirWrite {
|
|
20 |
$data = $this->getTestData();
|
21 |
$now = Services::Request()->ts();
|
22 |
|
23 |
-
if ( ( $data[ 'last_success_at' ] === 0 || $now -
|
24 |
&& ( $now - HOUR_IN_SECONDS > $data[ 'last_test_at' ] ) ) {
|
25 |
|
26 |
-
|
27 |
-
$
|
|
|
28 |
&& $this->canCreateWriteDeleteFile()
|
29 |
&& $this->canCreateWriteDeleteDir();
|
30 |
|
@@ -40,13 +41,14 @@ class TestCacheDirWrite {
|
|
40 |
|
41 |
$FS = Services::WpFs();
|
42 |
|
43 |
-
$testDir = $this->getCon()->
|
44 |
$FS->mkdir( $testDir );
|
45 |
if ( $FS->isDir( $testDir ) ) {
|
46 |
-
$
|
47 |
-
$FS->touch( $
|
|
|
48 |
$FS->deleteDir( $testDir );
|
49 |
-
$canWrite = !$FS->isDir( $testDir );
|
50 |
}
|
51 |
return $canWrite;
|
52 |
}
|
@@ -56,16 +58,12 @@ class TestCacheDirWrite {
|
|
56 |
|
57 |
$FS = Services::WpFs();
|
58 |
|
59 |
-
$testFile = $this->getCon()->
|
60 |
-
$
|
61 |
-
|
62 |
-
if ( $FS->
|
63 |
-
$
|
64 |
-
$FS->
|
65 |
-
if ( $FS->getFileContent( $testFile ) == $uniq ) {
|
66 |
-
$FS->deleteFile( $testFile );
|
67 |
-
$canWrite = !$FS->exists( $testFile );
|
68 |
-
}
|
69 |
}
|
70 |
return $canWrite;
|
71 |
}
|
20 |
$data = $this->getTestData();
|
21 |
$now = Services::Request()->ts();
|
22 |
|
23 |
+
if ( ( $data[ 'last_success_at' ] === 0 || $now - HOUR_IN_SECONDS > $data[ 'last_success_at' ] )
|
24 |
&& ( $now - HOUR_IN_SECONDS > $data[ 'last_test_at' ] ) ) {
|
25 |
|
26 |
+
// Use simple cachdir lookup, not the controller getCachePath to prevent infinite loops
|
27 |
+
$cacheDir = $this->getCon()->paths->cacheDir();
|
28 |
+
$canWrite = !empty( $cacheDir )
|
29 |
&& $this->canCreateWriteDeleteFile()
|
30 |
&& $this->canCreateWriteDeleteDir();
|
31 |
|
41 |
|
42 |
$FS = Services::WpFs();
|
43 |
|
44 |
+
$testDir = $this->getCon()->paths->forCacheItem( uniqid() );
|
45 |
$FS->mkdir( $testDir );
|
46 |
if ( $FS->isDir( $testDir ) ) {
|
47 |
+
$file = path_join( $testDir, uniqid() );
|
48 |
+
$FS->touch( $file );
|
49 |
+
$canTouchFile = $FS->isFile( $file );
|
50 |
$FS->deleteDir( $testDir );
|
51 |
+
$canWrite = $canTouchFile && !$FS->isDir( $testDir );
|
52 |
}
|
53 |
return $canWrite;
|
54 |
}
|
58 |
|
59 |
$FS = Services::WpFs();
|
60 |
|
61 |
+
$testFile = $this->getCon()->paths->forCacheItem( 'test_write_file.txt' );
|
62 |
+
$uniq = uniqid();
|
63 |
+
$FS->putFileContent( $testFile, $uniq );
|
64 |
+
if ( $FS->getFileContent( $testFile ) == $uniq ) {
|
65 |
+
$FS->deleteFile( $testFile );
|
66 |
+
$canWrite = !$FS->exists( $testFile );
|
|
|
|
|
|
|
|
|
67 |
}
|
68 |
return $canWrite;
|
69 |
}
|
src/lib/src/Modules/Plugin/Options.php
CHANGED
@@ -63,14 +63,6 @@ class Options extends BaseShield\Options {
|
|
63 |
return !$this->isOpt( 'tracking_permission_set_at', 0 );
|
64 |
}
|
65 |
|
66 |
-
/**
|
67 |
-
* @return bool
|
68 |
-
* @deprecated 11.4
|
69 |
-
*/
|
70 |
-
public function isImportExportPermitted() :bool {
|
71 |
-
return $this->isOpt( 'importexport_enable', 'Y' );
|
72 |
-
}
|
73 |
-
|
74 |
/**
|
75 |
* @return string[]
|
76 |
*/
|
63 |
return !$this->isOpt( 'tracking_permission_set_at', 0 );
|
64 |
}
|
65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
/**
|
67 |
* @return string[]
|
68 |
*/
|
src/lib/src/Modules/Plugin/WpCli/Export.php
CHANGED
@@ -36,51 +36,51 @@ class Export extends Base\WpCli\BaseWpCliCmd {
|
|
36 |
|
37 |
/**
|
38 |
* @param array $null
|
39 |
-
* @param array $
|
40 |
* @throws WP_CLI\ExitException
|
41 |
*/
|
42 |
-
public function cmdExport( array $null, array $
|
43 |
-
$
|
44 |
|
45 |
-
$
|
46 |
-
$bForce = $this->isForceFlag( $
|
47 |
-
if ( !path_is_absolute( $
|
48 |
-
$
|
49 |
-
WP_CLI::log( __( "
|
50 |
}
|
51 |
-
WP_CLI::log( sprintf( '%s: %s', __( 'Export file path', 'wp-simple-firewall' ), $
|
52 |
|
53 |
-
if ( $
|
54 |
WP_CLI::error( __( "The file specified is an existing directory.", 'wp-simple-firewall' ) );
|
55 |
}
|
56 |
|
57 |
-
$dir = dirname( $
|
58 |
-
if ( !$
|
59 |
if ( !$bForce ) {
|
60 |
WP_CLI::confirm( "The directory for the export file doesn't exist. Create it?" );
|
61 |
}
|
62 |
-
$
|
63 |
-
if ( $
|
64 |
WP_CLI::error( sprintf( __( "Couldn't create the directory: %s", 'wp-simple-firewall' ), $dir ) );
|
65 |
}
|
66 |
}
|
67 |
|
68 |
-
if ( $
|
69 |
WP_CLI::confirm( "The export file already exists. Overwrite?" );
|
70 |
}
|
71 |
|
72 |
-
$
|
73 |
-
if ( !$
|
74 |
WP_CLI::error( __( "Couldn't create the export file.", 'wp-simple-firewall' ) );
|
75 |
}
|
76 |
-
if ( !is_writable( $
|
77 |
WP_CLI::error( __( "The system reports that this file path isn't writable.", 'wp-simple-firewall' ) );
|
78 |
}
|
79 |
|
80 |
$aData = ( new Lib\ImportExport\Export() )
|
81 |
->setMod( $this->getMod() )
|
82 |
->toStandardArray();
|
83 |
-
if ( !$
|
84 |
WP_CLI::error( __( "The system reports that writing the export file failed.", 'wp-simple-firewall' ) );
|
85 |
}
|
86 |
|
36 |
|
37 |
/**
|
38 |
* @param array $null
|
39 |
+
* @param array $args
|
40 |
* @throws WP_CLI\ExitException
|
41 |
*/
|
42 |
+
public function cmdExport( array $null, array $args ) {
|
43 |
+
$FS = Services::WpFs();
|
44 |
|
45 |
+
$file = $args[ 'file' ];
|
46 |
+
$bForce = $this->isForceFlag( $args );
|
47 |
+
if ( !path_is_absolute( $file ) ) {
|
48 |
+
$file = path_join( ABSPATH, $file );
|
49 |
+
WP_CLI::log( __( "File provied wasn't an absolute path, so we're using the following path to the export file" ) );
|
50 |
}
|
51 |
+
WP_CLI::log( sprintf( '%s: %s', __( 'Export file path', 'wp-simple-firewall' ), $file ) );
|
52 |
|
53 |
+
if ( $FS->isDir( $file ) ) {
|
54 |
WP_CLI::error( __( "The file specified is an existing directory.", 'wp-simple-firewall' ) );
|
55 |
}
|
56 |
|
57 |
+
$dir = dirname( $file );
|
58 |
+
if ( !$FS->isDir( $dir ) ) {
|
59 |
if ( !$bForce ) {
|
60 |
WP_CLI::confirm( "The directory for the export file doesn't exist. Create it?" );
|
61 |
}
|
62 |
+
$FS->mkdir( $file );
|
63 |
+
if ( $FS->mkdir( $file ) && !$FS->isDir( $dir ) ) {
|
64 |
WP_CLI::error( sprintf( __( "Couldn't create the directory: %s", 'wp-simple-firewall' ), $dir ) );
|
65 |
}
|
66 |
}
|
67 |
|
68 |
+
if ( $FS->isFile( $file ) && !$bForce ) {
|
69 |
WP_CLI::confirm( "The export file already exists. Overwrite?" );
|
70 |
}
|
71 |
|
72 |
+
$FS->touch( $file );
|
73 |
+
if ( !$FS->isFile( $file ) ) {
|
74 |
WP_CLI::error( __( "Couldn't create the export file.", 'wp-simple-firewall' ) );
|
75 |
}
|
76 |
+
if ( !is_writable( $file ) ) {
|
77 |
WP_CLI::error( __( "The system reports that this file path isn't writable.", 'wp-simple-firewall' ) );
|
78 |
}
|
79 |
|
80 |
$aData = ( new Lib\ImportExport\Export() )
|
81 |
->setMod( $this->getMod() )
|
82 |
->toStandardArray();
|
83 |
+
if ( !$FS->putFileContent( $file, implode( "\n", $aData ) ) ) {
|
84 |
WP_CLI::error( __( "The system reports that writing the export file failed.", 'wp-simple-firewall' ) );
|
85 |
}
|
86 |
|
src/lib/src/Modules/Plugin/WpCli/ForceOff.php
CHANGED
@@ -33,12 +33,12 @@ class ForceOff extends BaseWpCliCmd {
|
|
33 |
}
|
34 |
|
35 |
public function cmdForceOff( $null, $aA ) {
|
36 |
-
$
|
37 |
-
$
|
38 |
|
39 |
switch ( $aA[ 'action' ] ) {
|
40 |
case 'query':
|
41 |
-
if ( $
|
42 |
WP_CLI::log( '`forceoff` file is present.' );
|
43 |
}
|
44 |
else {
|
@@ -47,8 +47,8 @@ class ForceOff extends BaseWpCliCmd {
|
|
47 |
break;
|
48 |
|
49 |
case 'create':
|
50 |
-
$
|
51 |
-
if ( $
|
52 |
WP_CLI::success( '`forceoff` file created successfully.' );
|
53 |
}
|
54 |
else {
|
@@ -57,12 +57,12 @@ class ForceOff extends BaseWpCliCmd {
|
|
57 |
break;
|
58 |
|
59 |
case 'delete':
|
60 |
-
if ( !$
|
61 |
WP_CLI::success( "`forceoff` doesn't exist." );
|
62 |
}
|
63 |
else {
|
64 |
-
$
|
65 |
-
if ( $
|
66 |
WP_CLI::error( "`forceoff` file couldn't be deleted." );
|
67 |
}
|
68 |
else {
|
33 |
}
|
34 |
|
35 |
public function cmdForceOff( $null, $aA ) {
|
36 |
+
$FS = Services::WpFs();
|
37 |
+
$path = path_join( $this->getCon()->getRootDir(), 'forceoff' );
|
38 |
|
39 |
switch ( $aA[ 'action' ] ) {
|
40 |
case 'query':
|
41 |
+
if ( $FS->exists( $path ) ) {
|
42 |
WP_CLI::log( '`forceoff` file is present.' );
|
43 |
}
|
44 |
else {
|
47 |
break;
|
48 |
|
49 |
case 'create':
|
50 |
+
$FS->touch( $path );
|
51 |
+
if ( $FS->exists( $path ) ) {
|
52 |
WP_CLI::success( '`forceoff` file created successfully.' );
|
53 |
}
|
54 |
else {
|
57 |
break;
|
58 |
|
59 |
case 'delete':
|
60 |
+
if ( !$FS->exists( $path ) ) {
|
61 |
WP_CLI::success( "`forceoff` doesn't exist." );
|
62 |
}
|
63 |
else {
|
64 |
+
$FS->deleteFile( $path );
|
65 |
+
if ( $FS->exists( $path ) ) {
|
66 |
WP_CLI::error( "`forceoff` file couldn't be deleted." );
|
67 |
}
|
68 |
else {
|
src/lib/src/Modules/Reporting/Lib/Reports/BaseReporter.php
CHANGED
@@ -13,10 +13,7 @@ abstract class BaseReporter {
|
|
13 |
*/
|
14 |
private $rep;
|
15 |
|
16 |
-
|
17 |
-
* @return array
|
18 |
-
*/
|
19 |
-
public function build() {
|
20 |
return [];
|
21 |
}
|
22 |
|
13 |
*/
|
14 |
private $rep;
|
15 |
|
16 |
+
public function build() :array {
|
|
|
|
|
|
|
17 |
return [];
|
18 |
}
|
19 |
|
src/lib/src/Modules/Reporting/Lib/Reports/Build/BaseBuilder.php
CHANGED
@@ -43,7 +43,7 @@ abstract class BaseBuilder {
|
|
43 |
*/
|
44 |
abstract protected function gather() :array;
|
45 |
|
46 |
-
abstract protected function render( array $
|
47 |
|
48 |
/**
|
49 |
* When displaying, we must take into account the GMT offset of the site.
|
43 |
*/
|
44 |
abstract protected function gather() :array;
|
45 |
|
46 |
+
abstract protected function render( array $gathered ) :string;
|
47 |
|
48 |
/**
|
49 |
* When displaying, we must take into account the GMT offset of the site.
|
src/lib/src/Modules/Reporting/Lib/Reports/Build/BuilderAlerts.php
CHANGED
@@ -26,12 +26,12 @@ class BuilderAlerts extends BaseBuilder {
|
|
26 |
return $reports;
|
27 |
}
|
28 |
|
29 |
-
protected function render( array $
|
30 |
return $this->getMod()->renderTemplate(
|
31 |
'/components/reports/alert_body.twig',
|
32 |
[
|
33 |
'vars' => [
|
34 |
-
'alerts' => $
|
35 |
],
|
36 |
'strings' => [
|
37 |
'title' => __( 'Important Alerts', 'wp-simple-firewall' ),
|
26 |
return $reports;
|
27 |
}
|
28 |
|
29 |
+
protected function render( array $gathered ) :string {
|
30 |
return $this->getMod()->renderTemplate(
|
31 |
'/components/reports/alert_body.twig',
|
32 |
[
|
33 |
'vars' => [
|
34 |
+
'alerts' => $gathered
|
35 |
],
|
36 |
'strings' => [
|
37 |
'title' => __( 'Important Alerts', 'wp-simple-firewall' ),
|
src/lib/src/Modules/Reporting/Lib/Reports/Build/BuilderInfo.php
CHANGED
@@ -25,12 +25,12 @@ class BuilderInfo extends BaseBuilder {
|
|
25 |
return $reports;
|
26 |
}
|
27 |
|
28 |
-
protected function render( array $
|
29 |
return $this->getMod()->renderTemplate(
|
30 |
'/components/reports/info_body.twig',
|
31 |
[
|
32 |
'vars' => [
|
33 |
-
'alerts' => $
|
34 |
],
|
35 |
'strings' => [
|
36 |
'title' => __( 'Site Information Report', 'wp-simple-firewall' ),
|
25 |
return $reports;
|
26 |
}
|
27 |
|
28 |
+
protected function render( array $gathered ) :string {
|
29 |
return $this->getMod()->renderTemplate(
|
30 |
'/components/reports/info_body.twig',
|
31 |
[
|
32 |
'vars' => [
|
33 |
+
'alerts' => $gathered
|
34 |
],
|
35 |
'strings' => [
|
36 |
'title' => __( 'Site Information Report', 'wp-simple-firewall' ),
|
src/lib/src/Modules/SecurityAdmin/Options.php
CHANGED
@@ -15,18 +15,6 @@ class Options extends BaseShield\Options {
|
|
15 |
return $this->isOpt( 'admin_access_restrict_options', 'Y' );
|
16 |
}
|
17 |
|
18 |
-
public function getAdminAccessArea_Plugins() :array {
|
19 |
-
return $this->getAdminAccessArea( 'plugins' );
|
20 |
-
}
|
21 |
-
|
22 |
-
public function getAdminAccessArea_Themes() :array {
|
23 |
-
return $this->getAdminAccessArea( 'themes' );
|
24 |
-
}
|
25 |
-
|
26 |
-
public function getAdminAccessArea_Posts() :array {
|
27 |
-
return $this->getAdminAccessArea( 'posts' );
|
28 |
-
}
|
29 |
-
|
30 |
/**
|
31 |
* @param string $area one of plugins, themes
|
32 |
* @return array
|
@@ -37,16 +25,6 @@ class Options extends BaseShield\Options {
|
|
37 |
return is_array( $d ) ? $d : [];
|
38 |
}
|
39 |
|
40 |
-
/**
|
41 |
-
* @param string $sArea one of plugins, themes
|
42 |
-
* @return array
|
43 |
-
* @deprecated 11.1
|
44 |
-
*/
|
45 |
-
private function getAdminAccessArea( $sArea = 'plugins' ) :array {
|
46 |
-
$d = $this->getOpt( 'admin_access_restrict_'.$sArea, [] );
|
47 |
-
return is_array( $d ) ? $d : [];
|
48 |
-
}
|
49 |
-
|
50 |
private function getRestrictedOptions() :array {
|
51 |
$options = $this->getDef( 'options_to_restrict' );
|
52 |
return is_array( $options ) ? $options : [];
|
15 |
return $this->isOpt( 'admin_access_restrict_options', 'Y' );
|
16 |
}
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
/**
|
19 |
* @param string $area one of plugins, themes
|
20 |
* @return array
|
25 |
return is_array( $d ) ? $d : [];
|
26 |
}
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
private function getRestrictedOptions() :array {
|
29 |
$options = $this->getDef( 'options_to_restrict' );
|
30 |
return is_array( $options ) ? $options : [];
|
src/lib/src/Modules/Sessions/Lib/Ops/Retrieve.php
DELETED
@@ -1,38 +0,0 @@
|
|
1 |
-
<?php declare( strict_types=1 );
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Sessions\Lib\Ops;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Session\{
|
6 |
-
EntryVO,
|
7 |
-
Select
|
8 |
-
};
|
9 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
10 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Sessions\ModCon;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Class Retrieve
|
14 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\Sessions\Lib\Ops
|
15 |
-
* @deprecated 11.2
|
16 |
-
*/
|
17 |
-
class Retrieve {
|
18 |
-
|
19 |
-
use ModConsumer;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* @param string $ip
|
23 |
-
* @return EntryVO|null
|
24 |
-
*/
|
25 |
-
public function byIP( string $ip ) {
|
26 |
-
return $this->getSelector()->filterByIp( $ip )->first();
|
27 |
-
}
|
28 |
-
|
29 |
-
public function byUsername( string $username ) :bool {
|
30 |
-
return $this->getSelector()->filterByUsername( $username )->first();
|
31 |
-
}
|
32 |
-
|
33 |
-
private function getSelector() :Select {
|
34 |
-
/** @var ModCon $mod */
|
35 |
-
$mod = $this->getMod();
|
36 |
-
return $mod->getDbHandler_Sessions()->getQuerySelector();
|
37 |
-
}
|
38 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Scans/Apc/ConvertVosToResults.php
DELETED
@@ -1,32 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Class ConvertVosToResults
|
9 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc
|
10 |
-
*/
|
11 |
-
class ConvertVosToResults extends Shield\Scans\Base\BaseConvertVosToResults {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @param Shield\Databases\Scanner\EntryVO[] $VOs
|
15 |
-
* @return ResultsSet
|
16 |
-
*/
|
17 |
-
public function convert( $VOs ) {
|
18 |
-
$oRes = new ResultsSet();
|
19 |
-
foreach ( $VOs as $oVo ) {
|
20 |
-
$oRes->addItem( $this->convertItem( $oVo ) );
|
21 |
-
}
|
22 |
-
return $oRes;
|
23 |
-
}
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @param Shield\Databases\Scanner\EntryVO $VO
|
27 |
-
* @return ResultItem
|
28 |
-
*/
|
29 |
-
public function convertItem( $VO ) {
|
30 |
-
return ( new ResultItem() )->applyFromArray( $VO->meta );
|
31 |
-
}
|
32 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Scans/Apc/ResultItem.php
CHANGED
@@ -9,6 +9,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc;
|
|
9 |
* @property string $context
|
10 |
* @property int $last_updated_at
|
11 |
*/
|
12 |
-
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\
|
13 |
|
14 |
}
|
9 |
* @property string $context
|
10 |
* @property int $last_updated_at
|
11 |
*/
|
12 |
+
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultItem {
|
13 |
|
14 |
}
|
src/lib/src/Scans/Apc/ResultsSet.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc;
|
4 |
|
@@ -9,114 +9,21 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc
|
11 |
*/
|
12 |
-
class ResultsSet extends Base\
|
13 |
|
14 |
/**
|
15 |
-
* @
|
|
|
16 |
*/
|
17 |
-
public function
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
public function countUniqueSlugsForPluginsContext() {
|
25 |
-
return count( $this->getAllResultsSetsForPluginsContext() );
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @return int
|
30 |
-
*/
|
31 |
-
public function countUniqueSlugsForThemesContext() {
|
32 |
-
return count( $this->getAllResultsSetsForThemesContext() );
|
33 |
-
}
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Provides a collection of ResultsSets for Plugins.
|
37 |
-
* @return ResultsSet[]
|
38 |
-
*/
|
39 |
-
public function getAllResultsSetsForPluginsContext() {
|
40 |
-
return $this->getAllResultsSetsForContext( 'plugins' );
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Provides a collection of ResultsSets for Themes.
|
45 |
-
* @return ResultsSet[]
|
46 |
-
*/
|
47 |
-
public function getAllResultsSetsForThemesContext() {
|
48 |
-
return $this->getAllResultsSetsForContext( 'themes' );
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* @param string $sContext
|
53 |
-
* @return ResultsSet[]
|
54 |
-
*/
|
55 |
-
public function getAllResultsSetsForContext( $sContext ) {
|
56 |
-
$aCollection = [];
|
57 |
-
foreach ( $this->getAllResultsSetsForUniqueSlugs() as $sSlug => $oRS ) {
|
58 |
-
if ( $oRS->getItems()[ 0 ]->context == $sContext ) {
|
59 |
-
$aCollection[ $sSlug ] = $oRS;
|
60 |
}
|
61 |
}
|
62 |
-
return $
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* @return ResultsSet[]
|
67 |
-
*/
|
68 |
-
public function getAllResultsSetsForUniqueSlugs() {
|
69 |
-
$aCollection = [];
|
70 |
-
foreach ( $this->getUniqueSlugs() as $sSlug ) {
|
71 |
-
$oRS = $this->getResultsSetForSlug( $sSlug );
|
72 |
-
if ( $oRS->hasItems() ) {
|
73 |
-
$aCollection[ $sSlug ] = $oRS;
|
74 |
-
}
|
75 |
-
}
|
76 |
-
ksort( $aCollection, SORT_NATURAL );
|
77 |
-
return $aCollection;
|
78 |
-
}
|
79 |
-
|
80 |
-
/**
|
81 |
-
* @param string $sSlug
|
82 |
-
* @return ResultItem[]
|
83 |
-
*/
|
84 |
-
public function getItemsForSlug( $sSlug ) {
|
85 |
-
return array_values( array_filter(
|
86 |
-
$this->getItems(),
|
87 |
-
function ( $oItem ) use ( $sSlug ) {
|
88 |
-
/** @var ResultItem $oItem */
|
89 |
-
return $oItem->slug == $sSlug;
|
90 |
-
}
|
91 |
-
) );
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* @param string $sSlug
|
96 |
-
* @return ResultsSet
|
97 |
-
*/
|
98 |
-
public function getResultsSetForSlug( $sSlug ) {
|
99 |
-
$oRes = new ResultsSet();
|
100 |
-
array_map(
|
101 |
-
function ( $oItem ) use ( $oRes ) {
|
102 |
-
/** @var ResultItem $oItem */
|
103 |
-
$oRes->addItem( $oItem );
|
104 |
-
},
|
105 |
-
$this->getItemsForSlug( $sSlug )
|
106 |
-
);
|
107 |
-
return $oRes;
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* @return string[]
|
112 |
-
*/
|
113 |
-
public function getUniqueSlugs() {
|
114 |
-
return array_unique( array_map(
|
115 |
-
function ( $oItem ) {
|
116 |
-
/** @var ResultItem $oItem */
|
117 |
-
return $oItem->slug;
|
118 |
-
},
|
119 |
-
$this->getItems()
|
120 |
-
) );
|
121 |
}
|
122 |
}
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc;
|
4 |
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc
|
11 |
*/
|
12 |
+
class ResultsSet extends Base\ResultsSet {
|
13 |
|
14 |
/**
|
15 |
+
* @param string $slug
|
16 |
+
* @return ResultItem|null
|
17 |
*/
|
18 |
+
public function getItemForSlug( string $slug ) {
|
19 |
+
$theItem = null;
|
20 |
+
/** @var ResultItem $item */
|
21 |
+
foreach ( $this->getItems() as $item ) {
|
22 |
+
if ( $item->slug === $slug ) {
|
23 |
+
$theItem = $item;
|
24 |
+
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
}
|
27 |
+
return $theItem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
}
|
29 |
}
|
src/lib/src/Scans/Apc/Scan.php
CHANGED
@@ -14,7 +14,7 @@ class Scan extends Shield\Scans\Base\BaseScan {
|
|
14 |
|
15 |
foreach ( $oAction->items as $nKey => $sItem ) {
|
16 |
$oItem = $this->getItemScanner()->scan( $sItem );
|
17 |
-
if ( $oItem instanceof Shield\Scans\Base\
|
18 |
$oTempRs->addItem( $oItem );
|
19 |
}
|
20 |
}
|
14 |
|
15 |
foreach ( $oAction->items as $nKey => $sItem ) {
|
16 |
$oItem = $this->getItemScanner()->scan( $sItem );
|
17 |
+
if ( $oItem instanceof Shield\Scans\Base\ResultItem ) {
|
18 |
$oTempRs->addItem( $oItem );
|
19 |
}
|
20 |
}
|
src/lib/src/Scans/Apc/Utilities/ItemActionHandler.php
CHANGED
@@ -12,10 +12,4 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandler {
|
|
12 |
public function getRepairer() {
|
13 |
return ( new Repair() )->setScanItem( $this->getScanItem() );
|
14 |
}
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @param bool $success
|
18 |
-
*/
|
19 |
-
protected function fireRepairEvent( $success ) {
|
20 |
-
}
|
21 |
}
|
12 |
public function getRepairer() {
|
13 |
return ( new Repair() )->setScanItem( $this->getScanItem() );
|
14 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
}
|
src/lib/src/Scans/Apc/Utilities/Repair.php
CHANGED
@@ -14,7 +14,7 @@ class Repair extends Scans\Base\Utilities\BaseRepair {
|
|
14 |
* @return bool
|
15 |
* @throws \Exception
|
16 |
*/
|
17 |
-
public function repairItem() {
|
18 |
throw new \Exception( 'Repair action is not supported' );
|
19 |
}
|
20 |
}
|
14 |
* @return bool
|
15 |
* @throws \Exception
|
16 |
*/
|
17 |
+
public function repairItem() :bool {
|
18 |
throw new \Exception( 'Repair action is not supported' );
|
19 |
}
|
20 |
}
|
src/lib/src/Scans/Base/BaseBuildFileMap.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Options;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanActionConsumer;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal\ScanActionVO;
|
9 |
+
|
10 |
+
abstract class BaseBuildFileMap {
|
11 |
+
|
12 |
+
use Shield\Modules\ModConsumer;
|
13 |
+
use ScanActionConsumer;
|
14 |
+
|
15 |
+
abstract public function build() :array;
|
16 |
+
|
17 |
+
protected function isAutoFilterFile( \SplFileInfo $file ) :bool {
|
18 |
+
/** @var Options $opts */
|
19 |
+
$opts = $this->getOptions();
|
20 |
+
return $opts->isAutoFilterResults()
|
21 |
+
&& $file->getSize() === 0;
|
22 |
+
}
|
23 |
+
|
24 |
+
protected function isWhitelistedPath( string $path ) :bool {
|
25 |
+
$whitelisted = false;
|
26 |
+
|
27 |
+
/** @var ScanActionVO $action */
|
28 |
+
$action = $this->getScanActionVO();
|
29 |
+
foreach ( $action->paths_whitelisted as $wlPathRegEx ) {
|
30 |
+
if ( preg_match( $wlPathRegEx, $path ) ) {
|
31 |
+
$whitelisted = true;
|
32 |
+
break;
|
33 |
+
}
|
34 |
+
}
|
35 |
+
return $whitelisted;
|
36 |
+
}
|
37 |
+
}
|
src/lib/src/Scans/Base/BaseBuildScanAction.php
CHANGED
@@ -14,14 +14,15 @@ abstract class BaseBuildScanAction {
|
|
14 |
* @throws \Exception
|
15 |
*/
|
16 |
public function build() {
|
17 |
-
$
|
18 |
-
if ( !$
|
19 |
throw new \Exception( 'Scan Action VO not provided.' );
|
20 |
}
|
21 |
-
if ( empty( $
|
22 |
throw new \Exception( 'Scan Slug not provided.' );
|
23 |
}
|
24 |
|
|
|
25 |
$this->setCustomFields();
|
26 |
$this->buildScanItems();
|
27 |
$this->setStandardFields();
|
@@ -31,26 +32,33 @@ abstract class BaseBuildScanAction {
|
|
31 |
* @throws \Exception
|
32 |
*/
|
33 |
protected function buildScanItems() {
|
34 |
-
$
|
35 |
$this->buildItems();
|
36 |
-
$
|
37 |
}
|
38 |
|
39 |
abstract protected function buildItems();
|
40 |
|
41 |
protected function setStandardFields() {
|
42 |
-
$
|
43 |
-
if ( empty( $
|
44 |
-
$
|
45 |
-
$
|
46 |
-
$
|
47 |
-
$
|
48 |
$this->getCon()->prefix( 'scan_block_sleep' ),
|
49 |
-
$
|
50 |
) ) );
|
51 |
}
|
52 |
}
|
53 |
|
54 |
protected function setCustomFields() {
|
55 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
14 |
* @throws \Exception
|
15 |
*/
|
16 |
public function build() {
|
17 |
+
$action = $this->getScanActionVO();
|
18 |
+
if ( !$action instanceof BaseScanActionVO ) {
|
19 |
throw new \Exception( 'Scan Action VO not provided.' );
|
20 |
}
|
21 |
+
if ( empty( $action->scan ) ) {
|
22 |
throw new \Exception( 'Scan Slug not provided.' );
|
23 |
}
|
24 |
|
25 |
+
$this->setWhitelists();
|
26 |
$this->setCustomFields();
|
27 |
$this->buildScanItems();
|
28 |
$this->setStandardFields();
|
32 |
* @throws \Exception
|
33 |
*/
|
34 |
protected function buildScanItems() {
|
35 |
+
$action = $this->getScanActionVO();
|
36 |
$this->buildItems();
|
37 |
+
$action->total_items = count( $action->items );
|
38 |
}
|
39 |
|
40 |
abstract protected function buildItems();
|
41 |
|
42 |
protected function setStandardFields() {
|
43 |
+
$action = $this->getScanActionVO();
|
44 |
+
if ( empty( $action->created_at ) ) {
|
45 |
+
$action->created_at = Services::Request()->ts();
|
46 |
+
$action->started_at = 0;
|
47 |
+
$action->finished_at = 0;
|
48 |
+
$action->usleep = (int)( 1000000*max( 0, apply_filters(
|
49 |
$this->getCon()->prefix( 'scan_block_sleep' ),
|
50 |
+
$action::DEFAULT_SLEEP_SECONDS, $action->scan
|
51 |
) ) );
|
52 |
}
|
53 |
}
|
54 |
|
55 |
protected function setCustomFields() {
|
56 |
}
|
57 |
+
|
58 |
+
protected function setWhitelists() {
|
59 |
+
/** @var Shield\Modules\HackGuard\Options $opts */
|
60 |
+
$opts = $this->getOptions();
|
61 |
+
$action = $this->getScanActionVO();
|
62 |
+
$action->paths_whitelisted = $opts->getWhitelistedPathsAsRegex();
|
63 |
+
}
|
64 |
}
|
src/lib/src/Scans/Base/BaseConvertVosToResults.php
DELETED
@@ -1,30 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Class BaseConvertVosToResults
|
9 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Base
|
10 |
-
*/
|
11 |
-
abstract class BaseConvertVosToResults {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @param EntryVO[] $VOs
|
15 |
-
* @return BaseResultsSet
|
16 |
-
*/
|
17 |
-
public function convert( $VOs ) {
|
18 |
-
$oRes = new BaseResultsSet();
|
19 |
-
foreach ( $VOs as $oVo ) {
|
20 |
-
$oRes->addItem( $this->convertItem( $oVo ) );
|
21 |
-
}
|
22 |
-
return $oRes;
|
23 |
-
}
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @param EntryVO $VO
|
27 |
-
* @return BaseResultItem
|
28 |
-
*/
|
29 |
-
abstract public function convertItem( $VO );
|
30 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Scans/Base/BaseFileScanActionVO.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Data\Adapter\DynProperties;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Table\BaseEntryFormatter;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class BaseFileScanActionVO
|
10 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Base
|
11 |
+
* @property string[] $paths_whitelisted
|
12 |
+
*/
|
13 |
+
abstract class BaseFileScanActionVO extends BaseScanActionVO {
|
14 |
+
|
15 |
+
}
|
src/lib/src/Scans/Base/BaseMergeItems.php
CHANGED
@@ -10,9 +10,9 @@ class BaseMergeItems {
|
|
10 |
|
11 |
/**
|
12 |
* Merges any data from $oMergeItem into $oBaseItem, overwriting Base Item data
|
13 |
-
* @param
|
14 |
-
* @param
|
15 |
-
* @return
|
16 |
*/
|
17 |
public function mergeItemTo( $oBaseItem, $oMergeItem ) {
|
18 |
foreach ( $oMergeItem->getRawData() as $sKey => $mVal ) {
|
10 |
|
11 |
/**
|
12 |
* Merges any data from $oMergeItem into $oBaseItem, overwriting Base Item data
|
13 |
+
* @param ResultItem $oBaseItem
|
14 |
+
* @param ResultItem $oMergeItem
|
15 |
+
* @return ResultItem
|
16 |
*/
|
17 |
public function mergeItemTo( $oBaseItem, $oMergeItem ) {
|
18 |
foreach ( $oMergeItem->getRawData() as $sKey => $mVal ) {
|
src/lib/src/Scans/Base/BaseScan.php
CHANGED
@@ -35,19 +35,19 @@ abstract class BaseScan {
|
|
35 |
}
|
36 |
|
37 |
protected function scan() {
|
38 |
-
$
|
39 |
|
40 |
-
if ( empty( $
|
41 |
-
$
|
42 |
}
|
43 |
else {
|
44 |
$this->scanSlice();
|
45 |
-
if ( empty( $
|
46 |
-
$
|
47 |
}
|
48 |
}
|
49 |
|
50 |
-
return $
|
51 |
}
|
52 |
|
53 |
/**
|
35 |
}
|
36 |
|
37 |
protected function scan() {
|
38 |
+
$action = $this->getScanActionVO();
|
39 |
|
40 |
+
if ( empty( $action->items ) ) {
|
41 |
+
$action->finished_at = Services::Request()->ts();
|
42 |
}
|
43 |
else {
|
44 |
$this->scanSlice();
|
45 |
+
if ( empty( $action->items ) ) {
|
46 |
+
$action->finished_at = Services::Request()->ts();
|
47 |
}
|
48 |
}
|
49 |
|
50 |
+
return $action;
|
51 |
}
|
52 |
|
53 |
/**
|
src/lib/src/Scans/Base/BaseScanActionVO.php
CHANGED
@@ -26,7 +26,7 @@ abstract class BaseScanActionVO {
|
|
26 |
const DEFAULT_SLEEP_SECONDS = 0;
|
27 |
|
28 |
/**
|
29 |
-
* @return
|
30 |
*/
|
31 |
public function getNewResultItem() {
|
32 |
$class = $this->getScanNamespace().'ResultItem';
|
@@ -34,7 +34,7 @@ abstract class BaseScanActionVO {
|
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
-
* @return
|
38 |
*/
|
39 |
public function getNewResultsSet() {
|
40 |
$class = $this->getScanNamespace().'ResultsSet';
|
26 |
const DEFAULT_SLEEP_SECONDS = 0;
|
27 |
|
28 |
/**
|
29 |
+
* @return ResultItem|mixed
|
30 |
*/
|
31 |
public function getNewResultItem() {
|
32 |
$class = $this->getScanNamespace().'ResultItem';
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
+
* @return ResultsSet|mixed
|
38 |
*/
|
39 |
public function getNewResultsSet() {
|
40 |
$class = $this->getScanNamespace().'ResultsSet';
|
src/lib/src/Scans/Base/DiffResultForStorage.php
CHANGED
@@ -3,7 +3,6 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf\ResultsSet;
|
7 |
|
8 |
/**
|
9 |
* Class DiffResultForStorage
|
@@ -13,9 +12,9 @@ class DiffResultForStorage {
|
|
13 |
|
14 |
/**
|
15 |
* The Existing set will be updated to reflect the new current status of the scan
|
16 |
-
* @param
|
17 |
-
* @param
|
18 |
-
* @return
|
19 |
*/
|
20 |
public function diff( $oExistingRes, $oNewResults ) {
|
21 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
|
|
6 |
|
7 |
/**
|
8 |
* Class DiffResultForStorage
|
12 |
|
13 |
/**
|
14 |
* The Existing set will be updated to reflect the new current status of the scan
|
15 |
+
* @param ResultsSet $oExistingRes - will be updated with all items to DB Update
|
16 |
+
* @param ResultsSet $oNewResults - will be adjusted with all item to DB Insert
|
17 |
+
* @return ResultsSet - A results set of all out-of-date records that need to be deleted.
|
18 |
*/
|
19 |
public function diff( $oExistingRes, $oNewResults ) {
|
20 |
|
src/lib/src/Scans/Base/FileResultItem.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class FileResultItem
|
7 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Base
|
8 |
+
* @property string $path_full
|
9 |
+
* @property string $path_fragment - relative to ABSPATH
|
10 |
+
*/
|
11 |
+
class FileResultItem extends ResultItem {
|
12 |
+
|
13 |
+
}
|
src/lib/src/Scans/Base/Files/BaseFileScanner.php
CHANGED
@@ -15,7 +15,7 @@ abstract class BaseFileScanner {
|
|
15 |
|
16 |
/**
|
17 |
* @param string $fullPath
|
18 |
-
* @return Shield\Scans\Base\
|
19 |
*/
|
20 |
abstract public function scan( string $fullPath );
|
21 |
}
|
15 |
|
16 |
/**
|
17 |
* @param string $fullPath
|
18 |
+
* @return Shield\Scans\Base\ResultItem|null
|
19 |
*/
|
20 |
abstract public function scan( string $fullPath );
|
21 |
}
|
src/lib/src/Scans/Base/Files/BaseScanFromFileMap.php
CHANGED
@@ -2,8 +2,11 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Files;
|
4 |
|
|
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
|
|
7 |
|
8 |
/**
|
9 |
* Class BaseScanFromFileMap
|
@@ -15,17 +18,30 @@ abstract class BaseScanFromFileMap {
|
|
15 |
use Scans\Common\ScanActionConsumer;
|
16 |
|
17 |
/**
|
18 |
-
* @return Scans\Base\
|
19 |
*/
|
20 |
public function run() {
|
|
|
|
|
|
|
21 |
$action = $this->getScanActionVO();
|
22 |
$results = $action->getNewResultsSet();
|
23 |
|
|
|
|
|
24 |
if ( is_array( $action->items ) ) {
|
|
|
25 |
foreach ( $action->items as $key => $fullPath ) {
|
26 |
-
|
27 |
-
if (
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
}
|
31 |
}
|
@@ -37,4 +53,17 @@ abstract class BaseScanFromFileMap {
|
|
37 |
* @return BaseFileScanner
|
38 |
*/
|
39 |
abstract protected function getFileScanner();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Files;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Utility\VerifyFileByHash;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Options;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
9 |
+
use FernleafSystems\Wordpress\Services\Utilities\Code\AssessPhpFile;
|
10 |
|
11 |
/**
|
12 |
* Class BaseScanFromFileMap
|
18 |
use Scans\Common\ScanActionConsumer;
|
19 |
|
20 |
/**
|
21 |
+
* @return Scans\Base\ResultsSet
|
22 |
*/
|
23 |
public function run() {
|
24 |
+
/** @var Options $opts */
|
25 |
+
$opts = $this->getOptions();
|
26 |
+
|
27 |
$action = $this->getScanActionVO();
|
28 |
$results = $action->getNewResultsSet();
|
29 |
|
30 |
+
$isAutoFilter = $opts->isAutoFilterResults();
|
31 |
+
|
32 |
if ( is_array( $action->items ) ) {
|
33 |
+
$hashVerifier = ( new VerifyFileByHash() )->setMod( $this->getMod() );
|
34 |
foreach ( $action->items as $key => $fullPath ) {
|
35 |
+
|
36 |
+
if ( !$isAutoFilter || !$this->isEmptyOfCode( $fullPath ) ) {
|
37 |
+
|
38 |
+
if ( !$hashVerifier->verify( $fullPath ) ) {
|
39 |
+
$item = $this->getFileScanner()->scan( $fullPath );
|
40 |
+
// We can exclude files that are empty of relevant code
|
41 |
+
if ( $item instanceof Scans\Base\ResultItem ) {
|
42 |
+
$results->addItem( $item );
|
43 |
+
}
|
44 |
+
}
|
45 |
}
|
46 |
}
|
47 |
}
|
53 |
* @return BaseFileScanner
|
54 |
*/
|
55 |
abstract protected function getFileScanner();
|
56 |
+
|
57 |
+
protected function isEmptyOfCode( string $path ) :bool {
|
58 |
+
try {
|
59 |
+
if ( strpos( $path, wp_normalize_path( ABSPATH ) ) === false ) {
|
60 |
+
$path = path_join( ABSPATH, $path );
|
61 |
+
}
|
62 |
+
$isEmpty = ( new AssessPhpFile() )->isEmptyOfCode( $path );
|
63 |
+
}
|
64 |
+
catch ( \Exception $e ) {
|
65 |
+
$isEmpty = false;
|
66 |
+
}
|
67 |
+
return $isEmpty;
|
68 |
+
}
|
69 |
}
|
src/lib/src/Scans/Base/{BaseResultItem.php → ResultItem.php}
RENAMED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
4 |
|
5 |
use FernleafSystems\Utilities\Data\Adapter\DynProperties;
|
|
|
6 |
|
7 |
/**
|
8 |
* Class BaseResultItem
|
@@ -11,11 +12,17 @@ use FernleafSystems\Utilities\Data\Adapter\DynProperties;
|
|
11 |
* @property bool $is_excluded
|
12 |
* @property string $scan
|
13 |
* @property bool $repaired
|
|
|
14 |
*/
|
15 |
-
class
|
16 |
|
17 |
use DynProperties;
|
18 |
|
|
|
|
|
|
|
|
|
|
|
19 |
public function isReady() :bool {
|
20 |
return false;
|
21 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
4 |
|
5 |
use FernleafSystems\Utilities\Data\Adapter\DynProperties;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO;
|
7 |
|
8 |
/**
|
9 |
* Class BaseResultItem
|
12 |
* @property bool $is_excluded
|
13 |
* @property string $scan
|
14 |
* @property bool $repaired
|
15 |
+
* @property string $repair_event_status
|
16 |
*/
|
17 |
+
class ResultItem {
|
18 |
|
19 |
use DynProperties;
|
20 |
|
21 |
+
/**
|
22 |
+
* @var EntryVO
|
23 |
+
*/
|
24 |
+
public $VO;
|
25 |
+
|
26 |
public function isReady() :bool {
|
27 |
return false;
|
28 |
}
|
src/lib/src/Scans/Base/{BaseResultsSet.php → ResultsSet.php}
RENAMED
@@ -2,14 +2,10 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
4 |
|
5 |
-
|
6 |
-
* Class ResultsSet
|
7 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Base
|
8 |
-
*/
|
9 |
-
class BaseResultsSet {
|
10 |
|
11 |
/**
|
12 |
-
* @var
|
13 |
*/
|
14 |
protected $items;
|
15 |
|
@@ -19,22 +15,22 @@ class BaseResultsSet {
|
|
19 |
protected $bFilterExcluded = true;
|
20 |
|
21 |
/**
|
22 |
-
* @param
|
23 |
* @return $this
|
24 |
*/
|
25 |
-
public function addItem( $
|
26 |
-
$
|
27 |
-
if ( !isset( $
|
28 |
-
$
|
29 |
}
|
30 |
-
$
|
31 |
-
$this->items = $
|
32 |
return $this;
|
33 |
}
|
34 |
|
35 |
/**
|
36 |
* @param string $hash
|
37 |
-
* @return
|
38 |
*/
|
39 |
public function getItemByHash( $hash ) {
|
40 |
return $this->getItemExists( $hash ) ? $this->getAllItems()[ $hash ] : null;
|
@@ -50,7 +46,7 @@ class BaseResultsSet {
|
|
50 |
|
51 |
/**
|
52 |
* Ignores the "is_excluded" property on the items
|
53 |
-
* @return
|
54 |
*/
|
55 |
public function getAllItems() :array {
|
56 |
if ( !is_array( $this->items ) ) {
|
@@ -60,7 +56,7 @@ class BaseResultsSet {
|
|
60 |
}
|
61 |
|
62 |
/**
|
63 |
-
* @return
|
64 |
*/
|
65 |
public function getExcludedItems() :array {
|
66 |
return array_values( array_filter(
|
@@ -73,7 +69,7 @@ class BaseResultsSet {
|
|
73 |
|
74 |
/**
|
75 |
* Honours the exclusion flags
|
76 |
-
* @return
|
77 |
*/
|
78 |
public function getItems() :array {
|
79 |
return array_values( array_filter(
|
@@ -100,7 +96,7 @@ class BaseResultsSet {
|
|
100 |
}
|
101 |
|
102 |
/**
|
103 |
-
* @param
|
104 |
* @return $this
|
105 |
*/
|
106 |
public function removeItem( $item ) {
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
4 |
|
5 |
+
class ResultsSet {
|
|
|
|
|
|
|
|
|
6 |
|
7 |
/**
|
8 |
+
* @var ResultItem[]
|
9 |
*/
|
10 |
protected $items;
|
11 |
|
15 |
protected $bFilterExcluded = true;
|
16 |
|
17 |
/**
|
18 |
+
* @param ResultItem $item
|
19 |
* @return $this
|
20 |
*/
|
21 |
+
public function addItem( $item ) {
|
22 |
+
$all = $this->getAllItems();
|
23 |
+
if ( !isset( $item->hash ) ) {
|
24 |
+
$item->hash = $item->generateHash();
|
25 |
}
|
26 |
+
$all[ $item->hash ] = $item;
|
27 |
+
$this->items = $all;
|
28 |
return $this;
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
* @param string $hash
|
33 |
+
* @return ResultItem|null
|
34 |
*/
|
35 |
public function getItemByHash( $hash ) {
|
36 |
return $this->getItemExists( $hash ) ? $this->getAllItems()[ $hash ] : null;
|
46 |
|
47 |
/**
|
48 |
* Ignores the "is_excluded" property on the items
|
49 |
+
* @return ResultItem[]
|
50 |
*/
|
51 |
public function getAllItems() :array {
|
52 |
if ( !is_array( $this->items ) ) {
|
56 |
}
|
57 |
|
58 |
/**
|
59 |
+
* @return ResultItem[]
|
60 |
*/
|
61 |
public function getExcludedItems() :array {
|
62 |
return array_values( array_filter(
|
69 |
|
70 |
/**
|
71 |
* Honours the exclusion flags
|
72 |
+
* @return ResultItem[]
|
73 |
*/
|
74 |
public function getItems() :array {
|
75 |
return array_values( array_filter(
|
96 |
}
|
97 |
|
98 |
/**
|
99 |
+
* @param ResultItem $item
|
100 |
* @return $this
|
101 |
*/
|
102 |
public function removeItem( $item ) {
|
src/lib/src/Scans/Base/Table/BaseEntryFormatter.php
CHANGED
@@ -49,7 +49,7 @@ abstract class BaseEntryFormatter {
|
|
49 |
'download' => [
|
50 |
'text' => __( 'Download', 'wp-simple-firewall' ),
|
51 |
'classes' => [ 'href-download', 'text-info' ],
|
52 |
-
'data' => [ 'href-download' => $this->getScanController()->createFileDownloadLink( $this->getEntryVO() ) ]
|
53 |
],
|
54 |
];
|
55 |
}
|
@@ -59,7 +59,7 @@ abstract class BaseEntryFormatter {
|
|
59 |
}
|
60 |
|
61 |
/**
|
62 |
-
* @return Scans\Base\
|
63 |
*/
|
64 |
protected function getResultItem() {
|
65 |
return ( new Scan\Results\ConvertBetweenTypes() )
|
49 |
'download' => [
|
50 |
'text' => __( 'Download', 'wp-simple-firewall' ),
|
51 |
'classes' => [ 'href-download', 'text-info' ],
|
52 |
+
'data' => [ 'href-download' => $this->getScanController()->createFileDownloadLink( $this->getEntryVO()->id ) ]
|
53 |
],
|
54 |
];
|
55 |
}
|
59 |
}
|
60 |
|
61 |
/**
|
62 |
+
* @return Scans\Base\ResultItem|mixed
|
63 |
*/
|
64 |
protected function getResultItem() {
|
65 |
return ( new Scan\Results\ConvertBetweenTypes() )
|
src/lib/src/Scans/Base/Table/BaseFileEntryFormatter.php
CHANGED
@@ -63,7 +63,7 @@ abstract class BaseFileEntryFormatter extends BaseEntryFormatter {
|
|
63 |
'download' => [
|
64 |
'text' => sprintf( __( 'Download %s', 'wp-simple-firewall' ), __( 'File', 'wp-simple-firewall' ) ),
|
65 |
'classes' => [ 'href-download', 'text-info' ],
|
66 |
-
'data' => [ 'href-download' => $this->getScanController()->createFileDownloadLink( $this->getEntryVO() ) ]
|
67 |
],
|
68 |
];
|
69 |
}
|
63 |
'download' => [
|
64 |
'text' => sprintf( __( 'Download %s', 'wp-simple-firewall' ), __( 'File', 'wp-simple-firewall' ) ),
|
65 |
'classes' => [ 'href-download', 'text-info' ],
|
66 |
+
'data' => [ 'href-download' => $this->getScanController()->createFileDownloadLink( $this->getEntryVO()->id ) ]
|
67 |
],
|
68 |
];
|
69 |
}
|
src/lib/src/Scans/Base/Utilities/BaseRepair.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Utilities;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanItemConsumer;
|
6 |
|
7 |
/**
|
@@ -12,38 +13,25 @@ abstract class BaseRepair {
|
|
12 |
|
13 |
use ScanItemConsumer;
|
14 |
|
15 |
-
/**
|
16 |
-
* @var bool
|
17 |
-
*/
|
18 |
-
private $bAllowDelete = false;
|
19 |
-
|
20 |
/**
|
21 |
* @return bool
|
|
|
22 |
*/
|
23 |
-
public function
|
24 |
-
return (bool)$this->bAllowDelete;
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @param bool $bAllowDelete
|
29 |
-
* @return $this
|
30 |
-
*/
|
31 |
-
public function setAllowDelete( $bAllowDelete ) {
|
32 |
-
$this->bAllowDelete = $bAllowDelete;
|
33 |
-
return $this;
|
34 |
-
}
|
35 |
|
36 |
/**
|
37 |
* @return bool
|
38 |
* @throws \Exception
|
39 |
*/
|
40 |
-
|
|
|
|
|
41 |
|
42 |
/**
|
43 |
* @return bool
|
44 |
* @throws \Exception
|
45 |
*/
|
46 |
-
public function canRepair() {
|
47 |
return false;
|
48 |
}
|
49 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Utilities;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultItem;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanItemConsumer;
|
7 |
|
8 |
/**
|
13 |
|
14 |
use ScanItemConsumer;
|
15 |
|
|
|
|
|
|
|
|
|
|
|
16 |
/**
|
17 |
* @return bool
|
18 |
+
* @throws \Exception
|
19 |
*/
|
20 |
+
abstract public function repairItem() :bool;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
/**
|
23 |
* @return bool
|
24 |
* @throws \Exception
|
25 |
*/
|
26 |
+
public function deleteItem() :bool {
|
27 |
+
throw new \Exception( 'Delete is not supported' );
|
28 |
+
}
|
29 |
|
30 |
/**
|
31 |
* @return bool
|
32 |
* @throws \Exception
|
33 |
*/
|
34 |
+
public function canRepair() :bool {
|
35 |
return false;
|
36 |
}
|
37 |
}
|
src/lib/src/Scans/Base/Utilities/ItemActionHandler.php
CHANGED
@@ -5,6 +5,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Utilities;
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
|
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanItemConsumer;
|
9 |
|
10 |
abstract class ItemActionHandler {
|
@@ -32,22 +33,28 @@ abstract class ItemActionHandler {
|
|
32 |
$success = $this->repair();
|
33 |
break;
|
34 |
|
|
|
|
|
|
|
|
|
35 |
default:
|
36 |
throw new \Exception( 'Unsupported Scan Item Action' );
|
37 |
-
break;
|
38 |
}
|
39 |
return $success;
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
-
* TODO: Determine if "delete" is always the same as a "repair" - see UFC override
|
44 |
* @return bool
|
45 |
* @throws \Exception
|
46 |
*/
|
47 |
public function delete() {
|
48 |
-
|
49 |
-
|
50 |
-
|
|
|
|
|
|
|
|
|
51 |
}
|
52 |
|
53 |
/**
|
@@ -55,9 +62,7 @@ abstract class ItemActionHandler {
|
|
55 |
* @throws \Exception
|
56 |
*/
|
57 |
public function ignore() {
|
58 |
-
|
59 |
-
$oEntry = $this->getEntryVO();
|
60 |
-
if ( empty( $oEntry ) ) {
|
61 |
throw new \Exception( 'Item could not be found to ignore.' );
|
62 |
}
|
63 |
|
@@ -65,13 +70,21 @@ abstract class ItemActionHandler {
|
|
65 |
$mod = $this->getMod();
|
66 |
/** @var Scanner\Update $updater */
|
67 |
$updater = $mod->getDbHandler_ScanResults()->getQueryUpdater();
|
68 |
-
if ( !$updater->setIgnored( $
|
69 |
throw new \Exception( 'Item could not be ignored at this time.' );
|
70 |
}
|
71 |
|
72 |
return true;
|
73 |
}
|
74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
/**
|
76 |
* @param bool $allowDelete
|
77 |
* @return bool
|
@@ -79,49 +92,50 @@ abstract class ItemActionHandler {
|
|
79 |
*/
|
80 |
public function repair( bool $allowDelete = false ) {
|
81 |
$repairer = $this->getRepairer();
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
84 |
}
|
|
|
|
|
|
|
|
|
85 |
|
86 |
-
$repairer->
|
|
|
|
|
|
|
87 |
|
88 |
-
$
|
89 |
-
$item->repaired = $repairer->repairItem();
|
90 |
-
$this->fireRepairEvent( $item->repaired );
|
91 |
|
92 |
if ( $item->repaired ) {
|
93 |
/** @var HackGuard\ModCon $mod */
|
94 |
$mod = $this->getMod();
|
95 |
/** @var Scanner\Delete $deleter */
|
96 |
-
$
|
97 |
-
|
98 |
-
|
99 |
-
->query();
|
100 |
}
|
101 |
|
102 |
return $item->repaired;
|
103 |
}
|
104 |
|
105 |
-
/**
|
106 |
-
* @return Scanner\EntryVO|null
|
107 |
-
*/
|
108 |
-
protected function getEntryVO() {
|
109 |
-
/** @var HackGuard\ModCon $mod */
|
110 |
-
$mod = $this->getMod();
|
111 |
-
/** @var Scanner\Select $selector */
|
112 |
-
$selector = $mod->getDbHandler_ScanResults()->getQuerySelector();
|
113 |
-
return $selector->filterByHash( $this->getScanItem()->hash )
|
114 |
-
->filterByScan( $this->getScanController()->getSlug() )
|
115 |
-
->first();
|
116 |
-
}
|
117 |
-
|
118 |
/**
|
119 |
* @return BaseRepair|mixed
|
120 |
*/
|
121 |
abstract public function getRepairer();
|
122 |
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
}
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultItem;
|
9 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanItemConsumer;
|
10 |
|
11 |
abstract class ItemActionHandler {
|
33 |
$success = $this->repair();
|
34 |
break;
|
35 |
|
36 |
+
case 'repair-delete':
|
37 |
+
$success = $this->repairDelete();
|
38 |
+
break;
|
39 |
+
|
40 |
default:
|
41 |
throw new \Exception( 'Unsupported Scan Item Action' );
|
|
|
42 |
}
|
43 |
return $success;
|
44 |
}
|
45 |
|
46 |
/**
|
|
|
47 |
* @return bool
|
48 |
* @throws \Exception
|
49 |
*/
|
50 |
public function delete() {
|
51 |
+
$item = $this->getScanItem();
|
52 |
+
if ( $this->getRepairer()->deleteItem() ) {
|
53 |
+
$item->repaired = true;
|
54 |
+
$item->repair_event_status = 'delete_success';
|
55 |
+
}
|
56 |
+
$this->fireRepairEvent();
|
57 |
+
return $item->repaired;
|
58 |
}
|
59 |
|
60 |
/**
|
62 |
* @throws \Exception
|
63 |
*/
|
64 |
public function ignore() {
|
65 |
+
if ( empty( $this->getScanItem()->VO ) ) {
|
|
|
|
|
66 |
throw new \Exception( 'Item could not be found to ignore.' );
|
67 |
}
|
68 |
|
70 |
$mod = $this->getMod();
|
71 |
/** @var Scanner\Update $updater */
|
72 |
$updater = $mod->getDbHandler_ScanResults()->getQueryUpdater();
|
73 |
+
if ( !$updater->setIgnored( $this->getScanItem()->VO ) ) {
|
74 |
throw new \Exception( 'Item could not be ignored at this time.' );
|
75 |
}
|
76 |
|
77 |
return true;
|
78 |
}
|
79 |
|
80 |
+
/**
|
81 |
+
* @return bool
|
82 |
+
* @throws \Exception
|
83 |
+
*/
|
84 |
+
public function repairDelete() :bool {
|
85 |
+
throw new \Exception( 'Certain items cannot be automatically bulk repaired / deleted.' );
|
86 |
+
}
|
87 |
+
|
88 |
/**
|
89 |
* @param bool $allowDelete
|
90 |
* @return bool
|
92 |
*/
|
93 |
public function repair( bool $allowDelete = false ) {
|
94 |
$repairer = $this->getRepairer();
|
95 |
+
|
96 |
+
$item = $this->getScanItem();
|
97 |
+
|
98 |
+
try {
|
99 |
+
$item->repaired = $repairer->repairItem();
|
100 |
}
|
101 |
+
catch ( \Exception $e ) {
|
102 |
+
$item->repaired = false;
|
103 |
+
}
|
104 |
+
$item->repair_event_status = $item->repaired ? 'repair_success' : 'repair_fail';
|
105 |
|
106 |
+
if ( $allowDelete && !$item->repaired && $repairer->deleteItem() ) {
|
107 |
+
$item->repaired = true;
|
108 |
+
$item->repair_event_status = 'delete_success';
|
109 |
+
}
|
110 |
|
111 |
+
$this->fireRepairEvent();
|
|
|
|
|
112 |
|
113 |
if ( $item->repaired ) {
|
114 |
/** @var HackGuard\ModCon $mod */
|
115 |
$mod = $this->getMod();
|
116 |
/** @var Scanner\Delete $deleter */
|
117 |
+
$mod->getDbHandler_ScanResults()
|
118 |
+
->getQueryDeleter()
|
119 |
+
->deleteById( $item->VO->id );
|
|
|
120 |
}
|
121 |
|
122 |
return $item->repaired;
|
123 |
}
|
124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
/**
|
126 |
* @return BaseRepair|mixed
|
127 |
*/
|
128 |
abstract public function getRepairer();
|
129 |
|
130 |
+
protected function fireRepairEvent() {
|
131 |
+
/** @var ResultItem $item */
|
132 |
+
$item = $this->getScanItem();
|
133 |
+
|
134 |
+
if ( !empty( $item->path_full ) && !empty( $item->repair_event_status ) ) {
|
135 |
+
$this->getCon()->fireEvent(
|
136 |
+
sprintf( 'scan_item_%s', $item->repair_event_status ),
|
137 |
+
[ 'audit' => [ 'path_full' => $item->path_full ] ]
|
138 |
+
);
|
139 |
+
}
|
140 |
+
}
|
141 |
}
|
src/lib/src/Scans/Base/Utilities/ItemActionHandlerAssets.php
CHANGED
@@ -21,15 +21,15 @@ abstract class ItemActionHandlerAssets extends ItemActionHandler {
|
|
21 |
switch ( $action ) {
|
22 |
|
23 |
case 'asset_deactivate':
|
24 |
-
$
|
25 |
break;
|
26 |
|
27 |
default:
|
28 |
-
$
|
29 |
break;
|
30 |
}
|
31 |
|
32 |
-
return $
|
33 |
}
|
34 |
|
35 |
/**
|
21 |
switch ( $action ) {
|
22 |
|
23 |
case 'asset_deactivate':
|
24 |
+
$success = $this->assetDeactivate();
|
25 |
break;
|
26 |
|
27 |
default:
|
28 |
+
$success = parent::process( $action );
|
29 |
break;
|
30 |
}
|
31 |
|
32 |
+
return $success;
|
33 |
}
|
34 |
|
35 |
/**
|
src/lib/src/Scans/Common/ScanActionConsumer.php
CHANGED
@@ -19,11 +19,11 @@ trait ScanActionConsumer {
|
|
19 |
}
|
20 |
|
21 |
/**
|
22 |
-
* @param BaseScanActionVO $
|
23 |
* @return $this
|
24 |
*/
|
25 |
-
public function setScanActionVO( $
|
26 |
-
$this->oScanActionVO = $
|
27 |
return $this;
|
28 |
}
|
29 |
}
|
19 |
}
|
20 |
|
21 |
/**
|
22 |
+
* @param BaseScanActionVO $action
|
23 |
* @return $this
|
24 |
*/
|
25 |
+
public function setScanActionVO( $action ) {
|
26 |
+
$this->oScanActionVO = $action;
|
27 |
return $this;
|
28 |
}
|
29 |
}
|
src/lib/src/Scans/Common/ScanItemConsumer.php
CHANGED
@@ -2,28 +2,28 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Common;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\
|
6 |
|
7 |
trait ScanItemConsumer {
|
8 |
|
9 |
/**
|
10 |
-
* @var
|
11 |
*/
|
12 |
-
private $
|
13 |
|
14 |
/**
|
15 |
-
* @return
|
16 |
*/
|
17 |
public function getScanItem() {
|
18 |
-
return $this->
|
19 |
}
|
20 |
|
21 |
/**
|
22 |
-
* @param
|
23 |
* @return $this
|
24 |
*/
|
25 |
-
public function setScanItem( $
|
26 |
-
$this->
|
27 |
return $this;
|
28 |
}
|
29 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Common;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultItem;
|
6 |
|
7 |
trait ScanItemConsumer {
|
8 |
|
9 |
/**
|
10 |
+
* @var ResultItem
|
11 |
*/
|
12 |
+
private $scanItem;
|
13 |
|
14 |
/**
|
15 |
+
* @return ResultItem|mixed
|
16 |
*/
|
17 |
public function getScanItem() {
|
18 |
+
return $this->scanItem;
|
19 |
}
|
20 |
|
21 |
/**
|
22 |
+
* @param ResultItem|mixed $item
|
23 |
* @return $this
|
24 |
*/
|
25 |
+
public function setScanItem( $item ) {
|
26 |
+
$this->scanItem = $item;
|
27 |
return $this;
|
28 |
}
|
29 |
}
|
src/lib/src/Scans/Helpers/CopyResultsSets.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\
|
6 |
|
7 |
/**
|
8 |
* Class CopyResultsSets
|
@@ -11,8 +11,8 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseResultsSet;
|
|
11 |
class CopyResultsSets {
|
12 |
|
13 |
/**
|
14 |
-
* @param
|
15 |
-
* @param
|
16 |
*/
|
17 |
public function copyTo( $oFromRS1, $oToRS2 ) {
|
18 |
foreach ( $oFromRS1->getAllItems() as $oIt ) {
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultsSet;
|
6 |
|
7 |
/**
|
8 |
* Class CopyResultsSets
|
11 |
class CopyResultsSets {
|
12 |
|
13 |
/**
|
14 |
+
* @param ResultsSet $oFromRS1
|
15 |
+
* @param ResultsSet $oToRS2
|
16 |
*/
|
17 |
public function copyTo( $oFromRS1, $oToRS2 ) {
|
18 |
foreach ( $oFromRS1->getAllItems() as $oIt ) {
|
src/lib/src/Scans/Helpers/MergeResultsSets.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\
|
6 |
|
7 |
/**
|
8 |
* Class MergeResultsSets
|
@@ -11,9 +11,9 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseResultsSet;
|
|
11 |
class MergeResultsSets {
|
12 |
|
13 |
/**
|
14 |
-
* @param
|
15 |
-
* @param
|
16 |
-
* @return
|
17 |
*/
|
18 |
public function merge( $oRs1, $oRs2 ) {
|
19 |
$oNewRs = clone $oRs1;
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultsSet;
|
6 |
|
7 |
/**
|
8 |
* Class MergeResultsSets
|
11 |
class MergeResultsSets {
|
12 |
|
13 |
/**
|
14 |
+
* @param ResultsSet $oRs1
|
15 |
+
* @param ResultsSet $oRs2
|
16 |
+
* @return ResultsSet
|
17 |
*/
|
18 |
public function merge( $oRs1, $oRs2 ) {
|
19 |
$oNewRs = clone $oRs1;
|
src/lib/src/Scans/Helpers/WpCoreFile.php
CHANGED
@@ -22,21 +22,21 @@ class WpCoreFile {
|
|
22 |
protected $sVersion;
|
23 |
|
24 |
/**
|
25 |
-
* @param string $
|
26 |
* @return bool
|
27 |
*/
|
28 |
-
public function replace( $
|
29 |
-
$
|
30 |
-
if ( Services::CoreFileHashes()->isCoreFile( $
|
31 |
$oFiles = Services::WpGeneral()->isClassicPress() ? new WpOrg\Cp\Files() : new WpOrg\Wp\Files();
|
32 |
try {
|
33 |
-
$oFiles->replaceFileFromVcs( $
|
34 |
-
$
|
35 |
}
|
36 |
catch ( \InvalidArgumentException $e ) {
|
37 |
}
|
38 |
}
|
39 |
-
return $
|
40 |
}
|
41 |
|
42 |
/**
|
22 |
protected $sVersion;
|
23 |
|
24 |
/**
|
25 |
+
* @param string $path
|
26 |
* @return bool
|
27 |
*/
|
28 |
+
public function replace( $path ) :bool {
|
29 |
+
$success = false;
|
30 |
+
if ( Services::CoreFileHashes()->isCoreFile( $path ) ) {
|
31 |
$oFiles = Services::WpGeneral()->isClassicPress() ? new WpOrg\Cp\Files() : new WpOrg\Wp\Files();
|
32 |
try {
|
33 |
+
$oFiles->replaceFileFromVcs( $path );
|
34 |
+
$success = true;
|
35 |
}
|
36 |
catch ( \InvalidArgumentException $e ) {
|
37 |
}
|
38 |
}
|
39 |
+
return $success;
|
40 |
}
|
41 |
|
42 |
/**
|
src/lib/src/Scans/Mal/BuildFileMap.php
CHANGED
@@ -2,16 +2,11 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanActionConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
|
7 |
|
8 |
-
|
9 |
-
* Class BuildFileMap
|
10 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal
|
11 |
-
*/
|
12 |
-
class BuildFileMap {
|
13 |
-
|
14 |
-
use ScanActionConsumer;
|
15 |
|
16 |
/**
|
17 |
* @return string[]
|
@@ -27,10 +22,10 @@ class BuildFileMap {
|
|
27 |
try {
|
28 |
foreach ( StandardDirectoryIterator::create( $scanDir, (int)$depth, $action->file_exts, false ) as $item ) {
|
29 |
/** @var \SplFileInfo $item */
|
30 |
-
$
|
31 |
try {
|
32 |
-
if ( !$this->isWhitelistedPath( $
|
33 |
-
$files[] = $
|
34 |
}
|
35 |
}
|
36 |
catch ( \Exception $e ) {
|
@@ -66,18 +61,4 @@ class BuildFileMap {
|
|
66 |
$action->paths_whitelisted = [];
|
67 |
}
|
68 |
}
|
69 |
-
|
70 |
-
private function isWhitelistedPath( string $path ) :bool {
|
71 |
-
$whitelisted = false;
|
72 |
-
|
73 |
-
/** @var ScanActionVO $oAction */
|
74 |
-
$oAction = $this->getScanActionVO();
|
75 |
-
foreach ( $oAction->paths_whitelisted as $sWlPath ) {
|
76 |
-
if ( stripos( $path, $sWlPath ) === 0 ) {
|
77 |
-
$whitelisted = true;
|
78 |
-
break;
|
79 |
-
}
|
80 |
-
}
|
81 |
-
return $whitelisted;
|
82 |
-
}
|
83 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseBuildFileMap;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanActionConsumer;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
|
8 |
|
9 |
+
class BuildFileMap extends BaseBuildFileMap {
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
/**
|
12 |
* @return string[]
|
22 |
try {
|
23 |
foreach ( StandardDirectoryIterator::create( $scanDir, (int)$depth, $action->file_exts, false ) as $item ) {
|
24 |
/** @var \SplFileInfo $item */
|
25 |
+
$path = wp_normalize_path( $item->getPathname() );
|
26 |
try {
|
27 |
+
if ( !$this->isWhitelistedPath( $path ) && !$this->isAutoFilterFile( $item ) ) {
|
28 |
+
$files[] = $path;
|
29 |
}
|
30 |
}
|
31 |
catch ( \Exception $e ) {
|
61 |
$action->paths_whitelisted = [];
|
62 |
}
|
63 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
}
|
src/lib/src/Scans/Mal/BuildScanAction.php
CHANGED
@@ -8,20 +8,17 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
|
8 |
class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
|
9 |
|
10 |
protected function buildItems() {
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
->setScanActionVO( $oAction )
|
15 |
->build();
|
|
|
|
|
16 |
}
|
17 |
|
18 |
protected function setCustomFields() {
|
19 |
-
/** @var ScanActionVO $
|
20 |
-
$
|
21 |
-
|
22 |
-
$oOpts = $this->getOptions();
|
23 |
-
|
24 |
-
$oAction->paths_whitelisted = $oOpts->getMalWhitelistPaths();
|
25 |
-
$oAction->file_exts = [ 'php', 'php5', 'php7' ];
|
26 |
}
|
27 |
}
|
8 |
class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
|
9 |
|
10 |
protected function buildItems() {
|
11 |
+
$items = ( new BuildFileMap() )
|
12 |
+
->setMod( $this->getMod() )
|
13 |
+
->setScanActionVO( $this->getScanActionVO() )
|
|
|
14 |
->build();
|
15 |
+
asort( $items );
|
16 |
+
$this->getScanActionVO()->items = $items;
|
17 |
}
|
18 |
|
19 |
protected function setCustomFields() {
|
20 |
+
/** @var ScanActionVO $action */
|
21 |
+
$action = $this->getScanActionVO();
|
22 |
+
$action->file_exts = [ 'php', 'php5', 'php7' ];
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
}
|
src/lib/src/Scans/Mal/FileScanner.php
CHANGED
@@ -11,10 +11,6 @@ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
|
|
11 |
use FernleafSystems\Wordpress\Services\Services;
|
12 |
use FernleafSystems\Wordpress\Services\Utilities;
|
13 |
|
14 |
-
/**
|
15 |
-
* Class FileScanner
|
16 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal
|
17 |
-
*/
|
18 |
class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
19 |
|
20 |
/**
|
@@ -43,27 +39,28 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
43 |
foreach ( $action->patterns_simple as $signature ) {
|
44 |
$item = $this->scanForSig( $signature );
|
45 |
if ( $item instanceof ResultItem ) {
|
46 |
-
|
47 |
}
|
48 |
}
|
49 |
}
|
50 |
|
51 |
-
|
52 |
-
|
53 |
$this->locator->setIsRegEx( true );
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
58 |
}
|
59 |
}
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
return $item;
|
67 |
}
|
68 |
}
|
69 |
}
|
11 |
use FernleafSystems\Wordpress\Services\Services;
|
12 |
use FernleafSystems\Wordpress\Services\Utilities;
|
13 |
|
|
|
|
|
|
|
|
|
14 |
class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
15 |
|
16 |
/**
|
39 |
foreach ( $action->patterns_simple as $signature ) {
|
40 |
$item = $this->scanForSig( $signature );
|
41 |
if ( $item instanceof ResultItem ) {
|
42 |
+
break;
|
43 |
}
|
44 |
}
|
45 |
}
|
46 |
|
47 |
+
if ( !$item instanceof ResultItem ) {
|
48 |
+
// RegEx Patterns
|
49 |
$this->locator->setIsRegEx( true );
|
50 |
+
if ( empty( $action->patterns_fullregex ) ) {
|
51 |
+
foreach ( $action->patterns_regex as $signature ) {
|
52 |
+
$item = $this->scanForSig( $signature );
|
53 |
+
if ( $item instanceof ResultItem ) {
|
54 |
+
break;
|
55 |
+
}
|
56 |
}
|
57 |
}
|
58 |
+
else { // Full regex patterns
|
59 |
+
foreach ( $action->patterns_fullregex as $signature ) {
|
60 |
+
$item = $this->scanForSig( $signature );
|
61 |
+
if ( $item instanceof ResultItem ) {
|
62 |
+
break;
|
63 |
+
}
|
|
|
64 |
}
|
65 |
}
|
66 |
}
|
src/lib/src/Scans/Mal/ResultItem.php
CHANGED
@@ -5,14 +5,12 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
|
|
5 |
/**
|
6 |
* Class ResultItem
|
7 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal
|
8 |
-
* @property string $path_full
|
9 |
-
* @property string $path_fragment - relative to ABSPATH
|
10 |
* @property bool $is_mal
|
11 |
* @property string $mal_sig
|
12 |
* @property int[] $file_lines
|
13 |
* @property int $fp_confidence - false positive confidence level
|
14 |
*/
|
15 |
-
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\
|
16 |
|
17 |
public function generateHash() :string {
|
18 |
return md5( $this->path_full );
|
5 |
/**
|
6 |
* Class ResultItem
|
7 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal
|
|
|
|
|
8 |
* @property bool $is_mal
|
9 |
* @property string $mal_sig
|
10 |
* @property int[] $file_lines
|
11 |
* @property int $fp_confidence - false positive confidence level
|
12 |
*/
|
13 |
+
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
|
14 |
|
15 |
public function generateHash() :string {
|
16 |
return md5( $this->path_full );
|
src/lib/src/Scans/Mal/ResultsSet.php
CHANGED
@@ -9,7 +9,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal
|
11 |
*/
|
12 |
-
class ResultsSet extends Base\
|
13 |
|
14 |
/**
|
15 |
* @param ResultItem[] $aItems
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal
|
11 |
*/
|
12 |
+
class ResultsSet extends Base\ResultsSet {
|
13 |
|
14 |
/**
|
15 |
* @param ResultItem[] $aItems
|
src/lib/src/Scans/Mal/ScanActionVO.php
CHANGED
@@ -16,5 +16,5 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
|
|
16 |
class ScanActionVO extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO {
|
17 |
|
18 |
const QUEUE_GROUP_SIZE_LIMIT = 50;
|
19 |
-
const DEFAULT_SLEEP_SECONDS = 1;
|
20 |
}
|
16 |
class ScanActionVO extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO {
|
17 |
|
18 |
const QUEUE_GROUP_SIZE_LIMIT = 50;
|
19 |
+
const DEFAULT_SLEEP_SECONDS = 0.1;
|
20 |
}
|
src/lib/src/Scans/Mal/Utilities/ItemActionHandler.php
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal\Utilities;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
|
|
|
7 |
|
8 |
class ItemActionHandler extends Base\Utilities\ItemActionHandler {
|
9 |
|
@@ -21,6 +22,14 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandler {
|
|
21 |
return true;
|
22 |
}
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
/**
|
25 |
* @return Repair
|
26 |
*/
|
@@ -29,16 +38,4 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandler {
|
|
29 |
->setScanItem( $this->getScanItem() )
|
30 |
->setMod( $this->getMod() );
|
31 |
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* @param bool $success
|
35 |
-
*/
|
36 |
-
protected function fireRepairEvent( $success ) {
|
37 |
-
/** @var Mal\ResultItem $oItem */
|
38 |
-
$oItem = $this->getScanItem();
|
39 |
-
$this->getCon()->fireEvent(
|
40 |
-
$this->getScanController()->getSlug().'_item_repair_'.( $success ? 'success' : 'fail' ),
|
41 |
-
[ 'audit' => [ 'fragment' => $oItem->path_full ] ]
|
42 |
-
);
|
43 |
-
}
|
44 |
}
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal\Utilities;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
|
7 |
+
use FernleafSystems\Wordpress\Services\Utilities\WpOrg;
|
8 |
|
9 |
class ItemActionHandler extends Base\Utilities\ItemActionHandler {
|
10 |
|
22 |
return true;
|
23 |
}
|
24 |
|
25 |
+
/**
|
26 |
+
* @return bool
|
27 |
+
* @throws \Exception
|
28 |
+
*/
|
29 |
+
public function repairDelete() :bool {
|
30 |
+
return $this->repair( true );
|
31 |
+
}
|
32 |
+
|
33 |
/**
|
34 |
* @return Repair
|
35 |
*/
|
38 |
->setScanItem( $this->getScanItem() )
|
39 |
->setMod( $this->getMod() );
|
40 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
}
|
src/lib/src/Scans/Mal/Utilities/Patterns.php
CHANGED
@@ -22,7 +22,7 @@ class Patterns {
|
|
22 |
$mod = $this->getMod();
|
23 |
|
24 |
$cacher = new Cache\CacheDefVO();
|
25 |
-
$cacher->dir = $mod->
|
26 |
if ( !empty( $cacher->dir ) ) {
|
27 |
$cacher->file_fragment = 'cache_patterns.txt';
|
28 |
$cacher->expiration = HOUR_IN_SECONDS;
|
@@ -50,9 +50,11 @@ class Patterns {
|
|
50 |
}
|
51 |
|
52 |
$cacher->data = $patterns;
|
53 |
-
(
|
54 |
-
|
55 |
-
|
|
|
|
|
56 |
}
|
57 |
|
58 |
return $cacher->data;
|
22 |
$mod = $this->getMod();
|
23 |
|
24 |
$cacher = new Cache\CacheDefVO();
|
25 |
+
$cacher->dir = $mod->getScansTempDir();
|
26 |
if ( !empty( $cacher->dir ) ) {
|
27 |
$cacher->file_fragment = 'cache_patterns.txt';
|
28 |
$cacher->expiration = HOUR_IN_SECONDS;
|
50 |
}
|
51 |
|
52 |
$cacher->data = $patterns;
|
53 |
+
if ( !empty( $cacher->dir ) ) {
|
54 |
+
( new Cache\StoreToCache() )
|
55 |
+
->setCacheDef( $cacher )
|
56 |
+
->store();
|
57 |
+
}
|
58 |
}
|
59 |
|
60 |
return $cacher->data;
|
src/lib/src/Scans/Mal/Utilities/Repair.php
CHANGED
@@ -15,10 +15,7 @@ class Repair extends Shield\Scans\Base\Utilities\BaseRepair {
|
|
15 |
|
16 |
use Shield\Modules\ModConsumer;
|
17 |
|
18 |
-
|
19 |
-
* @return bool
|
20 |
-
*/
|
21 |
-
public function repairItem() {
|
22 |
/** @var ResultItem $item */
|
23 |
$item = $this->getScanItem();
|
24 |
/** @var Shield\Modules\HackGuard\Options $opts */
|
@@ -35,32 +32,28 @@ class Repair extends Shield\Scans\Base\Utilities\BaseRepair {
|
|
35 |
if ( $canRepair ) {
|
36 |
|
37 |
if ( Services\Services::CoreFileHashes()->isCoreFile( $item->path_fragment ) ) {
|
38 |
-
$success = $this->repairCoreItem(
|
39 |
}
|
40 |
else {
|
41 |
$plugin = ( new WpOrg\Plugin\Files() )->findPluginFromFile( $item->path_full );
|
42 |
if ( $plugin instanceof Services\Core\VOs\Assets\WpPluginVo && $plugin->isWpOrg() ) {
|
43 |
|
44 |
-
$success = $this->repairItemInPlugin(
|
45 |
}
|
46 |
else {
|
47 |
$theme = ( new WpOrg\Theme\Files() )->findThemeFromFile( $item->path_full );
|
48 |
if ( $theme instanceof Services\Core\VOs\Assets\WpThemeVo && $theme->isWpOrg() ) {
|
49 |
|
50 |
-
$success = $this->repairItemInTheme(
|
51 |
}
|
52 |
elseif ( $opts->isMalAutoRepairSurgical() ) {
|
53 |
-
$success = $this->repairSurgicalItem(
|
54 |
}
|
55 |
}
|
56 |
}
|
57 |
}
|
58 |
-
elseif ( $this->isAllowDelete() ) {
|
59 |
-
$success = $this->repairItemByDelete( $item );
|
60 |
-
}
|
61 |
|
62 |
if ( $success ) {
|
63 |
-
// 1) Report the file as being malware.
|
64 |
( new Shield\Scans\Mal\Utilities\FalsePositiveReporter() )
|
65 |
->setMod( $this->getMod() )
|
66 |
->reportResultItem( $item, false );
|
@@ -69,59 +62,58 @@ class Repair extends Shield\Scans\Base\Utilities\BaseRepair {
|
|
69 |
return $success;
|
70 |
}
|
71 |
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
private function repairItemByDelete( $item ) {
|
77 |
-
return Services\Services::WpFs()->deleteFile( $item->path_full );
|
78 |
}
|
79 |
|
80 |
/**
|
81 |
* @return bool
|
82 |
* @throws \Exception
|
83 |
*/
|
84 |
-
public function canRepair() {
|
85 |
return $this->canAutoRepairFromSource( $this->getScanItem() );
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
* Can only repair a WP Core file, or a plugin that is WP.org, has no update available
|
90 |
* and the latest version uses SVN tags.
|
91 |
-
* @param ResultItem $
|
92 |
* @return bool
|
93 |
* @throws \Exception
|
94 |
*/
|
95 |
-
public function canAutoRepairFromSource( $
|
96 |
-
$bCanRepair = Services\Services::CoreFileHashes()->isCoreFile( $oItem->path_fragment );
|
97 |
-
if ( !$bCanRepair ) {
|
98 |
|
99 |
-
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
102 |
throw new \Exception( sprintf(
|
103 |
__( "%s not installed from WordPress.org.", 'wp-simple-firewall' ),
|
104 |
__( 'Plugin', 'wp-simple-firewall' )
|
105 |
)
|
106 |
);
|
107 |
}
|
108 |
-
if ( !$
|
109 |
throw new \Exception( __( "Plugin developer doesn't use SVN tags for official releases.", 'wp-simple-firewall' ) );
|
110 |
}
|
111 |
|
112 |
-
$
|
113 |
}
|
114 |
else {
|
115 |
-
$
|
116 |
-
if ( $
|
117 |
-
if ( $
|
118 |
throw new \Exception( sprintf(
|
119 |
__( "%s is a child of another theme.", 'wp-simple-firewall' ),
|
120 |
__( 'Theme', 'wp-simple-firewall' )
|
121 |
)
|
122 |
);
|
123 |
}
|
124 |
-
if ( !$
|
125 |
throw new \Exception( sprintf(
|
126 |
__( "%s not installed from WordPress.org.", 'wp-simple-firewall' ),
|
127 |
__( 'Theme', 'wp-simple-firewall' )
|
@@ -129,67 +121,61 @@ class Repair extends Shield\Scans\Base\Utilities\BaseRepair {
|
|
129 |
);
|
130 |
}
|
131 |
if ( !( new WpOrg\Theme\Versions() )
|
132 |
-
->setWorkingSlug( $
|
133 |
-
->exists( $
|
134 |
throw new \Exception( __( "Theme version doesn't appear to exist.", 'wp-simple-firewall' ) );
|
135 |
}
|
136 |
|
137 |
-
$
|
138 |
}
|
139 |
}
|
140 |
}
|
141 |
|
142 |
-
return $
|
143 |
}
|
144 |
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
$oFiles = Services\Services::WpGeneral()->isClassicPress() ? new WpOrg\Cp\Files() : new WpOrg\Wp\Files();
|
151 |
try {
|
152 |
-
$
|
153 |
}
|
154 |
catch ( \InvalidArgumentException $e ) {
|
155 |
-
$
|
156 |
}
|
157 |
-
return $
|
158 |
}
|
159 |
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
$
|
166 |
-
foreach ( $oItem->file_lines as $nLine ) {
|
167 |
try {
|
168 |
-
( new Services\Utilities\File\RemoveLineFromFile() )->run( $
|
169 |
-
$
|
170 |
}
|
171 |
catch ( \Exception $e ) {
|
172 |
-
$
|
173 |
break;
|
174 |
}
|
175 |
}
|
176 |
-
return $
|
177 |
}
|
178 |
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
private function repairItemInPlugin( $oItem ) {
|
184 |
$success = false;
|
185 |
|
186 |
-
$
|
187 |
try {
|
188 |
-
if ( $
|
189 |
-
$success = $
|
190 |
-
}
|
191 |
-
elseif ( $this->isAllowDelete() ) {
|
192 |
-
$success = (bool)Services\Services::WpFs()->deleteFile( $oItem->path_full );
|
193 |
}
|
194 |
}
|
195 |
catch ( \InvalidArgumentException $e ) {
|
@@ -198,20 +184,16 @@ class Repair extends Shield\Scans\Base\Utilities\BaseRepair {
|
|
198 |
return $success;
|
199 |
}
|
200 |
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
private function repairItemInTheme( $oItem ) {
|
206 |
$success = false;
|
207 |
|
208 |
-
$
|
209 |
try {
|
210 |
-
if ( $
|
211 |
-
$success = $
|
212 |
-
}
|
213 |
-
elseif ( $this->isAllowDelete() ) {
|
214 |
-
$success = (bool)Services\Services::WpFs()->deleteFile( $oItem->path_full );
|
215 |
}
|
216 |
}
|
217 |
catch ( \InvalidArgumentException $e ) {
|
15 |
|
16 |
use Shield\Modules\ModConsumer;
|
17 |
|
18 |
+
public function repairItem() :bool {
|
|
|
|
|
|
|
19 |
/** @var ResultItem $item */
|
20 |
$item = $this->getScanItem();
|
21 |
/** @var Shield\Modules\HackGuard\Options $opts */
|
32 |
if ( $canRepair ) {
|
33 |
|
34 |
if ( Services\Services::CoreFileHashes()->isCoreFile( $item->path_fragment ) ) {
|
35 |
+
$success = $this->repairCoreItem();
|
36 |
}
|
37 |
else {
|
38 |
$plugin = ( new WpOrg\Plugin\Files() )->findPluginFromFile( $item->path_full );
|
39 |
if ( $plugin instanceof Services\Core\VOs\Assets\WpPluginVo && $plugin->isWpOrg() ) {
|
40 |
|
41 |
+
$success = $this->repairItemInPlugin();
|
42 |
}
|
43 |
else {
|
44 |
$theme = ( new WpOrg\Theme\Files() )->findThemeFromFile( $item->path_full );
|
45 |
if ( $theme instanceof Services\Core\VOs\Assets\WpThemeVo && $theme->isWpOrg() ) {
|
46 |
|
47 |
+
$success = $this->repairItemInTheme();
|
48 |
}
|
49 |
elseif ( $opts->isMalAutoRepairSurgical() ) {
|
50 |
+
$success = $this->repairSurgicalItem();
|
51 |
}
|
52 |
}
|
53 |
}
|
54 |
}
|
|
|
|
|
|
|
55 |
|
56 |
if ( $success ) {
|
|
|
57 |
( new Shield\Scans\Mal\Utilities\FalsePositiveReporter() )
|
58 |
->setMod( $this->getMod() )
|
59 |
->reportResultItem( $item, false );
|
62 |
return $success;
|
63 |
}
|
64 |
|
65 |
+
public function deleteItem() :bool {
|
66 |
+
/** @var ResultItem $item */
|
67 |
+
$item = $this->getScanItem();
|
68 |
+
return (bool)Services\Services::WpFs()->deleteFile( $item->path_full );
|
|
|
|
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
* @return bool
|
73 |
* @throws \Exception
|
74 |
*/
|
75 |
+
public function canRepair() :bool {
|
76 |
return $this->canAutoRepairFromSource( $this->getScanItem() );
|
77 |
}
|
78 |
|
79 |
/**
|
80 |
* Can only repair a WP Core file, or a plugin that is WP.org, has no update available
|
81 |
* and the latest version uses SVN tags.
|
82 |
+
* @param ResultItem $item
|
83 |
* @return bool
|
84 |
* @throws \Exception
|
85 |
*/
|
86 |
+
public function canAutoRepairFromSource( ResultItem $item ) :bool {
|
|
|
|
|
87 |
|
88 |
+
$canRepair = Services\Services::CoreFileHashes()->isCoreFile( $item->path_fragment );
|
89 |
+
if ( !$canRepair ) {
|
90 |
+
|
91 |
+
$plugin = ( new WpOrg\Plugin\Files() )->findPluginFromFile( $item->path_full );
|
92 |
+
if ( !empty( $plugin ) ) {
|
93 |
+
if ( !$plugin->isWpOrg() ) {
|
94 |
throw new \Exception( sprintf(
|
95 |
__( "%s not installed from WordPress.org.", 'wp-simple-firewall' ),
|
96 |
__( 'Plugin', 'wp-simple-firewall' )
|
97 |
)
|
98 |
);
|
99 |
}
|
100 |
+
if ( !$plugin->svn_uses_tags ) {
|
101 |
throw new \Exception( __( "Plugin developer doesn't use SVN tags for official releases.", 'wp-simple-firewall' ) );
|
102 |
}
|
103 |
|
104 |
+
$canRepair = true;
|
105 |
}
|
106 |
else {
|
107 |
+
$theme = ( new WpOrg\Theme\Files() )->findThemeFromFile( $item->path_full );
|
108 |
+
if ( !empty( $theme ) ) {
|
109 |
+
if ( $theme->is_child ) {
|
110 |
throw new \Exception( sprintf(
|
111 |
__( "%s is a child of another theme.", 'wp-simple-firewall' ),
|
112 |
__( 'Theme', 'wp-simple-firewall' )
|
113 |
)
|
114 |
);
|
115 |
}
|
116 |
+
if ( !$theme->isWpOrg() ) {
|
117 |
throw new \Exception( sprintf(
|
118 |
__( "%s not installed from WordPress.org.", 'wp-simple-firewall' ),
|
119 |
__( 'Theme', 'wp-simple-firewall' )
|
121 |
);
|
122 |
}
|
123 |
if ( !( new WpOrg\Theme\Versions() )
|
124 |
+
->setWorkingSlug( $theme->stylesheet )
|
125 |
+
->exists( $theme->version, true ) ) {
|
126 |
throw new \Exception( __( "Theme version doesn't appear to exist.", 'wp-simple-firewall' ) );
|
127 |
}
|
128 |
|
129 |
+
$canRepair = true;
|
130 |
}
|
131 |
}
|
132 |
}
|
133 |
|
134 |
+
return $canRepair;
|
135 |
}
|
136 |
|
137 |
+
private function repairCoreItem() :bool {
|
138 |
+
/** @var ResultItem $item */
|
139 |
+
$item = $this->getScanItem();
|
140 |
+
|
141 |
+
$files = Services\Services::WpGeneral()->isClassicPress() ? new WpOrg\Cp\Files() : new WpOrg\Wp\Files();
|
|
|
142 |
try {
|
143 |
+
$success = $files->replaceFileFromVcs( $item->path_fragment );
|
144 |
}
|
145 |
catch ( \InvalidArgumentException $e ) {
|
146 |
+
$success = false;
|
147 |
}
|
148 |
+
return $success;
|
149 |
}
|
150 |
|
151 |
+
private function repairSurgicalItem() :bool {
|
152 |
+
/** @var ResultItem $item */
|
153 |
+
$item = $this->getScanItem();
|
154 |
+
|
155 |
+
$success = false;
|
156 |
+
foreach ( $item->file_lines as $nLine ) {
|
|
|
157 |
try {
|
158 |
+
( new Services\Utilities\File\RemoveLineFromFile() )->run( $item->path_full, $nLine );
|
159 |
+
$success = true;
|
160 |
}
|
161 |
catch ( \Exception $e ) {
|
162 |
+
$success = false;
|
163 |
break;
|
164 |
}
|
165 |
}
|
166 |
+
return $success;
|
167 |
}
|
168 |
|
169 |
+
private function repairItemInPlugin() :bool {
|
170 |
+
/** @var ResultItem $item */
|
171 |
+
$item = $this->getScanItem();
|
172 |
+
|
|
|
173 |
$success = false;
|
174 |
|
175 |
+
$files = new WpOrg\Plugin\Files();
|
176 |
try {
|
177 |
+
if ( $files->isValidFileFromPlugin( $item->path_full ) ) {
|
178 |
+
$success = $files->replaceFileFromVcs( $item->path_full );
|
|
|
|
|
|
|
179 |
}
|
180 |
}
|
181 |
catch ( \InvalidArgumentException $e ) {
|
184 |
return $success;
|
185 |
}
|
186 |
|
187 |
+
private function repairItemInTheme() :bool {
|
188 |
+
/** @var ResultItem $item */
|
189 |
+
$item = $this->getScanItem();
|
190 |
+
|
|
|
191 |
$success = false;
|
192 |
|
193 |
+
$files = new WpOrg\Theme\Files();
|
194 |
try {
|
195 |
+
if ( $files->isValidFileFromTheme( $item->path_full ) ) {
|
196 |
+
$success = $files->replaceFileFromVcs( $item->path_full );
|
|
|
|
|
|
|
197 |
}
|
198 |
}
|
199 |
catch ( \InvalidArgumentException $e ) {
|
src/lib/src/Scans/Ptg/BuildFileMap.php
CHANGED
@@ -2,35 +2,30 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans\
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
-
|
10 |
-
* Class BuildFileMap
|
11 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
|
12 |
-
*/
|
13 |
-
class BuildFileMap {
|
14 |
-
|
15 |
-
use ScanActionConsumer;
|
16 |
|
17 |
/**
|
18 |
* @return string[]
|
19 |
*/
|
20 |
-
public function build() {
|
21 |
-
$
|
22 |
|
23 |
-
/** @var ScanActionVO $
|
24 |
-
$
|
25 |
|
26 |
-
$
|
27 |
-
foreach ( $this->getScanRoots() as $
|
28 |
try {
|
29 |
-
foreach ( StandardDirectoryIterator::create( $
|
30 |
-
/** @var \SplFileInfo $
|
|
|
31 |
try {
|
32 |
-
if (
|
33 |
-
$
|
34 |
}
|
35 |
}
|
36 |
catch ( \Exception $e ) {
|
@@ -40,34 +35,31 @@ class BuildFileMap {
|
|
40 |
catch ( \Exception $e ) {
|
41 |
error_log(
|
42 |
sprintf( 'Shield file scanner (%s) attempted to read directory (%s) but there was error: "%s".',
|
43 |
-
$
|
44 |
);
|
45 |
}
|
46 |
}
|
47 |
|
48 |
-
return $
|
49 |
}
|
50 |
|
51 |
-
|
52 |
-
|
53 |
-
*/
|
54 |
-
private function getScanRoots() {
|
55 |
-
$aRoots = [];
|
56 |
|
57 |
-
$
|
58 |
-
foreach ( $
|
59 |
-
if ( $
|
60 |
-
$
|
61 |
}
|
62 |
}
|
63 |
|
64 |
-
$
|
65 |
-
$
|
66 |
-
$
|
67 |
-
if ( $
|
68 |
-
$
|
69 |
}
|
70 |
|
71 |
-
return $
|
72 |
}
|
73 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseBuildFileMap;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
+
class BuildFileMap extends BaseBuildFileMap {
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
/**
|
12 |
* @return string[]
|
13 |
*/
|
14 |
+
public function build() :array {
|
15 |
+
$files = [];
|
16 |
|
17 |
+
/** @var ScanActionVO $action */
|
18 |
+
$action = $this->getScanActionVO();
|
19 |
|
20 |
+
$abspath = wp_normalize_path( ABSPATH );
|
21 |
+
foreach ( $this->getScanRoots() as $dir ) {
|
22 |
try {
|
23 |
+
foreach ( StandardDirectoryIterator::create( $dir, 0, $action->file_exts ) as $item ) {
|
24 |
+
/** @var \SplFileInfo $item */
|
25 |
+
$path = wp_normalize_path( $item->getPathname() );
|
26 |
try {
|
27 |
+
if ( !$this->isWhitelistedPath( $path ) && !$this->isAutoFilterFile( $item ) ) {
|
28 |
+
$files[] = str_replace( $abspath, '', $path );
|
29 |
}
|
30 |
}
|
31 |
catch ( \Exception $e ) {
|
35 |
catch ( \Exception $e ) {
|
36 |
error_log(
|
37 |
sprintf( 'Shield file scanner (%s) attempted to read directory (%s) but there was error: "%s".',
|
38 |
+
$action->scan, $dir, $e->getMessage() )
|
39 |
);
|
40 |
}
|
41 |
}
|
42 |
|
43 |
+
return $files;
|
44 |
}
|
45 |
|
46 |
+
private function getScanRoots() :array {
|
47 |
+
$roots = [];
|
|
|
|
|
|
|
48 |
|
49 |
+
$WPP = Services::WpPlugins();
|
50 |
+
foreach ( $WPP->getPluginsAsVo() as $plugin ) {
|
51 |
+
if ( $plugin->active ) {
|
52 |
+
$roots[] = $plugin->getInstallDir();
|
53 |
}
|
54 |
}
|
55 |
|
56 |
+
$WPT = Services::WpThemes();
|
57 |
+
$current = $WPT->getCurrent();
|
58 |
+
$roots[] = $current->get_stylesheet_directory();
|
59 |
+
if ( $WPT->isActiveThemeAChild() ) {
|
60 |
+
$roots[] = $current->get_template_directory();
|
61 |
}
|
62 |
|
63 |
+
return $roots;
|
64 |
}
|
65 |
}
|
src/lib/src/Scans/Ptg/BuildScanAction.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
|
4 |
|
@@ -7,27 +7,22 @@ use FernleafSystems\Wordpress\Plugin\Shield;
|
|
7 |
class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
|
8 |
|
9 |
protected function buildItems() {
|
10 |
-
/** @var ScanActionVO $
|
11 |
-
$
|
12 |
-
$
|
13 |
-
->
|
|
|
14 |
->build();
|
15 |
}
|
16 |
|
17 |
protected function setCustomFields() {
|
18 |
-
/** @var ScanActionVO $
|
19 |
-
$
|
20 |
-
$
|
21 |
}
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
private function getFileExts() {
|
27 |
-
$aFileExts = apply_filters(
|
28 |
-
$this->getCon()->prefix( 'scan_ptg_file_exts' ),
|
29 |
-
[ 'js', 'json', 'otf', 'svg', 'ttf', 'eot', 'woff', 'woff2', 'php', 'php5', 'php7', 'phtml' ]
|
30 |
-
);
|
31 |
-
return is_array( $aFileExts ) ? $aFileExts : [];
|
32 |
}
|
33 |
}
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
|
4 |
|
7 |
class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
|
8 |
|
9 |
protected function buildItems() {
|
10 |
+
/** @var ScanActionVO $action */
|
11 |
+
$action = $this->getScanActionVO();
|
12 |
+
$action->items = ( new BuildFileMap() )
|
13 |
+
->setMod( $this->getMod() )
|
14 |
+
->setScanActionVO( $action )
|
15 |
->build();
|
16 |
}
|
17 |
|
18 |
protected function setCustomFields() {
|
19 |
+
/** @var ScanActionVO $action */
|
20 |
+
$action = $this->getScanActionVO();
|
21 |
+
$action->file_exts = $this->getFileExts();
|
22 |
}
|
23 |
|
24 |
+
private function getFileExts() :array {
|
25 |
+
$ext = apply_filters( 'shield/scan_ptg_file_exts', $this->getOptions()->getDef( 'file_scan_extensions' ) );
|
26 |
+
return is_array( $ext ) ? $ext : $this->getOptions()->getDef( 'file_scan_extensions' );
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
}
|
src/lib/src/Scans/Ptg/FileScanner.php
CHANGED
@@ -6,6 +6,7 @@ use FernleafSystems\Wordpress\Plugin\Shield;
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib;
|
7 |
use FernleafSystems\Wordpress\Services\Core\VOs\Assets;
|
8 |
use FernleafSystems\Wordpress\Services\Utilities\File\Compare\CompareHash;
|
|
|
9 |
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Query;
|
10 |
use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
|
11 |
use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
|
@@ -21,13 +22,14 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
21 |
*/
|
22 |
private $assetStore;
|
23 |
|
|
|
|
|
24 |
/**
|
25 |
* @param string $fullPath - in this case it's relative to ABSPATH
|
26 |
* @return ResultItem|null
|
27 |
*/
|
28 |
public function scan( string $fullPath ) {
|
29 |
$item = null;
|
30 |
-
// file paths are stored in the queue relatives to ABSPATH
|
31 |
$fullPath = path_join( wp_normalize_path( ABSPATH ), $fullPath );
|
32 |
try {
|
33 |
$asset = ( new Plugin\Files() )->findPluginFromFile( $fullPath );
|
@@ -38,7 +40,12 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
38 |
throw new \Exception( sprintf( 'Could not load asset for: %s', $fullPath ) );
|
39 |
}
|
40 |
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
42 |
}
|
43 |
catch ( \Exception $e ) {
|
44 |
error_log( $e->getMessage() );
|
@@ -55,6 +62,39 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
55 |
*/
|
56 |
private function scanWithStore( string $fullPath, $asset ) {
|
57 |
$assetHashes = $this->getStore( $asset )->getSnapData();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
$pathFragment = str_replace( $asset->getInstallDir(), '', $fullPath );
|
59 |
if ( empty( $assetHashes[ $pathFragment ] ) ) {
|
60 |
$item = $this->getNewItem( $asset, $fullPath );
|
@@ -73,6 +113,8 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
73 |
}
|
74 |
|
75 |
/**
|
|
|
|
|
76 |
* @param string $fullPath
|
77 |
* @param Assets\WpPluginVo|Assets\WpThemeVo $asset
|
78 |
* @return ResultItem|null
|
@@ -80,17 +122,24 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
80 |
*/
|
81 |
private function scanWithCsHashes( string $fullPath, $asset ) {
|
82 |
$assetHashes = $this->loadCsHashes( $asset );
|
83 |
-
|
|
|
|
|
84 |
|
85 |
$item = null;
|
86 |
-
|
|
|
|
|
|
|
|
|
|
|
87 |
$item = $this->getNewItem( $asset, $fullPath );
|
88 |
-
$item->path_fragment = $
|
89 |
$item->is_unrecognised = true;
|
90 |
}
|
91 |
else {
|
92 |
$found = false;
|
93 |
-
foreach ( $assetHashes[ $
|
94 |
if ( ( new CompareHash() )->isEqualFileSha1( $fullPath, $hash ) ) {
|
95 |
$found = true;
|
96 |
break;
|
@@ -99,37 +148,34 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
99 |
|
100 |
if ( !$found ) {
|
101 |
$item = $this->getNewItem( $asset, $fullPath );
|
102 |
-
$item->path_fragment = $
|
103 |
$item->is_different = true;
|
104 |
}
|
105 |
}
|
|
|
106 |
return $item;
|
107 |
}
|
108 |
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
|
114 |
-
|
115 |
-
|
116 |
-
$
|
117 |
->getHashesFromVO( $asset );
|
118 |
-
|
119 |
-
|
120 |
-
$tmpFileHandler->store( $uniqueId, $hashes );
|
121 |
-
}
|
122 |
}
|
123 |
-
return $hashes;
|
124 |
-
}
|
125 |
|
126 |
-
|
127 |
-
* @param Assets\WpPluginVo|Assets\WpThemeVo $asset
|
128 |
-
* @return string[]
|
129 |
-
* @throws \Exception
|
130 |
-
*/
|
131 |
-
private function getCSHashes( $asset ) {
|
132 |
-
return $this->getStore( $asset )->getSnapData();
|
133 |
}
|
134 |
|
135 |
/**
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib;
|
7 |
use FernleafSystems\Wordpress\Services\Core\VOs\Assets;
|
8 |
use FernleafSystems\Wordpress\Services\Utilities\File\Compare\CompareHash;
|
9 |
+
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
|
10 |
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Query;
|
11 |
use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
|
12 |
use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
|
22 |
*/
|
23 |
private $assetStore;
|
24 |
|
25 |
+
private $csHashes;
|
26 |
+
|
27 |
/**
|
28 |
* @param string $fullPath - in this case it's relative to ABSPATH
|
29 |
* @return ResultItem|null
|
30 |
*/
|
31 |
public function scan( string $fullPath ) {
|
32 |
$item = null;
|
|
|
33 |
$fullPath = path_join( wp_normalize_path( ABSPATH ), $fullPath );
|
34 |
try {
|
35 |
$asset = ( new Plugin\Files() )->findPluginFromFile( $fullPath );
|
40 |
throw new \Exception( sprintf( 'Could not load asset for: %s', $fullPath ) );
|
41 |
}
|
42 |
|
43 |
+
try {
|
44 |
+
$item = $this->scanWithCsHashes( $fullPath, $asset );
|
45 |
+
}
|
46 |
+
catch ( \Exception $eScan ) {
|
47 |
+
$item = $this->scanWithStore( $fullPath, $asset );
|
48 |
+
}
|
49 |
}
|
50 |
catch ( \Exception $e ) {
|
51 |
error_log( $e->getMessage() );
|
62 |
*/
|
63 |
private function scanWithStore( string $fullPath, $asset ) {
|
64 |
$assetHashes = $this->getStore( $asset )->getSnapData();
|
65 |
+
if ( empty( $assetHashes ) ) {
|
66 |
+
throw new \Exception( 'File hashes from store is empty' );
|
67 |
+
}
|
68 |
+
$pathFragment = str_replace( strtolower( $asset->getInstallDir() ), '', $fullPath );
|
69 |
+
if ( empty( $assetHashes[ $pathFragment ] ) ) {
|
70 |
+
$item = $this->getNewItem( $asset, $fullPath );
|
71 |
+
$item->path_fragment = $pathFragment;
|
72 |
+
$item->is_unrecognised = true;
|
73 |
+
}
|
74 |
+
elseif ( !( new CompareHash() )->isEqualFileMd5( $fullPath, $assetHashes[ $pathFragment ] ) ) {
|
75 |
+
$item = $this->getNewItem( $asset, $fullPath );
|
76 |
+
$item->path_fragment = $pathFragment;
|
77 |
+
$item->is_different = true;
|
78 |
+
}
|
79 |
+
else {
|
80 |
+
$item = null;
|
81 |
+
}
|
82 |
+
return $item;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* @param string $fullPath
|
87 |
+
* @param Assets\WpPluginVo|Assets\WpThemeVo $asset
|
88 |
+
* @return ResultItem|null
|
89 |
+
* @throws \InvalidArgumentException|\Exception
|
90 |
+
*/
|
91 |
+
private function scanWithHashes( string $fullPath, $asset ) {
|
92 |
+
$assetHashes = ( $asset->asset_type === 'plugin' ) ?
|
93 |
+
( new WpHashes\Hashes\Plugin() )->getPluginHashes( $asset )
|
94 |
+
: ( new WpHashes\Hashes\Theme() )->getThemeHashes( $asset );
|
95 |
+
if ( empty( $assetHashes ) ) {
|
96 |
+
throw new \Exception( 'File hashes from WPHashes is empty' );
|
97 |
+
}
|
98 |
$pathFragment = str_replace( $asset->getInstallDir(), '', $fullPath );
|
99 |
if ( empty( $assetHashes[ $pathFragment ] ) ) {
|
100 |
$item = $this->getNewItem( $asset, $fullPath );
|
113 |
}
|
114 |
|
115 |
/**
|
116 |
+
* CSHashes path fragments are all lower-case
|
117 |
+
* We need to main the true, unchanged fullpath to the file, while looking up with the lower-case path fragment.
|
118 |
* @param string $fullPath
|
119 |
* @param Assets\WpPluginVo|Assets\WpThemeVo $asset
|
120 |
* @return ResultItem|null
|
122 |
*/
|
123 |
private function scanWithCsHashes( string $fullPath, $asset ) {
|
124 |
$assetHashes = $this->loadCsHashes( $asset );
|
125 |
+
if ( empty( $assetHashes ) ) {
|
126 |
+
throw new \Exception( 'Could not retrieve CS Hashes' );
|
127 |
+
}
|
128 |
|
129 |
$item = null;
|
130 |
+
|
131 |
+
$trueFragment = str_replace( $asset->getInstallDir(), '', $fullPath );
|
132 |
+
|
133 |
+
// we must use a lower-case key for "scan", but can't use this anywhere else.
|
134 |
+
$scanFragment = strtolower( $trueFragment );
|
135 |
+
if ( empty( $assetHashes[ $scanFragment ] ) ) {
|
136 |
$item = $this->getNewItem( $asset, $fullPath );
|
137 |
+
$item->path_fragment = $trueFragment;
|
138 |
$item->is_unrecognised = true;
|
139 |
}
|
140 |
else {
|
141 |
$found = false;
|
142 |
+
foreach ( $assetHashes[ $scanFragment ] as $hash ) {
|
143 |
if ( ( new CompareHash() )->isEqualFileSha1( $fullPath, $hash ) ) {
|
144 |
$found = true;
|
145 |
break;
|
148 |
|
149 |
if ( !$found ) {
|
150 |
$item = $this->getNewItem( $asset, $fullPath );
|
151 |
+
$item->path_fragment = $trueFragment;
|
152 |
$item->is_different = true;
|
153 |
}
|
154 |
}
|
155 |
+
|
156 |
return $item;
|
157 |
}
|
158 |
|
159 |
+
/**
|
160 |
+
* We "cache" the hashes temporarily in this current load
|
161 |
+
* @param Assets\WpPluginVo|Assets\WpThemeVo $asset
|
162 |
+
* @return string[][]
|
163 |
+
*/
|
164 |
+
private function loadCsHashes( $asset ) :array {
|
165 |
+
|
166 |
+
if ( is_array( $this->csHashes ) && $asset->unique_id !== $this->csHashes[ 0 ] ) {
|
167 |
+
unset( $this->csHashes );
|
168 |
+
}
|
169 |
|
170 |
+
if ( empty( $this->csHashes ) ) {
|
171 |
+
|
172 |
+
$hashes = ( $asset->asset_type === 'plugin' ? new Query\Plugin() : new Query\Theme() )
|
173 |
->getHashesFromVO( $asset );
|
174 |
+
|
175 |
+
$this->csHashes = [ $asset->unique_id, is_array( $hashes ) ? $hashes : [] ];
|
|
|
|
|
176 |
}
|
|
|
|
|
177 |
|
178 |
+
return $this->csHashes[ 1 ];
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
}
|
180 |
|
181 |
/**
|
src/lib/src/Scans/Ptg/ResultItem.php
CHANGED
@@ -5,15 +5,13 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
|
|
5 |
/**
|
6 |
* Class ResultItem
|
7 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
|
8 |
-
* @property string $path_full
|
9 |
-
* @property string $path_fragment
|
10 |
* @property string $slug
|
11 |
* @property string $context
|
12 |
* @property string $is_unrecognised
|
13 |
* @property string $is_different
|
14 |
* @property string $is_missing
|
15 |
*/
|
16 |
-
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\
|
17 |
|
18 |
public function generateHash() :string {
|
19 |
return md5( $this->path_full );
|
5 |
/**
|
6 |
* Class ResultItem
|
7 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
|
|
|
|
|
8 |
* @property string $slug
|
9 |
* @property string $context
|
10 |
* @property string $is_unrecognised
|
11 |
* @property string $is_different
|
12 |
* @property string $is_missing
|
13 |
*/
|
14 |
+
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
|
15 |
|
16 |
public function generateHash() :string {
|
17 |
return md5( $this->path_full );
|
src/lib/src/Scans/Ptg/ResultsSet.php
CHANGED
@@ -9,7 +9,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
|
11 |
*/
|
12 |
-
class ResultsSet extends Base\
|
13 |
|
14 |
/**
|
15 |
* @var string
|
@@ -93,18 +93,18 @@ class ResultsSet extends Base\BaseResultsSet {
|
|
93 |
}
|
94 |
|
95 |
/**
|
96 |
-
* @param string $
|
97 |
* @return ResultsSet
|
98 |
*/
|
99 |
-
public function getResultsForContext( $
|
100 |
-
$
|
101 |
-
foreach ( $this->getAllItems() as $
|
102 |
-
/** @var ResultItem $
|
103 |
-
if ( $
|
104 |
-
$
|
105 |
}
|
106 |
}
|
107 |
-
return $
|
108 |
}
|
109 |
|
110 |
/**
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
|
11 |
*/
|
12 |
+
class ResultsSet extends Base\ResultsSet {
|
13 |
|
14 |
/**
|
15 |
* @var string
|
93 |
}
|
94 |
|
95 |
/**
|
96 |
+
* @param string $context
|
97 |
* @return ResultsSet
|
98 |
*/
|
99 |
+
public function getResultsForContext( $context ) {
|
100 |
+
$results = new ResultsSet();
|
101 |
+
foreach ( $this->getAllItems() as $item ) {
|
102 |
+
/** @var ResultItem $item */
|
103 |
+
if ( $item->context == $context ) {
|
104 |
+
$results->addItem( $item );
|
105 |
}
|
106 |
}
|
107 |
+
return $results;
|
108 |
}
|
109 |
|
110 |
/**
|
src/lib/src/Scans/Ptg/ScanFromFileMap.php
CHANGED
@@ -13,17 +13,17 @@ class ScanFromFileMap extends BaseScanFromFileMap {
|
|
13 |
/**
|
14 |
* @var FileScanner
|
15 |
*/
|
16 |
-
private $
|
17 |
|
18 |
/**
|
19 |
* @return FileScanner
|
20 |
*/
|
21 |
protected function getFileScanner() {
|
22 |
-
if ( empty( $this->
|
23 |
-
$this->
|
24 |
->setMod( $this->getMod() )
|
25 |
->setScanActionVO( $this->getScanActionVO() );
|
26 |
}
|
27 |
-
return $this->
|
28 |
}
|
29 |
}
|
13 |
/**
|
14 |
* @var FileScanner
|
15 |
*/
|
16 |
+
private $fileScanner;
|
17 |
|
18 |
/**
|
19 |
* @return FileScanner
|
20 |
*/
|
21 |
protected function getFileScanner() {
|
22 |
+
if ( empty( $this->fileScanner ) ) {
|
23 |
+
$this->fileScanner = ( new FileScanner() )
|
24 |
->setMod( $this->getMod() )
|
25 |
->setScanActionVO( $this->getScanActionVO() );
|
26 |
}
|
27 |
+
return $this->fileScanner;
|
28 |
}
|
29 |
}
|
src/lib/src/Scans/Ptg/Utilities/ItemActionHandler.php
CHANGED
@@ -19,19 +19,19 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandlerAssets {
|
|
19 |
switch ( $action ) {
|
20 |
|
21 |
case 'asset_accept':
|
22 |
-
$
|
23 |
break;
|
24 |
|
25 |
case 'asset_reinstall':
|
26 |
-
$
|
27 |
break;
|
28 |
|
29 |
default:
|
30 |
-
$
|
31 |
break;
|
32 |
}
|
33 |
|
34 |
-
return $
|
35 |
}
|
36 |
|
37 |
/**
|
@@ -45,10 +45,10 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandlerAssets {
|
|
45 |
/** @var Ptg\ResultItem $item */
|
46 |
$item = $this->getScanItem();
|
47 |
|
48 |
-
foreach ( $results->getItemsForSlug( $item->slug ) as $
|
49 |
$tmpHandler = clone $this;
|
50 |
-
$tmpHandler->setScanItem( $
|
51 |
-
|
52 |
}
|
53 |
|
54 |
( new Snapshots\StoreAction\Build() )
|
@@ -99,21 +99,18 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandlerAssets {
|
|
99 |
}
|
100 |
|
101 |
/**
|
102 |
-
*
|
|
|
|
|
103 |
*/
|
104 |
-
public function
|
105 |
-
return
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
-
* @
|
110 |
*/
|
111 |
-
|
112 |
-
|
113 |
-
$oItem = $this->getScanItem();
|
114 |
-
$this->getCon()->fireEvent(
|
115 |
-
$this->getScanController()->getSlug().'_item_repair_'.( $success ? 'success' : 'fail' ),
|
116 |
-
[ 'audit' => [ 'fragment' => $oItem->path_full ] ]
|
117 |
-
);
|
118 |
}
|
119 |
}
|
19 |
switch ( $action ) {
|
20 |
|
21 |
case 'asset_accept':
|
22 |
+
$success = $this->assetAccept();
|
23 |
break;
|
24 |
|
25 |
case 'asset_reinstall':
|
26 |
+
$success = $this->assetReinstall();
|
27 |
break;
|
28 |
|
29 |
default:
|
30 |
+
$success = parent::process( $action );
|
31 |
break;
|
32 |
}
|
33 |
|
34 |
+
return $success;
|
35 |
}
|
36 |
|
37 |
/**
|
45 |
/** @var Ptg\ResultItem $item */
|
46 |
$item = $this->getScanItem();
|
47 |
|
48 |
+
foreach ( $results->getItemsForSlug( $item->slug ) as $item ) {
|
49 |
$tmpHandler = clone $this;
|
50 |
+
$tmpHandler->setScanItem( $item )
|
51 |
+
->ignore();
|
52 |
}
|
53 |
|
54 |
( new Snapshots\StoreAction\Build() )
|
99 |
}
|
100 |
|
101 |
/**
|
102 |
+
* Repair PTG item if it's repairable, or it's unrecognised (i.e. delete)
|
103 |
+
* @return bool
|
104 |
+
* @throws \Exception
|
105 |
*/
|
106 |
+
public function repairDelete() :bool {
|
107 |
+
return $this->repair( true );
|
108 |
}
|
109 |
|
110 |
/**
|
111 |
+
* @return Repair
|
112 |
*/
|
113 |
+
public function getRepairer() {
|
114 |
+
return ( new Repair() )->setScanItem( $this->getScanItem() );
|
|
|
|
|
|
|
|
|
|
|
115 |
}
|
116 |
}
|
src/lib/src/Scans/Ptg/Utilities/Repair.php
CHANGED
@@ -4,10 +4,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg\Utilities;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
|
7 |
-
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
|
8 |
-
WpPluginVo,
|
9 |
-
WpThemeVo
|
10 |
-
};
|
11 |
use FernleafSystems\Wordpress\Services\Services;
|
12 |
use FernleafSystems\Wordpress\Services\Utilities\WpOrg;
|
13 |
|
@@ -17,79 +13,65 @@ use FernleafSystems\Wordpress\Services\Utilities\WpOrg;
|
|
17 |
*/
|
18 |
class Repair extends Scans\Base\Utilities\BaseRepair {
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
/**
|
21 |
* @return bool
|
22 |
* @throws \Exception
|
23 |
*/
|
24 |
-
public function repairItem() {
|
25 |
/** @var Ptg\ResultItem $item */
|
26 |
$item = $this->getScanItem();
|
27 |
|
28 |
if ( $this->canRepair() ) {
|
29 |
-
|
30 |
-
$
|
31 |
-
|
32 |
-
else {
|
33 |
-
$bSuccess = $this->repairThemeFile( $item->path_full );
|
34 |
-
}
|
35 |
}
|
36 |
else {
|
37 |
-
$
|
38 |
}
|
39 |
|
40 |
-
return $
|
41 |
}
|
42 |
|
43 |
-
|
44 |
-
* @param string $sPath
|
45 |
-
* @return bool
|
46 |
-
*/
|
47 |
-
private function repairPluginFile( $sPath ) {
|
48 |
$success = false;
|
49 |
$files = new WpOrg\Plugin\Files();
|
50 |
try {
|
51 |
-
if ( $files->isValidFileFromPlugin( $
|
52 |
-
$success = $files->replaceFileFromVcs( $
|
53 |
-
}
|
54 |
-
elseif ( $this->isAllowDelete() ) {
|
55 |
-
$success = (bool)Services::WpFs()->deleteFile( $sPath );
|
56 |
}
|
57 |
}
|
58 |
catch ( \InvalidArgumentException $e ) {
|
59 |
}
|
60 |
-
return
|
61 |
}
|
62 |
|
63 |
-
|
64 |
-
* @param string $path
|
65 |
-
* @return bool
|
66 |
-
*/
|
67 |
-
private function repairThemeFile( $path ) {
|
68 |
$success = false;
|
69 |
$files = new WpOrg\Theme\Files();
|
70 |
try {
|
71 |
if ( $files->isValidFileFromTheme( $path ) ) {
|
72 |
$success = $files->replaceFileFromVcs( $path );
|
73 |
}
|
74 |
-
elseif ( $this->isAllowDelete() ) {
|
75 |
-
$success = (bool)Services::WpFs()->deleteFile( $path );
|
76 |
-
}
|
77 |
}
|
78 |
catch ( \InvalidArgumentException $e ) {
|
79 |
}
|
80 |
return $success;
|
81 |
}
|
82 |
|
83 |
-
|
84 |
-
* @return bool
|
85 |
-
*/
|
86 |
-
public function canRepair() {
|
87 |
/** @var Ptg\ResultItem $item */
|
88 |
$item = $this->getScanItem();
|
89 |
if ( $item->context == 'plugins' ) {
|
90 |
$asset = Services::WpPlugins()->getPluginAsVo( $item->slug );
|
91 |
$canRepair = $asset->asset_type === 'plugin'
|
92 |
-
|
93 |
}
|
94 |
else {
|
95 |
$asset = Services::WpThemes()->getThemeAsVo( $item->slug );
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
|
|
|
|
|
|
|
|
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
use FernleafSystems\Wordpress\Services\Utilities\WpOrg;
|
9 |
|
13 |
*/
|
14 |
class Repair extends Scans\Base\Utilities\BaseRepair {
|
15 |
|
16 |
+
public function deleteItem() :bool {
|
17 |
+
/** @var Ptg\ResultItem $item */
|
18 |
+
$item = $this->getScanItem();
|
19 |
+
return $item->is_unrecognised && (bool)Services::WpFs()->deleteFile( $item->path_full );
|
20 |
+
}
|
21 |
+
|
22 |
/**
|
23 |
* @return bool
|
24 |
* @throws \Exception
|
25 |
*/
|
26 |
+
public function repairItem() :bool {
|
27 |
/** @var Ptg\ResultItem $item */
|
28 |
$item = $this->getScanItem();
|
29 |
|
30 |
if ( $this->canRepair() ) {
|
31 |
+
$success = ( $item->context == 'plugins' ) ?
|
32 |
+
$this->repairPluginFile( $item->path_full )
|
33 |
+
: $this->repairThemeFile( $item->path_full );
|
|
|
|
|
|
|
34 |
}
|
35 |
else {
|
36 |
+
$success = false;
|
37 |
}
|
38 |
|
39 |
+
return $success;
|
40 |
}
|
41 |
|
42 |
+
private function repairPluginFile( string $path ) :bool {
|
|
|
|
|
|
|
|
|
43 |
$success = false;
|
44 |
$files = new WpOrg\Plugin\Files();
|
45 |
try {
|
46 |
+
if ( $files->isValidFileFromPlugin( $path ) ) {
|
47 |
+
$success = $files->replaceFileFromVcs( $path );
|
|
|
|
|
|
|
48 |
}
|
49 |
}
|
50 |
catch ( \InvalidArgumentException $e ) {
|
51 |
}
|
52 |
+
return $success;
|
53 |
}
|
54 |
|
55 |
+
private function repairThemeFile( string $path ) :bool {
|
|
|
|
|
|
|
|
|
56 |
$success = false;
|
57 |
$files = new WpOrg\Theme\Files();
|
58 |
try {
|
59 |
if ( $files->isValidFileFromTheme( $path ) ) {
|
60 |
$success = $files->replaceFileFromVcs( $path );
|
61 |
}
|
|
|
|
|
|
|
62 |
}
|
63 |
catch ( \InvalidArgumentException $e ) {
|
64 |
}
|
65 |
return $success;
|
66 |
}
|
67 |
|
68 |
+
public function canRepair() :bool {
|
|
|
|
|
|
|
69 |
/** @var Ptg\ResultItem $item */
|
70 |
$item = $this->getScanItem();
|
71 |
if ( $item->context == 'plugins' ) {
|
72 |
$asset = Services::WpPlugins()->getPluginAsVo( $item->slug );
|
73 |
$canRepair = $asset->asset_type === 'plugin'
|
74 |
+
&& $asset->isWpOrg() && $asset->svn_uses_tags;
|
75 |
}
|
76 |
else {
|
77 |
$asset = Services::WpThemes()->getThemeAsVo( $item->slug );
|
src/lib/src/Scans/Ufc/BuildFileMap.php
CHANGED
@@ -2,32 +2,28 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc;
|
4 |
|
|
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanActionConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
-
|
10 |
-
* Class BuildFileMap
|
11 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc
|
12 |
-
*/
|
13 |
-
class BuildFileMap {
|
14 |
-
|
15 |
-
use ScanActionConsumer;
|
16 |
|
17 |
/**
|
18 |
* @return string[]
|
19 |
*/
|
20 |
-
public function build() {
|
21 |
-
$
|
22 |
-
$
|
23 |
-
if ( !$
|
24 |
-
return $
|
25 |
}
|
26 |
|
27 |
-
/** @var ScanActionVO $
|
28 |
-
$
|
29 |
|
30 |
-
foreach ( $
|
31 |
try {
|
32 |
/**
|
33 |
* The filter handles the bulk of the file inclusions and exclusions
|
@@ -36,21 +32,21 @@ class BuildFileMap {
|
|
36 |
* The filter will also be responsible (in this case) for filtering out
|
37 |
* WP Core files from the collection of files to be assessed
|
38 |
*/
|
39 |
-
foreach ( StandardDirectoryIterator::create( $
|
40 |
-
/** @var \SplFileInfo $
|
41 |
-
$
|
42 |
-
if ( !$
|
43 |
-
$
|
44 |
}
|
45 |
}
|
46 |
}
|
47 |
catch ( \Exception $e ) {
|
48 |
error_log(
|
49 |
sprintf( 'Shield file scanner (%s) attempted to read directory (%s) but there was error: "%s".',
|
50 |
-
$
|
51 |
);
|
52 |
}
|
53 |
}
|
54 |
-
return $
|
55 |
}
|
56 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Options;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseBuildFileMap;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanActionConsumer;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
|
9 |
use FernleafSystems\Wordpress\Services\Services;
|
10 |
|
11 |
+
class BuildFileMap extends BaseBuildFileMap {
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
/**
|
14 |
* @return string[]
|
15 |
*/
|
16 |
+
public function build() :array {
|
17 |
+
$files = [];
|
18 |
+
$coreHashes = Services::CoreFileHashes();
|
19 |
+
if ( !$coreHashes->isReady() ) {
|
20 |
+
return $files;
|
21 |
}
|
22 |
|
23 |
+
/** @var ScanActionVO $action */
|
24 |
+
$action = $this->getScanActionVO();
|
25 |
|
26 |
+
foreach ( $action->scan_dirs as $dir => $fileExts ) {
|
27 |
try {
|
28 |
/**
|
29 |
* The filter handles the bulk of the file inclusions and exclusions
|
32 |
* The filter will also be responsible (in this case) for filtering out
|
33 |
* WP Core files from the collection of files to be assessed
|
34 |
*/
|
35 |
+
foreach ( StandardDirectoryIterator::create( $dir, 0, $fileExts, true ) as $file ) {
|
36 |
+
/** @var \SplFileInfo $file */
|
37 |
+
$path = wp_normalize_path( $file->getPathname() );
|
38 |
+
if ( !$coreHashes->isCoreFile( $path ) && !$this->isWhitelistedPath( $path ) && !$this->isAutoFilterFile( $file ) ) {
|
39 |
+
$files[] = wp_normalize_path( $path );
|
40 |
}
|
41 |
}
|
42 |
}
|
43 |
catch ( \Exception $e ) {
|
44 |
error_log(
|
45 |
sprintf( 'Shield file scanner (%s) attempted to read directory (%s) but there was error: "%s".',
|
46 |
+
$action->scan, $dir, $e->getMessage() )
|
47 |
);
|
48 |
}
|
49 |
}
|
50 |
+
return $files;
|
51 |
}
|
52 |
}
|
src/lib/src/Scans/Ufc/BuildScanAction.php
CHANGED
@@ -11,10 +11,11 @@ use FernleafSystems\Wordpress\Plugin\Shield;
|
|
11 |
class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
|
12 |
|
13 |
protected function buildItems() {
|
14 |
-
/** @var ScanActionVO $
|
15 |
-
$
|
16 |
-
$
|
17 |
-
->
|
|
|
18 |
->build();
|
19 |
}
|
20 |
|
11 |
class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
|
12 |
|
13 |
protected function buildItems() {
|
14 |
+
/** @var ScanActionVO $action */
|
15 |
+
$action = $this->getScanActionVO();
|
16 |
+
$action->items = ( new Shield\Scans\Ufc\BuildFileMap() )
|
17 |
+
->setMod( $this->getMod() )
|
18 |
+
->setScanActionVO( $action )
|
19 |
->build();
|
20 |
}
|
21 |
|
src/lib/src/Scans/Ufc/ConvertVosToResults.php
DELETED
@@ -1,33 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Class ConvertVosToResults
|
10 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc
|
11 |
-
*/
|
12 |
-
class ConvertVosToResults extends Scans\Base\BaseConvertVosToResults {
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @param EntryVO[] $VOs
|
16 |
-
* @return ResultsSet
|
17 |
-
*/
|
18 |
-
public function convert( $VOs ) {
|
19 |
-
$oRes = new ResultsSet();
|
20 |
-
foreach ( $VOs as $oVo ) {
|
21 |
-
$oRes->addItem( $this->convertItem( $oVo ) );
|
22 |
-
}
|
23 |
-
return $oRes;
|
24 |
-
}
|
25 |
-
|
26 |
-
/**
|
27 |
-
* @param EntryVO $VO
|
28 |
-
* @return ResultItem
|
29 |
-
*/
|
30 |
-
public function convertItem( $VO ) {
|
31 |
-
return ( new ResultItem() )->applyFromArray( $VO->meta );
|
32 |
-
}
|
33 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Scans/Ufc/ResultItem.php
CHANGED
@@ -2,13 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc;
|
4 |
|
5 |
-
|
6 |
-
* Class ResultItem
|
7 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc
|
8 |
-
* @property string $path_full
|
9 |
-
* @property string $path_fragment
|
10 |
-
*/
|
11 |
-
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseResultItem {
|
12 |
|
13 |
public function generateHash() :string {
|
14 |
return md5( $this->path_full );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc;
|
4 |
|
5 |
+
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
public function generateHash() :string {
|
8 |
return md5( $this->path_full );
|
src/lib/src/Scans/Ufc/ResultsSet.php
CHANGED
@@ -9,7 +9,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc
|
11 |
*/
|
12 |
-
class ResultsSet extends Base\
|
13 |
|
14 |
/**
|
15 |
* @return string[]
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc
|
11 |
*/
|
12 |
+
class ResultsSet extends Base\ResultsSet {
|
13 |
|
14 |
/**
|
15 |
* @return string[]
|
src/lib/src/Scans/Ufc/Utilities/ItemActionHandler.php
CHANGED
@@ -8,10 +8,11 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc;
|
|
8 |
class ItemActionHandler extends Base\Utilities\ItemActionHandler {
|
9 |
|
10 |
/**
|
11 |
-
* @
|
|
|
12 |
*/
|
13 |
-
public function
|
14 |
-
return $this->
|
15 |
}
|
16 |
|
17 |
/**
|
@@ -20,16 +21,4 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandler {
|
|
20 |
public function getRepairer() {
|
21 |
return ( new Repair() )->setScanItem( $this->getScanItem() );
|
22 |
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @param bool $success
|
26 |
-
*/
|
27 |
-
protected function fireRepairEvent( $success ) {
|
28 |
-
/** @var Ufc\ResultItem $item */
|
29 |
-
$item = $this->getScanItem();
|
30 |
-
$this->getCon()->fireEvent(
|
31 |
-
$this->getScanController()->getSlug().'_item_repair_'.( $success ? 'success' : 'fail' ),
|
32 |
-
[ 'audit' => [ 'fragment' => $item->path_full ] ]
|
33 |
-
);
|
34 |
-
}
|
35 |
}
|
8 |
class ItemActionHandler extends Base\Utilities\ItemActionHandler {
|
9 |
|
10 |
/**
|
11 |
+
* @return bool
|
12 |
+
* @throws \Exception
|
13 |
*/
|
14 |
+
public function repairDelete() :bool {
|
15 |
+
return $this->delete();
|
16 |
}
|
17 |
|
18 |
/**
|
21 |
public function getRepairer() {
|
22 |
return ( new Repair() )->setScanItem( $this->getScanItem() );
|
23 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
}
|
src/lib/src/Scans/Ufc/Utilities/Repair.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc\Utilities;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
@@ -13,35 +14,32 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
13 |
class Repair extends Scans\Base\Utilities\BaseRepair {
|
14 |
|
15 |
/**
|
16 |
-
* @
|
17 |
-
* @throws \Exception
|
18 |
*/
|
19 |
-
public function repairItem() {
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
$
|
25 |
-
|
26 |
-
throw new \Exception( sprintf( 'File "%s" is an official WordPress core file.', $oItem->path_fragment ) );
|
27 |
-
}
|
28 |
|
29 |
-
$
|
30 |
-
if ( $
|
31 |
-
|
32 |
-
$bSuccess = !$oFs->exists( $oItem->path_full );
|
33 |
}
|
34 |
|
35 |
-
|
|
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
* @return bool
|
40 |
* @throws \Exception
|
41 |
*/
|
42 |
-
public function canRepair() {
|
43 |
-
/** @var Ufc\ResultItem $
|
44 |
-
$
|
45 |
-
return Services::WpFs()->exists( $
|
46 |
}
|
47 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc\Utilities;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Reports\ScanRepairs;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
14 |
class Repair extends Scans\Base\Utilities\BaseRepair {
|
15 |
|
16 |
/**
|
17 |
+
* @inheritDoc
|
|
|
18 |
*/
|
19 |
+
public function repairItem() :bool {
|
20 |
+
throw new \Exception( 'Repair action is not supported' );
|
21 |
+
}
|
22 |
+
|
23 |
+
public function deleteItem() :bool {
|
24 |
+
/** @var Ufc\ResultItem $item */
|
25 |
+
$item = $this->getScanItem();
|
|
|
|
|
26 |
|
27 |
+
$coreHashes = Services::CoreFileHashes();
|
28 |
+
if ( $coreHashes->isCoreFile( $item->path_fragment ) ) {
|
29 |
+
throw new \Exception( sprintf( 'File "%s" is an official WordPress core file.', $item->path_fragment ) );
|
|
|
30 |
}
|
31 |
|
32 |
+
$FS = Services::WpFs();
|
33 |
+
return !$FS->isFile( $item->path_full ) || (bool)$FS->deleteFile( $item->path_full );
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
* @return bool
|
38 |
* @throws \Exception
|
39 |
*/
|
40 |
+
public function canRepair() :bool {
|
41 |
+
/** @var Ufc\ResultItem $item */
|
42 |
+
$item = $this->getScanItem();
|
43 |
+
return (bool)Services::WpFs()->exists( $item->path_full );
|
44 |
}
|
45 |
}
|
src/lib/src/Scans/Wcf/BuildFileMap.php
CHANGED
@@ -2,33 +2,34 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans\
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
/**
|
9 |
* Class BuildFileMap
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf
|
11 |
*/
|
12 |
-
class BuildFileMap {
|
13 |
-
|
14 |
-
use ScanActionConsumer;
|
15 |
|
16 |
/**
|
17 |
* @return string[]
|
18 |
*/
|
19 |
-
public function build() {
|
20 |
-
$
|
21 |
|
22 |
-
$
|
23 |
-
if ( $
|
24 |
-
foreach ( array_keys( $
|
25 |
// To reduce noise, we exclude plugins and themes (by default)
|
26 |
-
if ( strpos( $
|
27 |
continue;
|
28 |
}
|
29 |
-
$
|
|
|
|
|
|
|
30 |
}
|
31 |
}
|
32 |
-
return $
|
33 |
}
|
34 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseBuildFileMap;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
/**
|
9 |
* Class BuildFileMap
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf
|
11 |
*/
|
12 |
+
class BuildFileMap extends BaseBuildFileMap {
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
* @return string[]
|
16 |
*/
|
17 |
+
public function build() :array {
|
18 |
+
$files = [];
|
19 |
|
20 |
+
$coreHashes = Services::CoreFileHashes();
|
21 |
+
if ( $coreHashes->isReady() ) {
|
22 |
+
foreach ( array_keys( $coreHashes->getHashes() ) as $fragment ) {
|
23 |
// To reduce noise, we exclude plugins and themes (by default)
|
24 |
+
if ( strpos( $fragment, 'wp-content/' ) === 0 ) {
|
25 |
continue;
|
26 |
}
|
27 |
+
$fullPath = wp_normalize_path( path_join( ABSPATH, $fragment ) );
|
28 |
+
if ( !$this->isWhitelistedPath( $fullPath ) ) {
|
29 |
+
$files[] = $fullPath;
|
30 |
+
}
|
31 |
}
|
32 |
}
|
33 |
+
return $files;
|
34 |
}
|
35 |
}
|
src/lib/src/Scans/Wcf/BuildScanAction.php
CHANGED
@@ -7,20 +7,21 @@ use FernleafSystems\Wordpress\Plugin\Shield;
|
|
7 |
class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
|
8 |
|
9 |
protected function buildItems() {
|
10 |
-
/** @var ScanActionVO $
|
11 |
-
$
|
12 |
-
$
|
13 |
-
->
|
|
|
14 |
->build();
|
15 |
}
|
16 |
|
17 |
protected function setCustomFields() {
|
18 |
-
/** @var ScanActionVO $
|
19 |
-
$
|
20 |
-
/** @var Shield\Modules\HackGuard\Options $
|
21 |
-
$
|
22 |
|
23 |
-
$
|
24 |
-
$
|
25 |
}
|
26 |
}
|
7 |
class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
|
8 |
|
9 |
protected function buildItems() {
|
10 |
+
/** @var ScanActionVO $action */
|
11 |
+
$action = $this->getScanActionVO();
|
12 |
+
$action->items = ( new Shield\Scans\Wcf\BuildFileMap() )
|
13 |
+
->setMod( $this->getMod() )
|
14 |
+
->setScanActionVO( $action )
|
15 |
->build();
|
16 |
}
|
17 |
|
18 |
protected function setCustomFields() {
|
19 |
+
/** @var ScanActionVO $action */
|
20 |
+
$action = $this->getScanActionVO();
|
21 |
+
/** @var Shield\Modules\HackGuard\Options $opts */
|
22 |
+
$opts = $this->getOptions();
|
23 |
|
24 |
+
$action->exclusions_missing_regex = $opts->getWcfMissingExclusions();
|
25 |
+
$action->exclusions_files_regex = $opts->getWcfFileExclusions();
|
26 |
}
|
27 |
}
|
src/lib/src/Scans/Wcf/ConvertVosToResults.php
DELETED
@@ -1,33 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Class ConvertVosToResults
|
10 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf
|
11 |
-
*/
|
12 |
-
class ConvertVosToResults extends Scans\Base\BaseConvertVosToResults {
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @param EntryVO[] $VOs
|
16 |
-
* @return ResultsSet
|
17 |
-
*/
|
18 |
-
public function convert( $VOs ) {
|
19 |
-
$oRes = new ResultsSet();
|
20 |
-
foreach ( $VOs as $oVo ) {
|
21 |
-
$oRes->addItem( $this->convertItem( $oVo ) );
|
22 |
-
}
|
23 |
-
return $oRes;
|
24 |
-
}
|
25 |
-
|
26 |
-
/**
|
27 |
-
* @param EntryVO $VO
|
28 |
-
* @return ResultItem
|
29 |
-
*/
|
30 |
-
public function convertItem( $VO ) {
|
31 |
-
return ( new ResultItem() )->applyFromArray( $VO->meta );
|
32 |
-
}
|
33 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Scans/Wcf/FileScanner.php
CHANGED
@@ -17,24 +17,24 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
17 |
* @return ResultItem|null
|
18 |
*/
|
19 |
public function scan( string $fullPath ) {
|
20 |
-
$
|
21 |
$oHashes = Services::CoreFileHashes();
|
22 |
|
23 |
-
/** @var ResultItem $
|
24 |
-
$
|
25 |
-
$
|
26 |
-
$
|
27 |
-
$
|
28 |
-
$
|
29 |
-
$
|
30 |
-
$
|
31 |
-
|| ( $
|
32 |
|
33 |
-
if ( !$
|
34 |
-
$
|
35 |
}
|
36 |
|
37 |
-
return $
|
38 |
}
|
39 |
|
40 |
/**
|
17 |
* @return ResultItem|null
|
18 |
*/
|
19 |
public function scan( string $fullPath ) {
|
20 |
+
$results = null;
|
21 |
$oHashes = Services::CoreFileHashes();
|
22 |
|
23 |
+
/** @var ResultItem $item */
|
24 |
+
$item = $this->getScanActionVO()->getNewResultItem();
|
25 |
+
$item->path_full = $fullPath;
|
26 |
+
$item->path_fragment = $oHashes->getFileFragment( $fullPath );
|
27 |
+
$item->md5_file_wp = $oHashes->getFileHash( $item->path_fragment );
|
28 |
+
$item->is_missing = !Services::WpFs()->exists( $item->path_full );
|
29 |
+
$item->is_checksumfail = !$item->is_missing && $this->isChecksumFail( $item );
|
30 |
+
$item->is_excluded = $this->isExcluded( $item->path_fragment )
|
31 |
+
|| ( $item->is_missing && $this->isExcludedMissing( $item->path_fragment ) );
|
32 |
|
33 |
+
if ( !$item->is_excluded && ( $item->is_missing || $item->is_checksumfail ) ) {
|
34 |
+
$results = $item;
|
35 |
}
|
36 |
|
37 |
+
return $results;
|
38 |
}
|
39 |
|
40 |
/**
|
src/lib/src/Scans/Wcf/ResultItem.php
CHANGED
@@ -5,13 +5,11 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf;
|
|
5 |
/**
|
6 |
* Class ResultItem
|
7 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf
|
8 |
-
* @property string $path_full
|
9 |
-
* @property string $path_fragment
|
10 |
* @property string $md5_file_wp
|
11 |
* @property bool $is_checksumfail
|
12 |
* @property bool $is_missing
|
13 |
*/
|
14 |
-
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\
|
15 |
|
16 |
public function generateHash() :string {
|
17 |
return md5( $this->path_full );
|
5 |
/**
|
6 |
* Class ResultItem
|
7 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf
|
|
|
|
|
8 |
* @property string $md5_file_wp
|
9 |
* @property bool $is_checksumfail
|
10 |
* @property bool $is_missing
|
11 |
*/
|
12 |
+
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
|
13 |
|
14 |
public function generateHash() :string {
|
15 |
return md5( $this->path_full );
|
src/lib/src/Scans/Wcf/ResultsSet.php
CHANGED
@@ -9,19 +9,18 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf
|
11 |
*/
|
12 |
-
class ResultsSet extends Base\
|
13 |
|
14 |
/**
|
15 |
-
* @param ResultItem[] $
|
16 |
* @return string[]
|
17 |
*/
|
18 |
-
public function filterItemsForPaths( $
|
19 |
return array_map(
|
20 |
-
function ( $
|
21 |
-
|
22 |
-
return $oItem->path_fragment;
|
23 |
},
|
24 |
-
$
|
25 |
);
|
26 |
}
|
27 |
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf
|
11 |
*/
|
12 |
+
class ResultsSet extends Base\ResultsSet {
|
13 |
|
14 |
/**
|
15 |
+
* @param ResultItem[] $items
|
16 |
* @return string[]
|
17 |
*/
|
18 |
+
public function filterItemsForPaths( $items ) {
|
19 |
return array_map(
|
20 |
+
function ( $item ) {
|
21 |
+
return $item->path_fragment;
|
|
|
22 |
},
|
23 |
+
$items
|
24 |
);
|
25 |
}
|
26 |
|
src/lib/src/Scans/Wcf/Utilities/ItemActionHandler.php
CHANGED
@@ -15,14 +15,10 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandler {
|
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
-
* @
|
|
|
19 |
*/
|
20 |
-
|
21 |
-
|
22 |
-
$oItem = $this->getScanItem();
|
23 |
-
$this->getCon()->fireEvent(
|
24 |
-
$this->getScanController()->getSlug().'_item_repair_'.( $success ? 'success' : 'fail' ),
|
25 |
-
[ 'audit' => [ 'fragment' => $oItem->path_full ] ]
|
26 |
-
);
|
27 |
}
|
28 |
}
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
+
* @return bool
|
19 |
+
* @throws \Exception
|
20 |
*/
|
21 |
+
public function repairDelete() :bool {
|
22 |
+
return $this->repair();
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
}
|
src/lib/src/Scans/Wcf/Utilities/Repair.php
CHANGED
@@ -12,23 +12,20 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
12 |
*/
|
13 |
class Repair extends Scans\Base\Utilities\BaseRepair {
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
$oItem = $this->getScanItem();
|
21 |
-
$sPath = trim( wp_normalize_path( $oItem->path_fragment ), '/' );
|
22 |
-
return ( new Scans\Helpers\WpCoreFile() )->replace( $sPath );
|
23 |
}
|
24 |
|
25 |
/**
|
26 |
* @return bool
|
27 |
* @throws \Exception
|
28 |
*/
|
29 |
-
public function canRepair() {
|
30 |
-
/** @var Wcf\ResultItem $
|
31 |
-
$
|
32 |
-
return Services::CoreFileHashes()->isCoreFile( $
|
33 |
}
|
34 |
}
|
12 |
*/
|
13 |
class Repair extends Scans\Base\Utilities\BaseRepair {
|
14 |
|
15 |
+
public function repairItem() :bool {
|
16 |
+
/** @var Wcf\ResultItem $item */
|
17 |
+
$item = $this->getScanItem();
|
18 |
+
$path = trim( wp_normalize_path( $item->path_fragment ), '/' );
|
19 |
+
return ( new Scans\Helpers\WpCoreFile() )->replace( $path );
|
|
|
|
|
|
|
20 |
}
|
21 |
|
22 |
/**
|
23 |
* @return bool
|
24 |
* @throws \Exception
|
25 |
*/
|
26 |
+
public function canRepair() :bool {
|
27 |
+
/** @var Wcf\ResultItem $item */
|
28 |
+
$item = $this->getScanItem();
|
29 |
+
return Services::CoreFileHashes()->isCoreFile( $item->path_full );
|
30 |
}
|
31 |
}
|
src/lib/src/Scans/Wpv/ConvertVosToResults.php
DELETED
@@ -1,32 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Class ConvertVosToResults
|
9 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv
|
10 |
-
*/
|
11 |
-
class ConvertVosToResults extends Shield\Scans\Base\BaseConvertVosToResults {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @param Shield\Databases\Scanner\EntryVO[] $VOs
|
15 |
-
* @return ResultsSet
|
16 |
-
*/
|
17 |
-
public function convert( $VOs ) {
|
18 |
-
$results = new ResultsSet();
|
19 |
-
foreach ( $VOs as $vo ) {
|
20 |
-
$results->addItem( $this->convertItem( $vo ) );
|
21 |
-
}
|
22 |
-
return $results;
|
23 |
-
}
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @param Shield\Databases\Scanner\EntryVO $VO
|
27 |
-
* @return ResultItem
|
28 |
-
*/
|
29 |
-
public function convertItem( $VO ) {
|
30 |
-
return ( new ResultItem() )->applyFromArray( $VO->meta );
|
31 |
-
}
|
32 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Scans/Wpv/ResultItem.php
CHANGED
@@ -12,7 +12,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv\WpVulnDb\VulnVO;
|
|
12 |
* @property int $wpvuln_id
|
13 |
* @property array $wpvuln_vo
|
14 |
*/
|
15 |
-
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\
|
16 |
|
17 |
public function generateHash() :string {
|
18 |
return md5( $this->slug.$this->wpvuln_id );
|
12 |
* @property int $wpvuln_id
|
13 |
* @property array $wpvuln_vo
|
14 |
*/
|
15 |
+
class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultItem {
|
16 |
|
17 |
public function generateHash() :string {
|
18 |
return md5( $this->slug.$this->wpvuln_id );
|
src/lib/src/Scans/Wpv/ResultsSet.php
CHANGED
@@ -9,7 +9,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv
|
11 |
*/
|
12 |
-
class ResultsSet extends Base\
|
13 |
|
14 |
/**
|
15 |
* @return int
|
9 |
* @property ResultItem[] $items
|
10 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv
|
11 |
*/
|
12 |
+
class ResultsSet extends Base\ResultsSet {
|
13 |
|
14 |
/**
|
15 |
* @return int
|
src/lib/src/Scans/Wpv/Scan.php
CHANGED
@@ -9,25 +9,24 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Vulnerabi
|
|
9 |
class Scan extends Shield\Scans\Base\BaseScan {
|
10 |
|
11 |
protected function scanSlice() {
|
12 |
-
/** @var ScanActionVO $
|
13 |
-
$
|
14 |
-
$
|
15 |
|
16 |
-
$
|
17 |
-
foreach ( $
|
18 |
-
$
|
19 |
-
if ( $
|
20 |
-
$
|
21 |
}
|
22 |
}
|
23 |
-
|
24 |
-
$
|
25 |
-
|
26 |
-
|
27 |
-
$aNewItems[] = $item->getRawData();
|
28 |
}
|
29 |
}
|
30 |
-
$
|
31 |
}
|
32 |
|
33 |
/**
|
9 |
class Scan extends Shield\Scans\Base\BaseScan {
|
10 |
|
11 |
protected function scanSlice() {
|
12 |
+
/** @var ScanActionVO $action */
|
13 |
+
$action = $this->getScanActionVO();
|
14 |
+
$tmpResults = $action->getNewResultsSet();
|
15 |
|
16 |
+
$copier = new Shield\Scans\Helpers\CopyResultsSets();
|
17 |
+
foreach ( $action->items as $file => $context ) {
|
18 |
+
$results = $this->scanItem( $context, $file );
|
19 |
+
if ( $results instanceof Shield\Scans\Base\ResultsSet ) {
|
20 |
+
$copier->copyTo( $results, $tmpResults );
|
21 |
}
|
22 |
}
|
23 |
+
$items = [];
|
24 |
+
if ( $tmpResults->hasItems() ) {
|
25 |
+
foreach ( $tmpResults->getAllItems() as $item ) {
|
26 |
+
$items[] = $item->getRawData();
|
|
|
27 |
}
|
28 |
}
|
29 |
+
$action->results = $items;
|
30 |
}
|
31 |
|
32 |
/**
|
src/lib/src/Scans/Wpv/Utilities/ItemActionHandler.php
CHANGED
@@ -1,10 +1,8 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv\Utilities;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv;
|
7 |
-
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
class ItemActionHandler extends Base\Utilities\ItemActionHandlerAssets {
|
10 |
|
@@ -14,20 +12,4 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandlerAssets {
|
|
14 |
public function getRepairer() {
|
15 |
return ( new Repair() )->setScanItem( $this->getScanItem() );
|
16 |
}
|
17 |
-
|
18 |
-
/**
|
19 |
-
* @param bool $success
|
20 |
-
*/
|
21 |
-
protected function fireRepairEvent( $success ) {
|
22 |
-
/** @var Wpv\ResultItem $oItem */
|
23 |
-
$oItem = $this->getScanItem();
|
24 |
-
$this->getCon()->fireEvent(
|
25 |
-
$this->getScanController()->getSlug().'_item_repair_'.( $success ? 'success' : 'fail' ),
|
26 |
-
[
|
27 |
-
'audit' => [
|
28 |
-
'name' => Services::WpPlugins()->getPluginAsVo( $oItem->slug )->Name
|
29 |
-
]
|
30 |
-
]
|
31 |
-
);
|
32 |
-
}
|
33 |
}
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv\Utilities;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
|
|
|
|
|
6 |
|
7 |
class ItemActionHandler extends Base\Utilities\ItemActionHandlerAssets {
|
8 |
|
12 |
public function getRepairer() {
|
13 |
return ( new Repair() )->setScanItem( $this->getScanItem() );
|
14 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
}
|
src/lib/src/Scans/Wpv/Utilities/Repair.php
CHANGED
@@ -17,25 +17,22 @@ class Repair extends Scans\Base\Utilities\BaseRepair {
|
|
17 |
* @return bool
|
18 |
* @throws \Exception
|
19 |
*/
|
20 |
-
public function repairItem() {
|
21 |
if ( !$this->canRepair() ) {
|
22 |
throw new \Exception( 'An update is not currently available.' );
|
23 |
}
|
24 |
|
25 |
-
/** @var Wpv\ResultItem $
|
26 |
-
$
|
27 |
|
28 |
-
$
|
29 |
-
Services::WpPlugins()->update( $
|
30 |
-
: Services::WpThemes()->update( $
|
31 |
|
32 |
-
return $
|
33 |
}
|
34 |
|
35 |
-
|
36 |
-
* @return bool
|
37 |
-
*/
|
38 |
-
public function canRepair() {
|
39 |
/** @var Wpv\ResultItem $item */
|
40 |
$item = $this->getScanItem();
|
41 |
|
17 |
* @return bool
|
18 |
* @throws \Exception
|
19 |
*/
|
20 |
+
public function repairItem() :bool {
|
21 |
if ( !$this->canRepair() ) {
|
22 |
throw new \Exception( 'An update is not currently available.' );
|
23 |
}
|
24 |
|
25 |
+
/** @var Wpv\ResultItem $item */
|
26 |
+
$item = $this->getScanItem();
|
27 |
|
28 |
+
$data = ( $item->context == 'plugins' ) ?
|
29 |
+
Services::WpPlugins()->update( $item->slug )
|
30 |
+
: Services::WpThemes()->update( $item->slug );
|
31 |
|
32 |
+
return (bool)$data[ 'successful' ];
|
33 |
}
|
34 |
|
35 |
+
public function canRepair() :bool {
|
|
|
|
|
|
|
36 |
/** @var Wpv\ResultItem $item */
|
37 |
$item = $this->getScanItem();
|
38 |
|
src/lib/src/Scans/Wpv/WpVulnDb/WpVulnVO.php
DELETED
@@ -1,43 +0,0 @@
|
|
1 |
-
<?php declare( strict_types=1 );
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv\WpVulnDb;
|
4 |
-
|
5 |
-
use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Class WpVulnVO
|
9 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv\WpVulnDb
|
10 |
-
* @property int $id
|
11 |
-
* @property string $url
|
12 |
-
* @property string $title
|
13 |
-
* @property string $vuln_type
|
14 |
-
* @property string $fixed_in
|
15 |
-
* @property string $references
|
16 |
-
* @property int $updated_at
|
17 |
-
* @property int $created_at
|
18 |
-
* @property int $published_date
|
19 |
-
*/
|
20 |
-
class WpVulnVO extends DynPropertiesClass {
|
21 |
-
|
22 |
-
const URL_BASE = 'https://wpscan.com/vulnerability/%s';
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @inheritDoc
|
26 |
-
*/
|
27 |
-
public function __get( string $key ) {
|
28 |
-
$val = parent::__get( $key );
|
29 |
-
switch ( $key ) {
|
30 |
-
|
31 |
-
case 'url':
|
32 |
-
if ( empty( $val ) ) {
|
33 |
-
$val = sprintf( self::URL_BASE, $this->id );
|
34 |
-
}
|
35 |
-
break;
|
36 |
-
|
37 |
-
default:
|
38 |
-
break;
|
39 |
-
}
|
40 |
-
|
41 |
-
return $val;
|
42 |
-
}
|
43 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/ShieldNetApi/FileLocker/DecryptFile.php
CHANGED
@@ -2,7 +2,6 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\FileLocker;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Common\BaseShieldNetApi;
|
7 |
use FernleafSystems\Wordpress\Services\Utilities\Encrypt\OpenSslEncryptVo;
|
8 |
|
@@ -11,18 +10,19 @@ class DecryptFile extends BaseShieldNetApi {
|
|
11 |
const API_ACTION = 'filelocker/decrypt';
|
12 |
|
13 |
/**
|
14 |
-
* @param OpenSslEncryptVo $
|
15 |
-
* @param int $
|
16 |
* @return string|null
|
17 |
*/
|
18 |
-
public function retrieve( OpenSslEncryptVo $
|
19 |
$content = null;
|
20 |
|
21 |
$this->request_method = 'post';
|
22 |
$this->params_body = [
|
23 |
-
'key_id' => $
|
24 |
-
'sealed_data' => $
|
25 |
-
'sealed_pass' => $
|
|
|
26 |
];
|
27 |
|
28 |
$raw = $this->sendReq();
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\FileLocker;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Common\BaseShieldNetApi;
|
6 |
use FernleafSystems\Wordpress\Services\Utilities\Encrypt\OpenSslEncryptVo;
|
7 |
|
10 |
const API_ACTION = 'filelocker/decrypt';
|
11 |
|
12 |
/**
|
13 |
+
* @param OpenSslEncryptVo $openSslVO
|
14 |
+
* @param int $publicKeyId
|
15 |
* @return string|null
|
16 |
*/
|
17 |
+
public function retrieve( OpenSslEncryptVo $openSslVO, $publicKeyId ) {
|
18 |
$content = null;
|
19 |
|
20 |
$this->request_method = 'post';
|
21 |
$this->params_body = [
|
22 |
+
'key_id' => $publicKeyId,
|
23 |
+
'sealed_data' => $openSslVO->sealed_data,
|
24 |
+
'sealed_pass' => $openSslVO->sealed_password,
|
25 |
+
'cipher' => $openSslVO->cipher,
|
26 |
];
|
27 |
|
28 |
$raw = $this->sendReq();
|
src/lib/src/Tables/Build/ScanAggregate.php
CHANGED
@@ -7,10 +7,6 @@ use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner;
|
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
9 |
|
10 |
-
/**
|
11 |
-
* Class ScanAggregate
|
12 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Tables\Build
|
13 |
-
*/
|
14 |
class ScanAggregate extends ScanBase {
|
15 |
|
16 |
/**
|
@@ -20,8 +16,8 @@ class ScanAggregate extends ScanBase {
|
|
20 |
/** @var HackGuard\ModCon $mod */
|
21 |
$mod = $this->getMod();
|
22 |
|
23 |
-
foreach ( $this->getIncludedScanSlugs() as $
|
24 |
-
$mod->getScanCon( $
|
25 |
}
|
26 |
|
27 |
return $this;
|
@@ -118,8 +114,8 @@ class ScanAggregate extends ScanBase {
|
|
118 |
/**
|
119 |
* @return string[]
|
120 |
*/
|
121 |
-
private function getIncludedScanSlugs() {
|
122 |
-
return [ 'mal'
|
123 |
}
|
124 |
|
125 |
protected function getCustomParams() :array {
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
9 |
|
|
|
|
|
|
|
|
|
10 |
class ScanAggregate extends ScanBase {
|
11 |
|
12 |
/**
|
16 |
/** @var HackGuard\ModCon $mod */
|
17 |
$mod = $this->getMod();
|
18 |
|
19 |
+
foreach ( $this->getIncludedScanSlugs() as $scan ) {
|
20 |
+
$mod->getScanCon( $scan )->cleanStalesResults();
|
21 |
}
|
22 |
|
23 |
return $this;
|
114 |
/**
|
115 |
* @return string[]
|
116 |
*/
|
117 |
+
private function getIncludedScanSlugs() :array {
|
118 |
+
return [ 'mal' ];
|
119 |
}
|
120 |
|
121 |
protected function getCustomParams() :array {
|
src/lib/src/Tables/Build/ScanApc.php
CHANGED
@@ -28,15 +28,15 @@ class ScanApc extends ScanBase {
|
|
28 |
$oWpPlugins = Services::WpPlugins();
|
29 |
foreach ( $this->getEntriesRaw() as $nKey => $entry ) {
|
30 |
/** @var Shield\Databases\Scanner\EntryVO $entry */
|
31 |
-
/** @var Shield\Scans\Apc\ResultItem $
|
32 |
-
$
|
33 |
->setScanController( $mod->getScanCon( $entry->scan ) )
|
34 |
->convertVoToResultItem( $entry );
|
35 |
-
$oPlugin = $oWpPlugins->getPluginAsVo( $
|
36 |
$aE = $entry->getRawData();
|
37 |
$aE[ 'plugin' ] = sprintf( '%s (%s)', $oPlugin->Name, $oPlugin->Version );
|
38 |
$aE[ 'status' ] = sprintf( '%s: %s',
|
39 |
-
__( 'Abandoned', 'wp-simple-firewall' ), $oCarbon->setTimestamp( $
|
40 |
->diffForHumans() );
|
41 |
$aE[ 'ignored' ] = $this->formatIsIgnored( $entry );
|
42 |
$aE[ 'created_at' ] = $this->formatTimestampField( $entry->created_at );
|
28 |
$oWpPlugins = Services::WpPlugins();
|
29 |
foreach ( $this->getEntriesRaw() as $nKey => $entry ) {
|
30 |
/** @var Shield\Databases\Scanner\EntryVO $entry */
|
31 |
+
/** @var Shield\Scans\Apc\ResultItem $item */
|
32 |
+
$item = $oConverter
|
33 |
->setScanController( $mod->getScanCon( $entry->scan ) )
|
34 |
->convertVoToResultItem( $entry );
|
35 |
+
$oPlugin = $oWpPlugins->getPluginAsVo( $item->slug );
|
36 |
$aE = $entry->getRawData();
|
37 |
$aE[ 'plugin' ] = sprintf( '%s (%s)', $oPlugin->Name, $oPlugin->Version );
|
38 |
$aE[ 'status' ] = sprintf( '%s: %s',
|
39 |
+
__( 'Abandoned', 'wp-simple-firewall' ), $oCarbon->setTimestamp( $item->last_updated_at )
|
40 |
->diffForHumans() );
|
41 |
$aE[ 'ignored' ] = $this->formatIsIgnored( $entry );
|
42 |
$aE[ 'created_at' ] = $this->formatTimestampField( $entry->created_at );
|
src/lib/src/Tables/DataTables/Build/AuditTrail/ForAuditTrail.php
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\AuditTrail;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Base;
|
7 |
+
|
8 |
+
class ForAuditTrail extends Base {
|
9 |
+
|
10 |
+
protected function getOrderColumnSlug() :string {
|
11 |
+
return 'detected';
|
12 |
+
}
|
13 |
+
|
14 |
+
protected function getColumnsToDisplay() :array {
|
15 |
+
return [
|
16 |
+
'rid',
|
17 |
+
'file_as_href',
|
18 |
+
'status',
|
19 |
+
'file_type',
|
20 |
+
'detected',
|
21 |
+
'actions',
|
22 |
+
];
|
23 |
+
}
|
24 |
+
|
25 |
+
protected function getColumnDefs() :array {
|
26 |
+
return [
|
27 |
+
'rid' => [
|
28 |
+
'data' => 'rid',
|
29 |
+
'title' => 'ID',
|
30 |
+
'orderable' => true,
|
31 |
+
'searchable' => false,
|
32 |
+
'visible' => false,
|
33 |
+
],
|
34 |
+
'file' => [
|
35 |
+
'data' => 'file',
|
36 |
+
'title' => __( 'File' ),
|
37 |
+
'className' => 'file',
|
38 |
+
'orderable' => true,
|
39 |
+
'searchable' => true,
|
40 |
+
'visible' => true,
|
41 |
+
],
|
42 |
+
'file_as_href' => [
|
43 |
+
'data' => 'file_as_href',
|
44 |
+
'title' => __( 'File' ),
|
45 |
+
'className' => 'file_as_href',
|
46 |
+
'orderable' => true,
|
47 |
+
'searchable' => true,
|
48 |
+
'visible' => true,
|
49 |
+
],
|
50 |
+
'file_type' => [
|
51 |
+
'data' => 'file_type',
|
52 |
+
'title' => __( 'Type' ),
|
53 |
+
'className' => 'file_type',
|
54 |
+
'orderable' => true,
|
55 |
+
'searchable' => true,
|
56 |
+
'visible' => true,
|
57 |
+
],
|
58 |
+
'status' => [
|
59 |
+
'data' => 'status',
|
60 |
+
'title' => __( 'Status' ),
|
61 |
+
'className' => 'status',
|
62 |
+
'orderable' => true,
|
63 |
+
'searchable' => false,
|
64 |
+
'visible' => true,
|
65 |
+
],
|
66 |
+
'detected' => [
|
67 |
+
'data' => [
|
68 |
+
'_' => 'detected_since',
|
69 |
+
'sort' => 'detected_at',
|
70 |
+
],
|
71 |
+
'title' => __( 'Detected' ),
|
72 |
+
'className' => 'detected',
|
73 |
+
'orderable' => true,
|
74 |
+
'searchable' => false,
|
75 |
+
'visible' => true,
|
76 |
+
],
|
77 |
+
'actions' => [
|
78 |
+
'data' => 'actions',
|
79 |
+
'title' => __( 'Actions' ),
|
80 |
+
'className' => 'actions',
|
81 |
+
'orderable' => false,
|
82 |
+
'searchable' => false,
|
83 |
+
'visible' => true,
|
84 |
+
],
|
85 |
+
'fp_confidence' => [
|
86 |
+
'data' => 'fp_confidence',
|
87 |
+
'title' => __( 'False Positive Confidence' ),
|
88 |
+
'className' => 'fp_confidence',
|
89 |
+
'orderable' => true,
|
90 |
+
'searchable' => false,
|
91 |
+
'visible' => true,
|
92 |
+
],
|
93 |
+
'line_numbers' => [
|
94 |
+
'data' => 'line_numbers',
|
95 |
+
'title' => __( 'Line Numbers' ),
|
96 |
+
'className' => 'line_numbers',
|
97 |
+
'orderable' => false,
|
98 |
+
'searchable' => false,
|
99 |
+
'visible' => true,
|
100 |
+
],
|
101 |
+
'mal_sig' => [
|
102 |
+
'data' => 'mal_sig',
|
103 |
+
'title' => __( 'Pattern Detected' ),
|
104 |
+
'className' => 'mal_sig',
|
105 |
+
'orderable' => false,
|
106 |
+
'searchable' => true,
|
107 |
+
'visible' => true,
|
108 |
+
],
|
109 |
+
];
|
110 |
+
}
|
111 |
+
}
|
src/lib/src/Tables/DataTables/Build/Base.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
+
|
8 |
+
abstract class Base {
|
9 |
+
|
10 |
+
use ModConsumer;
|
11 |
+
|
12 |
+
abstract protected function getColumnDefs() :array;
|
13 |
+
|
14 |
+
abstract protected function getColumnsToDisplay() :array;
|
15 |
+
|
16 |
+
abstract protected function getOrderColumnSlug() :string;
|
17 |
+
|
18 |
+
public function build() :string {
|
19 |
+
return json_encode( [
|
20 |
+
// array_values() to ensure data of the correct format
|
21 |
+
'columns' => array_values( $this->getColumnsForDisplay() ),
|
22 |
+
'order' => $this->getInitialOrdering()
|
23 |
+
] );
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @return array
|
28 |
+
* @throws \Exception
|
29 |
+
*/
|
30 |
+
public function getInitialOrdering() :array {
|
31 |
+
$thePosition = 0;
|
32 |
+
foreach ( $this->getColumnsForDisplay() as $position => $columnDef ) {
|
33 |
+
if ( $columnDef === $this->getOrderColumnSlug() ) {
|
34 |
+
$thePosition = $position;
|
35 |
+
break;
|
36 |
+
}
|
37 |
+
}
|
38 |
+
return [
|
39 |
+
[ $thePosition, $this->getOrderMethod() ]
|
40 |
+
];
|
41 |
+
}
|
42 |
+
|
43 |
+
protected function getOrderMethod() :string {
|
44 |
+
return 'desc';
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @return array
|
49 |
+
* @throws \Exception
|
50 |
+
*/
|
51 |
+
public function getColumnsForDisplay() :array {
|
52 |
+
$columns = [];
|
53 |
+
foreach ( $this->getColumnsToDisplay() as $colSlug ) {
|
54 |
+
$columns[ $colSlug ] = $this->pluckColumn( $colSlug );
|
55 |
+
}
|
56 |
+
return $columns;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @param string $columnSlug
|
61 |
+
* @return array
|
62 |
+
* @throws \Exception
|
63 |
+
*/
|
64 |
+
protected function pluckColumn( string $columnSlug ) :array {
|
65 |
+
$col = null;
|
66 |
+
foreach ( $this->getColumnDefs() as $slug => $columnDef ) {
|
67 |
+
if ( $slug === $columnSlug ) {
|
68 |
+
$col = $columnDef;
|
69 |
+
break;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
if ( empty( $col ) ) {
|
73 |
+
throw new \Exception( 'Column Definition does not exist for slug: '.$columnSlug );
|
74 |
+
}
|
75 |
+
return $col;
|
76 |
+
}
|
77 |
+
}
|
src/lib/src/Tables/DataTables/Build/Scans/BaseForScan.php
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Scans;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Base;
|
7 |
+
|
8 |
+
class BaseForScan extends Base {
|
9 |
+
|
10 |
+
protected function getOrderColumnSlug() :string {
|
11 |
+
return 'detected';
|
12 |
+
}
|
13 |
+
|
14 |
+
protected function getColumnsToDisplay() :array {
|
15 |
+
return [
|
16 |
+
'rid',
|
17 |
+
'file_as_href',
|
18 |
+
'status',
|
19 |
+
'file_type',
|
20 |
+
'detected',
|
21 |
+
'actions',
|
22 |
+
];
|
23 |
+
}
|
24 |
+
|
25 |
+
protected function getColumnDefs() :array {
|
26 |
+
return [
|
27 |
+
'rid' => [
|
28 |
+
'data' => 'rid',
|
29 |
+
'title' => 'ID',
|
30 |
+
'orderable' => true,
|
31 |
+
'searchable' => false,
|
32 |
+
'visible' => false,
|
33 |
+
],
|
34 |
+
'file' => [
|
35 |
+
'data' => 'file',
|
36 |
+
'title' => __( 'File' ),
|
37 |
+
'className' => 'file',
|
38 |
+
'orderable' => true,
|
39 |
+
'searchable' => true,
|
40 |
+
'visible' => true,
|
41 |
+
],
|
42 |
+
'file_as_href' => [
|
43 |
+
'data' => 'file_as_href',
|
44 |
+
'title' => __( 'File' ),
|
45 |
+
'className' => 'file_as_href',
|
46 |
+
'orderable' => true,
|
47 |
+
'searchable' => true,
|
48 |
+
'visible' => true,
|
49 |
+
],
|
50 |
+
'file_type' => [
|
51 |
+
'data' => 'file_type',
|
52 |
+
'title' => __( 'Type' ),
|
53 |
+
'className' => 'file_type',
|
54 |
+
'orderable' => true,
|
55 |
+
'searchable' => true,
|
56 |
+
'visible' => true,
|
57 |
+
],
|
58 |
+
'status' => [
|
59 |
+
'data' => 'status',
|
60 |
+
'title' => __( 'Status' ),
|
61 |
+
'className' => 'status',
|
62 |
+
'orderable' => true,
|
63 |
+
'searchable' => false,
|
64 |
+
'visible' => true,
|
65 |
+
],
|
66 |
+
'detected' => [
|
67 |
+
'data' => [
|
68 |
+
'_' => 'detected_since',
|
69 |
+
'sort' => 'detected_at',
|
70 |
+
],
|
71 |
+
'title' => __( 'Detected' ),
|
72 |
+
'className' => 'detected',
|
73 |
+
'orderable' => true,
|
74 |
+
'searchable' => false,
|
75 |
+
'visible' => true,
|
76 |
+
],
|
77 |
+
'actions' => [
|
78 |
+
'data' => 'actions',
|
79 |
+
'title' => __( 'Actions' ),
|
80 |
+
'className' => 'actions',
|
81 |
+
'orderable' => false,
|
82 |
+
'searchable' => false,
|
83 |
+
'visible' => true,
|
84 |
+
],
|
85 |
+
'fp_confidence' => [
|
86 |
+
'data' => 'fp_confidence',
|
87 |
+
'title' => __( 'False Positive Confidence' ),
|
88 |
+
'className' => 'fp_confidence',
|
89 |
+
'orderable' => true,
|
90 |
+
'searchable' => false,
|
91 |
+
'visible' => true,
|
92 |
+
],
|
93 |
+
'line_numbers' => [
|
94 |
+
'data' => 'line_numbers',
|
95 |
+
'title' => __( 'Line Numbers' ),
|
96 |
+
'className' => 'line_numbers',
|
97 |
+
'orderable' => false,
|
98 |
+
'searchable' => false,
|
99 |
+
'visible' => true,
|
100 |
+
],
|
101 |
+
'mal_sig' => [
|
102 |
+
'data' => 'mal_sig',
|
103 |
+
'title' => __( 'Pattern Detected' ),
|
104 |
+
'className' => 'mal_sig',
|
105 |
+
'orderable' => false,
|
106 |
+
'searchable' => true,
|
107 |
+
'visible' => true,
|
108 |
+
],
|
109 |
+
];
|
110 |
+
}
|
111 |
+
}
|
src/lib/src/Tables/DataTables/Build/Scans/ForMalware.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Scans;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
+
|
7 |
+
class ForMalware extends BaseForScan {
|
8 |
+
|
9 |
+
protected function getColumnsToDisplay() :array {
|
10 |
+
return [
|
11 |
+
'rid',
|
12 |
+
'file_as_href',
|
13 |
+
'status',
|
14 |
+
'fp_confidence',
|
15 |
+
'line_numbers',
|
16 |
+
'mal_sig',
|
17 |
+
'detected',
|
18 |
+
'actions',
|
19 |
+
];
|
20 |
+
}
|
21 |
+
|
22 |
+
protected function getColumnDefs() :array {
|
23 |
+
$colDefs = parent::getColumnDefs();
|
24 |
+
$colDefs[ 'fp_confidence' ] = [
|
25 |
+
'data' => 'fp_confidence',
|
26 |
+
'title' => __( 'False Positive Confidence' ),
|
27 |
+
'className' => 'fp_confidence',
|
28 |
+
'orderable' => true,
|
29 |
+
'searchable' => false,
|
30 |
+
'visible' => true,
|
31 |
+
];
|
32 |
+
$colDefs[ 'line_numbers' ] = [
|
33 |
+
'data' => 'line_numbers',
|
34 |
+
'title' => __( 'Line Numbers' ),
|
35 |
+
'className' => 'line_numbers',
|
36 |
+
'orderable' => false,
|
37 |
+
'searchable' => false,
|
38 |
+
'visible' => true,
|
39 |
+
];
|
40 |
+
$colDefs[ 'mal_sig' ] = [
|
41 |
+
'data' => 'mal_sig',
|
42 |
+
'title' => __( 'Pattern Detected' ),
|
43 |
+
'className' => 'mal_sig',
|
44 |
+
'orderable' => false,
|
45 |
+
'searchable' => true,
|
46 |
+
'visible' => true,
|
47 |
+
];
|
48 |
+
return $colDefs;
|
49 |
+
}
|
50 |
+
}
|
src/lib/src/Tables/DataTables/Build/Scans/ForPluginTheme.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Scans;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
+
|
7 |
+
class ForPluginTheme extends BaseForScan {
|
8 |
+
|
9 |
+
}
|
src/lib/src/Tables/DataTables/Build/Scans/ForWordpress.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Scans;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
+
|
7 |
+
class ForWordpress extends BaseForScan {
|
8 |
+
|
9 |
+
}
|
src/lib/src/Tables/Render/DataTable/Base.php
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
<?php declare( strict_types=1 );
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\Render\DataTable;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Tables\Render\Common\BaseTable;
|
7 |
-
|
8 |
-
class Base extends BaseTable {
|
9 |
-
|
10 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Tables/Render/DataTable/ScanBase.php
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
<?php declare( strict_types=1 );
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\Render\DataTable;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
-
|
7 |
-
class ScanBase extends Base {
|
8 |
-
|
9 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Tables/Render/DataTable/ScanWcf.php
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
<?php declare( strict_types=1 );
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\Render\DataTable;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
-
|
7 |
-
class ScanWcf extends ScanBase {
|
8 |
-
|
9 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Utilities/CacheDir.php
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Utilities;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib\TestCacheDirWrite;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class CacheDir {
|
10 |
+
|
11 |
+
use PluginControllerConsumer;
|
12 |
+
|
13 |
+
public function build() :string {
|
14 |
+
$con = $this->getCon();
|
15 |
+
|
16 |
+
$dir = '';
|
17 |
+
try {
|
18 |
+
$maybeDir = $this->getDir();
|
19 |
+
if ( !isset( $con->cache_dir_ready ) ) {
|
20 |
+
if ( !Services::WpFs()->mkdir( $maybeDir ) ) {
|
21 |
+
throw new \Exception( 'Failed to mkdir cache dir' );
|
22 |
+
}
|
23 |
+
$this->testWrite();
|
24 |
+
$this->addProtections();
|
25 |
+
$con->cache_dir_ready = true;
|
26 |
+
}
|
27 |
+
if ( $con->cache_dir_ready ) {
|
28 |
+
$dir = $maybeDir;
|
29 |
+
}
|
30 |
+
}
|
31 |
+
catch ( \Exception $e ) {
|
32 |
+
$con->cache_dir_ready = false;
|
33 |
+
}
|
34 |
+
return $dir;
|
35 |
+
}
|
36 |
+
|
37 |
+
public function buildSubDir( string $subDir ) :string {
|
38 |
+
$finalDir = '';
|
39 |
+
$baseDir = $this->build();
|
40 |
+
if ( !empty( $baseDir ) ) {
|
41 |
+
$FS = Services::WpFs();
|
42 |
+
$finalDir = path_join( $baseDir, $subDir );
|
43 |
+
if ( !$FS->mkdir( $finalDir ) ) {
|
44 |
+
$finalDir = '';
|
45 |
+
}
|
46 |
+
}
|
47 |
+
return $finalDir;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @return bool
|
52 |
+
* @throws \Exception
|
53 |
+
*/
|
54 |
+
private function testWrite() :bool {
|
55 |
+
$tester = ( new TestCacheDirWrite() )->setMod( $this->getCon()->getModule_Plugin() );
|
56 |
+
if ( !$tester->canWrite() ) {
|
57 |
+
throw new \Exception( 'Failed Test-Write' );
|
58 |
+
}
|
59 |
+
return true;
|
60 |
+
}
|
61 |
+
|
62 |
+
private function addProtections() :bool {
|
63 |
+
$FS = Services::WpFs();
|
64 |
+
$cacheDir = $this->getDir();
|
65 |
+
|
66 |
+
$htFile = path_join( $cacheDir, '.htaccess' );
|
67 |
+
$htContent = implode( "\n", [
|
68 |
+
"# BEGIN SHIELD",
|
69 |
+
"Options -Indexes",
|
70 |
+
"Order allow,deny",
|
71 |
+
"Deny from all",
|
72 |
+
'<FilesMatch "^.*\.(css|js)$">',
|
73 |
+
" Allow from all",
|
74 |
+
'</FilesMatch>',
|
75 |
+
"# END SHIELD"
|
76 |
+
] );
|
77 |
+
if ( !$FS->exists( $htFile ) || ( md5_file( $htFile ) !== md5( $htContent ) ) ) {
|
78 |
+
$FS->putFileContent( $htFile, $htContent );
|
79 |
+
}
|
80 |
+
$index = path_join( $cacheDir, 'index.php' );
|
81 |
+
$indexContent = "<?php\nhttp_response_code(404);";
|
82 |
+
if ( !$FS->exists( $index ) || ( md5_file( $index ) !== md5( $indexContent ) ) ) {
|
83 |
+
$FS->putFileContent( $index, $indexContent );
|
84 |
+
}
|
85 |
+
|
86 |
+
return true;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @return string
|
91 |
+
* @throws \Exception
|
92 |
+
*/
|
93 |
+
private function getDir() :string {
|
94 |
+
$con = $this->getCon();
|
95 |
+
if ( empty( $con->cfg->paths[ 'cache' ] ) ) {
|
96 |
+
throw new \Exception( 'No slug for cache dir' );
|
97 |
+
}
|
98 |
+
return $this->getCon()->paths->cacheDir();
|
99 |
+
}
|
100 |
+
}
|
src/lib/src/Utilities/HumanSpam/TestContent.php
CHANGED
@@ -46,8 +46,8 @@ class TestContent {
|
|
46 |
if ( empty( $this->list ) ) {
|
47 |
$FS = Services::WpFs();
|
48 |
$file = $this->getFile();
|
49 |
-
if ( !$FS->exists( $file )
|
50 |
-
|
51 |
$this->importBlacklist();
|
52 |
}
|
53 |
$this->list = array_map( 'base64_decode', explode( "\n", $FS->getFileContent( $file, true ) ) );
|
@@ -59,7 +59,7 @@ class TestContent {
|
|
59 |
$success = false;
|
60 |
$mod = $this->getCon()->getModule_Comments();
|
61 |
$rawList = Services::HttpRequest()->getContent( $mod->getOptions()->getDef( 'url_spam_blacklist_terms' ) );
|
62 |
-
if ( !empty( $rawList ) ) {
|
63 |
$success = Services::WpFs()->putFileContent(
|
64 |
$this->getFile(),
|
65 |
implode( "\n", array_map( 'base64_encode', array_filter( array_map( 'trim', explode( "\n", $rawList ) ) ) ) ),
|
@@ -70,6 +70,6 @@ class TestContent {
|
|
70 |
}
|
71 |
|
72 |
private function getFile() :string {
|
73 |
-
return $this->getCon()->
|
74 |
}
|
75 |
}
|
46 |
if ( empty( $this->list ) ) {
|
47 |
$FS = Services::WpFs();
|
48 |
$file = $this->getFile();
|
49 |
+
if ( !$FS->exists( $file )
|
50 |
+
|| Services::Request()->ts() - $FS->getModifiedTime( $file ) > MONTH_IN_SECONDS ) {
|
51 |
$this->importBlacklist();
|
52 |
}
|
53 |
$this->list = array_map( 'base64_decode', explode( "\n", $FS->getFileContent( $file, true ) ) );
|
59 |
$success = false;
|
60 |
$mod = $this->getCon()->getModule_Comments();
|
61 |
$rawList = Services::HttpRequest()->getContent( $mod->getOptions()->getDef( 'url_spam_blacklist_terms' ) );
|
62 |
+
if ( !empty( $rawList ) && !empty( $this->getFile() ) ) {
|
63 |
$success = Services::WpFs()->putFileContent(
|
64 |
$this->getFile(),
|
65 |
implode( "\n", array_map( 'base64_encode', array_filter( array_map( 'trim', explode( "\n", $rawList ) ) ) ) ),
|
70 |
}
|
71 |
|
72 |
private function getFile() :string {
|
73 |
+
return $this->getCon()->paths->forCacheItem( 'spamblacklist.txt' );
|
74 |
}
|
75 |
}
|
src/lib/src/Utilities/Resources/Dynamic.php
CHANGED
@@ -5,6 +5,11 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Utilities\Resources;
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
|
|
|
|
|
|
|
|
|
|
8 |
class Dynamic {
|
9 |
|
10 |
const RESOURCES_DIR = 'resources';
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
+
/**
|
9 |
+
* Class Dynamic
|
10 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Utilities\Resources
|
11 |
+
* @deprecated 11.4
|
12 |
+
*/
|
13 |
class Dynamic {
|
14 |
|
15 |
const RESOURCES_DIR = 'resources';
|
src/lib/src/Utilities/Tool/TmpFileStore.php
CHANGED
@@ -2,19 +2,19 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Utilities\Tool;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
|
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
class TmpFileStore {
|
9 |
|
|
|
10 |
use PluginControllerConsumer;
|
11 |
|
12 |
private static $slugs = [];
|
13 |
|
14 |
-
|
15 |
-
* @throws \Exception
|
16 |
-
*/
|
17 |
-
public function __construct() {
|
18 |
if ( $this->getCon()->hasCacheDir() ) {
|
19 |
add_action( $this->getCon()->prefix( 'plugin_shutdown' ), function () {
|
20 |
$FS = Services::WpFs();
|
@@ -33,8 +33,15 @@ class TmpFileStore {
|
|
33 |
* @return mixed|null
|
34 |
*/
|
35 |
public function load( string $slug ) {
|
36 |
-
$data =
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
}
|
39 |
|
40 |
public function store( string $slug, $data ) {
|
@@ -43,6 +50,8 @@ class TmpFileStore {
|
|
43 |
}
|
44 |
|
45 |
private function getTmpDir() :string {
|
46 |
-
return
|
|
|
|
|
47 |
}
|
48 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Utilities\Tool;
|
4 |
|
5 |
+
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\CacheDir;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
9 |
|
10 |
class TmpFileStore {
|
11 |
|
12 |
+
use ExecOnce;
|
13 |
use PluginControllerConsumer;
|
14 |
|
15 |
private static $slugs = [];
|
16 |
|
17 |
+
protected function run() {
|
|
|
|
|
|
|
18 |
if ( $this->getCon()->hasCacheDir() ) {
|
19 |
add_action( $this->getCon()->prefix( 'plugin_shutdown' ), function () {
|
20 |
$FS = Services::WpFs();
|
33 |
* @return mixed|null
|
34 |
*/
|
35 |
public function load( string $slug ) {
|
36 |
+
$data = null;
|
37 |
+
$tmpFile = path_join( $this->getTmpDir(), $slug );
|
38 |
+
if ( Services::WpFs()->isFile( $tmpFile ) ) {
|
39 |
+
$contents = Services::WpFs()->getFileContent( path_join( $this->getTmpDir(), $slug ) );
|
40 |
+
if ( !empty( $contents ) ) {
|
41 |
+
$data = unserialize( $contents );
|
42 |
+
}
|
43 |
+
}
|
44 |
+
return $data;
|
45 |
}
|
46 |
|
47 |
public function store( string $slug, $data ) {
|
50 |
}
|
51 |
|
52 |
private function getTmpDir() :string {
|
53 |
+
return ( new CacheDir() )
|
54 |
+
->setCon( $this->getCon() )
|
55 |
+
->buildSubDir( 'tmp_files' );
|
56 |
}
|
57 |
}
|
src/lib/vendor/composer/autoload_classmap.php
CHANGED
@@ -251,6 +251,7 @@ return array(
|
|
251 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => $baseDir . '/src/Modules/Base/ModCon.php',
|
252 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options' => $baseDir . '/src/Modules/Base/Options.php',
|
253 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options\\OptValueSanitize' => $baseDir . '/src/Modules/Base/Options/OptValueSanitize.php',
|
|
|
254 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Processor' => $baseDir . '/src/Modules/Base/Processor.php',
|
255 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Reporting' => $baseDir . '/src/Modules/Base/Reporting.php',
|
256 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\RestHandler' => $baseDir . '/src/Modules/Base/RestHandler.php',
|
@@ -291,7 +292,6 @@ return array(
|
|
291 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\EventsListener' => $baseDir . '/src/Modules/Events/Lib/EventsListener.php',
|
292 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\EventsService' => $baseDir . '/src/Modules/Events/Lib/EventsService.php',
|
293 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\Reports\\KeyStats' => $baseDir . '/src/Modules/Events/Lib/Reports/KeyStats.php',
|
294 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\Reports\\ScanRepairs' => $baseDir . '/src/Modules/Events/Lib/Reports/ScanRepairs.php',
|
295 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\StatsWriter' => $baseDir . '/src/Modules/Events/Lib/StatsWriter.php',
|
296 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\UI\\BuildDataForStats' => $baseDir . '/src/Modules/Events/Lib/UI/BuildDataForStats.php',
|
297 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\ModCon' => $baseDir . '/src/Modules/Events/ModCon.php',
|
@@ -333,6 +333,10 @@ return array(
|
|
333 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\FileLockerAlerts' => $baseDir . '/src/Modules/HackGuard/Lib/Reports/FileLockerAlerts.php',
|
334 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\Query\\ScanCounts' => $baseDir . '/src/Modules/HackGuard/Lib/Reports/Query/ScanCounts.php',
|
335 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\ScanAlerts' => $baseDir . '/src/Modules/HackGuard/Lib/Reports/ScanAlerts.php',
|
|
|
|
|
|
|
|
|
336 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForAsset' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForAsset.php',
|
337 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForCrowdSource' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForCrowdSource.php',
|
338 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromApi' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromApi.php',
|
@@ -351,9 +355,17 @@ return array(
|
|
351 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\ScheduleBuildAll' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/ScheduleBuildAll.php',
|
352 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\TouchAll' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/TouchAll.php',
|
353 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Utility\\FileDownloadHandler' => $baseDir . '/src/Modules/HackGuard/Lib/Utility/FileDownloadHandler.php',
|
|
|
354 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\ModCon' => $baseDir . '/src/Modules/HackGuard/ModCon.php',
|
355 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Options' => $baseDir . '/src/Modules/HackGuard/Options.php',
|
356 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Processor' => $baseDir . '/src/Modules/HackGuard/Processor.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
357 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Reporting' => $baseDir . '/src/Modules/HackGuard/Reporting.php',
|
358 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Scan\\Controller\\Apc' => $baseDir . '/src/Modules/HackGuard/Scan/Controller/Apc.php',
|
359 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Scan\\Controller\\Base' => $baseDir . '/src/Modules/HackGuard/Scan/Controller/Base.php',
|
@@ -472,6 +484,7 @@ return array(
|
|
472 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\KaliForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/KaliForms.php',
|
473 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\NinjaForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/NinjaForms.php',
|
474 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\SuperForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SuperForms.php',
|
|
|
475 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\WPForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WPForms.php',
|
476 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\WpForo' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WpForo.php',
|
477 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\SpamController' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/SpamController.php',
|
@@ -578,7 +591,6 @@ return array(
|
|
578 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\AntiBot\\ProtectionProviders\\GoogleRecaptcha' => $baseDir . '/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/GoogleRecaptcha.php',
|
579 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\AntiBot\\ProtectionProviders\\HCaptcha' => $baseDir . '/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/HCaptcha.php',
|
580 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownFlagFile' => $baseDir . '/src/Modules/LoginGuard/Lib/CooldownFlagFile.php',
|
581 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownRedirect' => $baseDir . '/src/Modules/LoginGuard/Lib/CooldownRedirect.php',
|
582 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\Rename\\RenameLogin' => $baseDir . '/src/Modules/LoginGuard/Lib/Rename/RenameLogin.php',
|
583 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\LoginIntentPage' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php',
|
584 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\MfaController' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php',
|
@@ -734,7 +746,6 @@ return array(
|
|
734 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\WpCli\\SessionTerminate' => $baseDir . '/src/Modules/UserManagement/WpCli/SessionTerminate.php',
|
735 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Render\\LocateTemplateDirs' => $baseDir . '/src/Render/LocateTemplateDirs.php',
|
736 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\BuildScanAction' => $baseDir . '/src/Scans/Apc/BuildScanAction.php',
|
737 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ConvertVosToResults' => $baseDir . '/src/Scans/Apc/ConvertVosToResults.php',
|
738 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\PluginScanner' => $baseDir . '/src/Scans/Apc/PluginScanner.php',
|
739 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultItem' => $baseDir . '/src/Scans/Apc/ResultItem.php',
|
740 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultsSet' => $baseDir . '/src/Scans/Apc/ResultsSet.php',
|
@@ -742,17 +753,19 @@ return array(
|
|
742 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ScanActionVO' => $baseDir . '/src/Scans/Apc/ScanActionVO.php',
|
743 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Apc/Utilities/ItemActionHandler.php',
|
744 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\Repair' => $baseDir . '/src/Scans/Apc/Utilities/Repair.php',
|
|
|
745 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseBuildScanAction' => $baseDir . '/src/Scans/Base/BaseBuildScanAction.php',
|
746 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\
|
747 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseMergeItems' => $baseDir . '/src/Scans/Base/BaseMergeItems.php',
|
748 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseResultItem' => $baseDir . '/src/Scans/Base/BaseResultItem.php',
|
749 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseResultsSet' => $baseDir . '/src/Scans/Base/BaseResultsSet.php',
|
750 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScan' => $baseDir . '/src/Scans/Base/BaseScan.php',
|
751 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScanActionVO' => $baseDir . '/src/Scans/Base/BaseScanActionVO.php',
|
752 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\DiffResultForStorage' => $baseDir . '/src/Scans/Base/DiffResultForStorage.php',
|
|
|
753 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileMapScan' => $baseDir . '/src/Scans/Base/Files/BaseFileMapScan.php',
|
754 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileScanner' => $baseDir . '/src/Scans/Base/Files/BaseFileScanner.php',
|
755 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseScanFromFileMap' => $baseDir . '/src/Scans/Base/Files/BaseScanFromFileMap.php',
|
|
|
|
|
756 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Table\\BaseEntryFormatter' => $baseDir . '/src/Scans/Base/Table/BaseEntryFormatter.php',
|
757 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Table\\BaseFileEntryFormatter' => $baseDir . '/src/Scans/Base/Table/BaseFileEntryFormatter.php',
|
758 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BaseRepair' => $baseDir . '/src/Scans/Base/Utilities/BaseRepair.php',
|
@@ -793,7 +806,6 @@ return array(
|
|
793 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\Repair' => $baseDir . '/src/Scans/Ptg/Utilities/Repair.php',
|
794 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\BuildFileMap' => $baseDir . '/src/Scans/Ufc/BuildFileMap.php',
|
795 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\BuildScanAction' => $baseDir . '/src/Scans/Ufc/BuildScanAction.php',
|
796 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ConvertVosToResults' => $baseDir . '/src/Scans/Ufc/ConvertVosToResults.php',
|
797 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\FileScanner' => $baseDir . '/src/Scans/Ufc/FileScanner.php',
|
798 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ResultItem' => $baseDir . '/src/Scans/Ufc/ResultItem.php',
|
799 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ResultsSet' => $baseDir . '/src/Scans/Ufc/ResultsSet.php',
|
@@ -805,7 +817,6 @@ return array(
|
|
805 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\Utilities\\Repair' => $baseDir . '/src/Scans/Ufc/Utilities/Repair.php',
|
806 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\BuildFileMap' => $baseDir . '/src/Scans/Wcf/BuildFileMap.php',
|
807 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\BuildScanAction' => $baseDir . '/src/Scans/Wcf/BuildScanAction.php',
|
808 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ConvertVosToResults' => $baseDir . '/src/Scans/Wcf/ConvertVosToResults.php',
|
809 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\FileScanner' => $baseDir . '/src/Scans/Wcf/FileScanner.php',
|
810 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ResultItem' => $baseDir . '/src/Scans/Wcf/ResultItem.php',
|
811 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ResultsSet' => $baseDir . '/src/Scans/Wcf/ResultsSet.php',
|
@@ -816,7 +827,6 @@ return array(
|
|
816 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Wcf/Utilities/ItemActionHandler.php',
|
817 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\Utilities\\Repair' => $baseDir . '/src/Scans/Wcf/Utilities/Repair.php',
|
818 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\BuildScanAction' => $baseDir . '/src/Scans/Wpv/BuildScanAction.php',
|
819 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ConvertVosToResults' => $baseDir . '/src/Scans/Wpv/ConvertVosToResults.php',
|
820 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultItem' => $baseDir . '/src/Scans/Wpv/ResultItem.php',
|
821 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultsSet' => $baseDir . '/src/Scans/Wpv/ResultsSet.php',
|
822 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Scan' => $baseDir . '/src/Scans/Wpv/Scan.php',
|
@@ -854,10 +864,13 @@ return array(
|
|
854 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\ScanWpv' => $baseDir . '/src/Tables/Build/ScanWpv.php',
|
855 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\Sessions' => $baseDir . '/src/Tables/Build/Sessions.php',
|
856 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\Traffic' => $baseDir . '/src/Tables/Build/Traffic.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
857 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\Common\\BaseTable' => $baseDir . '/src/Tables/Render/Common/BaseTable.php',
|
858 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\DataTable\\Base' => $baseDir . '/src/Tables/Render/DataTable/Base.php',
|
859 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\DataTable\\ScanBase' => $baseDir . '/src/Tables/Render/DataTable/ScanBase.php',
|
860 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\DataTable\\ScanWcf' => $baseDir . '/src/Tables/Render/DataTable/ScanWcf.php',
|
861 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpCliTable\\AuditTrail' => $baseDir . '/src/Tables/Render/WpCliTable/AuditTrail.php',
|
862 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpCliTable\\Base' => $baseDir . '/src/Tables/Render/WpCliTable/Base.php',
|
863 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpListTable\\AdminNotes' => $baseDir . '/src/Tables/Render/WpListTable/AdminNotes.php',
|
@@ -881,6 +894,7 @@ return array(
|
|
881 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Users\\ShieldUserMeta' => $baseDir . '/src/Users/ShieldUserMeta.php',
|
882 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\Controller' => $baseDir . '/src/Utilities/AdminNotices/Controller.php',
|
883 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\NoticeVO' => $baseDir . '/src/Utilities/AdminNotices/NoticeVO.php',
|
|
|
884 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Changelog\\Retrieve' => $baseDir . '/src/Utilities/Changelog/Retrieve.php',
|
885 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Consumer\\WpLoginCapture' => $baseDir . '/src/Utilities/Consumer/WpLoginCapture.php',
|
886 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Consumer\\WpUserConsumer' => $baseDir . '/src/Utilities/Consumer/WpUserConsumer.php',
|
@@ -933,9 +947,11 @@ return array(
|
|
933 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
934 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
|
935 |
'FernleafSystems\\Wordpress\\Services\\Services' => $vendorDir . '/fernleafsystems/wordpress-services/src/Services.php',
|
|
|
936 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Autoloading\\FindClassFromNamespaceRoots' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php',
|
937 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
|
938 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
|
|
|
939 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Constants\\Regex' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Constants/Regex.php',
|
940 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Consumers\\PluginConsumer' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Consumers/PluginConsumer.php',
|
941 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Data' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Data.php',
|
251 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => $baseDir . '/src/Modules/Base/ModCon.php',
|
252 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options' => $baseDir . '/src/Modules/Base/Options.php',
|
253 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options\\OptValueSanitize' => $baseDir . '/src/Modules/Base/Options/OptValueSanitize.php',
|
254 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options\\WildCardOptions' => $baseDir . '/src/Modules/Base/Options/WildCardOptions.php',
|
255 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Processor' => $baseDir . '/src/Modules/Base/Processor.php',
|
256 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Reporting' => $baseDir . '/src/Modules/Base/Reporting.php',
|
257 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\RestHandler' => $baseDir . '/src/Modules/Base/RestHandler.php',
|
292 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\EventsListener' => $baseDir . '/src/Modules/Events/Lib/EventsListener.php',
|
293 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\EventsService' => $baseDir . '/src/Modules/Events/Lib/EventsService.php',
|
294 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\Reports\\KeyStats' => $baseDir . '/src/Modules/Events/Lib/Reports/KeyStats.php',
|
|
|
295 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\StatsWriter' => $baseDir . '/src/Modules/Events/Lib/StatsWriter.php',
|
296 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\UI\\BuildDataForStats' => $baseDir . '/src/Modules/Events/Lib/UI/BuildDataForStats.php',
|
297 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\ModCon' => $baseDir . '/src/Modules/Events/ModCon.php',
|
333 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\FileLockerAlerts' => $baseDir . '/src/Modules/HackGuard/Lib/Reports/FileLockerAlerts.php',
|
334 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\Query\\ScanCounts' => $baseDir . '/src/Modules/HackGuard/Lib/Reports/Query/ScanCounts.php',
|
335 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\ScanAlerts' => $baseDir . '/src/Modules/HackGuard/Lib/Reports/ScanAlerts.php',
|
336 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\ScanRepairs' => $baseDir . '/src/Modules/HackGuard/Lib/Reports/ScanRepairs.php',
|
337 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\ScanTables\\DelegateAjaxHandler' => $baseDir . '/src/Modules/HackGuard/Lib/ScanTables/DelegateAjaxHandler.php',
|
338 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\ScanTables\\LoadRawTableData' => $baseDir . '/src/Modules/HackGuard/Lib/ScanTables/LoadRawTableData.php',
|
339 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\ScanTables\\RetrieveFileContents' => $baseDir . '/src/Modules/HackGuard/Lib/ScanTables/RetrieveFileContents.php',
|
340 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForAsset' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForAsset.php',
|
341 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForCrowdSource' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForCrowdSource.php',
|
342 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromApi' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromApi.php',
|
355 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\ScheduleBuildAll' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/ScheduleBuildAll.php',
|
356 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\TouchAll' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/TouchAll.php',
|
357 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Utility\\FileDownloadHandler' => $baseDir . '/src/Modules/HackGuard/Lib/Utility/FileDownloadHandler.php',
|
358 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Utility\\VerifyFileByHash' => $baseDir . '/src/Modules/HackGuard/Lib/Utility/VerifyFileByHash.php',
|
359 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\ModCon' => $baseDir . '/src/Modules/HackGuard/ModCon.php',
|
360 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Options' => $baseDir . '/src/Modules/HackGuard/Options.php',
|
361 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Processor' => $baseDir . '/src/Modules/HackGuard/Processor.php',
|
362 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionBase' => $baseDir . '/src/Modules/HackGuard/Render/ScanResults/SectionBase.php',
|
363 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionLogs' => $baseDir . '/src/Modules/HackGuard/Render/ScanResults/SectionLogs.php',
|
364 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionMalware' => $baseDir . '/src/Modules/HackGuard/Render/ScanResults/SectionMalware.php',
|
365 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionPluginThemesBase' => $baseDir . '/src/Modules/HackGuard/Render/ScanResults/SectionPluginThemesBase.php',
|
366 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionPlugins' => $baseDir . '/src/Modules/HackGuard/Render/ScanResults/SectionPlugins.php',
|
367 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionThemes' => $baseDir . '/src/Modules/HackGuard/Render/ScanResults/SectionThemes.php',
|
368 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionWordpress' => $baseDir . '/src/Modules/HackGuard/Render/ScanResults/SectionWordpress.php',
|
369 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Reporting' => $baseDir . '/src/Modules/HackGuard/Reporting.php',
|
370 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Scan\\Controller\\Apc' => $baseDir . '/src/Modules/HackGuard/Scan/Controller/Apc.php',
|
371 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Scan\\Controller\\Base' => $baseDir . '/src/Modules/HackGuard/Scan/Controller/Base.php',
|
484 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\KaliForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/KaliForms.php',
|
485 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\NinjaForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/NinjaForms.php',
|
486 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\SuperForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SuperForms.php',
|
487 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\SupportCandy' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SupportCandy.php',
|
488 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\WPForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WPForms.php',
|
489 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\WpForo' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WpForo.php',
|
490 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\SpamController' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/SpamController.php',
|
591 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\AntiBot\\ProtectionProviders\\GoogleRecaptcha' => $baseDir . '/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/GoogleRecaptcha.php',
|
592 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\AntiBot\\ProtectionProviders\\HCaptcha' => $baseDir . '/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/HCaptcha.php',
|
593 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownFlagFile' => $baseDir . '/src/Modules/LoginGuard/Lib/CooldownFlagFile.php',
|
|
|
594 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\Rename\\RenameLogin' => $baseDir . '/src/Modules/LoginGuard/Lib/Rename/RenameLogin.php',
|
595 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\LoginIntentPage' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php',
|
596 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\MfaController' => $baseDir . '/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php',
|
746 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\WpCli\\SessionTerminate' => $baseDir . '/src/Modules/UserManagement/WpCli/SessionTerminate.php',
|
747 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Render\\LocateTemplateDirs' => $baseDir . '/src/Render/LocateTemplateDirs.php',
|
748 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\BuildScanAction' => $baseDir . '/src/Scans/Apc/BuildScanAction.php',
|
|
|
749 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\PluginScanner' => $baseDir . '/src/Scans/Apc/PluginScanner.php',
|
750 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultItem' => $baseDir . '/src/Scans/Apc/ResultItem.php',
|
751 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultsSet' => $baseDir . '/src/Scans/Apc/ResultsSet.php',
|
753 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ScanActionVO' => $baseDir . '/src/Scans/Apc/ScanActionVO.php',
|
754 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Apc/Utilities/ItemActionHandler.php',
|
755 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\Repair' => $baseDir . '/src/Scans/Apc/Utilities/Repair.php',
|
756 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseBuildFileMap' => $baseDir . '/src/Scans/Base/BaseBuildFileMap.php',
|
757 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseBuildScanAction' => $baseDir . '/src/Scans/Base/BaseBuildScanAction.php',
|
758 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseFileScanActionVO' => $baseDir . '/src/Scans/Base/BaseFileScanActionVO.php',
|
759 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseMergeItems' => $baseDir . '/src/Scans/Base/BaseMergeItems.php',
|
|
|
|
|
760 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScan' => $baseDir . '/src/Scans/Base/BaseScan.php',
|
761 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScanActionVO' => $baseDir . '/src/Scans/Base/BaseScanActionVO.php',
|
762 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\DiffResultForStorage' => $baseDir . '/src/Scans/Base/DiffResultForStorage.php',
|
763 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\FileResultItem' => $baseDir . '/src/Scans/Base/FileResultItem.php',
|
764 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileMapScan' => $baseDir . '/src/Scans/Base/Files/BaseFileMapScan.php',
|
765 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileScanner' => $baseDir . '/src/Scans/Base/Files/BaseFileScanner.php',
|
766 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseScanFromFileMap' => $baseDir . '/src/Scans/Base/Files/BaseScanFromFileMap.php',
|
767 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultItem' => $baseDir . '/src/Scans/Base/ResultItem.php',
|
768 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultsSet' => $baseDir . '/src/Scans/Base/ResultsSet.php',
|
769 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Table\\BaseEntryFormatter' => $baseDir . '/src/Scans/Base/Table/BaseEntryFormatter.php',
|
770 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Table\\BaseFileEntryFormatter' => $baseDir . '/src/Scans/Base/Table/BaseFileEntryFormatter.php',
|
771 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BaseRepair' => $baseDir . '/src/Scans/Base/Utilities/BaseRepair.php',
|
806 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\Repair' => $baseDir . '/src/Scans/Ptg/Utilities/Repair.php',
|
807 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\BuildFileMap' => $baseDir . '/src/Scans/Ufc/BuildFileMap.php',
|
808 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\BuildScanAction' => $baseDir . '/src/Scans/Ufc/BuildScanAction.php',
|
|
|
809 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\FileScanner' => $baseDir . '/src/Scans/Ufc/FileScanner.php',
|
810 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ResultItem' => $baseDir . '/src/Scans/Ufc/ResultItem.php',
|
811 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ResultsSet' => $baseDir . '/src/Scans/Ufc/ResultsSet.php',
|
817 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\Utilities\\Repair' => $baseDir . '/src/Scans/Ufc/Utilities/Repair.php',
|
818 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\BuildFileMap' => $baseDir . '/src/Scans/Wcf/BuildFileMap.php',
|
819 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\BuildScanAction' => $baseDir . '/src/Scans/Wcf/BuildScanAction.php',
|
|
|
820 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\FileScanner' => $baseDir . '/src/Scans/Wcf/FileScanner.php',
|
821 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ResultItem' => $baseDir . '/src/Scans/Wcf/ResultItem.php',
|
822 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ResultsSet' => $baseDir . '/src/Scans/Wcf/ResultsSet.php',
|
827 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Wcf/Utilities/ItemActionHandler.php',
|
828 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\Utilities\\Repair' => $baseDir . '/src/Scans/Wcf/Utilities/Repair.php',
|
829 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\BuildScanAction' => $baseDir . '/src/Scans/Wpv/BuildScanAction.php',
|
|
|
830 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultItem' => $baseDir . '/src/Scans/Wpv/ResultItem.php',
|
831 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultsSet' => $baseDir . '/src/Scans/Wpv/ResultsSet.php',
|
832 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Scan' => $baseDir . '/src/Scans/Wpv/Scan.php',
|
864 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\ScanWpv' => $baseDir . '/src/Tables/Build/ScanWpv.php',
|
865 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\Sessions' => $baseDir . '/src/Tables/Build/Sessions.php',
|
866 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\Traffic' => $baseDir . '/src/Tables/Build/Traffic.php',
|
867 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\AuditTrail\\ForAuditTrail' => $baseDir . '/src/Tables/DataTables/Build/AuditTrail/ForAuditTrail.php',
|
868 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\Base' => $baseDir . '/src/Tables/DataTables/Build/Base.php',
|
869 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\Scans\\BaseForScan' => $baseDir . '/src/Tables/DataTables/Build/Scans/BaseForScan.php',
|
870 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\Scans\\ForMalware' => $baseDir . '/src/Tables/DataTables/Build/Scans/ForMalware.php',
|
871 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\Scans\\ForPluginTheme' => $baseDir . '/src/Tables/DataTables/Build/Scans/ForPluginTheme.php',
|
872 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\Scans\\ForWordpress' => $baseDir . '/src/Tables/DataTables/Build/Scans/ForWordpress.php',
|
873 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\Common\\BaseTable' => $baseDir . '/src/Tables/Render/Common/BaseTable.php',
|
|
|
|
|
|
|
874 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpCliTable\\AuditTrail' => $baseDir . '/src/Tables/Render/WpCliTable/AuditTrail.php',
|
875 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpCliTable\\Base' => $baseDir . '/src/Tables/Render/WpCliTable/Base.php',
|
876 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpListTable\\AdminNotes' => $baseDir . '/src/Tables/Render/WpListTable/AdminNotes.php',
|
894 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Users\\ShieldUserMeta' => $baseDir . '/src/Users/ShieldUserMeta.php',
|
895 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\Controller' => $baseDir . '/src/Utilities/AdminNotices/Controller.php',
|
896 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\NoticeVO' => $baseDir . '/src/Utilities/AdminNotices/NoticeVO.php',
|
897 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\CacheDir' => $baseDir . '/src/Utilities/CacheDir.php',
|
898 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Changelog\\Retrieve' => $baseDir . '/src/Utilities/Changelog/Retrieve.php',
|
899 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Consumer\\WpLoginCapture' => $baseDir . '/src/Utilities/Consumer/WpLoginCapture.php',
|
900 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Consumer\\WpUserConsumer' => $baseDir . '/src/Utilities/Consumer/WpUserConsumer.php',
|
947 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
948 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
|
949 |
'FernleafSystems\\Wordpress\\Services\\Services' => $vendorDir . '/fernleafsystems/wordpress-services/src/Services.php',
|
950 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Assets\\DetectInstallationDate' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Assets/DetectInstallationDate.php',
|
951 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Autoloading\\FindClassFromNamespaceRoots' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php',
|
952 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
|
953 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
|
954 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Code\\AssessPhpFile' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Code/AssessPhpFile.php',
|
955 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Constants\\Regex' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Constants/Regex.php',
|
956 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Consumers\\PluginConsumer' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Consumers/PluginConsumer.php',
|
957 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Data' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Data.php',
|
src/lib/vendor/composer/autoload_static.php
CHANGED
@@ -424,6 +424,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
424 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Base/ModCon.php',
|
425 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options' => __DIR__ . '/../..' . '/src/Modules/Base/Options.php',
|
426 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options\\OptValueSanitize' => __DIR__ . '/../..' . '/src/Modules/Base/Options/OptValueSanitize.php',
|
|
|
427 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Processor' => __DIR__ . '/../..' . '/src/Modules/Base/Processor.php',
|
428 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Reporting' => __DIR__ . '/../..' . '/src/Modules/Base/Reporting.php',
|
429 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\RestHandler' => __DIR__ . '/../..' . '/src/Modules/Base/RestHandler.php',
|
@@ -464,7 +465,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
464 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\EventsListener' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/EventsListener.php',
|
465 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\EventsService' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/EventsService.php',
|
466 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\Reports\\KeyStats' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/Reports/KeyStats.php',
|
467 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\Reports\\ScanRepairs' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/Reports/ScanRepairs.php',
|
468 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\StatsWriter' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/StatsWriter.php',
|
469 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\UI\\BuildDataForStats' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/UI/BuildDataForStats.php',
|
470 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Events/ModCon.php',
|
@@ -506,6 +506,10 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
506 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\FileLockerAlerts' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Reports/FileLockerAlerts.php',
|
507 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\Query\\ScanCounts' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Reports/Query/ScanCounts.php',
|
508 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\ScanAlerts' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Reports/ScanAlerts.php',
|
|
|
|
|
|
|
|
|
509 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForAsset' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForAsset.php',
|
510 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForCrowdSource' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForCrowdSource.php',
|
511 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromApi' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromApi.php',
|
@@ -524,9 +528,17 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
524 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\ScheduleBuildAll' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/ScheduleBuildAll.php',
|
525 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\TouchAll' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/TouchAll.php',
|
526 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Utility\\FileDownloadHandler' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Utility/FileDownloadHandler.php',
|
|
|
527 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\ModCon' => __DIR__ . '/../..' . '/src/Modules/HackGuard/ModCon.php',
|
528 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Options' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Options.php',
|
529 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Processor' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Processor.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
530 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Reporting' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Reporting.php',
|
531 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Scan\\Controller\\Apc' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Scan/Controller/Apc.php',
|
532 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Scan\\Controller\\Base' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Scan/Controller/Base.php',
|
@@ -645,6 +657,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
645 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\KaliForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/KaliForms.php',
|
646 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\NinjaForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/NinjaForms.php',
|
647 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\SuperForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SuperForms.php',
|
|
|
648 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\WPForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WPForms.php',
|
649 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\WpForo' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WpForo.php',
|
650 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\SpamController' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/SpamController.php',
|
@@ -751,7 +764,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
751 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\AntiBot\\ProtectionProviders\\GoogleRecaptcha' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/GoogleRecaptcha.php',
|
752 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\AntiBot\\ProtectionProviders\\HCaptcha' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/HCaptcha.php',
|
753 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownFlagFile' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/CooldownFlagFile.php',
|
754 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownRedirect' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/CooldownRedirect.php',
|
755 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\Rename\\RenameLogin' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/Rename/RenameLogin.php',
|
756 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\LoginIntentPage' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php',
|
757 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\MfaController' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php',
|
@@ -907,7 +919,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
907 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\WpCli\\SessionTerminate' => __DIR__ . '/../..' . '/src/Modules/UserManagement/WpCli/SessionTerminate.php',
|
908 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Render\\LocateTemplateDirs' => __DIR__ . '/../..' . '/src/Render/LocateTemplateDirs.php',
|
909 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Apc/BuildScanAction.php',
|
910 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ConvertVosToResults' => __DIR__ . '/../..' . '/src/Scans/Apc/ConvertVosToResults.php',
|
911 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\PluginScanner' => __DIR__ . '/../..' . '/src/Scans/Apc/PluginScanner.php',
|
912 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Apc/ResultItem.php',
|
913 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Apc/ResultsSet.php',
|
@@ -915,17 +926,19 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
915 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Apc/ScanActionVO.php',
|
916 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Apc/Utilities/ItemActionHandler.php',
|
917 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Apc/Utilities/Repair.php',
|
|
|
918 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseBuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Base/BaseBuildScanAction.php',
|
919 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\
|
920 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseMergeItems' => __DIR__ . '/../..' . '/src/Scans/Base/BaseMergeItems.php',
|
921 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseResultItem' => __DIR__ . '/../..' . '/src/Scans/Base/BaseResultItem.php',
|
922 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseResultsSet' => __DIR__ . '/../..' . '/src/Scans/Base/BaseResultsSet.php',
|
923 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScan' => __DIR__ . '/../..' . '/src/Scans/Base/BaseScan.php',
|
924 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Base/BaseScanActionVO.php',
|
925 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\DiffResultForStorage' => __DIR__ . '/../..' . '/src/Scans/Base/DiffResultForStorage.php',
|
|
|
926 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileMapScan' => __DIR__ . '/../..' . '/src/Scans/Base/Files/BaseFileMapScan.php',
|
927 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileScanner' => __DIR__ . '/../..' . '/src/Scans/Base/Files/BaseFileScanner.php',
|
928 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseScanFromFileMap' => __DIR__ . '/../..' . '/src/Scans/Base/Files/BaseScanFromFileMap.php',
|
|
|
|
|
929 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Table\\BaseEntryFormatter' => __DIR__ . '/../..' . '/src/Scans/Base/Table/BaseEntryFormatter.php',
|
930 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Table\\BaseFileEntryFormatter' => __DIR__ . '/../..' . '/src/Scans/Base/Table/BaseFileEntryFormatter.php',
|
931 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BaseRepair' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/BaseRepair.php',
|
@@ -966,7 +979,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
966 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Ptg/Utilities/Repair.php',
|
967 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\BuildFileMap' => __DIR__ . '/../..' . '/src/Scans/Ufc/BuildFileMap.php',
|
968 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Ufc/BuildScanAction.php',
|
969 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ConvertVosToResults' => __DIR__ . '/../..' . '/src/Scans/Ufc/ConvertVosToResults.php',
|
970 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\FileScanner' => __DIR__ . '/../..' . '/src/Scans/Ufc/FileScanner.php',
|
971 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Ufc/ResultItem.php',
|
972 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Ufc/ResultsSet.php',
|
@@ -978,7 +990,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
978 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Ufc/Utilities/Repair.php',
|
979 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\BuildFileMap' => __DIR__ . '/../..' . '/src/Scans/Wcf/BuildFileMap.php',
|
980 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Wcf/BuildScanAction.php',
|
981 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ConvertVosToResults' => __DIR__ . '/../..' . '/src/Scans/Wcf/ConvertVosToResults.php',
|
982 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\FileScanner' => __DIR__ . '/../..' . '/src/Scans/Wcf/FileScanner.php',
|
983 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Wcf/ResultItem.php',
|
984 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Wcf/ResultsSet.php',
|
@@ -989,7 +1000,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
989 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Wcf/Utilities/ItemActionHandler.php',
|
990 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Wcf/Utilities/Repair.php',
|
991 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Wpv/BuildScanAction.php',
|
992 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ConvertVosToResults' => __DIR__ . '/../..' . '/src/Scans/Wpv/ConvertVosToResults.php',
|
993 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Wpv/ResultItem.php',
|
994 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Wpv/ResultsSet.php',
|
995 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Scan' => __DIR__ . '/../..' . '/src/Scans/Wpv/Scan.php',
|
@@ -1027,10 +1037,13 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
1027 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\ScanWpv' => __DIR__ . '/../..' . '/src/Tables/Build/ScanWpv.php',
|
1028 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\Sessions' => __DIR__ . '/../..' . '/src/Tables/Build/Sessions.php',
|
1029 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\Traffic' => __DIR__ . '/../..' . '/src/Tables/Build/Traffic.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
1030 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\Common\\BaseTable' => __DIR__ . '/../..' . '/src/Tables/Render/Common/BaseTable.php',
|
1031 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\DataTable\\Base' => __DIR__ . '/../..' . '/src/Tables/Render/DataTable/Base.php',
|
1032 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\DataTable\\ScanBase' => __DIR__ . '/../..' . '/src/Tables/Render/DataTable/ScanBase.php',
|
1033 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\DataTable\\ScanWcf' => __DIR__ . '/../..' . '/src/Tables/Render/DataTable/ScanWcf.php',
|
1034 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpCliTable\\AuditTrail' => __DIR__ . '/../..' . '/src/Tables/Render/WpCliTable/AuditTrail.php',
|
1035 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpCliTable\\Base' => __DIR__ . '/../..' . '/src/Tables/Render/WpCliTable/Base.php',
|
1036 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpListTable\\AdminNotes' => __DIR__ . '/../..' . '/src/Tables/Render/WpListTable/AdminNotes.php',
|
@@ -1054,6 +1067,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
1054 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Users\\ShieldUserMeta' => __DIR__ . '/../..' . '/src/Users/ShieldUserMeta.php',
|
1055 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\Controller' => __DIR__ . '/../..' . '/src/Utilities/AdminNotices/Controller.php',
|
1056 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\NoticeVO' => __DIR__ . '/../..' . '/src/Utilities/AdminNotices/NoticeVO.php',
|
|
|
1057 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Changelog\\Retrieve' => __DIR__ . '/../..' . '/src/Utilities/Changelog/Retrieve.php',
|
1058 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Consumer\\WpLoginCapture' => __DIR__ . '/../..' . '/src/Utilities/Consumer/WpLoginCapture.php',
|
1059 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Consumer\\WpUserConsumer' => __DIR__ . '/../..' . '/src/Utilities/Consumer/WpUserConsumer.php',
|
@@ -1106,9 +1120,11 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
1106 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
1107 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
|
1108 |
'FernleafSystems\\Wordpress\\Services\\Services' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Services.php',
|
|
|
1109 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Autoloading\\FindClassFromNamespaceRoots' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php',
|
1110 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
|
1111 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
|
|
|
1112 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Constants\\Regex' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Constants/Regex.php',
|
1113 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Consumers\\PluginConsumer' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Consumers/PluginConsumer.php',
|
1114 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Data' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Data.php',
|
424 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Base/ModCon.php',
|
425 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options' => __DIR__ . '/../..' . '/src/Modules/Base/Options.php',
|
426 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options\\OptValueSanitize' => __DIR__ . '/../..' . '/src/Modules/Base/Options/OptValueSanitize.php',
|
427 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options\\WildCardOptions' => __DIR__ . '/../..' . '/src/Modules/Base/Options/WildCardOptions.php',
|
428 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Processor' => __DIR__ . '/../..' . '/src/Modules/Base/Processor.php',
|
429 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Reporting' => __DIR__ . '/../..' . '/src/Modules/Base/Reporting.php',
|
430 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\RestHandler' => __DIR__ . '/../..' . '/src/Modules/Base/RestHandler.php',
|
465 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\EventsListener' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/EventsListener.php',
|
466 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\EventsService' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/EventsService.php',
|
467 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\Reports\\KeyStats' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/Reports/KeyStats.php',
|
|
|
468 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\StatsWriter' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/StatsWriter.php',
|
469 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Lib\\UI\\BuildDataForStats' => __DIR__ . '/../..' . '/src/Modules/Events/Lib/UI/BuildDataForStats.php',
|
470 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Events/ModCon.php',
|
506 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\FileLockerAlerts' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Reports/FileLockerAlerts.php',
|
507 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\Query\\ScanCounts' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Reports/Query/ScanCounts.php',
|
508 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\ScanAlerts' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Reports/ScanAlerts.php',
|
509 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Reports\\ScanRepairs' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Reports/ScanRepairs.php',
|
510 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\ScanTables\\DelegateAjaxHandler' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/ScanTables/DelegateAjaxHandler.php',
|
511 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\ScanTables\\LoadRawTableData' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/ScanTables/LoadRawTableData.php',
|
512 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\ScanTables\\RetrieveFileContents' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/ScanTables/RetrieveFileContents.php',
|
513 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForAsset' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForAsset.php',
|
514 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForCrowdSource' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForCrowdSource.php',
|
515 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromApi' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromApi.php',
|
528 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\ScheduleBuildAll' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/ScheduleBuildAll.php',
|
529 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\TouchAll' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/TouchAll.php',
|
530 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Utility\\FileDownloadHandler' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Utility/FileDownloadHandler.php',
|
531 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Utility\\VerifyFileByHash' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Utility/VerifyFileByHash.php',
|
532 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\ModCon' => __DIR__ . '/../..' . '/src/Modules/HackGuard/ModCon.php',
|
533 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Options' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Options.php',
|
534 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Processor' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Processor.php',
|
535 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionBase' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Render/ScanResults/SectionBase.php',
|
536 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionLogs' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Render/ScanResults/SectionLogs.php',
|
537 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionMalware' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Render/ScanResults/SectionMalware.php',
|
538 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionPluginThemesBase' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Render/ScanResults/SectionPluginThemesBase.php',
|
539 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionPlugins' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Render/ScanResults/SectionPlugins.php',
|
540 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionThemes' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Render/ScanResults/SectionThemes.php',
|
541 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Render\\ScanResults\\SectionWordpress' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Render/ScanResults/SectionWordpress.php',
|
542 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Reporting' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Reporting.php',
|
543 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Scan\\Controller\\Apc' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Scan/Controller/Apc.php',
|
544 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Scan\\Controller\\Base' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Scan/Controller/Base.php',
|
657 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\KaliForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/KaliForms.php',
|
658 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\NinjaForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/NinjaForms.php',
|
659 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\SuperForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SuperForms.php',
|
660 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\SupportCandy' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SupportCandy.php',
|
661 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\WPForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WPForms.php',
|
662 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\WpForo' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WpForo.php',
|
663 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\SpamController' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/SpamController.php',
|
764 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\AntiBot\\ProtectionProviders\\GoogleRecaptcha' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/GoogleRecaptcha.php',
|
765 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\AntiBot\\ProtectionProviders\\HCaptcha' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/HCaptcha.php',
|
766 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\CooldownFlagFile' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/CooldownFlagFile.php',
|
|
|
767 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\Rename\\RenameLogin' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/Rename/RenameLogin.php',
|
768 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\LoginIntentPage' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php',
|
769 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\LoginGuard\\Lib\\TwoFactor\\MfaController' => __DIR__ . '/../..' . '/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php',
|
919 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\WpCli\\SessionTerminate' => __DIR__ . '/../..' . '/src/Modules/UserManagement/WpCli/SessionTerminate.php',
|
920 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Render\\LocateTemplateDirs' => __DIR__ . '/../..' . '/src/Render/LocateTemplateDirs.php',
|
921 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Apc/BuildScanAction.php',
|
|
|
922 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\PluginScanner' => __DIR__ . '/../..' . '/src/Scans/Apc/PluginScanner.php',
|
923 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Apc/ResultItem.php',
|
924 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Apc/ResultsSet.php',
|
926 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Apc/ScanActionVO.php',
|
927 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Apc/Utilities/ItemActionHandler.php',
|
928 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Apc/Utilities/Repair.php',
|
929 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseBuildFileMap' => __DIR__ . '/../..' . '/src/Scans/Base/BaseBuildFileMap.php',
|
930 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseBuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Base/BaseBuildScanAction.php',
|
931 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseFileScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Base/BaseFileScanActionVO.php',
|
932 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseMergeItems' => __DIR__ . '/../..' . '/src/Scans/Base/BaseMergeItems.php',
|
|
|
|
|
933 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScan' => __DIR__ . '/../..' . '/src/Scans/Base/BaseScan.php',
|
934 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Base/BaseScanActionVO.php',
|
935 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\DiffResultForStorage' => __DIR__ . '/../..' . '/src/Scans/Base/DiffResultForStorage.php',
|
936 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\FileResultItem' => __DIR__ . '/../..' . '/src/Scans/Base/FileResultItem.php',
|
937 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileMapScan' => __DIR__ . '/../..' . '/src/Scans/Base/Files/BaseFileMapScan.php',
|
938 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileScanner' => __DIR__ . '/../..' . '/src/Scans/Base/Files/BaseFileScanner.php',
|
939 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseScanFromFileMap' => __DIR__ . '/../..' . '/src/Scans/Base/Files/BaseScanFromFileMap.php',
|
940 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Base/ResultItem.php',
|
941 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Base/ResultsSet.php',
|
942 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Table\\BaseEntryFormatter' => __DIR__ . '/../..' . '/src/Scans/Base/Table/BaseEntryFormatter.php',
|
943 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Table\\BaseFileEntryFormatter' => __DIR__ . '/../..' . '/src/Scans/Base/Table/BaseFileEntryFormatter.php',
|
944 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BaseRepair' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/BaseRepair.php',
|
979 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Ptg/Utilities/Repair.php',
|
980 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\BuildFileMap' => __DIR__ . '/../..' . '/src/Scans/Ufc/BuildFileMap.php',
|
981 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Ufc/BuildScanAction.php',
|
|
|
982 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\FileScanner' => __DIR__ . '/../..' . '/src/Scans/Ufc/FileScanner.php',
|
983 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Ufc/ResultItem.php',
|
984 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Ufc/ResultsSet.php',
|
990 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Ufc/Utilities/Repair.php',
|
991 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\BuildFileMap' => __DIR__ . '/../..' . '/src/Scans/Wcf/BuildFileMap.php',
|
992 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Wcf/BuildScanAction.php',
|
|
|
993 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\FileScanner' => __DIR__ . '/../..' . '/src/Scans/Wcf/FileScanner.php',
|
994 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Wcf/ResultItem.php',
|
995 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Wcf/ResultsSet.php',
|
1000 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Wcf/Utilities/ItemActionHandler.php',
|
1001 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Wcf/Utilities/Repair.php',
|
1002 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Wpv/BuildScanAction.php',
|
|
|
1003 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Wpv/ResultItem.php',
|
1004 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Wpv/ResultsSet.php',
|
1005 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Scan' => __DIR__ . '/../..' . '/src/Scans/Wpv/Scan.php',
|
1037 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\ScanWpv' => __DIR__ . '/../..' . '/src/Tables/Build/ScanWpv.php',
|
1038 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\Sessions' => __DIR__ . '/../..' . '/src/Tables/Build/Sessions.php',
|
1039 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\Traffic' => __DIR__ . '/../..' . '/src/Tables/Build/Traffic.php',
|
1040 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\AuditTrail\\ForAuditTrail' => __DIR__ . '/../..' . '/src/Tables/DataTables/Build/AuditTrail/ForAuditTrail.php',
|
1041 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\Base' => __DIR__ . '/../..' . '/src/Tables/DataTables/Build/Base.php',
|
1042 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\Scans\\BaseForScan' => __DIR__ . '/../..' . '/src/Tables/DataTables/Build/Scans/BaseForScan.php',
|
1043 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\Scans\\ForMalware' => __DIR__ . '/../..' . '/src/Tables/DataTables/Build/Scans/ForMalware.php',
|
1044 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\Scans\\ForPluginTheme' => __DIR__ . '/../..' . '/src/Tables/DataTables/Build/Scans/ForPluginTheme.php',
|
1045 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\DataTables\\Build\\Scans\\ForWordpress' => __DIR__ . '/../..' . '/src/Tables/DataTables/Build/Scans/ForWordpress.php',
|
1046 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\Common\\BaseTable' => __DIR__ . '/../..' . '/src/Tables/Render/Common/BaseTable.php',
|
|
|
|
|
|
|
1047 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpCliTable\\AuditTrail' => __DIR__ . '/../..' . '/src/Tables/Render/WpCliTable/AuditTrail.php',
|
1048 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpCliTable\\Base' => __DIR__ . '/../..' . '/src/Tables/Render/WpCliTable/Base.php',
|
1049 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Render\\WpListTable\\AdminNotes' => __DIR__ . '/../..' . '/src/Tables/Render/WpListTable/AdminNotes.php',
|
1067 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Users\\ShieldUserMeta' => __DIR__ . '/../..' . '/src/Users/ShieldUserMeta.php',
|
1068 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\Controller' => __DIR__ . '/../..' . '/src/Utilities/AdminNotices/Controller.php',
|
1069 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\NoticeVO' => __DIR__ . '/../..' . '/src/Utilities/AdminNotices/NoticeVO.php',
|
1070 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\CacheDir' => __DIR__ . '/../..' . '/src/Utilities/CacheDir.php',
|
1071 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Changelog\\Retrieve' => __DIR__ . '/../..' . '/src/Utilities/Changelog/Retrieve.php',
|
1072 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Consumer\\WpLoginCapture' => __DIR__ . '/../..' . '/src/Utilities/Consumer/WpLoginCapture.php',
|
1073 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Consumer\\WpUserConsumer' => __DIR__ . '/../..' . '/src/Utilities/Consumer/WpUserConsumer.php',
|
1120 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
1121 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
|
1122 |
'FernleafSystems\\Wordpress\\Services\\Services' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Services.php',
|
1123 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Assets\\DetectInstallationDate' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Assets/DetectInstallationDate.php',
|
1124 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Autoloading\\FindClassFromNamespaceRoots' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php',
|
1125 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
|
1126 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
|
1127 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Code\\AssessPhpFile' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Code/AssessPhpFile.php',
|
1128 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Constants\\Regex' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Constants/Regex.php',
|
1129 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Consumers\\PluginConsumer' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Consumers/PluginConsumer.php',
|
1130 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Data' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Data.php',
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Fs.php
CHANGED
@@ -239,45 +239,37 @@ class Fs {
|
|
239 |
);
|
240 |
}
|
241 |
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
*/
|
246 |
-
public function getModifiedTime( $sFilePath ) {
|
247 |
-
return $this->getTime( $sFilePath, 'modified' );
|
248 |
}
|
249 |
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
*/
|
254 |
-
public function getAccessedTime( $sFilePath ) {
|
255 |
-
return $this->getTime( $sFilePath, 'accessed' );
|
256 |
}
|
257 |
|
258 |
/**
|
259 |
-
* @param string $
|
260 |
-
* @param string $
|
261 |
* @return int|null
|
|
|
262 |
*/
|
263 |
-
public function getTime( $
|
264 |
|
265 |
-
if ( !$this->exists( $
|
266 |
return null;
|
267 |
}
|
268 |
|
269 |
-
$
|
270 |
-
switch ( $
|
271 |
|
272 |
case 'modified' :
|
273 |
-
return $
|
274 |
-
break;
|
275 |
case 'accessed' :
|
276 |
-
return $
|
277 |
-
break;
|
278 |
default:
|
279 |
return null;
|
280 |
-
break;
|
281 |
}
|
282 |
}
|
283 |
|
@@ -309,9 +301,9 @@ class Fs {
|
|
309 |
*/
|
310 |
public function getFileContent( $sFilePath, $bIsCompressed = false ) {
|
311 |
$sContents = null;
|
312 |
-
$
|
313 |
-
if ( $
|
314 |
-
$sContents = $
|
315 |
}
|
316 |
|
317 |
if ( empty( $sContents ) && function_exists( 'file_get_contents' ) ) {
|
@@ -476,7 +468,7 @@ class Fs {
|
|
476 |
|
477 |
public function isFile( $path ) :bool {
|
478 |
return ( $this->hasWpfs() && $this->getWpfs()->is_file( $path ) )
|
479 |
-
|| ( function_exists( 'is_file' )
|
480 |
}
|
481 |
|
482 |
public function isFilesystemAccessDirect() :bool {
|
@@ -493,15 +485,18 @@ class Fs {
|
|
493 |
|
494 |
/**
|
495 |
* @param string $path
|
496 |
-
* @param int $
|
497 |
* @return bool|mixed
|
498 |
*/
|
499 |
-
public function touch( $path, $
|
500 |
-
$
|
501 |
-
if (
|
|
|
|
|
|
|
502 |
return true;
|
503 |
}
|
504 |
-
return function_exists( 'touch' )
|
505 |
}
|
506 |
|
507 |
/**
|
239 |
);
|
240 |
}
|
241 |
|
242 |
+
public function getModifiedTime( string $path ) :int {
|
243 |
+
$FS = $this->getWpfs();
|
244 |
+
return (int)( $FS ? $FS->mtime( $path ) : @filemtime( $path ) );
|
|
|
|
|
|
|
245 |
}
|
246 |
|
247 |
+
public function getAccessedTime( string $path ) :int {
|
248 |
+
$FS = $this->getWpfs();
|
249 |
+
return (int)( $FS ? $FS->atime( $path ) : @fileatime( $path ) );
|
|
|
|
|
|
|
250 |
}
|
251 |
|
252 |
/**
|
253 |
+
* @param string $path
|
254 |
+
* @param string $property
|
255 |
* @return int|null
|
256 |
+
* @deprecated
|
257 |
*/
|
258 |
+
public function getTime( $path, $property = 'modified' ) {
|
259 |
|
260 |
+
if ( !$this->exists( $path ) ) {
|
261 |
return null;
|
262 |
}
|
263 |
|
264 |
+
$FS = $this->getWpfs();
|
265 |
+
switch ( $property ) {
|
266 |
|
267 |
case 'modified' :
|
268 |
+
return $FS ? $FS->mtime( $path ) : filemtime( $path );
|
|
|
269 |
case 'accessed' :
|
270 |
+
return $FS ? $FS->atime( $path ) : fileatime( $path );
|
|
|
271 |
default:
|
272 |
return null;
|
|
|
273 |
}
|
274 |
}
|
275 |
|
301 |
*/
|
302 |
public function getFileContent( $sFilePath, $bIsCompressed = false ) {
|
303 |
$sContents = null;
|
304 |
+
$FS = $this->getWpfs();
|
305 |
+
if ( $FS ) {
|
306 |
+
$sContents = $FS->get_contents( $sFilePath );
|
307 |
}
|
308 |
|
309 |
if ( empty( $sContents ) && function_exists( 'file_get_contents' ) ) {
|
468 |
|
469 |
public function isFile( $path ) :bool {
|
470 |
return ( $this->hasWpfs() && $this->getWpfs()->is_file( $path ) )
|
471 |
+
|| ( function_exists( 'is_file' ) && is_file( $path ) );
|
472 |
}
|
473 |
|
474 |
public function isFilesystemAccessDirect() :bool {
|
485 |
|
486 |
/**
|
487 |
* @param string $path
|
488 |
+
* @param int $time
|
489 |
* @return bool|mixed
|
490 |
*/
|
491 |
+
public function touch( $path, $time = null ) {
|
492 |
+
$FS = $this->getWpfs();
|
493 |
+
if ( empty( $time ) ) {
|
494 |
+
$time = time();
|
495 |
+
}
|
496 |
+
if ( $FS && $FS->touch( $path, $time ) ) {
|
497 |
return true;
|
498 |
}
|
499 |
+
return function_exists( 'touch' ) && @touch( $path, $time );
|
500 |
}
|
501 |
|
502 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpBaseVo.php
CHANGED
@@ -21,13 +21,13 @@ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
|
21 |
*/
|
22 |
abstract class WpBaseVo extends DynPropertiesClass {
|
23 |
|
24 |
-
protected $
|
25 |
|
26 |
public function __get( string $key ) {
|
27 |
|
28 |
-
if ( empty( $this->
|
29 |
$this->applyFromArray( array_merge( $this->getRawData(), $this->getExtendedData() ) );
|
30 |
-
$this->
|
31 |
}
|
32 |
|
33 |
$value = parent::__get( $key );
|
21 |
*/
|
22 |
abstract class WpBaseVo extends DynPropertiesClass {
|
23 |
|
24 |
+
protected $extendedDataLoaded = false;
|
25 |
|
26 |
public function __get( string $key ) {
|
27 |
|
28 |
+
if ( empty( $this->extendedDataLoaded ) && in_array( $key, $this->getExtendedDataSlugs() ) ) {
|
29 |
$this->applyFromArray( array_merge( $this->getRawData(), $this->getExtendedData() ) );
|
30 |
+
$this->extendedDataLoaded = true;
|
31 |
}
|
32 |
|
33 |
$value = parent::__get( $key );
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpPluginVo.php
CHANGED
@@ -52,6 +52,12 @@ class WpPluginVo extends WpBaseVo {
|
|
52 |
$value = 'plugin';
|
53 |
break;
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
case 'unique_id':
|
56 |
$value = $this->file;
|
57 |
break;
|
52 |
$value = 'plugin';
|
53 |
break;
|
54 |
|
55 |
+
case 'slug':
|
56 |
+
if ( empty( $value ) ) {
|
57 |
+
$value = dirname( $this->file );
|
58 |
+
}
|
59 |
+
break;
|
60 |
+
|
61 |
case 'unique_id':
|
62 |
$value = $this->file;
|
63 |
break;
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpThemeVo.php
CHANGED
@@ -21,7 +21,9 @@ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
|
|
21 |
* @property bool $is_parent
|
22 |
*
|
23 |
* Dynamic Properties:
|
24 |
-
* @property string $slug
|
|
|
|
|
25 |
*/
|
26 |
class WpThemeVo extends WpBaseVo {
|
27 |
|
@@ -44,6 +46,7 @@ class WpThemeVo extends WpBaseVo {
|
|
44 |
}
|
45 |
|
46 |
public function __get( string $key ) {
|
|
|
47 |
|
48 |
$value = parent::__get( $key );
|
49 |
|
@@ -68,6 +71,14 @@ class WpThemeVo extends WpBaseVo {
|
|
68 |
}
|
69 |
break;
|
70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
default:
|
72 |
break;
|
73 |
}
|
21 |
* @property bool $is_parent
|
22 |
*
|
23 |
* Dynamic Properties:
|
24 |
+
* @property string $slug (alias for Stylesheet)
|
25 |
+
* @property WpThemeVo|null $parent_theme
|
26 |
+
* @property WpThemeVo|null $child_theme
|
27 |
*/
|
28 |
class WpThemeVo extends WpBaseVo {
|
29 |
|
46 |
}
|
47 |
|
48 |
public function __get( string $key ) {
|
49 |
+
$WPT = Services::WpThemes();
|
50 |
|
51 |
$value = parent::__get( $key );
|
52 |
|
71 |
}
|
72 |
break;
|
73 |
|
74 |
+
case 'child_theme':
|
75 |
+
$value = $this->is_parent ? $WPT->getThemeAsVo( $this->wp_theme->get_stylesheet() ) : null;
|
76 |
+
break;
|
77 |
+
|
78 |
+
case 'parent_theme':
|
79 |
+
$value = $this->is_child ? $WPT->getThemeAsVo( $this->wp_theme->get_template() ) : null;
|
80 |
+
break;
|
81 |
+
|
82 |
default:
|
83 |
break;
|
84 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Assets/DetectInstallationDate.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Services\Utilities\Assets;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
|
6 |
+
WpPluginVo,
|
7 |
+
WpThemeVo
|
8 |
+
};
|
9 |
+
use FernleafSystems\Wordpress\Services\Services;
|
10 |
+
|
11 |
+
class DetectInstallationDate {
|
12 |
+
|
13 |
+
public function plugin( WpPluginVo $asset ) :int {
|
14 |
+
return $this->detectFromDir( $asset->getInstallDir() );
|
15 |
+
}
|
16 |
+
|
17 |
+
public function theme( WpThemeVo $asset ) :int {
|
18 |
+
return $this->detectFromDir( $asset->getInstallDir() );
|
19 |
+
}
|
20 |
+
|
21 |
+
private function detectFromDir( string $dir ) :int {
|
22 |
+
$FS = Services::WpFs();
|
23 |
+
$time = $FS->getModifiedTime( $dir );
|
24 |
+
foreach ( $FS->getFilesInDir( $dir ) as $fileInfo ) {
|
25 |
+
$time = min( $time, $fileInfo->getMTime() );
|
26 |
+
}
|
27 |
+
return $time;
|
28 |
+
}
|
29 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Code/AssessPhpFile.php
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Services\Utilities\Code;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
+
class AssessPhpFile {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @param string $file
|
11 |
+
* @return bool
|
12 |
+
* @throws \Exception
|
13 |
+
*/
|
14 |
+
public function isEmptyOfCode( string $file ) :bool {
|
15 |
+
$this->canRun();
|
16 |
+
|
17 |
+
$ext = strtolower( Services::Data()->getExtension( $file ) );
|
18 |
+
if ( !in_array( $ext, [ 'php', 'php5', 'php7', 'phtml' ] ) ) {
|
19 |
+
throw new \Exception( 'Not a standard PHP file.' );
|
20 |
+
}
|
21 |
+
if ( !Services::WpFs()->isFile( $file ) ) {
|
22 |
+
throw new \Exception( 'File does not exist on disk.' );
|
23 |
+
}
|
24 |
+
|
25 |
+
$Ts = token_get_all( $this->getRelevantContent( $file ) );
|
26 |
+
|
27 |
+
if ( !is_array( $Ts ) ) {
|
28 |
+
throw new \Exception( 'Could not get tokens.' );
|
29 |
+
}
|
30 |
+
|
31 |
+
$Ts = array_values( array_filter( $Ts, function ( $token ) {
|
32 |
+
return is_array( $token ) &&
|
33 |
+
!in_array( $token[ 0 ], [ T_WHITESPACE, T_DOC_COMMENT, T_COMMENT, T_INLINE_HTML ] );
|
34 |
+
} ) );
|
35 |
+
|
36 |
+
// If there is at least 1 token we assess it
|
37 |
+
if ( !empty( $Ts ) ) {
|
38 |
+
|
39 |
+
// If the 1st token isn't <?php
|
40 |
+
if ( $Ts[ 0 ][ 0 ] !== T_OPEN_TAG ) {
|
41 |
+
throw new \Exception( 'Irregular start to PHP file.' );
|
42 |
+
}
|
43 |
+
unset( $Ts[ 0 ] );
|
44 |
+
|
45 |
+
$Ts = array_values( $Ts );
|
46 |
+
|
47 |
+
if ( count( $Ts ) >= 3 ) {
|
48 |
+
if ( $Ts[ 0 ][ 0 ] == T_DECLARE &&
|
49 |
+
$Ts[ 1 ][ 0 ] == T_STRING && $Ts[ 2 ][ 0 ] == T_LNUMBER ) {
|
50 |
+
unset( $Ts[ 0 ], $Ts[ 1 ], $Ts[ 2 ] );
|
51 |
+
|
52 |
+
$Ts = array_values( $Ts );
|
53 |
+
}
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
return empty( $Ts );
|
58 |
+
}
|
59 |
+
|
60 |
+
private function printTokens( $Ts ) {
|
61 |
+
foreach ( $Ts as $t ) {
|
62 |
+
if ( is_array( $t ) ) {
|
63 |
+
echo "Line {$t[2]}: ", token_name( $t[ 0 ] ), " ('{$t[1]}')", PHP_EOL;
|
64 |
+
}
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
private function getRelevantContent( $file ) :string {
|
69 |
+
return php_strip_whitespace( $file );
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @throws \Exception
|
74 |
+
*/
|
75 |
+
private function canRun() {
|
76 |
+
$constants = [
|
77 |
+
'T_WHITESPACE',
|
78 |
+
'T_DOC_COMMENT',
|
79 |
+
'T_COMMENT',
|
80 |
+
'T_INLINE_HTML',
|
81 |
+
'T_OPEN_TAG',
|
82 |
+
'T_DECLARE',
|
83 |
+
'T_STRING',
|
84 |
+
'T_LNUMBER',
|
85 |
+
];
|
86 |
+
$notDefined = array_filter( $constants, function ( $constant ) {
|
87 |
+
return !defined( $constant );
|
88 |
+
} );
|
89 |
+
if ( !empty( $notDefined ) ) {
|
90 |
+
throw new \Exception( 'Not defined: '.implode( ', ', $notDefined ) );
|
91 |
+
}
|
92 |
+
}
|
93 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Data.php
CHANGED
@@ -35,12 +35,12 @@ class Data {
|
|
35 |
}
|
36 |
|
37 |
/**
|
38 |
-
* @param string $
|
39 |
* @return string
|
40 |
*/
|
41 |
-
public function getExtension( $
|
42 |
-
$
|
43 |
-
return ( $
|
44 |
}
|
45 |
|
46 |
/**
|
35 |
}
|
36 |
|
37 |
/**
|
38 |
+
* @param string $path
|
39 |
* @return string
|
40 |
*/
|
41 |
+
public function getExtension( $path ) {
|
42 |
+
$extPeriod = strrpos( $path, '.' );
|
43 |
+
return ( $extPeriod === false ) ? $path : str_replace( '.', '', substr( $path, $extPeriod ) );
|
44 |
}
|
45 |
|
46 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Encrypt/OpenSslEncrypt.php
CHANGED
@@ -9,124 +9,144 @@ namespace FernleafSystems\Wordpress\Services\Utilities\Encrypt;
|
|
9 |
class OpenSslEncrypt {
|
10 |
|
11 |
/**
|
12 |
-
* @param array $
|
13 |
* @return array - keys are private & public as pem strings
|
14 |
* @throws \Exception
|
15 |
*/
|
16 |
-
public function createNewPrivatePublicKeyPair( $
|
17 |
-
$rKey = openssl_pkey_new( $
|
18 |
if ( empty( $rKey ) || !is_resource( $rKey ) ) {
|
19 |
throw new \Exception( 'Could not generate new private key' );
|
20 |
}
|
21 |
-
if ( !openssl_pkey_export( $rKey, $
|
22 |
throw new \Exception( 'Could not export new private key' );
|
23 |
}
|
24 |
-
$
|
25 |
-
if ( empty( $
|
26 |
throw new \Exception( 'Could not generate public key from private' );
|
27 |
}
|
28 |
return [
|
29 |
-
'private' => $
|
30 |
-
'public' => $
|
31 |
];
|
32 |
}
|
33 |
|
34 |
/**
|
35 |
-
* @param string $
|
36 |
* @return string
|
37 |
* @throws \Exception
|
38 |
*/
|
39 |
-
public function getPublicKeyFromPrivateKey( $
|
40 |
-
$rKey = openssl_pkey_get_private( $
|
41 |
if ( empty( $rKey ) || !is_resource( $rKey ) ) {
|
42 |
throw new \Exception( 'Could not build private key' );
|
43 |
}
|
44 |
-
$
|
45 |
-
if ( empty( $
|
46 |
throw new \Exception( 'Could not generate public key from private' );
|
47 |
}
|
48 |
-
return $
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
-
* @param OpenSslEncryptVo $
|
53 |
-
* @param string $
|
54 |
-
* @return
|
55 |
*/
|
56 |
-
public function openDataVo( $
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
}
|
59 |
|
60 |
/**
|
61 |
-
* @param string $
|
62 |
-
* @param string $
|
63 |
-
* @param string $
|
64 |
* @return string|false
|
|
|
65 |
*/
|
66 |
-
public function openData( $
|
67 |
-
$
|
68 |
-
return $
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
* @param mixed $mDataToEncrypt
|
73 |
-
* @param string $
|
74 |
* @return OpenSslEncryptVo
|
75 |
*/
|
76 |
-
public function sealData( $mDataToEncrypt, $
|
77 |
|
78 |
-
$
|
79 |
|
80 |
if ( empty( $mDataToEncrypt ) ) {
|
81 |
-
$
|
82 |
-
$
|
83 |
-
return $
|
84 |
}
|
85 |
elseif ( !$this->isSupportedOpenSslDataEncryption() ) {
|
86 |
-
$
|
87 |
-
$
|
|
|
|
|
|
|
|
|
88 |
}
|
89 |
else {
|
90 |
-
$
|
91 |
}
|
92 |
|
93 |
// If at this stage we're not 'success' we return it.
|
94 |
-
if ( !$
|
95 |
-
return $
|
96 |
}
|
97 |
|
98 |
-
|
99 |
-
|
100 |
-
|
|
|
|
|
101 |
}
|
102 |
else {
|
103 |
-
$
|
|
|
104 |
}
|
105 |
|
106 |
-
$
|
107 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
|
109 |
-
$
|
110 |
-
|
111 |
-
|
112 |
-
$oVo->sealed_data = $sEncryptedData;
|
113 |
-
$oVo->sealed_password = $aPasswordKeys[ 0 ];
|
114 |
}
|
115 |
|
116 |
-
return $
|
117 |
}
|
118 |
|
119 |
-
|
120 |
-
* @return bool
|
121 |
-
*/
|
122 |
-
public function isSupportedOpenSsl() {
|
123 |
return extension_loaded( 'openssl' );
|
124 |
}
|
125 |
|
126 |
-
|
127 |
-
* @return bool
|
128 |
-
*/
|
129 |
-
public function isSupportedOpenSslSign() {
|
130 |
return function_exists( 'base64_decode' )
|
131 |
&& extension_loaded( 'openssl' )
|
132 |
&& function_exists( 'openssl_sign' )
|
@@ -134,43 +154,42 @@ class OpenSslEncrypt {
|
|
134 |
&& defined( 'OPENSSL_ALGO_SHA1' );
|
135 |
}
|
136 |
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
public function isSupportedOpenSslDataEncryption() {
|
141 |
-
$bSupported = $this->isSupportedOpenSsl();
|
142 |
-
$aFunc = [
|
143 |
'openssl_seal',
|
144 |
'openssl_open',
|
145 |
'openssl_pkey_new',
|
146 |
'openssl_pkey_export',
|
147 |
'openssl_pkey_get_details',
|
148 |
-
'openssl_pkey_get_private'
|
|
|
149 |
];
|
150 |
-
foreach ( $
|
151 |
-
$
|
152 |
}
|
153 |
-
return $
|
154 |
}
|
155 |
|
156 |
/**
|
157 |
-
* @param string $
|
158 |
-
* @param string $
|
159 |
-
* @param string $
|
160 |
* @return int 1: Success; 0: Failure; -1: Error; -2: Not supported
|
161 |
*/
|
162 |
-
public function verifySslSignature( $
|
163 |
-
$
|
164 |
if ( $this->isSupportedOpenSslSign() ) {
|
165 |
-
$
|
166 |
}
|
167 |
-
return $
|
168 |
}
|
169 |
|
170 |
-
|
171 |
-
* @return OpenSslEncryptVo
|
172 |
-
*/
|
173 |
-
protected function getStandardEncryptResponse() {
|
174 |
return new OpenSslEncryptVo();
|
175 |
}
|
|
|
|
|
|
|
|
|
176 |
}
|
9 |
class OpenSslEncrypt {
|
10 |
|
11 |
/**
|
12 |
+
* @param array $args
|
13 |
* @return array - keys are private & public as pem strings
|
14 |
* @throws \Exception
|
15 |
*/
|
16 |
+
public function createNewPrivatePublicKeyPair( $args = [] ) {
|
17 |
+
$rKey = openssl_pkey_new( $args );
|
18 |
if ( empty( $rKey ) || !is_resource( $rKey ) ) {
|
19 |
throw new \Exception( 'Could not generate new private key' );
|
20 |
}
|
21 |
+
if ( !openssl_pkey_export( $rKey, $private ) || empty( $private ) ) {
|
22 |
throw new \Exception( 'Could not export new private key' );
|
23 |
}
|
24 |
+
$pub = openssl_pkey_get_details( $rKey );
|
25 |
+
if ( empty( $pub ) || empty( $pub[ 'key' ] ) ) {
|
26 |
throw new \Exception( 'Could not generate public key from private' );
|
27 |
}
|
28 |
return [
|
29 |
+
'private' => $private,
|
30 |
+
'public' => $pub[ 'key' ],
|
31 |
];
|
32 |
}
|
33 |
|
34 |
/**
|
35 |
+
* @param string $key
|
36 |
* @return string
|
37 |
* @throws \Exception
|
38 |
*/
|
39 |
+
public function getPublicKeyFromPrivateKey( $key ) {
|
40 |
+
$rKey = openssl_pkey_get_private( $key );
|
41 |
if ( empty( $rKey ) || !is_resource( $rKey ) ) {
|
42 |
throw new \Exception( 'Could not build private key' );
|
43 |
}
|
44 |
+
$public = openssl_pkey_get_details( $rKey );
|
45 |
+
if ( empty( $public ) || empty( $public[ 'key' ] ) ) {
|
46 |
throw new \Exception( 'Could not generate public key from private' );
|
47 |
}
|
48 |
+
return $public[ 'key' ];
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
+
* @param OpenSslEncryptVo $VO
|
53 |
+
* @param string $privateKey
|
54 |
+
* @return string|false
|
55 |
*/
|
56 |
+
public function openDataVo( OpenSslEncryptVo $VO, string $privateKey ) {
|
57 |
+
$success = \openssl_open(
|
58 |
+
$VO->sealed_data,
|
59 |
+
$openedData,
|
60 |
+
$VO->sealed_password,
|
61 |
+
$privateKey,
|
62 |
+
$VO->cipher
|
63 |
+
);
|
64 |
+
return $success ? $openedData : false;
|
65 |
}
|
66 |
|
67 |
/**
|
68 |
+
* @param string $sealedData
|
69 |
+
* @param string $sealedPassword
|
70 |
+
* @param string $privateKey
|
71 |
* @return string|false
|
72 |
+
* @deprecated
|
73 |
*/
|
74 |
+
public function openData( $sealedData, $sealedPassword, $privateKey, string $cipher = 'rc4' ) {
|
75 |
+
$success = \openssl_open( $sealedData, $openedData, $sealedPassword, $privateKey, $cipher );
|
76 |
+
return $success ? $openedData : false;
|
77 |
}
|
78 |
|
79 |
/**
|
80 |
* @param mixed $mDataToEncrypt
|
81 |
+
* @param string $publicKey
|
82 |
* @return OpenSslEncryptVo
|
83 |
*/
|
84 |
+
public function sealData( $mDataToEncrypt, $publicKey, $cipher = 'rc4' ) {
|
85 |
|
86 |
+
$VO = $this->getStandardEncryptResponse();
|
87 |
|
88 |
if ( empty( $mDataToEncrypt ) ) {
|
89 |
+
$VO->success = false;
|
90 |
+
$VO->message = 'Data to encrypt was empty';
|
91 |
+
return $VO;
|
92 |
}
|
93 |
elseif ( !$this->isSupportedOpenSslDataEncryption() ) {
|
94 |
+
$VO->success = false;
|
95 |
+
$VO->message = 'Does not support OpenSSL data encryption';
|
96 |
+
}
|
97 |
+
elseif ( !$this->hasCipherAlgo( $cipher ) ) {
|
98 |
+
$VO->message = sprintf( 'Defaulting to RC4 as cipher %s is not available', $cipher );
|
99 |
+
$cipher = 'rc4';
|
100 |
}
|
101 |
else {
|
102 |
+
$VO->success = true;
|
103 |
}
|
104 |
|
105 |
// If at this stage we're not 'success' we return it.
|
106 |
+
if ( !$VO->success ) {
|
107 |
+
return $VO;
|
108 |
}
|
109 |
|
110 |
+
$VO->cipher = $cipher;
|
111 |
+
|
112 |
+
if ( is_string( $mDataToEncrypt ) ) {
|
113 |
+
$finalDataToEncrypt = $mDataToEncrypt;
|
114 |
+
$VO->json_encoded = false;
|
115 |
}
|
116 |
else {
|
117 |
+
$finalDataToEncrypt = json_encode( $mDataToEncrypt );
|
118 |
+
$VO->json_encoded = true;
|
119 |
}
|
120 |
|
121 |
+
$passwordKeys = [];
|
122 |
+
$mResult = openssl_seal(
|
123 |
+
$finalDataToEncrypt,
|
124 |
+
$encryptedData,
|
125 |
+
$passwordKeys,
|
126 |
+
[ $publicKey ],
|
127 |
+
$cipher
|
128 |
+
);
|
129 |
+
|
130 |
+
$VO->result = $mResult;
|
131 |
+
$VO->success = is_int( $mResult ) && $mResult > 0 && !is_null( $encryptedData );
|
132 |
+
if ( $VO->success ) {
|
133 |
+
$VO->sealed_data = $encryptedData;
|
134 |
+
$VO->sealed_password = $passwordKeys[ 0 ];
|
135 |
+
}
|
136 |
|
137 |
+
if ( $cipher !== 'rc4' ) {
|
138 |
+
// we do a backup seal as rc4 while we determine availability of other cipers
|
139 |
+
$VO->rc4_fallback = $this->sealData( $mDataToEncrypt, $publicKey, 'rc4' );
|
|
|
|
|
140 |
}
|
141 |
|
142 |
+
return $VO;
|
143 |
}
|
144 |
|
145 |
+
public function isSupportedOpenSsl() :bool {
|
|
|
|
|
|
|
146 |
return extension_loaded( 'openssl' );
|
147 |
}
|
148 |
|
149 |
+
public function isSupportedOpenSslSign() :bool {
|
|
|
|
|
|
|
150 |
return function_exists( 'base64_decode' )
|
151 |
&& extension_loaded( 'openssl' )
|
152 |
&& function_exists( 'openssl_sign' )
|
154 |
&& defined( 'OPENSSL_ALGO_SHA1' );
|
155 |
}
|
156 |
|
157 |
+
public function isSupportedOpenSslDataEncryption() :bool {
|
158 |
+
$supported = $this->isSupportedOpenSsl();
|
159 |
+
$funcs = [
|
|
|
|
|
|
|
160 |
'openssl_seal',
|
161 |
'openssl_open',
|
162 |
'openssl_pkey_new',
|
163 |
'openssl_pkey_export',
|
164 |
'openssl_pkey_get_details',
|
165 |
+
'openssl_pkey_get_private',
|
166 |
+
'openssl_get_cipher_methods',
|
167 |
];
|
168 |
+
foreach ( $funcs as $func ) {
|
169 |
+
$supported = $supported && function_exists( $func );
|
170 |
}
|
171 |
+
return $supported;
|
172 |
}
|
173 |
|
174 |
/**
|
175 |
+
* @param string $verificationCode
|
176 |
+
* @param string $signature
|
177 |
+
* @param string $publicKey
|
178 |
* @return int 1: Success; 0: Failure; -1: Error; -2: Not supported
|
179 |
*/
|
180 |
+
public function verifySslSignature( $verificationCode, $signature, $publicKey ) {
|
181 |
+
$result = -2;
|
182 |
if ( $this->isSupportedOpenSslSign() ) {
|
183 |
+
$result = openssl_verify( $verificationCode, $signature, $publicKey );
|
184 |
}
|
185 |
+
return $result;
|
186 |
}
|
187 |
|
188 |
+
protected function getStandardEncryptResponse() :OpenSslEncryptVo {
|
|
|
|
|
|
|
189 |
return new OpenSslEncryptVo();
|
190 |
}
|
191 |
+
|
192 |
+
public function hasCipherAlgo( string $cipher ) :bool {
|
193 |
+
return in_array( strtolower( $cipher ), array_map( 'strtolower', openssl_get_cipher_methods( true ) ) );
|
194 |
+
}
|
195 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Encrypt/OpenSslEncryptVo.php
CHANGED
@@ -7,12 +7,14 @@ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
|
7 |
/**
|
8 |
* Class EncryptVo
|
9 |
* @package FernleafSystems\Wordpress\Services\Utilities\Encrypt
|
10 |
-
* @property bool
|
11 |
-
* @property int
|
12 |
-
* @property string
|
13 |
-
* @property
|
14 |
-
* @property
|
15 |
-
* @property string
|
|
|
|
|
16 |
*/
|
17 |
class OpenSslEncryptVo extends DynPropertiesClass {
|
18 |
|
@@ -30,6 +32,12 @@ class OpenSslEncryptVo extends DynPropertiesClass {
|
|
30 |
$value = base64_decode( $value );
|
31 |
break;
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
default:
|
34 |
break;
|
35 |
}
|
7 |
/**
|
8 |
* Class EncryptVo
|
9 |
* @package FernleafSystems\Wordpress\Services\Utilities\Encrypt
|
10 |
+
* @property bool $success
|
11 |
+
* @property int $result
|
12 |
+
* @property string $cipher
|
13 |
+
* @property string $message
|
14 |
+
* @property bool $json_encoded
|
15 |
+
* @property string $sealed_data
|
16 |
+
* @property string $sealed_password
|
17 |
+
* @property OpenSslEncryptVo $rc4_fallback
|
18 |
*/
|
19 |
class OpenSslEncryptVo extends DynPropertiesClass {
|
20 |
|
32 |
$value = base64_decode( $value );
|
33 |
break;
|
34 |
|
35 |
+
case 'cipher':
|
36 |
+
if ( empty( $value ) ) {
|
37 |
+
$value = 'rc4'; // The default
|
38 |
+
}
|
39 |
+
break;
|
40 |
+
|
41 |
default:
|
42 |
break;
|
43 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/LocateStrInFile.php
CHANGED
@@ -35,6 +35,8 @@ class LocateStrInFile {
|
|
35 |
*/
|
36 |
private $isRegExNeedle;
|
37 |
|
|
|
|
|
38 |
/**
|
39 |
* @return string[]
|
40 |
*/
|
@@ -48,10 +50,10 @@ class LocateStrInFile {
|
|
48 |
protected function runAsRegEx() :array {
|
49 |
$lines = [];
|
50 |
|
51 |
-
|
|
|
52 |
foreach ( $matches[ 0 ] as $match ) {
|
53 |
-
// use + for numerical index
|
54 |
-
$lines = $lines + $this->findLinesFor( $match );
|
55 |
}
|
56 |
}
|
57 |
return $lines;
|
@@ -93,20 +95,28 @@ class LocateStrInFile {
|
|
93 |
*/
|
94 |
protected function getLines() :array {
|
95 |
if ( is_null( $this->lines ) ) {
|
96 |
-
$this->lines = array_filter(
|
97 |
-
array_map( 'trim', preg_split( '/\r\n|\r|\n/', $this->getContent() ) )
|
98 |
-
);
|
99 |
}
|
100 |
return $this->lines;
|
101 |
}
|
102 |
|
103 |
public function getContent() :string {
|
104 |
if ( is_null( $this->content ) ) {
|
105 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
}
|
107 |
return $this->content;
|
108 |
}
|
109 |
|
|
|
|
|
|
|
|
|
110 |
public function getNeedle() :string {
|
111 |
return $this->needle;
|
112 |
}
|
@@ -116,7 +126,7 @@ class LocateStrInFile {
|
|
116 |
}
|
117 |
|
118 |
public function isRegEx() :bool {
|
119 |
-
return
|
120 |
}
|
121 |
|
122 |
public function setIsRegEx( bool $isRegEx ) :self {
|
@@ -129,6 +139,11 @@ class LocateStrInFile {
|
|
129 |
return $this;
|
130 |
}
|
131 |
|
|
|
|
|
|
|
|
|
|
|
132 |
/**
|
133 |
* @param string $path
|
134 |
* @return $this
|
@@ -143,7 +158,6 @@ class LocateStrInFile {
|
|
143 |
throw new \Exception( "File isn't readable" );
|
144 |
}
|
145 |
$this->path = $path;
|
146 |
-
$this->getContent();
|
147 |
return $this->reset();
|
148 |
}
|
149 |
|
35 |
*/
|
36 |
private $isRegExNeedle;
|
37 |
|
38 |
+
private $stripPhpFile = true;
|
39 |
+
|
40 |
/**
|
41 |
* @return string[]
|
42 |
*/
|
50 |
protected function runAsRegEx() :array {
|
51 |
$lines = [];
|
52 |
|
53 |
+
$content = $this->getContent();
|
54 |
+
if ( !empty( $content ) && preg_match_all( '/('.$this->getNeedle().')/i', $content, $matches, PREG_PATTERN_ORDER ) ) {
|
55 |
foreach ( $matches[ 0 ] as $match ) {
|
56 |
+
$lines = $lines + $this->findLinesFor( $match ); // use + for numerical index
|
|
|
57 |
}
|
58 |
}
|
59 |
return $lines;
|
95 |
*/
|
96 |
protected function getLines() :array {
|
97 |
if ( is_null( $this->lines ) ) {
|
98 |
+
$this->lines = array_filter( array_map( 'trim', preg_split( '/\r\n|\r|\n/', $this->getRawContent() ) ) );
|
|
|
|
|
99 |
}
|
100 |
return $this->lines;
|
101 |
}
|
102 |
|
103 |
public function getContent() :string {
|
104 |
if ( is_null( $this->content ) ) {
|
105 |
+
$p = $this->getPath();
|
106 |
+
if ( $this->stripPhpFile && in_array( Services::Data()->getExtension( $p ), [ 'php', 'php5', 'php7' ] ) ) {
|
107 |
+
$this->content = php_strip_whitespace( $p );
|
108 |
+
}
|
109 |
+
else {
|
110 |
+
$this->content = $this->getRawContent();
|
111 |
+
}
|
112 |
}
|
113 |
return $this->content;
|
114 |
}
|
115 |
|
116 |
+
protected function getRawContent() :string {
|
117 |
+
return (string)Services::WpFs()->getFileContent( $this->getPath() );
|
118 |
+
}
|
119 |
+
|
120 |
public function getNeedle() :string {
|
121 |
return $this->needle;
|
122 |
}
|
126 |
}
|
127 |
|
128 |
public function isRegEx() :bool {
|
129 |
+
return $this->isRegExNeedle ?? false;
|
130 |
}
|
131 |
|
132 |
public function setIsRegEx( bool $isRegEx ) :self {
|
139 |
return $this;
|
140 |
}
|
141 |
|
142 |
+
public function setIsStripPhp( bool $strip ) :self {
|
143 |
+
$this->stripPhpFile = $strip;
|
144 |
+
return $this;
|
145 |
+
}
|
146 |
+
|
147 |
/**
|
148 |
* @param string $path
|
149 |
* @return $this
|
158 |
throw new \Exception( "File isn't readable" );
|
159 |
}
|
160 |
$this->path = $path;
|
|
|
161 |
return $this->reset();
|
162 |
}
|
163 |
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/ReadDataFromFileEncrypted.php
CHANGED
@@ -12,31 +12,31 @@ use FernleafSystems\Wordpress\Services\Utilities\Encrypt\OpenSslEncryptVo;
|
|
12 |
class ReadDataFromFileEncrypted {
|
13 |
|
14 |
/**
|
15 |
-
* @param string $
|
16 |
-
* @param string $
|
17 |
* @return string
|
18 |
* @throws \Exception
|
19 |
*/
|
20 |
-
public function run( $
|
21 |
-
$
|
22 |
-
if ( !$
|
23 |
-
throw new \Exception( 'File path does not exist: '.$
|
24 |
}
|
25 |
-
$
|
26 |
-
if ( empty( $
|
27 |
-
throw new \Exception( 'Could not read data from file: '.$
|
28 |
}
|
29 |
-
$
|
30 |
-
if ( empty( $
|
31 |
throw new \Exception( 'Parsing raw data from file failed' );
|
32 |
}
|
33 |
|
34 |
-
$
|
35 |
|
36 |
-
$
|
37 |
-
if ( $
|
38 |
throw new \Exception( 'Decrypting sealed data failed.' );
|
39 |
}
|
40 |
-
return $
|
41 |
}
|
42 |
}
|
12 |
class ReadDataFromFileEncrypted {
|
13 |
|
14 |
/**
|
15 |
+
* @param string $path
|
16 |
+
* @param string $privateKey
|
17 |
* @return string
|
18 |
* @throws \Exception
|
19 |
*/
|
20 |
+
public function run( $path, $privateKey ) {
|
21 |
+
$FS = Services::WpFs();
|
22 |
+
if ( !$FS->exists( $path ) || !$FS->isFile( $path ) ) {
|
23 |
+
throw new \Exception( 'File path does not exist: '.$path );
|
24 |
}
|
25 |
+
$rawFile = $FS->getFileContent( $path );
|
26 |
+
if ( empty( $rawFile ) ) {
|
27 |
+
throw new \Exception( 'Could not read data from file: '.$rawFile );
|
28 |
}
|
29 |
+
$rawData = @json_decode( $rawFile, true );
|
30 |
+
if ( empty( $rawData ) || !is_array( $rawData ) ) {
|
31 |
throw new \Exception( 'Parsing raw data from file failed' );
|
32 |
}
|
33 |
|
34 |
+
$VO = ( new OpenSslEncryptVo() )->applyFromArray( $rawData );
|
35 |
|
36 |
+
$data = Services::Encrypt()->openDataVo( $VO, $privateKey );
|
37 |
+
if ( $data === false ) {
|
38 |
throw new \Exception( 'Decrypting sealed data failed.' );
|
39 |
}
|
40 |
+
return $data;
|
41 |
}
|
42 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/WriteDataToFileEncrypted.php
CHANGED
@@ -11,24 +11,24 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
11 |
class WriteDataToFileEncrypted {
|
12 |
|
13 |
/**
|
14 |
-
* @param string $
|
15 |
-
* @param string $
|
16 |
-
* @param string $
|
17 |
-
* @param string $
|
18 |
* @return bool
|
19 |
* @throws \Exception
|
20 |
*/
|
21 |
-
public function run( $
|
22 |
-
$
|
23 |
|
24 |
-
$
|
25 |
-
if ( !$
|
26 |
-
throw new \Exception( 'Could not seal data with message: '.$
|
27 |
}
|
28 |
|
29 |
-
$bSuccess = Services::WpFs()->putFileContent( $
|
30 |
-
if ( $bSuccess && !empty( $
|
31 |
-
$bSuccess = ( new ReadDataFromFileEncrypted() )->run( $
|
32 |
}
|
33 |
return $bSuccess;
|
34 |
}
|
11 |
class WriteDataToFileEncrypted {
|
12 |
|
13 |
/**
|
14 |
+
* @param string $path
|
15 |
+
* @param string $data
|
16 |
+
* @param string $publicKey
|
17 |
+
* @param string $privateKeyForVerify - verify writing successful if private key supplied
|
18 |
* @return bool
|
19 |
* @throws \Exception
|
20 |
*/
|
21 |
+
public function run( $path, $data, $publicKey, $privateKeyForVerify = null ) {
|
22 |
+
$srvEncrypt = Services::Encrypt();
|
23 |
|
24 |
+
$encrypted = $srvEncrypt->sealData( $data, $publicKey );
|
25 |
+
if ( !$encrypted->success ) {
|
26 |
+
throw new \Exception( 'Could not seal data with message: '.$encrypted->message );
|
27 |
}
|
28 |
|
29 |
+
$bSuccess = Services::WpFs()->putFileContent( $path, json_encode( $encrypted->getRawData() ) );
|
30 |
+
if ( $bSuccess && !empty( $privateKeyForVerify ) ) {
|
31 |
+
$bSuccess = ( new ReadDataFromFileEncrypted() )->run( $path, $privateKeyForVerify ) === $data;
|
32 |
}
|
33 |
return $bSuccess;
|
34 |
}
|
templates/twig/components/reports/mod/events/alert_scanrepairs.twig
DELETED
@@ -1,8 +0,0 @@
|
|
1 |
-
<div style="padding-left: 10px;">
|
2 |
-
<h3>{{ strings.title }}</h3>
|
3 |
-
<ul>
|
4 |
-
{% for event_data in vars.counts %}
|
5 |
-
<li>{{ event_data.name }}: {{ event_data.count }}</li>
|
6 |
-
{% endfor %}
|
7 |
-
</ul>
|
8 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/components/reports/mod/hack_protect/alert_scanrepairs.twig
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div style="padding-left: 10px;">
|
2 |
+
<h3>{{ strings.title }}</h3>
|
3 |
+
<ul>
|
4 |
+
{% for repair_data in vars.repairs %}
|
5 |
+
<li>
|
6 |
+
{{ repair_data.name }}: {{ repair_data.count }}
|
7 |
+
{% if repair_data.repairs is not empty %}
|
8 |
+
<ul>
|
9 |
+
{% for repair in repair_data.repairs %}
|
10 |
+
<li><code>{{ repair }}</code></li>
|
11 |
+
{% endfor %}
|
12 |
+
{{ repair_data.count > repair_data.repairs|length ? '<li>...</li>' : '' }}
|
13 |
+
</ul>
|
14 |
+
{% endif %}
|
15 |
+
</li>
|
16 |
+
{% endfor %}
|
17 |
+
</ul>
|
18 |
+
<p><a href="{{ hrefs.audit_trail }}" target="_blank">{{ strings.audit_trail }}</a></p>
|
19 |
+
</div>
|
templates/twig/components/reports/mod/hack_protect/alert_scanresults.twig
CHANGED
@@ -1,5 +1,8 @@
|
|
1 |
<div style="padding-left: 10px;">
|
2 |
-
<h3>
|
|
|
|
|
|
|
3 |
<ul>
|
4 |
{% for scan_slug,scan_data in vars.scan_counts %}
|
5 |
<li>{{ scan_data.name }}: {{ scan_data.count }}</li>
|
1 |
<div style="padding-left: 10px;">
|
2 |
+
<h3>
|
3 |
+
{{ strings.title }}
|
4 |
+
<br/><small>{{ strings.note_changes }}</small>
|
5 |
+
</h3>
|
6 |
<ul>
|
7 |
{% for scan_slug,scan_data in vars.scan_counts %}
|
8 |
<li>{{ scan_data.name }}: {{ scan_data.count }}</li>
|
templates/twig/wpadmin_pages/components/page/nav_sidebar.twig
CHANGED
@@ -13,8 +13,8 @@
|
|
13 |
<li class="nav-item mb-0 pl-0 py-1">
|
14 |
<span class="text-secondary font-italic text-monospace">{{ mitem.title }}</span>
|
15 |
</li>
|
16 |
-
|
17 |
-
|
18 |
<a class="p-0 nav-link {{ sub.classes|default([])|join( ' ' ) }}"
|
19 |
href="{{ sub.href|default('#') }}"
|
20 |
{% for data_key,data_val in sub.data|default([]) %}
|
@@ -23,13 +23,13 @@
|
|
23 |
{% if sub.target|default('') is not empty %}target="{{ sub.target }}"{% endif %}
|
24 |
>{{ sub.title }}</a>
|
25 |
</li>
|
26 |
-
|
27 |
</ul>
|
28 |
</div>
|
29 |
{% endif %}
|
30 |
|
31 |
<a class="nav-link p-0 {{ mitem.classes|default([])|join( ' ' ) }} mb-1 text-center"
|
32 |
-
href="{{ mitem.href|default('
|
33 |
{% for data_key,data_val in mitem.data|default([]) %}
|
34 |
data-{{ data_key }}="{{ data_val }}"
|
35 |
{% endfor %}
|
13 |
<li class="nav-item mb-0 pl-0 py-1">
|
14 |
<span class="text-secondary font-italic text-monospace">{{ mitem.title }}</span>
|
15 |
</li>
|
16 |
+
{% for sub in mitem.sub_items %}
|
17 |
+
<li class="mb-2 pl-0 py-1">
|
18 |
<a class="p-0 nav-link {{ sub.classes|default([])|join( ' ' ) }}"
|
19 |
href="{{ sub.href|default('#') }}"
|
20 |
{% for data_key,data_val in sub.data|default([]) %}
|
23 |
{% if sub.target|default('') is not empty %}target="{{ sub.target }}"{% endif %}
|
24 |
>{{ sub.title }}</a>
|
25 |
</li>
|
26 |
+
{% endfor %}
|
27 |
</ul>
|
28 |
</div>
|
29 |
{% endif %}
|
30 |
|
31 |
<a class="nav-link p-0 {{ mitem.classes|default([])|join( ' ' ) }} mb-1 text-center"
|
32 |
+
href="{{ mitem.sub_items|default([]) is empty ? mitem.href|default('javascript:{}') : 'javascript:{}' }}"
|
33 |
{% for data_key,data_val in mitem.data|default([]) %}
|
34 |
data-{{ data_key }}="{{ data_val }}"
|
35 |
{% endfor %}
|
templates/twig/wpadmin_pages/insights/scans/modal/code_block.twig
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<pre class="icwp-code-render">{% for line in lines %}<code>{{ line }}</code>{% endfor %}</pre>
|
templates/twig/wpadmin_pages/insights/scans/modal/code_render.twig
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="modal" id="CodeRenderModal" tabindex="-1" role="dialog" aria-labelledby=""
|
2 |
+
style="z-index: 10000000;"
|
3 |
+
aria-hidden="true">
|
4 |
+
<div class="modal-dialog modal-dialog-centered modal-xl modal-dialog-scrollable" role="document" style="z-index: 10000001;">
|
5 |
+
<div class="modal-content">
|
6 |
+
<div class="modal-header">
|
7 |
+
<h5 class="modal-title">
|
8 |
+
code
|
9 |
+
</h5>
|
10 |
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
11 |
+
<span aria-hidden="true">×</span>
|
12 |
+
</button>
|
13 |
+
</div>
|
14 |
+
<div class="modal-body">
|
15 |
+
</div>
|
16 |
+
<div class="modal-footer">
|
17 |
+
</div>
|
18 |
+
</div>
|
19 |
+
</div>
|
20 |
+
</div>
|
templates/twig/wpadmin_pages/insights/scans/results/index.twig
CHANGED
@@ -6,5 +6,6 @@
|
|
6 |
{% include '/wpadmin_pages/insights/scans/results/scan_results.twig' %}
|
7 |
</div>
|
8 |
</div>
|
|
|
9 |
{% include '/wpadmin_pages/insights/scans/modal/progress.twig' %}
|
10 |
{% endblock %}
|
6 |
{% include '/wpadmin_pages/insights/scans/results/scan_results.twig' %}
|
7 |
</div>
|
8 |
</div>
|
9 |
+
{% include '/wpadmin_pages/insights/scans/modal/code_render.twig' %}
|
10 |
{% include '/wpadmin_pages/insights/scans/modal/progress.twig' %}
|
11 |
{% endblock %}
|
templates/twig/wpadmin_pages/insights/scans/results/scan_results.twig
CHANGED
@@ -1,63 +1,117 @@
|
|
1 |
<ul class="nav nav-tabs" id="ScanResultsTabsNav" role="tablist">
|
2 |
|
3 |
<li class="nav-item">
|
4 |
-
<a class="nav-link active" id="h-tabs-
|
5 |
-
role="tab" aria-controls="h-tabs-
|
6 |
-
|
7 |
-
|
8 |
-
|
|
|
|
|
|
|
9 |
</a>
|
10 |
</li>
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
<li class="nav-item">
|
31 |
<a class="nav-link" id="h-tabs-home-tab" data-toggle="tab" href="#h-tabs-file_locker"
|
32 |
role="tab" aria-controls="h-tabs-file_locker">
|
33 |
-
|
34 |
-
>{% if file_locker.count > 0 %}!{% endif %}</span>
|
35 |
{{ file_locker.strings.title }}
|
|
|
|
|
|
|
|
|
|
|
36 |
</a>
|
37 |
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
</ul>
|
39 |
|
40 |
<div class="tab-content mb-5" id="ScanResultsTabsContent">
|
41 |
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
|
|
46 |
</div>
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
{
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
57 |
|
58 |
<div class="tab-pane show" id="h-tabs-file_locker" role="tabpanel"
|
59 |
-
aria-labelledby="h-tabs-
|
60 |
{% set scan = file_locker %}
|
61 |
{% include '/wpadmin_pages/insights/scans/results/realtime/file_locker/index.twig' %}
|
62 |
</div>
|
63 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<ul class="nav nav-tabs" id="ScanResultsTabsNav" role="tablist">
|
2 |
|
3 |
<li class="nav-item">
|
4 |
+
<a class="nav-link active" id="h-tabs-wordpress-tab" data-toggle="tab" href="#h-tabs-wordpress"
|
5 |
+
role="tab" aria-controls="h-tabs-wordpress">
|
6 |
+
WordPress
|
7 |
+
{% if vars.sections.wordpress.count > 0 %}
|
8 |
+
<span class="badge badge-danger">{{ vars.sections.wordpress.count }}</span>
|
9 |
+
{% else %}
|
10 |
+
<span class="badge badge-success">✓</span>
|
11 |
+
{% endif %}
|
12 |
</a>
|
13 |
</li>
|
14 |
|
15 |
+
<li class="nav-item">
|
16 |
+
<a class="nav-link" id="h-tabs-plugins-tab" data-toggle="tab" href="#h-tabs-plugins"
|
17 |
+
role="tab" aria-controls="h-tabs-plugins">
|
18 |
+
Plugins
|
19 |
+
{% if vars.sections.plugins.count > 0 %}
|
20 |
+
<span class="badge badge-danger">{{ vars.sections.plugins.count }}</span>
|
21 |
+
{% else %}
|
22 |
+
<span class="badge badge-success">✓</span>
|
23 |
+
{% endif %}
|
24 |
+
</a>
|
25 |
+
</li>
|
26 |
+
|
27 |
+
<li class="nav-item">
|
28 |
+
<a class="nav-link" id="h-tabs-themes-tab" data-toggle="tab" href="#h-tabs-themes"
|
29 |
+
role="tab" aria-controls="h-tabs-themes">
|
30 |
+
Themes
|
31 |
+
{% if vars.sections.themes.count > 0 %}
|
32 |
+
<span class="badge badge-danger">{{ vars.sections.themes.count }}</span>
|
33 |
+
{% else %}
|
34 |
+
<span class="badge badge-success">✓</span>
|
35 |
+
{% endif %}
|
36 |
+
</a>
|
37 |
+
</li>
|
38 |
+
|
39 |
+
<li class="nav-item">
|
40 |
+
<a class="nav-link" id="h-tabs-malware-tab" data-toggle="tab" href="#h-tabs-malware"
|
41 |
+
role="tab" aria-controls="h-tabs-malware">
|
42 |
+
Malware
|
43 |
+
{% if vars.sections.malware.count > 0 %}
|
44 |
+
<span class="badge badge-danger">{{ vars.sections.malware.count }}</span>
|
45 |
+
{% else %}
|
46 |
+
<span class="badge badge-success">✓</span>
|
47 |
+
{% endif %}
|
48 |
+
</a>
|
49 |
+
</li>
|
50 |
|
51 |
<li class="nav-item">
|
52 |
<a class="nav-link" id="h-tabs-home-tab" data-toggle="tab" href="#h-tabs-file_locker"
|
53 |
role="tab" aria-controls="h-tabs-file_locker">
|
54 |
+
|
|
|
55 |
{{ file_locker.strings.title }}
|
56 |
+
{% if file_locker.count > 0 %}
|
57 |
+
<span class="badge badge-danger">{{ file_locker.count }}</span>
|
58 |
+
{% else %}
|
59 |
+
<span class="badge badge-success">✓</span>
|
60 |
+
{% endif %}
|
61 |
</a>
|
62 |
</li>
|
63 |
+
|
64 |
+
{# <li class="nav-item">#}
|
65 |
+
{# <a class="nav-link" id="h-tabs-log-tab" data-toggle="tab" href="#h-tabs-log"#}
|
66 |
+
{# role="tab" aria-controls="h-tabs-log">#}
|
67 |
+
{# Logs#}
|
68 |
+
{# </a>#}
|
69 |
+
{# </li>#}
|
70 |
+
|
71 |
</ul>
|
72 |
|
73 |
<div class="tab-content mb-5" id="ScanResultsTabsContent">
|
74 |
|
75 |
+
<div class="tab-pane show active" id="h-tabs-wordpress" role="tabpanel"
|
76 |
+
aria-labelledby="h-tabs-wordpress-tab">
|
77 |
+
{{ content.section.wordpress|raw }}
|
78 |
+
</div>
|
79 |
+
|
80 |
+
<div class="tab-pane" id="h-tabs-plugins" role="tabpanel"
|
81 |
+
aria-labelledby="h-tabs-plugins-tab">
|
82 |
+
{{ content.section.plugins|raw }}
|
83 |
</div>
|
84 |
|
85 |
+
<div class="tab-pane" id="h-tabs-themes" role="tabpanel"
|
86 |
+
aria-labelledby="h-tabs-themes-tab">
|
87 |
+
{{ content.section.themes|raw }}
|
88 |
+
</div>
|
89 |
+
|
90 |
+
<div class="tab-pane" id="h-tabs-malware" role="tabpanel"
|
91 |
+
aria-labelledby="h-tabs-malware-tab">
|
92 |
+
{{ content.section.malware|raw }}
|
93 |
+
</div>
|
94 |
+
|
95 |
+
{# <div class="tab-pane" id="h-tabs-log" role="tabpanel"#}
|
96 |
+
{# aria-labelledby="h-tabs-log-tab">#}
|
97 |
+
{# {{ content.section.logs|raw }}#}
|
98 |
+
{# </div>#}
|
99 |
|
100 |
<div class="tab-pane show" id="h-tabs-file_locker" role="tabpanel"
|
101 |
+
aria-labelledby="h-tabs-file_locker-tab">
|
102 |
{% set scan = file_locker %}
|
103 |
{% include '/wpadmin_pages/insights/scans/results/realtime/file_locker/index.twig' %}
|
104 |
</div>
|
105 |
+
</div>
|
106 |
+
|
107 |
+
<script>
|
108 |
+
(function ( $ ) {
|
109 |
+
$( document ).ready( function () {
|
110 |
+
$( '.nav-vertical a[data-toggle="tab"]' ).on( 'shown.bs.tab', function ( evt ) {
|
111 |
+
console.log();
|
112 |
+
let target = document.querySelector( evt.currentTarget.getAttribute( 'href' ) );
|
113 |
+
window.scrollTo( { top: 0, behavior: 'smooth' } )
|
114 |
+
} );
|
115 |
+
} );
|
116 |
+
})( jQuery );
|
117 |
+
</script>
|
templates/twig/wpadmin_pages/insights/scans/results/section/malware/index.twig
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% set mal = vars.malware %}
|
2 |
+
<div class="row mt-3" id="ScanResultsMalware">
|
3 |
+
<div class="col-12">
|
4 |
+
|
5 |
+
<ul class="list-group">
|
6 |
+
<li class="list-group-item">
|
7 |
+
<span class="font-weight-bold">Understanding Malware</span>:
|
8 |
+
<span>
|
9 |
+
PHP Malware is a complex topic and scanning for malware is not simple.
|
10 |
+
Please take a moment to read some of
|
11 |
+
<a href="javascript:{}" class="font-weight-bold beacon-article"
|
12 |
+
data-beacon-article-format="sidebar"
|
13 |
+
data-beacon-article-id="{{ vars.beacon_help_id }}">
|
14 |
+
the help around this topic</a>.
|
15 |
+
</span>
|
16 |
+
</li>
|
17 |
+
|
18 |
+
{% if flags.mal_is_restricted %}
|
19 |
+
<li class="list-group-item list-group-item-warning">
|
20 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}:</span>
|
21 |
+
<span>{{ strings.mal_restricted }}</span>
|
22 |
+
</li>
|
23 |
+
{% else %}
|
24 |
+
{% if mal.flags.has_malware %}
|
25 |
+
<li class="list-group-item list-group-item-danger">
|
26 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}</span>
|
27 |
+
<span>{{ strings.files_found }}</span>
|
28 |
+
</li>
|
29 |
+
{% else %}
|
30 |
+
<li class="list-group-item list-group-item-success">
|
31 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}</span>
|
32 |
+
<span>{{ strings.no_files }}</span>
|
33 |
+
</li>
|
34 |
+
{% endif %}
|
35 |
+
{% endif %}
|
36 |
+
</ul>
|
37 |
+
</div>
|
38 |
+
|
39 |
+
<div class="col-12">
|
40 |
+
<div class="row mt-3">
|
41 |
+
{% if mal.flags.has_malware %}
|
42 |
+
<div class="col">
|
43 |
+
<table id="table_id-malware"
|
44 |
+
class="table table-striped table-bordered" style="width: 100%;"></table>
|
45 |
+
</div>
|
46 |
+
<script>
|
47 |
+
jQuery( document ).ready( function () {
|
48 |
+
jQuery( '#table_id-malware' ).icwpWpsfScanTableActions(
|
49 |
+
{
|
50 |
+
'type': 'malware',
|
51 |
+
'file': 'malware',
|
52 |
+
'ajax': {
|
53 |
+
'scanresults_action':{{ ajax.scanresults_action|raw }},
|
54 |
+
},
|
55 |
+
'datatables_init': {{ vars.datatables_init|raw }}
|
56 |
+
}
|
57 |
+
);
|
58 |
+
} );
|
59 |
+
</script>
|
60 |
+
{% endif %}
|
61 |
+
</div>
|
62 |
+
</div>
|
63 |
+
|
64 |
+
</div>
|
templates/twig/wpadmin_pages/insights/scans/results/section/plugins/index.twig
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="row mt-3 nav-vertical" id="ScanResultsPlugins">
|
2 |
+
|
3 |
+
<div class="col-2">
|
4 |
+
<ul class="nav nav-tabs flex-column">
|
5 |
+
{% for plugin_key,plugin in vars.plugins %}
|
6 |
+
<li class="nav-item mb-2">
|
7 |
+
<a class="nav-link {% if plugin_key < 1 %}active{% endif %}"
|
8 |
+
href="#plugin-tab-{{ plugin.info.slug }}"
|
9 |
+
data-toggle="tab"
|
10 |
+
>
|
11 |
+
{% if plugin.vars.count_items > 0 %}
|
12 |
+
<span class="badge badge-danger float-right">{{ plugin.vars.count_items }}</span>
|
13 |
+
{% elseif plugin.flags.has_warning %}
|
14 |
+
<span class="badge badge-warning float-right">!</span>
|
15 |
+
{% else %}
|
16 |
+
<span class="badge badge-success float-right">✓</span>
|
17 |
+
{% endif %}
|
18 |
+
{{ plugin.info.name }}
|
19 |
+
</a>
|
20 |
+
</li>
|
21 |
+
{% endfor %}
|
22 |
+
</ul>
|
23 |
+
</div>
|
24 |
+
|
25 |
+
<div class="col-10">
|
26 |
+
<div class="tab-content">
|
27 |
+
{% for plugin_key,plugin in vars.plugins %}
|
28 |
+
<div class="tab-pane {% if plugin_key < 1 %}show active{% endif %}"
|
29 |
+
id="plugin-tab-{{ plugin.info.slug }}"
|
30 |
+
role="tabpanel"
|
31 |
+
aria-labelledby="profile-tab"
|
32 |
+
>
|
33 |
+
{% include '/wpadmin_pages/insights/scans/results/section/plugins/plugin_panel.twig' %}
|
34 |
+
</div>
|
35 |
+
{% endfor %}
|
36 |
+
</div>
|
37 |
+
</div>
|
38 |
+
|
39 |
+
</div>
|
templates/twig/wpadmin_pages/insights/scans/results/section/plugins/plugin_panel.twig
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="row" id="PluginSection-{{ plugin.info.slug }}">
|
2 |
+
<div class="col">
|
3 |
+
|
4 |
+
<ul class="list-group">
|
5 |
+
{% if plugin.flags.is_vulnerable %}
|
6 |
+
<li class="list-group-item list-group-item-danger">
|
7 |
+
<span class="font-weight-bold">{{ strings.vulnerable }}</span>:
|
8 |
+
{{ strings.vulnerable_known }}
|
9 |
+
{{ strings.vulnerable_update }}
|
10 |
+
<a href="{{ plugin.hrefs.vul_info }}" target="_blank">{{ strings.more_info }}</a>
|
11 |
+
</li>
|
12 |
+
{% endif %}
|
13 |
+
{% if plugin.flags.is_abandoned %}
|
14 |
+
<li class="list-group-item list-group-item-danger">
|
15 |
+
<span class="font-weight-bold">{{ strings.abandoned }}</span>:
|
16 |
+
{{ plugin.info.abandoned_at }}
|
17 |
+
<button class="btn btn-light action standalone-action ignore"
|
18 |
+
title="Ignore"
|
19 |
+
data-rid="{{ plugin.vars.abandoned_rid }}">
|
20 |
+
{{ imgs.svgs.ignore|raw }}</button>
|
21 |
+
</li>
|
22 |
+
{% endif %}
|
23 |
+
{% if plugin.flags.has_update %}
|
24 |
+
<li class="list-group-item list-group-item-warning">
|
25 |
+
<span class="font-weight-bold">
|
26 |
+
<a href="{{ hrefs.upgrade }}" target="_blank">{{ strings.update_available }}</a>
|
27 |
+
</span>
|
28 |
+
</li>
|
29 |
+
{% endif %}
|
30 |
+
{% if not plugin.flags.is_active %}
|
31 |
+
<li class="list-group-item list-group-item-warning">
|
32 |
+
{{ strings.not_active }}
|
33 |
+
<a href="{{ hrefs.page_plugins }}" target="_blank">{{ strings.go_to_plugins }}</a>
|
34 |
+
</li>
|
35 |
+
{% endif %}
|
36 |
+
<li class="list-group-item">
|
37 |
+
<span class="font-weight-bold">{{ strings.name }}</span>: {{ plugin.info.name }};
|
38 |
+
<span class="font-weight-bold">{{ strings.version }}</span>: {{ plugin.info.version }};
|
39 |
+
<span class="font-weight-bold">{{ strings.installed_at }}</span>:
|
40 |
+
{{ plugin.info.installed_at }} <small>({{ strings.estimated }})</small>
|
41 |
+
</li>
|
42 |
+
<li class="list-group-item">
|
43 |
+
<span class="font-weight-bold">{{ strings.author }}</span>:
|
44 |
+
<a href="{{ plugin.info.author_url }}" target="_blank">{{ plugin.info.author }}</a>;
|
45 |
+
<span class="font-weight-bold">WordPress.org</span>: {{ plugin.flags.is_wporg ? 'Yes' : 'No' }}
|
46 |
+
</li>
|
47 |
+
<li class="list-group-item">
|
48 |
+
<span class="font-weight-bold">{{ strings.install_dir }}</span>:
|
49 |
+
<code>{{ plugin.info.dir }}</code>
|
50 |
+
<small>({{ strings.rel_to_abspath }})</small>
|
51 |
+
</li>
|
52 |
+
|
53 |
+
{% if flags.ptg_is_restricted %}
|
54 |
+
<li class="list-group-item list-group-item-warning">
|
55 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}</span>:
|
56 |
+
<span>{{ strings.ptg_not_available }}</span>
|
57 |
+
</li>
|
58 |
+
{% else %}
|
59 |
+
{% if plugin.flags.has_guard_files %}
|
60 |
+
<li class="list-group-item list-group-item-danger">
|
61 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}</span>:
|
62 |
+
<span>{{ strings.files_found }}</span>
|
63 |
+
</li>
|
64 |
+
{% else %}
|
65 |
+
<li class="list-group-item list-group-item-success">
|
66 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}</span>:
|
67 |
+
<span>{{ strings.no_files }}</span>
|
68 |
+
</li>
|
69 |
+
{% endif %}
|
70 |
+
{% endif %}
|
71 |
+
|
72 |
+
</ul>
|
73 |
+
</div>
|
74 |
+
</div>
|
75 |
+
|
76 |
+
<div class="col-12">
|
77 |
+
<div class="row mt-3">
|
78 |
+
<div class="col">
|
79 |
+
<table id="table_id-{{ plugin.info.slug }}"
|
80 |
+
class="table table-striped table-bordered" style="width: 100%;"></table>
|
81 |
+
</div>
|
82 |
+
</div>
|
83 |
+
</div>
|
84 |
+
|
85 |
+
<script>
|
86 |
+
jQuery( document ).ready( function () {
|
87 |
+
{% if plugin.flags.is_abandoned %}
|
88 |
+
jQuery( '#PluginSection-{{ plugin.info.slug }}' ).icwpWpsfScanResultsActions(
|
89 |
+
{
|
90 |
+
'ajax': {
|
91 |
+
'scanresults_action':{{ ajax.scanresults_action|raw }},
|
92 |
+
}
|
93 |
+
}
|
94 |
+
);
|
95 |
+
{% endif %}
|
96 |
+
{% if plugin.flags.has_guard_files %}
|
97 |
+
jQuery( '#table_id-{{ plugin.info.slug }}' ).icwpWpsfScanTableActions(
|
98 |
+
{
|
99 |
+
'type': '{{ plugin.info.type }}',
|
100 |
+
'file': '{{ plugin.info.file }}',
|
101 |
+
'ajax': {
|
102 |
+
'scanresults_action':{{ ajax.scanresults_action|raw }},
|
103 |
+
},
|
104 |
+
'datatables_init': {{ vars.datatables_init|raw }}
|
105 |
+
}
|
106 |
+
);
|
107 |
+
{% endif %}
|
108 |
+
} );
|
109 |
+
</script>
|
templates/twig/wpadmin_pages/insights/scans/results/section/themes/index.twig
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="row mt-3 nav-vertical" id="ScanResultsThemes">
|
2 |
+
|
3 |
+
<div class="col-2">
|
4 |
+
<ul class="nav nav-tabs flex-column">
|
5 |
+
{% for theme_key,theme in vars.themes %}
|
6 |
+
<li class="nav-item mb-2">
|
7 |
+
<a class="nav-link {% if theme_key < 1 %}active{% endif %}"
|
8 |
+
href="#theme-tab-{{ theme.info.slug }}"
|
9 |
+
data-toggle="tab"
|
10 |
+
>
|
11 |
+
{% if theme.vars.count_items > 0 %}
|
12 |
+
<span class="badge badge-danger float-right">{{ theme.vars.count_items }}</span>
|
13 |
+
{% elseif theme.flags.has_warning %}
|
14 |
+
<span class="badge badge-warning float-right">!</span>
|
15 |
+
{% else %}
|
16 |
+
<span class="badge badge-success float-right">✓</span>
|
17 |
+
{% endif %}
|
18 |
+
{{ theme.info.name }}
|
19 |
+
</a>
|
20 |
+
</li>
|
21 |
+
{% endfor %}
|
22 |
+
</ul>
|
23 |
+
</div>
|
24 |
+
|
25 |
+
<div class="col-10">
|
26 |
+
<div class="tab-content">
|
27 |
+
{% for theme_key,theme in vars.themes %}
|
28 |
+
<div class="tab-pane {% if theme_key < 1 %}show active{% endif %}"
|
29 |
+
id="theme-tab-{{ theme.info.slug }}"
|
30 |
+
role="tabpanel"
|
31 |
+
aria-labelledby="profile-tab"
|
32 |
+
>
|
33 |
+
{% include '/wpadmin_pages/insights/scans/results/section/themes/theme_panel.twig' %}
|
34 |
+
</div>
|
35 |
+
{% endfor %}
|
36 |
+
</div>
|
37 |
+
</div>
|
38 |
+
</div>
|
templates/twig/wpadmin_pages/insights/scans/results/section/themes/theme_panel.twig
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="row">
|
2 |
+
<div class="col">
|
3 |
+
|
4 |
+
<ul class="list-group">
|
5 |
+
{% if theme.flags.is_vulnerable %}
|
6 |
+
<li class="list-group-item list-group-item-danger">
|
7 |
+
<span class="font-weight-bold">{{ strings.vulnerable }}</span>:
|
8 |
+
{{ strings.vulnerable_known }}
|
9 |
+
{{ strings.vulnerable_update }}
|
10 |
+
<a href="{{ theme.hrefs.vul_info }}" target="_blank">{{ strings.more_info }}</a>
|
11 |
+
</li>
|
12 |
+
{% endif %}
|
13 |
+
{% if theme.flags.is_abandoned %}
|
14 |
+
<li class="list-group-item list-group-item-danger">
|
15 |
+
<span class="font-weight-bold">{{ strings.abandoned }}</span>:
|
16 |
+
{{ theme.info.abandoned_at }}
|
17 |
+
</li>
|
18 |
+
{% endif %}
|
19 |
+
{% if theme.flags.has_update %}
|
20 |
+
<li class="list-group-item list-group-item-warning">
|
21 |
+
<span class="font-weight-bold">
|
22 |
+
<a href="{{ hrefs.upgrade }}" target="_blank">{{ strings.update_available }}</a>
|
23 |
+
</span>
|
24 |
+
</li>
|
25 |
+
{% endif %}
|
26 |
+
{% if not theme.flags.is_active %}
|
27 |
+
<li class="list-group-item list-group-item-warning">
|
28 |
+
{{ strings.not_active }}
|
29 |
+
<a href="{{ hrefs.page_themes }}" target="_blank">{{ strings.go_to_themes }}</a>
|
30 |
+
</li>
|
31 |
+
{% endif %}
|
32 |
+
<li class="list-group-item">
|
33 |
+
<span class="font-weight-bold">{{ strings.name }}</span>: {{ theme.info.name }};
|
34 |
+
<span class="font-weight-bold">{{ strings.version }}</span>: {{ theme.info.version }};
|
35 |
+
<span class="font-weight-bold">{{ strings.installed_at }}</span>:
|
36 |
+
{{ theme.info.installed_at }} <small>({{ strings.estimated }})</small>
|
37 |
+
</li>
|
38 |
+
<li class="list-group-item">
|
39 |
+
<span class="font-weight-bold">{{ strings.author }}</span>:
|
40 |
+
<a href="{{ theme.info.author_url }}" target="_blank">{{ theme.info.author }}</a>;
|
41 |
+
<span class="font-weight-bold">WordPress.org</span>: {{ theme.flags.is_wporg ? 'Yes' : 'No' }}
|
42 |
+
</li>
|
43 |
+
{% if theme.flags.is_child %}
|
44 |
+
<li class="list-group-item">
|
45 |
+
<span class="font-weight-bold">{{ strings.parent_theme }}</span>: {{ theme.info.parent_theme }};
|
46 |
+
</li>
|
47 |
+
{% elseif theme.flags.is_parent %}
|
48 |
+
<li class="list-group-item">
|
49 |
+
<span class="font-weight-bold">{{ strings.child_theme }}</span>: {{ theme.info.child_theme }};
|
50 |
+
</li>
|
51 |
+
{% endif %}
|
52 |
+
<li class="list-group-item">
|
53 |
+
<span class="font-weight-bold">{{ strings.install_dir }}</span>:
|
54 |
+
<code>{{ theme.info.dir }}</code>
|
55 |
+
<small>({{ strings.rel_to_abspath }})</small>
|
56 |
+
</li>
|
57 |
+
|
58 |
+
{% if flags.ptg_is_restricted %}
|
59 |
+
<li class="list-group-item list-group-item-warning">
|
60 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}</span>:
|
61 |
+
<span>{{ strings.ptg_not_available }}</span>
|
62 |
+
</li>
|
63 |
+
{% else %}
|
64 |
+
{% if theme.flags.has_guard_files %}
|
65 |
+
<li class="list-group-item list-group-item-danger">
|
66 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}</span>:
|
67 |
+
<span>{{ strings.files_found }}</span>
|
68 |
+
</li>
|
69 |
+
{% else %}
|
70 |
+
<li class="list-group-item list-group-item-success">
|
71 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}</span>:
|
72 |
+
<span>{{ strings.no_files }}</span>
|
73 |
+
</li>
|
74 |
+
{% endif %}
|
75 |
+
{% endif %}
|
76 |
+
|
77 |
+
</ul>
|
78 |
+
</div>
|
79 |
+
</div>
|
80 |
+
|
81 |
+
<div class="col-12">
|
82 |
+
<div class="row mt-3">
|
83 |
+
{% if theme.flags.has_guard_files %}
|
84 |
+
<div class="col">
|
85 |
+
<table id="table_id-{{ theme.info.slug }}"
|
86 |
+
class="table table-striped table-bordered w-100"></table>
|
87 |
+
</div>
|
88 |
+
<script>
|
89 |
+
jQuery( document ).ready( function () {
|
90 |
+
jQuery( '#table_id-{{ theme.info.slug }}' ).icwpWpsfScanTableActions(
|
91 |
+
{
|
92 |
+
'type': '{{ theme.info.type }}',
|
93 |
+
'file': '{{ theme.info.file }}',
|
94 |
+
'ajax': {
|
95 |
+
'scanresults_action':{{ ajax.scanresults_action|raw }},
|
96 |
+
},
|
97 |
+
'datatables_init': {{ vars.datatables_init|raw }}
|
98 |
+
}
|
99 |
+
);
|
100 |
+
} );
|
101 |
+
</script>
|
102 |
+
{% endif %}
|
103 |
+
</div>
|
104 |
+
</div>
|
templates/twig/wpadmin_pages/insights/scans/results/section/wordpress/index.twig
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% set wp = vars.wordpress %}
|
2 |
+
<div class="row mt-3" id="ScanResultsWordpress">
|
3 |
+
<div class="col-12">
|
4 |
+
|
5 |
+
<ul class="list-group">
|
6 |
+
{% if wp.flags.is_vulnerable %}
|
7 |
+
<li class="list-group-item list-group-item-danger">
|
8 |
+
<span class="font-weight-bold">{{ strings.vulnerable }}</span>:
|
9 |
+
{{ strings.vulnerable_known }}
|
10 |
+
{{ strings.vulnerable_update }}
|
11 |
+
</li>
|
12 |
+
{% endif %}
|
13 |
+
{% if wp.flags.has_update %}
|
14 |
+
<li class="list-group-item list-group-item-warning">
|
15 |
+
<span class="font-weight-bold">
|
16 |
+
<a href="{{ hrefs.upgrade }}" target="_blank">{{ strings.update_available }}</a>
|
17 |
+
</span>
|
18 |
+
</li>
|
19 |
+
{% endif %}
|
20 |
+
<li class="list-group-item">
|
21 |
+
<span class="font-weight-bold">{{ strings.version }}</span>: {{ wp.info.version }}
|
22 |
+
</li>
|
23 |
+
<li class="list-group-item">
|
24 |
+
<span class="font-weight-bold">{{ strings.install_dir }}</span>:
|
25 |
+
<code>{{ wp.info.dir }}</code>
|
26 |
+
</li>
|
27 |
+
{% if wp.flags.has_core_files %}
|
28 |
+
<li class="list-group-item list-group-item-danger">
|
29 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}</span>:
|
30 |
+
<span>{{ strings.files_found }}</span>
|
31 |
+
</li>
|
32 |
+
{% else %}
|
33 |
+
<li class="list-group-item list-group-item-success">
|
34 |
+
<span class="font-weight-bold">{{ strings.file_integrity }}</span>:
|
35 |
+
<span>{{ strings.no_files }}</span>
|
36 |
+
</li>
|
37 |
+
{% endif %}
|
38 |
+
</ul>
|
39 |
+
</div>
|
40 |
+
|
41 |
+
<div class="col-12">
|
42 |
+
<div class="row mt-3">
|
43 |
+
{% if wp.flags.has_core_files %}
|
44 |
+
<div class="col">
|
45 |
+
<table id="table_id-wordpress"
|
46 |
+
class="table table-striped table-bordered" style="width: 100%;"></table>
|
47 |
+
</div>
|
48 |
+
<script>
|
49 |
+
jQuery( document ).ready( function () {
|
50 |
+
jQuery( '#table_id-wordpress' ).icwpWpsfScanTableActions(
|
51 |
+
{
|
52 |
+
'type': 'wordpress',
|
53 |
+
'file': 'wordpress',
|
54 |
+
'ajax': {
|
55 |
+
'scanresults_action':{{ ajax.scanresults_action|raw }},
|
56 |
+
},
|
57 |
+
'datatables_init': {{ vars.datatables_init|raw }}
|
58 |
+
}
|
59 |
+
);
|
60 |
+
} );
|
61 |
+
</script>
|
62 |
+
{% endif %}
|
63 |
+
</div>
|
64 |
+
</div>
|
65 |
+
|
66 |
+
</div>
|