PluginProbe
WebTotem Security / 3.0.1
WebTotem Security v3.0.1
3.0.1 3.0.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.1 2.2.2 2.2.3 2.2.4 All 109 releases
wt-security / lib / modules / login / Login.php

Login.php in WebTotem Security 3.0.1, at lib/modules/login/Login.php

257 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('WEBTOTEM_INIT') || WEBTOTEM_INIT !== true) {
3 if (!headers_sent()) {
4 header('HTTP/1.1 403 Forbidden');
5 }
6 die("Protected By WebTotem!");
7 }
8
9 require_once 'Captcha.php';
10 require_once 'BFProtection.php';
11 require_once 'GoogleAuthenticator.php';
12
13 /**
14 * WebTotem Login class for Wordpress.
15 */
16 class WebTotemLogin {
17
18 const RECOVERY_CODE_SIZE = 8;
19 const RECOVERY_CODE_COUNT = 5;
20
21 /**
22 * Generates a new set of recovery codes and saves them to $user if provided.
23 *
24 * @param int $count
25 * @return array
26 */
27 public static function generate_recovery_codes($count = self::RECOVERY_CODE_COUNT) {
28 $codes = array();
29 for ($i = 0; $i < $count; $i++) {
30 $codes[] = self::random_bytes(self::RECOVERY_CODE_SIZE);
31 }
32
33 return $codes;
34 }
35
36 /**
37 * Save user's 2fa data.
38 *
39 * @param int $user_id
40 * User ID.
41 *
42 * @return bool
43 * Returns TRUE after save settings.
44 */
45 public static function saveData( int $user_id, $codes, $secret ) {
46
47 $data = json_decode(WebTotemOption::getOption('two_factor_data'), true) ?: [];
48 $data[$user_id]['recovery'] = $codes;
49 $data[$user_id]['secret'] = $secret;
50 WebTotemOption::setOptions(['two_factor_data' => json_encode($data)]);
51
52 return TRUE;
53 }
54
55 /**
56 * Delete user's 2fa data.
57 *
58 * @param int $user_id
59 * User ID.
60 *
61 * @return bool
62 * Returns TRUE after save settings.
63 */
64 public static function delete( int $user_id ) {
65 $data = json_decode(WebTotemOption::getOption('two_factor_data'), true) ?: [];
66
67 if(isset($data[$user_id])) {
68 unset($data[$user_id]);
69 }
70 WebTotemOption::setOptions(['two_factor_data' => json_encode($data)]);
71
72 return TRUE;
73 }
74
75 /**
76 * Get user's 2fa data.
77 *
78 * @param int $user_id
79 * User ID.
80 *
81 * @return mixed
82 * Returns saved data by option name.
83 */
84 public static function getData($user_id) {
85
86 $data = json_decode(WebTotemOption::getOption('two_factor_data'), true) ?: [];
87
88 if(array_key_exists($user_id, $data)){
89 return $data[$user_id];
90 }
91
92 return false;
93 }
94
95 /**
96 * has user 2FA activated.
97 *
98 * @param WP_User $user
99 * User.
100 *
101 * @return bool
102 */
103 public static function hasUser2faActivated($user){
104 if(self::getData($user->ID)){
105 return true;
106 } else {
107 return false;
108 }
109 }
110
111
112 /**
113 * Check 2FA code by user.
114 *
115 * @param WP_User $user
116 * User.
117 *
118 * @return bool
119 */
120 public static function check2faCode($user, $code){
121 $data = self::getData($user->ID);
122 $g = new WebTotemGoogleAuthenticator();
123 $code = trim($code);
124
125 if(strlen($code) === 6 and $g->checkCode($data['secret'], $code)) {
126 return true;
127 } else if (strlen($code) >= 16) {
128 $code = str_replace(' ', '', $code);
129 $recovery = explode(',', $data['recovery']);
130 $is_verify = false;
131 foreach ($recovery as $key => $recoveryCode){
132 if($recoveryCode === $code){
133 $is_verify = true;
134 break;
135 }
136 }
137 if($is_verify){
138 // Delete this code from the database.
139 unset($recovery[$key]);
140 $recovery = implode(',', $recovery);
141 self::saveData($user->ID, $recovery, $data['secret']);
142
143 return true;
144 }
145 }
146
147 return false;
148 }
149
150 /**
151 * Get recovery data.
152 *
153 * @param WP_User $user
154 * User.
155 *
156 * @return array
157 * Returns saved data by option name.
158 */
159 public static function getRecoveryData( $user ){
160 $recovery = self::generate_recovery_codes();
161
162 $fileContents = sprintf(__('Two-Factor Authentication Recovery Codes. %s (%s)', 'wtotem'), home_url(), $user->user_login) . "\r\n";
163 $fileContents .= "\r\n" . __('Each line is a single recovery code, with optional spaces for readability. Your recovery codes are:', 'wtotem') . "\r\n\r\n";
164 $recoveryBlocks = [];
165 foreach ($recovery as $c) {
166 $hex = bin2hex( $c );
167 $blocks = str_split( $hex, 4 );
168 $blocks = implode( ' ', $blocks );
169 $fileContents .= $blocks . "\r\n";
170 $recoveryBlocks[] = $blocks;
171 }
172
173 $fileContents = str_replace("\n", "\\n", str_replace("\r", "\\r", addslashes($fileContents)));
174
175 return [
176 'fileName' => WEBTOTEM_SITE_DOMAIN . '_' . $user->user_login . '_recovery_codes.txt',
177 'fileContents' => $fileContents,
178 'recovery' => implode(',', array_map(function($c) { return bin2hex($c); }, $recovery)),
179 'blocks' => $recoveryBlocks,
180 ];
181
182 }
183
184 /**
185 * @throws Exception
186 */
187 public static function random_bytes($length) {
188 $length = (int) $length;
189 if (function_exists('random_bytes')) {
190 $rand = random_bytes($length);
191 if (is_string($rand)) {
192 return $rand;
193 }
194 }
195
196 $return = '';
197 for ($i = 0; $i < $length; $i++) {
198 $return .= chr(mt_rand(0, 255));
199 }
200 return $return;
201 }
202
203 /**
204 * Check to any two-factor activated.
205 *
206 * @return bool returns true if at least one activation.
207 */
208 public static function anyTwoFactorActivated($user = null) {
209 $data = json_decode(WebTotemOption::getOption('two_factor_data'), true) ?: [];
210 if($data){
211 return true;
212 }
213 return false;
214 }
215
216 /**
217 * Get two factor authenticator data.
218 *
219 * @return array
220 * Returns google authenticator data.
221 */
222 public static function getTwoFactorData($user = null) {
223
224 if(!$user) { $user = wp_get_current_user(); };
225
226 if($data = self::getData($user->ID)) {
227
228 return [
229 'isActivated' => true,
230 'recovery' => explode(',', $data['recovery']),
231 ];
232 }
233
234 $data = self::getRecoveryData($user);
235 $g = new WebTotemGoogleAuthenticator();
236
237 $host = WebTotemOption::getMainHost();
238 $data['secret'] = $g->generateSecret();
239 $data['qr_url'] = $g->getURL( $user->user_login, $host['name'], $data['secret'] );
240
241 $data['isActivated'] = false;
242
243 return $data;
244
245 }
246
247
248 /**
249 * Checks whether two-factor authorization is activated on the site.
250 *
251 * @return bool.
252 */
253 public static function isTwoFactorEnabled($user = null) {
254 return WebTotemOption::getPluginSettings('two_factor');
255 }
256
257 }