Version Description
( 2022-09-29 ) =
- Fix: Encrypt 2FA secret keys
Download this release
Release Info
Developer | BigTonny |
Plugin | Defender Security – Malware Scanner, Login Security & Firewall |
Version | 3.3.2 |
Comparing to | |
See all releases |
Code changes from version 3.3.1 to 3.3.2
- languages/wpdef-default.pot +32 -32
- readme.txt +6 -16
- src/component/crypt.php +61 -5
- src/component/def.key +17 -0
- src/component/two-factor/providers/totp.php +8 -90
- src/controller/two-factor.php +8 -5
- src/functions.php +1 -2
- src/upgrader.php +91 -17
- wp-defender.php +3 -3
languages/wpdef-default.pot
CHANGED
@@ -6,9 +6,9 @@
|
|
6 |
#, fuzzy
|
7 |
msgid ""
|
8 |
msgstr ""
|
9 |
-
"Project-Id-Version: wp-defender 3.3.
|
10 |
"Report-Msgid-Bugs-To: \n"
|
11 |
-
"POT-Creation-Date: 2022-09-
|
12 |
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
@@ -1090,7 +1090,7 @@ msgstr ""
|
|
1090 |
msgid "password reset"
|
1091 |
msgstr ""
|
1092 |
|
1093 |
-
#: src/component/backup-settings.php:529 src/upgrader.php:
|
1094 |
msgid "Basic Config"
|
1095 |
msgstr ""
|
1096 |
|
@@ -1128,8 +1128,8 @@ msgstr ""
|
|
1128 |
#: src/controller/password-protection.php:290
|
1129 |
#: src/controller/password-protection.php:296 src/controller/recaptcha.php:1017
|
1130 |
#: src/controller/scan.php:661 src/controller/scan.php:694
|
1131 |
-
#: src/controller/security-headers.php:167 src/controller/two-factor.php:
|
1132 |
-
#: src/controller/two-factor.php:
|
1133 |
#: front/src/module/dashboard/component/advanced-tools.vue:30
|
1134 |
#: front/src/module/dashboard/component/advanced-tools.vue:52
|
1135 |
#: front/src/module/dashboard/component/advanced-tools.vue:93
|
@@ -1147,8 +1147,8 @@ msgstr ""
|
|
1147 |
#: src/controller/mask-login.php:757 src/controller/password-protection.php:278
|
1148 |
#: src/controller/password-protection.php:295 src/controller/recaptcha.php:1017
|
1149 |
#: src/controller/scan.php:659 src/controller/scan.php:693
|
1150 |
-
#: src/controller/security-headers.php:167 src/controller/two-factor.php:
|
1151 |
-
#: src/controller/two-factor.php:
|
1152 |
#: front/src/module/dashboard/component/advanced-tools.vue:29
|
1153 |
#: front/src/module/dashboard/component/advanced-tools.vue:53
|
1154 |
#: front/src/module/dashboard/component/advanced-tools.vue:92
|
@@ -1201,7 +1201,7 @@ msgid "Firewall"
|
|
1201 |
msgstr ""
|
1202 |
|
1203 |
#: src/component/backup-settings.php:1195 src/controller/two-factor.php:68
|
1204 |
-
#: src/controller/two-factor.php:
|
1205 |
msgid "2FA"
|
1206 |
msgstr ""
|
1207 |
|
@@ -1987,7 +1987,7 @@ msgstr ""
|
|
1987 |
msgid "Your token is invalid."
|
1988 |
msgstr ""
|
1989 |
|
1990 |
-
#: src/component/two-fa.php:477 src/controller/two-factor.php:
|
1991 |
#: src/view/two-fa/user-options.php:12
|
1992 |
#: front/src/module/dashboard/component/preset-config.vue:123
|
1993 |
#: front/src/module/dashboard/component/two-fa.vue:6
|
@@ -2027,7 +2027,7 @@ msgid "Generate non-expirable backup codes that can be used to log in once."
|
|
2027 |
msgstr ""
|
2028 |
|
2029 |
#: src/component/two-factor/providers/backup-codes.php:77
|
2030 |
-
#: src/controller/two-factor.php:
|
2031 |
msgid "Each backup code can only be used to log in once."
|
2032 |
msgstr ""
|
2033 |
|
@@ -2045,7 +2045,7 @@ msgstr ""
|
|
2045 |
|
2046 |
#: src/component/two-factor/providers/backup-codes.php:138
|
2047 |
#: src/component/two-factor/providers/fallback-email.php:107
|
2048 |
-
#: src/component/two-factor/providers/totp.php:
|
2049 |
msgid "Authenticate"
|
2050 |
msgstr ""
|
2051 |
|
@@ -2062,7 +2062,7 @@ msgid "Generate Backup Codes"
|
|
2062 |
msgstr ""
|
2063 |
|
2064 |
#: src/component/two-factor/providers/backup-codes.php:233
|
2065 |
-
#: src/controller/two-factor.php:
|
2066 |
msgid "Get New Codes"
|
2067 |
msgstr ""
|
2068 |
|
@@ -2104,41 +2104,41 @@ msgstr ""
|
|
2104 |
msgid "ERROR: Invalid passcode."
|
2105 |
msgstr ""
|
2106 |
|
2107 |
-
#: src/component/two-factor/providers/totp.php:
|
2108 |
msgid "TOTP Authenticator App"
|
2109 |
msgstr ""
|
2110 |
|
2111 |
-
#: src/component/two-factor/providers/totp.php:
|
2112 |
msgid "TOTP Authentication"
|
2113 |
msgstr ""
|
2114 |
|
2115 |
-
#: src/component/two-factor/providers/totp.php:
|
2116 |
msgid "TOTP"
|
2117 |
msgstr ""
|
2118 |
|
2119 |
#. translators: %s: style class
|
2120 |
-
#: src/component/two-factor/providers/totp.php:
|
2121 |
#, php-format
|
2122 |
msgid ""
|
2123 |
"<button type=\"button\" class=\"button reset-totp-keys button-secondary hide-"
|
2124 |
"if-no-js\" %s>Reset Keys</button>"
|
2125 |
msgstr ""
|
2126 |
|
2127 |
-
#: src/component/two-factor/providers/totp.php:
|
2128 |
msgid "TOTP Authentication method is active for this site"
|
2129 |
msgstr ""
|
2130 |
|
2131 |
-
#: src/component/two-factor/providers/totp.php:
|
2132 |
msgid "Use an authenticator app to sign in with a separate passcode."
|
2133 |
msgstr ""
|
2134 |
|
2135 |
-
#: src/component/two-factor/providers/totp.php:
|
2136 |
#: src/controller/two-factor.php:401
|
2137 |
msgid "Whoops, the passcode you entered was incorrect or expired."
|
2138 |
msgstr ""
|
2139 |
|
2140 |
#: src/component/two-factor/providers/webauthn.php:46
|
2141 |
-
#: src/controller/two-factor.php:
|
2142 |
msgid "Beta"
|
2143 |
msgstr ""
|
2144 |
|
@@ -2298,7 +2298,7 @@ msgstr ""
|
|
2298 |
#: src/controller/firewall.php:144 src/controller/main-setting.php:97
|
2299 |
#: src/controller/mask-login.php:312 src/controller/password-protection.php:218
|
2300 |
#: src/controller/password-reset.php:198 src/controller/scan.php:361
|
2301 |
-
#: src/controller/security-headers.php:74 src/controller/two-factor.php:
|
2302 |
#: src/traits/setting.php:21
|
2303 |
msgid "Your settings have been updated."
|
2304 |
msgstr ""
|
@@ -2946,24 +2946,24 @@ msgstr ""
|
|
2946 |
msgid "You have logged in successfully."
|
2947 |
msgstr ""
|
2948 |
|
2949 |
-
#: src/controller/two-factor.php:
|
2950 |
msgid "Please input a valid OTP code."
|
2951 |
msgstr ""
|
2952 |
|
2953 |
-
#: src/controller/two-factor.php:
|
2954 |
msgid "Your OTP code is incorrect. Please try again."
|
2955 |
msgstr ""
|
2956 |
|
2957 |
-
#: src/controller/two-factor.php:
|
2958 |
msgid "Test email has been sent to your email."
|
2959 |
msgstr ""
|
2960 |
|
2961 |
-
#: src/controller/two-factor.php:
|
2962 |
msgid "Test email failed."
|
2963 |
msgstr ""
|
2964 |
|
2965 |
#. translators: %s: link
|
2966 |
-
#: src/controller/two-factor.php:
|
2967 |
#, php-format
|
2968 |
msgid ""
|
2969 |
"Web Authentication is now available. <a target=\"_blank\" href=\"%s\">Click "
|
@@ -2971,26 +2971,26 @@ msgid ""
|
|
2971 |
msgstr ""
|
2972 |
|
2973 |
#. translators: %s: count
|
2974 |
-
#: src/controller/two-factor.php:
|
2975 |
#, php-format
|
2976 |
msgid "2FA Backup Codes for %s:"
|
2977 |
msgstr ""
|
2978 |
|
2979 |
-
#: src/controller/two-factor.php:
|
2980 |
msgid "Reset two factor"
|
2981 |
msgstr ""
|
2982 |
|
2983 |
#. translators: %s: URL to regenerate code
|
2984 |
-
#: src/controller/two-factor.php:
|
2985 |
#, php-format
|
2986 |
msgid "Two factor authentication has been reset for <b>%s.</b>"
|
2987 |
msgstr ""
|
2988 |
|
2989 |
-
#: src/controller/two-factor.php:
|
2990 |
msgid "Save changes"
|
2991 |
msgstr ""
|
2992 |
|
2993 |
-
#: src/controller/two-factor.php:
|
2994 |
msgid "Two-Factor settings updated successfully."
|
2995 |
msgstr ""
|
2996 |
|
@@ -4225,7 +4225,7 @@ msgstr ""
|
|
4225 |
msgid "Hub"
|
4226 |
msgstr ""
|
4227 |
|
4228 |
-
#: src/upgrader.php:
|
4229 |
msgid "Basic config"
|
4230 |
msgstr ""
|
4231 |
|
6 |
#, fuzzy
|
7 |
msgid ""
|
8 |
msgstr ""
|
9 |
+
"Project-Id-Version: wp-defender 3.3.2\n"
|
10 |
"Report-Msgid-Bugs-To: \n"
|
11 |
+
"POT-Creation-Date: 2022-09-29 12:54+0300\n"
|
12 |
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
1090 |
msgid "password reset"
|
1091 |
msgstr ""
|
1092 |
|
1093 |
+
#: src/component/backup-settings.php:529 src/upgrader.php:649
|
1094 |
msgid "Basic Config"
|
1095 |
msgstr ""
|
1096 |
|
1128 |
#: src/controller/password-protection.php:290
|
1129 |
#: src/controller/password-protection.php:296 src/controller/recaptcha.php:1017
|
1130 |
#: src/controller/scan.php:661 src/controller/scan.php:694
|
1131 |
+
#: src/controller/security-headers.php:167 src/controller/two-factor.php:1134
|
1132 |
+
#: src/controller/two-factor.php:1146
|
1133 |
#: front/src/module/dashboard/component/advanced-tools.vue:30
|
1134 |
#: front/src/module/dashboard/component/advanced-tools.vue:52
|
1135 |
#: front/src/module/dashboard/component/advanced-tools.vue:93
|
1147 |
#: src/controller/mask-login.php:757 src/controller/password-protection.php:278
|
1148 |
#: src/controller/password-protection.php:295 src/controller/recaptcha.php:1017
|
1149 |
#: src/controller/scan.php:659 src/controller/scan.php:693
|
1150 |
+
#: src/controller/security-headers.php:167 src/controller/two-factor.php:1134
|
1151 |
+
#: src/controller/two-factor.php:1146
|
1152 |
#: front/src/module/dashboard/component/advanced-tools.vue:29
|
1153 |
#: front/src/module/dashboard/component/advanced-tools.vue:53
|
1154 |
#: front/src/module/dashboard/component/advanced-tools.vue:92
|
1201 |
msgstr ""
|
1202 |
|
1203 |
#: src/component/backup-settings.php:1195 src/controller/two-factor.php:68
|
1204 |
+
#: src/controller/two-factor.php:1415
|
1205 |
msgid "2FA"
|
1206 |
msgstr ""
|
1207 |
|
1987 |
msgid "Your token is invalid."
|
1988 |
msgstr ""
|
1989 |
|
1990 |
+
#: src/component/two-fa.php:477 src/controller/two-factor.php:968
|
1991 |
#: src/view/two-fa/user-options.php:12
|
1992 |
#: front/src/module/dashboard/component/preset-config.vue:123
|
1993 |
#: front/src/module/dashboard/component/two-fa.vue:6
|
2027 |
msgstr ""
|
2028 |
|
2029 |
#: src/component/two-factor/providers/backup-codes.php:77
|
2030 |
+
#: src/controller/two-factor.php:1293
|
2031 |
msgid "Each backup code can only be used to log in once."
|
2032 |
msgstr ""
|
2033 |
|
2045 |
|
2046 |
#: src/component/two-factor/providers/backup-codes.php:138
|
2047 |
#: src/component/two-factor/providers/fallback-email.php:107
|
2048 |
+
#: src/component/two-factor/providers/totp.php:118
|
2049 |
msgid "Authenticate"
|
2050 |
msgstr ""
|
2051 |
|
2062 |
msgstr ""
|
2063 |
|
2064 |
#: src/component/two-factor/providers/backup-codes.php:233
|
2065 |
+
#: src/controller/two-factor.php:1292
|
2066 |
msgid "Get New Codes"
|
2067 |
msgstr ""
|
2068 |
|
2104 |
msgid "ERROR: Invalid passcode."
|
2105 |
msgstr ""
|
2106 |
|
2107 |
+
#: src/component/two-factor/providers/totp.php:87
|
2108 |
msgid "TOTP Authenticator App"
|
2109 |
msgstr ""
|
2110 |
|
2111 |
+
#: src/component/two-factor/providers/totp.php:94
|
2112 |
msgid "TOTP Authentication"
|
2113 |
msgstr ""
|
2114 |
|
2115 |
+
#: src/component/two-factor/providers/totp.php:101
|
2116 |
msgid "TOTP"
|
2117 |
msgstr ""
|
2118 |
|
2119 |
#. translators: %s: style class
|
2120 |
+
#: src/component/two-factor/providers/totp.php:141
|
2121 |
#, php-format
|
2122 |
msgid ""
|
2123 |
"<button type=\"button\" class=\"button reset-totp-keys button-secondary hide-"
|
2124 |
"if-no-js\" %s>Reset Keys</button>"
|
2125 |
msgstr ""
|
2126 |
|
2127 |
+
#: src/component/two-factor/providers/totp.php:146
|
2128 |
msgid "TOTP Authentication method is active for this site"
|
2129 |
msgstr ""
|
2130 |
|
2131 |
+
#: src/component/two-factor/providers/totp.php:147
|
2132 |
msgid "Use an authenticator app to sign in with a separate passcode."
|
2133 |
msgstr ""
|
2134 |
|
2135 |
+
#: src/component/two-factor/providers/totp.php:224
|
2136 |
#: src/controller/two-factor.php:401
|
2137 |
msgid "Whoops, the passcode you entered was incorrect or expired."
|
2138 |
msgstr ""
|
2139 |
|
2140 |
#: src/component/two-factor/providers/webauthn.php:46
|
2141 |
+
#: src/controller/two-factor.php:1096
|
2142 |
msgid "Beta"
|
2143 |
msgstr ""
|
2144 |
|
2298 |
#: src/controller/firewall.php:144 src/controller/main-setting.php:97
|
2299 |
#: src/controller/mask-login.php:312 src/controller/password-protection.php:218
|
2300 |
#: src/controller/password-reset.php:198 src/controller/scan.php:361
|
2301 |
+
#: src/controller/security-headers.php:74 src/controller/two-factor.php:878
|
2302 |
#: src/traits/setting.php:21
|
2303 |
msgid "Your settings have been updated."
|
2304 |
msgstr ""
|
2946 |
msgid "You have logged in successfully."
|
2947 |
msgstr ""
|
2948 |
|
2949 |
+
#: src/controller/two-factor.php:638
|
2950 |
msgid "Please input a valid OTP code."
|
2951 |
msgstr ""
|
2952 |
|
2953 |
+
#: src/controller/two-factor.php:668
|
2954 |
msgid "Your OTP code is incorrect. Please try again."
|
2955 |
msgstr ""
|
2956 |
|
2957 |
+
#: src/controller/two-factor.php:980
|
2958 |
msgid "Test email has been sent to your email."
|
2959 |
msgstr ""
|
2960 |
|
2961 |
+
#: src/controller/two-factor.php:985
|
2962 |
msgid "Test email failed."
|
2963 |
msgstr ""
|
2964 |
|
2965 |
#. translators: %s: link
|
2966 |
+
#: src/controller/two-factor.php:1099
|
2967 |
#, php-format
|
2968 |
msgid ""
|
2969 |
"Web Authentication is now available. <a target=\"_blank\" href=\"%s\">Click "
|
2971 |
msgstr ""
|
2972 |
|
2973 |
#. translators: %s: count
|
2974 |
+
#: src/controller/two-factor.php:1289
|
2975 |
#, php-format
|
2976 |
msgid "2FA Backup Codes for %s:"
|
2977 |
msgstr ""
|
2978 |
|
2979 |
+
#: src/controller/two-factor.php:1318
|
2980 |
msgid "Reset two factor"
|
2981 |
msgstr ""
|
2982 |
|
2983 |
#. translators: %s: URL to regenerate code
|
2984 |
+
#: src/controller/two-factor.php:1363
|
2985 |
#, php-format
|
2986 |
msgid "Two factor authentication has been reset for <b>%s.</b>"
|
2987 |
msgstr ""
|
2988 |
|
2989 |
+
#: src/controller/two-factor.php:1388 src/controller/two-factor.php:1389
|
2990 |
msgid "Save changes"
|
2991 |
msgstr ""
|
2992 |
|
2993 |
+
#: src/controller/two-factor.php:1441
|
2994 |
msgid "Two-Factor settings updated successfully."
|
2995 |
msgstr ""
|
2996 |
|
4225 |
msgid "Hub"
|
4226 |
msgstr ""
|
4227 |
|
4228 |
+
#: src/upgrader.php:648
|
4229 |
msgid "Basic config"
|
4230 |
msgstr ""
|
4231 |
|
readme.txt
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
=== Defender Security - Malware Scanner, Login Security & Firewall ===
|
2 |
Plugin Name: Defender Security - Malware Scanner, Login Security & Firewall
|
3 |
-
Version: 3.3.
|
4 |
Author: WPMU DEV
|
5 |
Author URI: https://wpmudev.com/
|
6 |
Contributors: WPMUDEV
|
7 |
Tags: security plugin, security, firewall, malware, malware scanner, antivirus, ip blocking, login security, brute force attacks, limit login attempts, custom login url, activity log, audit logs, block hackers, two-factor authentication, 2fa, hack, captcha, webauthn, authentication, fido2, fingerprint, face verification, yubikey, USB keys, woocommerce
|
8 |
Requires at least: 5.2
|
9 |
Tested up to: 6.0.2
|
10 |
-
Stable tag: 3.3.
|
11 |
Requires PHP: 7.2.0
|
12 |
License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
13 |
|
@@ -247,6 +247,10 @@ Please open a new thread in Defender’s [support forum](https://wordpress.org/s
|
|
247 |
|
248 |
== Changelog ==
|
249 |
|
|
|
|
|
|
|
|
|
250 |
= 3.3.1 ( 2022-09-21 ) =
|
251 |
|
252 |
- Enhance: 2FA security improvements
|
@@ -315,20 +319,6 @@ Please open a new thread in Defender’s [support forum](https://wordpress.org/s
|
|
315 |
- Fix: Pwned Password updated with simple password on Profile page
|
316 |
- Fix: Storing the MaxMind DB file path relatively instead of a full path
|
317 |
|
318 |
-
= 3.0.1 ( 2022-06-14 ) =
|
319 |
-
|
320 |
-
- Fix: Beehive Pro plugin flagged issues
|
321 |
-
|
322 |
-
= 3.0.0 ( 2022-06-06 ) =
|
323 |
-
|
324 |
-
- New: Biometric Authentication
|
325 |
-
- New: Giveaway Opt-in for Free version
|
326 |
-
- Enhance: PHP version upgrade
|
327 |
-
- Enhance: Compatibility with WordPress 6.0
|
328 |
-
- Enhance: WP-CLI command to show Scan details
|
329 |
-
- Enhance: Update SUI to the latest version
|
330 |
-
- Fix: Audit events logged not showing after applying some date range
|
331 |
-
|
332 |
|
333 |
[Changelog for previous versions](https://wpmudev.com/project/wp-defender/#view-changelog).
|
334 |
|
1 |
=== Defender Security - Malware Scanner, Login Security & Firewall ===
|
2 |
Plugin Name: Defender Security - Malware Scanner, Login Security & Firewall
|
3 |
+
Version: 3.3.2
|
4 |
Author: WPMU DEV
|
5 |
Author URI: https://wpmudev.com/
|
6 |
Contributors: WPMUDEV
|
7 |
Tags: security plugin, security, firewall, malware, malware scanner, antivirus, ip blocking, login security, brute force attacks, limit login attempts, custom login url, activity log, audit logs, block hackers, two-factor authentication, 2fa, hack, captcha, webauthn, authentication, fido2, fingerprint, face verification, yubikey, USB keys, woocommerce
|
8 |
Requires at least: 5.2
|
9 |
Tested up to: 6.0.2
|
10 |
+
Stable tag: 3.3.2
|
11 |
Requires PHP: 7.2.0
|
12 |
License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
13 |
|
247 |
|
248 |
== Changelog ==
|
249 |
|
250 |
+
= 3.3.2 ( 2022-09-29 ) =
|
251 |
+
|
252 |
+
- Fix: Encrypt 2FA secret keys
|
253 |
+
|
254 |
= 3.3.1 ( 2022-09-21 ) =
|
255 |
|
256 |
- Enhance: 2FA security improvements
|
319 |
- Fix: Pwned Password updated with simple password on Profile page
|
320 |
- Fix: Storing the MaxMind DB file path relatively instead of a full path
|
321 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
|
323 |
[Changelog for previous versions](https://wpmudev.com/project/wp-defender/#view-changelog).
|
324 |
|
src/component/crypt.php
CHANGED
@@ -12,7 +12,7 @@ class Crypt extends \Calotes\Base\Component {
|
|
12 |
*
|
13 |
* @return string
|
14 |
*/
|
15 |
-
public function random_bytes( int $bytes ): string {
|
16 |
// Try with random_bytes.
|
17 |
if ( function_exists( 'random_bytes' ) ) {
|
18 |
try {
|
@@ -21,7 +21,8 @@ class Crypt extends \Calotes\Base\Component {
|
|
21 |
return $rand;
|
22 |
}
|
23 |
} catch ( \Exception $e ) {
|
24 |
-
$
|
|
|
25 |
}
|
26 |
}
|
27 |
// Try with openssl_random_pseudo_bytes.
|
@@ -48,16 +49,17 @@ class Crypt extends \Calotes\Base\Component {
|
|
48 |
*
|
49 |
* @return int
|
50 |
*/
|
51 |
-
public function random_int( $min = 0, $max = 0x7FFFFFFF ): int {
|
52 |
if ( function_exists( 'random_int' ) ) {
|
53 |
try {
|
54 |
return random_int( $min, $max );
|
55 |
} catch ( \Exception $e ) {
|
56 |
-
$
|
|
|
57 |
}
|
58 |
}
|
59 |
$diff = $max - $min;
|
60 |
-
$bytes =
|
61 |
if ( 4 !== strlen( $bytes ) ) {
|
62 |
throw new \RuntimeException( 'Unable to get 4 bytes' );
|
63 |
}
|
@@ -94,4 +96,58 @@ class Crypt extends \Calotes\Base\Component {
|
|
94 |
|
95 |
return 0 === $result;
|
96 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
}
|
12 |
*
|
13 |
* @return string
|
14 |
*/
|
15 |
+
public static function random_bytes( int $bytes ): string {
|
16 |
// Try with random_bytes.
|
17 |
if ( function_exists( 'random_bytes' ) ) {
|
18 |
try {
|
21 |
return $rand;
|
22 |
}
|
23 |
} catch ( \Exception $e ) {
|
24 |
+
$_this = new self();
|
25 |
+
$_this->log( $e->getMessage(), 'internal.log' );
|
26 |
}
|
27 |
}
|
28 |
// Try with openssl_random_pseudo_bytes.
|
49 |
*
|
50 |
* @return int
|
51 |
*/
|
52 |
+
public static function random_int( $min = 0, $max = 0x7FFFFFFF ): int {
|
53 |
if ( function_exists( 'random_int' ) ) {
|
54 |
try {
|
55 |
return random_int( $min, $max );
|
56 |
} catch ( \Exception $e ) {
|
57 |
+
$_this = new self();
|
58 |
+
$_this->log( $e->getMessage(), 'internal.log' );
|
59 |
}
|
60 |
}
|
61 |
$diff = $max - $min;
|
62 |
+
$bytes = self::random_bytes( 4 );
|
63 |
if ( 4 !== strlen( $bytes ) ) {
|
64 |
throw new \RuntimeException( 'Unable to get 4 bytes' );
|
65 |
}
|
96 |
|
97 |
return 0 === $result;
|
98 |
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* @param string $plaintext
|
102 |
+
* @param string $key
|
103 |
+
*
|
104 |
+
* @return string
|
105 |
+
*/
|
106 |
+
private static function encrypt_data( $plaintext, $key ) {
|
107 |
+
$cipher = 'aes-256-cbc';
|
108 |
+
$iv_len = openssl_cipher_iv_length( $cipher );
|
109 |
+
$iv = self::random_bytes( $iv_len );
|
110 |
+
$ciphertext_raw = openssl_encrypt( $plaintext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv );
|
111 |
+
$hmac = hash_hmac( 'sha256', $ciphertext_raw, $key, true );
|
112 |
+
|
113 |
+
return base64_encode( $iv . $hmac . $ciphertext_raw );
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* @param string $encrypt_data
|
118 |
+
* @param string $key
|
119 |
+
*
|
120 |
+
* @return string
|
121 |
+
*/
|
122 |
+
private static function decrypt_data( $encrypt_data, $key ) {
|
123 |
+
$str = base64_decode( $encrypt_data );
|
124 |
+
$cipher = 'aes-256-cbc';
|
125 |
+
$iv_len = openssl_cipher_iv_length( $cipher );
|
126 |
+
$iv = substr( $str, 0, $iv_len );
|
127 |
+
$ciphertext_raw = substr( $str, $iv_len + 32 );
|
128 |
+
|
129 |
+
return openssl_decrypt( $ciphertext_raw, $cipher, $key, OPENSSL_RAW_DATA, $iv );
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* @param string $data
|
134 |
+
*
|
135 |
+
* @return string
|
136 |
+
*/
|
137 |
+
public static function get_decrypted_string( $data ): string {
|
138 |
+
$key = file_get_contents( __DIR__ . '/def.key' );
|
139 |
+
|
140 |
+
return false !== $key ? self::decrypt_data( $data, $key ) : '';
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* @param string $data
|
145 |
+
*
|
146 |
+
* @return string
|
147 |
+
*/
|
148 |
+
public static function get_encrypted_string( $data ): string {
|
149 |
+
$key = file_get_contents( __DIR__ . '/def.key' );
|
150 |
+
|
151 |
+
return false !== $key ? self::encrypt_data( $data, $key ) : '';
|
152 |
+
}
|
153 |
}
|
src/component/def.key
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
-----BEGIN CERTIFICATE-----
|
2 |
+
MIICoDCCAYgCAQAwWzELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB0FsYWJhbWExEzAR
|
3 |
+
BgNVBAcMCkJpcm1pbmdoYW0xDzANBgNVBAoMBkluY3N1YjEUMBIGA1UEAwwLd3Bt
|
4 |
+
dWRldi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDADv0IRzpr
|
5 |
+
vGgteGzbzlXXI6JKd6nTM8q9jLXoFfnrmlGxbYJxnVd+86/99nUK9Z1cVwDEMNXO
|
6 |
+
NCdbX+7OFPSQs0A59VDS/qFwSc3LviLJU2QcwTxT1/04WWDUNgeAfBFXBDc/4AY7
|
7 |
+
0qEkiw5BVnsYGGSK/ZtDYxHgUjiAcw+pThCikRhfbz6XnEcKOBlrBuPa7vn4IS3Y
|
8 |
+
/v9GRLn3eBwsWJ93sBDuTyncKoCvwtPiWZS6XYNl5JgUmTALiAyNf0HM4g+mIwGU
|
9 |
+
rsneWofNS+VXVmc1zG8DnhYjVmv5kj18gA9ak25L+lXCBReDrlySP23JfhFOgmXh
|
10 |
+
PyKxjSRfaGhbAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEARJavBbMdiMOq5soH
|
11 |
+
KYcLMqS8XwEJRGmIed4j0JpLAADMHSU047XXhgXLHEb4XI2vdkz7SVzPALstAkQW
|
12 |
+
H8rrmCfjVdt8zDCm/wzqq3LsFaKECYDIOBEsuFpNOkmCFHwEPJfEWKS9dhganVQe
|
13 |
+
Y1HZMcxFX51x0CsMOWCgZCtpgJZN0lRuAuhKg9hX++kifNEKYHSwLwNw974M/+EM
|
14 |
+
Lykj8K1C4Jl9TfsR1JVaeJfCzWC8qXWkiaRSu95ffsO+MLuPCrmKRQ/WjAfgwAH9
|
15 |
+
WatxlmyzEKlJyrUeLaJXcJY3fXv8aOowEnXYvZfvJ/JOsrc3LY2azS8KnaMDgEy2
|
16 |
+
Wo3AaQ==
|
17 |
+
-----END CERTIFICATE-----
|
src/component/two-factor/providers/totp.php
CHANGED
@@ -4,6 +4,7 @@ declare( strict_types = 1 );
|
|
4 |
namespace WP_Defender\Component\Two_Factor\Providers;
|
5 |
|
6 |
use Calotes\Helper\HTTP;
|
|
|
7 |
use WP_Defender\Component\Two_Factor\Two_Factor_Provider;
|
8 |
use WP_Defender\Extra\Base2n;
|
9 |
use WP_Defender\Traits\IO;
|
@@ -228,88 +229,6 @@ class Totp extends Two_Factor_Provider {
|
|
228 |
return $this->get_component()->verify_otp( $otp, $user );
|
229 |
}
|
230 |
|
231 |
-
/**
|
232 |
-
* @return bool|array
|
233 |
-
*/
|
234 |
-
public function get_2fa_keys() {
|
235 |
-
$file = $this->get_2fa_lock_path();
|
236 |
-
if( file_exists( $file ) ) {
|
237 |
-
$content = file_get_contents( $file );
|
238 |
-
if ( trim( $content ) ) {
|
239 |
-
return preg_split( '/[\r\n]+/', $content );
|
240 |
-
}
|
241 |
-
}
|
242 |
-
|
243 |
-
return false;
|
244 |
-
}
|
245 |
-
|
246 |
-
/**
|
247 |
-
* @param int $user_id
|
248 |
-
* @param array $data
|
249 |
-
*
|
250 |
-
* @return string
|
251 |
-
*/
|
252 |
-
public function get_2fa_key_by( $user_id, $data ) {
|
253 |
-
if ( is_array( $data ) && ! empty( $data ) ) {
|
254 |
-
foreach ( $data as $key => $line ) {
|
255 |
-
if( 0 === strpos( $line, $user_id . '://:' ) ) {
|
256 |
-
[ $uid, $secret_key ] = explode( '://:', $line );
|
257 |
-
if ( $user_id === (int) $uid ) {
|
258 |
-
return $secret_key;
|
259 |
-
}
|
260 |
-
}
|
261 |
-
}
|
262 |
-
}
|
263 |
-
|
264 |
-
return '';
|
265 |
-
}
|
266 |
-
|
267 |
-
/**
|
268 |
-
* @param string $line
|
269 |
-
*
|
270 |
-
* @return false|int
|
271 |
-
*/
|
272 |
-
public function add_2fa_line( $line ) {
|
273 |
-
$file = $this->get_2fa_lock_path();
|
274 |
-
|
275 |
-
return file_put_contents( $file, $line, FILE_APPEND | LOCK_EX );
|
276 |
-
}
|
277 |
-
|
278 |
-
/**
|
279 |
-
* @param string $line
|
280 |
-
*
|
281 |
-
* @return false|int
|
282 |
-
*/
|
283 |
-
public function remove_2fa_line( $line ) {
|
284 |
-
|
285 |
-
$file = $this->get_2fa_lock_path();
|
286 |
-
$content = file_get_contents( $file );
|
287 |
-
$new_content = str_replace( $line, '', $content );
|
288 |
-
|
289 |
-
return file_put_contents( $file, $new_content, LOCK_EX );
|
290 |
-
}
|
291 |
-
|
292 |
-
/**
|
293 |
-
* @param int $user_id
|
294 |
-
*
|
295 |
-
* @return void
|
296 |
-
*/
|
297 |
-
public function remove_2fa_line_by( $user_id ) {
|
298 |
-
$data = $this->get_2fa_keys();
|
299 |
-
if ( is_array( $data ) && ! empty( $data ) ) {
|
300 |
-
foreach ( $data as $key => $line ) {
|
301 |
-
[ $uid, $secret_key ] = explode( '://:', $line );
|
302 |
-
if ( $user_id === (int) $uid ) {
|
303 |
-
$file = $this->get_2fa_lock_path();
|
304 |
-
$content = file_get_contents( $file );
|
305 |
-
$new_content = str_replace( $line . "\r\n", '', $content );
|
306 |
-
file_put_contents( $file, $new_content, LOCK_EX );
|
307 |
-
break;
|
308 |
-
}
|
309 |
-
}
|
310 |
-
}
|
311 |
-
}
|
312 |
-
|
313 |
/**
|
314 |
* @param WP_User|null $user
|
315 |
*
|
@@ -323,17 +242,16 @@ class Totp extends Two_Factor_Provider {
|
|
323 |
$user_id = get_current_user_id();
|
324 |
}
|
325 |
|
326 |
-
$
|
327 |
-
|
328 |
-
|
329 |
-
if ( ! empty( $secret ) ) {
|
330 |
-
return $secret;
|
331 |
}
|
332 |
// No data then add new one.
|
333 |
-
$
|
334 |
-
$
|
|
|
335 |
|
336 |
-
return $
|
337 |
}
|
338 |
|
339 |
/**
|
4 |
namespace WP_Defender\Component\Two_Factor\Providers;
|
5 |
|
6 |
use Calotes\Helper\HTTP;
|
7 |
+
use WP_Defender\Component\Crypt;
|
8 |
use WP_Defender\Component\Two_Factor\Two_Factor_Provider;
|
9 |
use WP_Defender\Extra\Base2n;
|
10 |
use WP_Defender\Traits\IO;
|
229 |
return $this->get_component()->verify_otp( $otp, $user );
|
230 |
}
|
231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
/**
|
233 |
* @param WP_User|null $user
|
234 |
*
|
242 |
$user_id = get_current_user_id();
|
243 |
}
|
244 |
|
245 |
+
$data = get_user_meta( $user_id, self::TOTP_SECRET_KEY, true );
|
246 |
+
if ( ! empty( $data ) ) {
|
247 |
+
return Crypt::get_decrypted_string( $data );
|
|
|
|
|
248 |
}
|
249 |
// No data then add new one.
|
250 |
+
$plaintext = defender_generate_random_string( self::TOTP_LENGTH, self::TOTP_CHARACTERS );
|
251 |
+
$secret = Crypt::get_encrypted_string( $plaintext );
|
252 |
+
update_user_meta( $user_id, self::TOTP_SECRET_KEY, $secret );
|
253 |
|
254 |
+
return $plaintext;
|
255 |
}
|
256 |
|
257 |
/**
|
src/controller/two-factor.php
CHANGED
@@ -410,8 +410,7 @@ class Two_Factor extends Controller {
|
|
410 |
* @return string
|
411 |
*/
|
412 |
public function get_token( int $user_id ): string {
|
413 |
-
$
|
414 |
-
$token = bin2hex( $crypt->random_bytes( 32 ) );
|
415 |
update_user_meta( $user_id, Two_Fa_Component::TOKEN_USER_KEY, wp_hash( $user_id . $token ) );
|
416 |
|
417 |
return $token;
|
@@ -600,7 +599,7 @@ class Two_Factor extends Controller {
|
|
600 |
$user_id = get_current_user_id();
|
601 |
update_user_meta( $user_id, Totp::TOTP_AUTH_KEY, 0 );
|
602 |
// Remove secret key.
|
603 |
-
(
|
604 |
// Remove TOTP from enabled providers.
|
605 |
$enabled_providers = get_user_meta( $user_id, Two_Fa_Component::ENABLED_PROVIDERS_USER_KEY, true );
|
606 |
if ( isset( $enabled_providers ) && ! empty( $enabled_providers ) ) {
|
@@ -1048,8 +1047,12 @@ class Two_Factor extends Controller {
|
|
1048 |
$wpdb->query( $query );
|
1049 |
// From Webauthn.
|
1050 |
wd_di()->get( Webauthn_Controller::class )->remove_data();
|
1051 |
-
//
|
1052 |
-
|
|
|
|
|
|
|
|
|
1053 |
}
|
1054 |
|
1055 |
/**
|
410 |
* @return string
|
411 |
*/
|
412 |
public function get_token( int $user_id ): string {
|
413 |
+
$token = bin2hex( Crypt::random_bytes( 32 ) );
|
|
|
414 |
update_user_meta( $user_id, Two_Fa_Component::TOKEN_USER_KEY, wp_hash( $user_id . $token ) );
|
415 |
|
416 |
return $token;
|
599 |
$user_id = get_current_user_id();
|
600 |
update_user_meta( $user_id, Totp::TOTP_AUTH_KEY, 0 );
|
601 |
// Remove secret key.
|
602 |
+
delete_user_meta( $user_id, Totp::TOTP_SECRET_KEY );
|
603 |
// Remove TOTP from enabled providers.
|
604 |
$enabled_providers = get_user_meta( $user_id, Two_Fa_Component::ENABLED_PROVIDERS_USER_KEY, true );
|
605 |
if ( isset( $enabled_providers ) && ! empty( $enabled_providers ) ) {
|
1047 |
$wpdb->query( $query );
|
1048 |
// From Webauthn.
|
1049 |
wd_di()->get( Webauthn_Controller::class )->remove_data();
|
1050 |
+
// Check if 2fa file exists.
|
1051 |
+
$file = $this->get_2fa_lock_path();
|
1052 |
+
if ( is_file( $file ) && is_readable( $file ) ) {
|
1053 |
+
// Delete 2fa file. It's actual for prev v3.3.1.
|
1054 |
+
@unlink( $file );
|
1055 |
+
}
|
1056 |
}
|
1057 |
|
1058 |
/**
|
src/functions.php
CHANGED
@@ -520,9 +520,8 @@ function defender_generate_random_string( $length = 16, $strings = 'ABCDEFGHIJKL
|
|
520 |
}
|
521 |
|
522 |
$secret = [];
|
523 |
-
$crypt = new \WP_Defender\Component\Crypt();
|
524 |
for ( $i = 0; $i < $length; $i ++ ) {
|
525 |
-
$secret[] = $strings[
|
526 |
}
|
527 |
|
528 |
return implode( '', $secret );
|
520 |
}
|
521 |
|
522 |
$secret = [];
|
|
|
523 |
for ( $i = 0; $i < $length; $i ++ ) {
|
524 |
+
$secret[] = $strings[ \WP_Defender\Component\Crypt::random_int( 0, strlen( $strings ) - 1 ) ];
|
525 |
}
|
526 |
|
527 |
return implode( '', $secret );
|
src/upgrader.php
CHANGED
@@ -321,6 +321,9 @@ class Upgrader {
|
|
321 |
if ( version_compare( $db_version, '3.3.1', '<' ) ) {
|
322 |
$this->upgrade_3_3_1();
|
323 |
}
|
|
|
|
|
|
|
324 |
|
325 |
defender_no_fresh_install();
|
326 |
// Don't run any function below this line.
|
@@ -1067,9 +1070,8 @@ Your temporary password is {{passcode}}. To finish logging in, copy and paste th
|
|
1067 |
);
|
1068 |
if ( $query->get_total() > 0 ) {
|
1069 |
// Hashed tokens.
|
1070 |
-
$crypt = new Crypt();
|
1071 |
foreach ( $query->get_results() as $user_id ) {
|
1072 |
-
$token = bin2hex(
|
1073 |
update_user_meta( $user_id, Two_Fa_Component::TOKEN_USER_KEY, wp_hash( $user_id . $token ) );
|
1074 |
}
|
1075 |
}
|
@@ -1093,7 +1095,83 @@ Your temporary password is {{passcode}}. To finish logging in, copy and paste th
|
|
1093 |
}
|
1094 |
}
|
1095 |
}
|
1096 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1097 |
$query = new \WP_User_Query(
|
1098 |
[
|
1099 |
'blog_id' => 0,
|
@@ -1102,21 +1180,17 @@ Your temporary password is {{passcode}}. To finish logging in, copy and paste th
|
|
1102 |
]
|
1103 |
);
|
1104 |
if ( $query->get_total() > 0 ) {
|
1105 |
-
$file = $this->get_2fa_lock_path();
|
1106 |
-
if ( ! is_file( $file ) && false === file_put_contents( $file, '' ) ) {
|
1107 |
-
$this->log( 'You don\'t have permission to write data.', 'internal.log' );
|
1108 |
-
return;
|
1109 |
-
}
|
1110 |
-
// Convert data from user meta to file system.
|
1111 |
foreach ( $query->get_results() as $user_id ) {
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
|
|
|
|
1120 |
}
|
1121 |
}
|
1122 |
}
|
321 |
if ( version_compare( $db_version, '3.3.1', '<' ) ) {
|
322 |
$this->upgrade_3_3_1();
|
323 |
}
|
324 |
+
if ( version_compare( $db_version, '3.3.2', '<' ) ) {
|
325 |
+
$this->upgrade_3_3_2();
|
326 |
+
}
|
327 |
|
328 |
defender_no_fresh_install();
|
329 |
// Don't run any function below this line.
|
1070 |
);
|
1071 |
if ( $query->get_total() > 0 ) {
|
1072 |
// Hashed tokens.
|
|
|
1073 |
foreach ( $query->get_results() as $user_id ) {
|
1074 |
+
$token = bin2hex( Crypt::random_bytes( 32 ) );
|
1075 |
update_user_meta( $user_id, Two_Fa_Component::TOKEN_USER_KEY, wp_hash( $user_id . $token ) );
|
1076 |
}
|
1077 |
}
|
1095 |
}
|
1096 |
}
|
1097 |
}
|
1098 |
+
}
|
1099 |
+
|
1100 |
+
/**
|
1101 |
+
* @param string $file
|
1102 |
+
* @param array $arr_user_ids
|
1103 |
+
*
|
1104 |
+
* @return array
|
1105 |
+
*/
|
1106 |
+
private function convert_2fa_lines( $file, &$arr_user_ids ): array {
|
1107 |
+
if ( is_file( $file ) && is_readable( $file ) ) {
|
1108 |
+
$content = file_get_contents( $file );
|
1109 |
+
if ( trim( $content ) ) {
|
1110 |
+
$lines = preg_split( '/[\r\n]+/', $content );
|
1111 |
+
if ( is_array( $lines ) && ! empty( $lines ) ) {
|
1112 |
+
foreach ( $lines as $line ) {
|
1113 |
+
if ( ! empty( trim( $line ) ) ) {
|
1114 |
+
[ $user_id, $skey ] = explode( '://:', $line );
|
1115 |
+
$user_id = (int) $user_id;
|
1116 |
+
// User ID's can be repeated for MU. Repetition must be avoided.
|
1117 |
+
if ( in_array( $user_id, $arr_user_ids, true ) ) {
|
1118 |
+
continue;
|
1119 |
+
}
|
1120 |
+
$plaintext = get_user_meta( $user_id, Totp::TOTP_SECRET_KEY, true );
|
1121 |
+
// Check that the plaintext of the key exists.
|
1122 |
+
if ( ! empty( $plaintext ) ) {
|
1123 |
+
// User_meta has an advantage over lock-file.
|
1124 |
+
$secret = Crypt::get_encrypted_string( $plaintext );
|
1125 |
+
} else {
|
1126 |
+
$secret = Crypt::get_encrypted_string( $skey );
|
1127 |
+
}
|
1128 |
+
// Update value.
|
1129 |
+
update_user_meta( $user_id, Totp::TOTP_SECRET_KEY, $secret );
|
1130 |
+
$arr_user_ids[] = $user_id;
|
1131 |
+
}
|
1132 |
+
}
|
1133 |
+
}
|
1134 |
+
}
|
1135 |
+
// Delete 2fa file.
|
1136 |
+
@unlink( $file );
|
1137 |
+
}
|
1138 |
+
|
1139 |
+
return $arr_user_ids;
|
1140 |
+
}
|
1141 |
+
|
1142 |
+
/**
|
1143 |
+
* @return array
|
1144 |
+
*/
|
1145 |
+
private function encrypt_secret_keys(): array {
|
1146 |
+
$arr_user_ids = [];
|
1147 |
+
// It's for a single site or for the main site on MU.
|
1148 |
+
$file = $this->get_2fa_lock_path();
|
1149 |
+
$arr_user_ids = $this->convert_2fa_lines( $file, $arr_user_ids );
|
1150 |
+
// For other subsites on MU.
|
1151 |
+
if ( is_multisite() ) {
|
1152 |
+
$site_ids = get_sites( [ 'fields' => 'ids', 'site__not_in' => get_main_site_id() ] );
|
1153 |
+
if ( ! empty( $site_ids ) ) {
|
1154 |
+
$upload_dir = wp_upload_dir()['basedir'];
|
1155 |
+
foreach ( $site_ids as $site_id ) {
|
1156 |
+
$file = $upload_dir . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . $site_id
|
1157 |
+
. DIRECTORY_SEPARATOR . 'wp-defender' . DIRECTORY_SEPARATOR . 'two-fa.lock';
|
1158 |
+
$arr_user_ids = $this->convert_2fa_lines( $file, $arr_user_ids );
|
1159 |
+
}
|
1160 |
+
}
|
1161 |
+
}
|
1162 |
+
|
1163 |
+
return $arr_user_ids;
|
1164 |
+
}
|
1165 |
+
|
1166 |
+
/**
|
1167 |
+
* Upgrade to 3.3.2: update auth secret keys.
|
1168 |
+
*
|
1169 |
+
* @return void
|
1170 |
+
*/
|
1171 |
+
private function upgrade_3_3_2() {
|
1172 |
+
// Data from a 2FA file. It's after the previous v3.3.1.
|
1173 |
+
$excluded_ids = $this->encrypt_secret_keys();
|
1174 |
+
// Data from plugin versions where the 2FA file concept was not used, before v3.3.1.
|
1175 |
$query = new \WP_User_Query(
|
1176 |
[
|
1177 |
'blog_id' => 0,
|
1180 |
]
|
1181 |
);
|
1182 |
if ( $query->get_total() > 0 ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
1183 |
foreach ( $query->get_results() as $user_id ) {
|
1184 |
+
// Exclude users whose data we have already updated.
|
1185 |
+
if ( in_array( $user_id, $excluded_ids, true ) ) {
|
1186 |
+
continue;
|
1187 |
+
}
|
1188 |
+
$plaintext = get_user_meta( $user_id, Totp::TOTP_SECRET_KEY, true );
|
1189 |
+
// Check that the plaintext is existed and no encrypted. Encrypted line has '=' symbol.
|
1190 |
+
if ( ! empty( $plaintext ) && false === strpos( $plaintext, '=' ) ) {
|
1191 |
+
$secret = Crypt::get_encrypted_string( $plaintext );
|
1192 |
+
// Update value.
|
1193 |
+
update_user_meta( $user_id, Totp::TOTP_SECRET_KEY, $secret );
|
1194 |
}
|
1195 |
}
|
1196 |
}
|
wp-defender.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
/**
|
3 |
* Plugin Name: Defender
|
4 |
* Plugin URI: https://wpmudev.com/project/wp-defender/
|
5 |
-
* Version: 3.3.
|
6 |
* Description: Get regular security scans, vulnerability reports, safety recommendations and customized hardening for your site in just a few clicks. Defender is the analyst and enforcer who never sleeps.
|
7 |
* Author: WPMU DEV
|
8 |
* Author URI: https://wpmudev.com/
|
@@ -33,10 +33,10 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
33 |
die;
|
34 |
}
|
35 |
if ( ! defined( 'DEFENDER_VERSION' ) ) {
|
36 |
-
define( 'DEFENDER_VERSION', '3.3.
|
37 |
}
|
38 |
if ( ! defined( 'DEFENDER_DB_VERSION' ) ) {
|
39 |
-
define( 'DEFENDER_DB_VERSION', '3.3.
|
40 |
}
|
41 |
if ( ! defined( 'DEFENDER_SUI' ) ) {
|
42 |
define( 'DEFENDER_SUI', '2-12-8' );
|
2 |
/**
|
3 |
* Plugin Name: Defender
|
4 |
* Plugin URI: https://wpmudev.com/project/wp-defender/
|
5 |
+
* Version: 3.3.2
|
6 |
* Description: Get regular security scans, vulnerability reports, safety recommendations and customized hardening for your site in just a few clicks. Defender is the analyst and enforcer who never sleeps.
|
7 |
* Author: WPMU DEV
|
8 |
* Author URI: https://wpmudev.com/
|
33 |
die;
|
34 |
}
|
35 |
if ( ! defined( 'DEFENDER_VERSION' ) ) {
|
36 |
+
define( 'DEFENDER_VERSION', '3.3.2' );
|
37 |
}
|
38 |
if ( ! defined( 'DEFENDER_DB_VERSION' ) ) {
|
39 |
+
define( 'DEFENDER_DB_VERSION', '3.3.2' );
|
40 |
}
|
41 |
if ( ! defined( 'DEFENDER_SUI' ) ) {
|
42 |
define( 'DEFENDER_SUI', '2-12-8' );
|