PluginProbe ʕ •ᴥ•ʔ
CloudSecure WP Security / 1.2.3
CloudSecure WP Security v1.2.3
1.4.10 1.4.9 trunk 0.9.0 1.0.2 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.19 1.3.2 1.3.20 1.3.21 1.3.22 1.3.23 1.3.24 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8
cloudsecure-wp-security / modules / two-factor-authentication.php
cloudsecure-wp-security / modules Last commit date
admin 2 years ago lib 2 years ago captcha.php 2 years ago cloudsecure-wp.php 2 years ago common.php 2 years ago config.php 2 years ago disable-author-query.php 2 years ago disable-login.php 2 years ago disable-restapi.php 2 years ago disable-xmlrpc.php 2 years ago htaccess.php 2 years ago login-log.php 2 years ago login-notification.php 2 years ago rename-login-page.php 2 years ago restrict-admin-page.php 2 years ago server-error-notification.php 2 years ago two-factor-authentication.php 2 years ago unify-messages.php 2 years ago update-notice.php 2 years ago
two-factor-authentication.php
249 lines
1 <?php
2
3 class CloudSecureWP_Two_Factor_Authentication extends CloudSecureWP_Common {
4 private const KEY_FEATURE = 'two_factor_authentication';
5
6 private $config;
7
8 /**
9 * @var CloudSecureWP_Disable_Login
10 */
11 private $disable_login;
12
13 function __construct( array $info, CloudSecureWP_Config $config, CloudSecureWP_Disable_Login $disable_login ) {
14 parent::__construct( $info );
15 $this->config = $config;
16 $this->disable_login = $disable_login;
17 }
18
19 /**
20 * 機能毎のKEY取得
21 *
22 * @return string
23 */
24 public function get_feature_key(): string {
25 return self::KEY_FEATURE;
26 }
27
28 /**
29 * 有効無効判定
30 *
31 * @return bool
32 */
33 public function is_enabled(): bool {
34 return $this->config->get( $this->get_feature_key() ) === 't';
35 }
36
37 /**
38 * 初期設定値取得
39 *
40 * @return array
41 */
42 public function get_default(): array {
43 return array( self::KEY_FEATURE => 'f' );
44 }
45
46 /**
47 * 設定値key取得
48 */
49 public function get_keys(): array {
50 return array( self::KEY_FEATURE );
51 }
52
53 /**
54 * 設定値取得
55 */
56 public function get_settings(): array {
57 $settings = array();
58 $keys = $this->get_keys();
59
60 foreach ( $keys as $key ) {
61 $settings[ $key ] = $this->config->get( $key );
62 }
63
64 return $settings;
65 }
66
67 /**
68 * 設定値保存
69 *
70 * @param array $settings
71 *
72 * @return void
73 */
74 public function save_settings( array $settings ): void {
75 $keys = $this->get_keys();
76
77 foreach ( $keys as $key ) {
78 $this->config->set( $key, $settings[ $key ] ?? '' );
79 }
80 $this->config->save();
81 }
82
83 /**
84 * 有効化
85 *
86 * @return void
87 */
88 public function activate(): void {
89 $settings = $this->get_default();
90 $this->save_settings( $settings );
91 }
92
93 /**
94 * 無効化
95 *
96 * @return void
97 */
98 public function deactivate(): void {
99 $settings = $this->get_settings();
100 $settings[ self::KEY_FEATURE ] = 'f';
101 $this->save_settings( $settings );
102 }
103
104 /**
105 * 管理画面上での有効無効判定
106 * 2段階認証の管理画面で「変更を保存」ボタンを押下時、
107 * is_enabled()のみを使うとデバイス登録のメニューが正しく表示されない。
108 *
109 * @return bool
110 */
111 public function is_enabled_on_screen(): bool {
112 if ( isset( $_POST['two_factor_authentication'] ) && ! empty( $_POST['two_factor_authentication'] ) ) {
113 return $this->check_environment() && sanitize_text_field( $_POST['two_factor_authentication'] ) === 't';
114 }
115
116 return $this->is_enabled();
117 }
118
119 /**
120 * 有効な権限グループに含まれるかどうか
121 *
122 * @param $role
123 *
124 * @return bool
125 */
126 private function is_role_enabled( $role ): bool {
127 return in_array( $role, get_option( 'cloudsecurewp_two_factor_authentication_roles', array() ) );
128 }
129
130 /**
131 * ログインフォーム2段階認証チェック
132 */
133 public function wp_login( $user_login, $user ) {
134 // 2段階認証が無効なとき
135 if ( ! $this->is_enabled() ) {
136 return;
137 }
138
139 // 有効な権限グループに含まれないとき
140 if ( ! $this->is_role_enabled( $user->roles[0] ) ) {
141 return;
142 }
143
144 $secret = get_user_option( 'cloudsecurewp_two_factor_authentication_secret', $user->ID );
145 // ユーザーがデバイス登録をしていないとき
146 if ( ! $secret ) {
147 return;
148 }
149
150 // 2段階認証コードが送られたとき
151 if ( ! empty( $_POST['google_authenticator_code'] ) && check_admin_referer( $this->get_feature_key() . '_csrf' ) ) {
152 $google_authenticator_code = sanitize_text_field( $_POST['google_authenticator_code'] );
153 // 2段階認証コードが有効なとき
154 if ( CloudSecureWP_Time_Based_One_Time_Password::verify_code( $secret, $google_authenticator_code, 2 ) ) {
155 return;
156 }
157 // ログイン失敗回数をインクリメントしデータベースに格納
158 $this->disable_login->wp_login_failed( $user_login );
159 }
160
161 wp_logout();
162 login_header( '2段階認証画面' );
163 $this->login_error();
164 $this->login_form();
165 login_footer();
166 exit;
167 }
168
169 /**
170 * 2段階認証のエラーを出力
171 *
172 * @return void
173 */
174 private function login_error() {
175 if ( array_key_exists( 'google_authenticator_code', $_REQUEST ) ) {
176 if ( sanitize_text_field( $_REQUEST['google_authenticator_code'] ) ) {
177 $errors = '認証コードが間違っているか、有効期限が切れています。';
178 } else {
179 $errors = '認証コードが�
180 �力されていません。';
181 }
182 echo '<div id="login_error">' . esc_html( apply_filters( 'login_errors', $errors ) ) . "</div>\n";
183 }
184 }
185
186 /**
187 * 2段階認証のログインフォームを出力
188 *
189 * @return void
190 */
191 private function login_form() {
192 ?>
193 <form name="loginform" id="loginform"
194 action="<?php echo esc_url( site_url( 'wp-login.php', 'login_post' ) ); ?>" method="post">
195 <input type="hidden" name="log" value="<?php echo esc_attr( sanitize_text_field( $_REQUEST['log'] ) ); ?>"/>
196 <input type="hidden" name="pwd" value="<?php echo esc_attr( sanitize_text_field( $_REQUEST['pwd'] ) ); ?>"/>
197 <?php if ( array_key_exists( 'cloudsecurewp_captcha', $_REQUEST ) ) : ?>
198 <input type="hidden" name="cloudsecurewp_captcha"
199 value="<?php echo esc_attr( sanitize_text_field( $_REQUEST['cloudsecurewp_captcha'] ) ); ?>"/>
200 <?php endif; ?>
201 <?php if ( array_key_exists( 'cloudsecurewp_captcha_prefix', $_REQUEST ) ) : ?>
202 <input type="hidden" name="cloudsecurewp_captcha_prefix"
203 value="<?php echo esc_attr( sanitize_text_field( $_REQUEST['cloudsecurewp_captcha_prefix'] ) ); ?>"/>
204 <?php endif; ?>
205 <?php if ( array_key_exists( 'cloudsecurewp_captcha_wpnonce', $_REQUEST ) ) : ?>
206 <input type="hidden" name="cloudsecurewp_captcha_wpnonce"
207 value="<?php echo esc_attr( sanitize_text_field( $_REQUEST['cloudsecurewp_captcha_wpnonce'] ) ); ?>"/>
208 <?php endif; ?>
209 <?php if ( array_key_exists( 'rememberme', $_REQUEST ) && 'forever' === sanitize_text_field( $_REQUEST['rememberme'] ) ) : ?>
210 <input name="rememberme" type="hidden" id="rememberme" value="forever"/>
211 <?php endif; ?>
212 <p>
213 <label for="google_authenticator_code">認証コード</label>
214 <input type="text" name="google_authenticator_code" id="google_authenticator_code" class="input"
215 value="" size="20"/>
216 </p>
217 <script type="text/javascript">document.getElementById("google_authenticator_code").focus();</script>
218 <p>デバイスのGoogle Authenticator アプリケーションに表示されている6桁の認証コードを�
219 �力してください。</p>
220 <p class="submit">
221 <?php wp_nonce_field( $this->get_feature_key() . '_csrf' ); ?>
222 <input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large"
223 value="<?php esc_attr_e( 'Log In' ); ?>"/>
224 <input type="hidden" name="redirect_to"
225 value="<?php echo esc_attr( sanitize_text_field( $_REQUEST['redirect_to'] ?? admin_url() ) ); ?>"/>
226 <input type="hidden" name="testcookie" value="1"/>
227 </p>
228 </form>
229 <?php
230 }
231
232 /**
233 * デバイス登録がまだのユーザーは、デバイス登録画面にリダイレクト
234 *
235 * @param $user_login
236 * @param $user
237 *
238 * @return void
239 * @noinspection PhpUnusedParameterInspection
240 */
241 public function redirect_if_not_two_factor_authentication_registered( $user_login, $user ) {
242 $secret = get_user_option( 'cloudsecurewp_two_factor_authentication_secret', $user->ID );
243 if ( $this->is_enabled() && $this->is_role_enabled( $user->roles[0] ) && ! $secret && $_SERVER['REQUEST_URI'] !== '/wp-admin/admin.php?page=two_factor_authentication_registration') {
244 wp_redirect( admin_url( 'admin.php?page=two_factor_authentication_registration' ) );
245 exit;
246 }
247 }
248 }
249