PluginProbe ʕ •ᴥ•ʔ
CloudSecure WP Security / 1.3.8
CloudSecure WP Security v1.3.8
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 / login-log.php
cloudsecure-wp-security / modules Last commit date
admin 1 year ago lib 1 year ago captcha.php 2 years ago cloudsecure-wp.php 1 year ago common.php 1 year ago config.php 2 years ago disable-access-system-file.php 1 year ago disable-author-query.php 2 years ago disable-login.php 1 year ago disable-restapi.php 2 years ago disable-xmlrpc.php 1 year ago htaccess.php 1 year ago login-log.php 1 year ago login-notification.php 1 year ago rename-login-page.php 1 year ago restrict-admin-page.php 1 year ago server-error-notification.php 1 year ago two-factor-authentication.php 1 year ago unify-messages.php 2 years ago update-notice.php 2 years ago waf-engine.php 1 year ago waf.php 1 year ago
login-log.php
282 lines
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 class CloudSecureWP_Login_Log extends CloudSecureWP_Common {
8 private const KEY_FEATURE = 'login_log';
9 private const KEY_CONDITIONS = self::KEY_FEATURE . '_conditions';
10 private const TABLE_NAME = 'cloudsecurewp_' . self::KEY_FEATURE;
11 private const COLUMN_ID = 'id';
12 private const COLUMN_NAME = 'name';
13 private const COLUMN_IP = 'ip';
14 private const COLUMN_STATUS = 'status';
15 private const COLUMN_METHOD = 'method';
16 private const COLUMN_LOGIN_AT = 'login_at';
17 private const COLUMNS = array(
18 self::COLUMN_ID => 'ID',
19 self::COLUMN_NAME => 'ユーザー名',
20 self::COLUMN_IP => 'IPアドレス',
21 self::COLUMN_STATUS => 'ログイン判定',
22 self::COLUMN_METHOD => 'ログイン種別',
23 self::COLUMN_LOGIN_AT => '日時',
24 );
25
26 private const METHOD_PAGE = 1;
27 private const METHOD_XMLRPC = 2;
28 // private const METHOD_RESTAPI = 3;
29 private const METHODS = array(
30 self::METHOD_PAGE => 'ログインページ',
31 self::METHOD_XMLRPC => 'XML-RPC',
32 // self::METHOD_RESTAPI => 'REST API',
33 );
34 private const MAX_LOG = 10000;
35 private $config;
36 private $disable_login;
37
38 function __construct( array $info, CloudSecureWP_Config $config, CloudSecureWP_Disable_Login $disable_login ) {
39 parent::__construct( $info );
40 $this->config = $config;
41 $this->disable_login = $disable_login;
42 }
43
44 /**
45 * 機能毎のKEY取得
46 *
47 * @return string
48 */
49 public function get_feature_key(): string {
50 return self::KEY_FEATURE;
51 }
52
53 /**
54 * テーブル名取得
55 *
56 * @return string
57 */
58 public function get_table_name(): string {
59 global $wpdb;
60 return $wpdb->prefix . self::TABLE_NAME;
61 }
62
63 /**
64 * LoginLogテーブルカラム�
65 報取得
66 */
67 public function get_cloumns(): array {
68 return self::COLUMNS;
69 }
70
71 /**
72 * ログイン種別取得
73 */
74 public function get_methods(): array {
75 return self::METHODS;
76 }
77
78 /**
79 * Xmlrpc判定
80 *
81 * @return bool
82 */
83 public function is_xmlrpc(): bool {
84 if ( 'xmlrpc.php' === basename( sanitize_text_field( $_SERVER['SCRIPT_NAME'] ) ) ) {
85 return true;
86 }
87 return false;
88 }
89
90 /**
91 * ログインログ登録
92 *
93 * @param string $name
94 * @param string $ip
95 * @param int $status
96 * @param int $method
97 * @return void
98 */
99 public function write_log( string $name, string $ip, int $status, int $method ): void {
100 global $wpdb;
101 $table_name = $wpdb->prefix . self::TABLE_NAME;
102 $max_log = self::MAX_LOG;
103
104 $data = array(
105 'name' => $name,
106 'ip' => $ip,
107 'status' => $status,
108 'method' => $method,
109 'login_at' => current_time( 'mysql' ),
110 );
111
112 $wpdb->query( 'START TRANSACTION' );
113 $wpdb->insert( $table_name, $data );
114 $row = $wpdb->get_row( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}cloudsecurewp_login_log ORDER BY id DESC LIMIT 1 OFFSET %d", $max_log ), ARRAY_A );
115
116 if ( ! empty( $row ?? array() ) ) {
117 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}cloudsecurewp_login_log WHERE id <= %d", $row['id'] ) );
118 }
119
120 $wpdb->query( 'COMMIT' );
121 }
122
123 /**
124 * ログインページログイン成功時
125 */
126 public function wp_login( $user_login ) {
127
128 global $wpdb;
129
130 $wpdb->query( 'START TRANSACTION' );
131 $this->disable_login->remove_expired_login();
132
133 $ip = $this->get_client_ip();
134 $data = array(
135 'ip' => $ip,
136 'status' => $this->disable_login->get_status_success(),
137 'failed_count' => 0,
138 'login_at' => current_time( 'mysql' ),
139 );
140
141 $row = $this->disable_login->get_row_by_ip( $ip );
142 if ( empty( $row ) ) {
143 $wpdb->insert( $this->disable_login->get_table_name(), $data );
144 } else {
145 $wpdb->update( $this->disable_login->get_table_name(), $data, array( 'ip' => $ip ) );
146 }
147 $wpdb->query( 'COMMIT' );
148
149 $ip = $this->get_client_ip();
150 $this->write_log( $user_login, $ip, self::LOGIN_STATUS_SUCCESS, self::METHOD_PAGE );
151 }
152
153 /**
154 * XML-RPCログイン成功時
155 */
156 public function xmlrpc_call() {
157 $user = wp_get_current_user();
158
159 if ( empty( $user->ID ) ) {
160 return;
161 }
162
163 $user_login = $user->user_login;
164 $ip = $this->get_client_ip();
165 $this->write_log( $user_login, $ip, self::LOGIN_STATUS_SUCCESS, self::METHOD_XMLRPC );
166 }
167
168 /**
169 * ログイン失敗時
170 */
171 public function wp_login_failed( $user_login ) {
172 $ip = $this->get_client_ip();
173 $status = $this->disable_login->get_login_status();
174 $method = $this->is_xmlrpc() ? self::METHOD_XMLRPC : self::METHOD_PAGE;
175 $this->write_log( $user_login, $ip, $status, $method );
176 }
177
178 /**
179 * ログインログ取得
180 *
181 * @param array $conditions
182 * @return array
183 */
184 public function get_login_history( array $conditions ): array {
185 global $wpdb;
186 $table_name = $wpdb->prefix . self::TABLE_NAME;
187 $prepare = array();
188
189 $sql = 'SELECT ';
190 $sql .= '* ';
191 $sql .= "FROM {$table_name} ";
192 $sql .= 'WHERE %d ';
193
194 $prepare[] = 1;
195
196 if ( ! empty( $conditions['condition_status'] ?? '' ) ) {
197 $sql .= 'AND status = %d ';
198 $prepare[] = (int) $conditions['condition_status'];
199 }
200
201 if ( ! empty( $conditions['condition_method'] ?? '' ) ) {
202 $sql .= 'AND method = %d ';
203 $prepare[] = (int) $conditions['condition_method'];
204 }
205
206 if ( ! empty( $conditions['condition_ip'] ?? '' ) ) {
207 if ( ! empty( $conditions['condition_ip_other_than'] ?? '' ) && 't' === $conditions['condition_ip_other_than'] ) {
208 $sql .= 'AND ip <> %s ';
209 } else {
210 $sql .= 'AND ip = %s ';
211 }
212 $prepare[] = $conditions['condition_ip'];
213 }
214
215 if ( ! empty( $conditions['condition_name'] ?? '' ) ) {
216 if ( ! empty( $conditions['condition_name_other_than'] ?? '' ) && 't' === $conditions['condition_name_other_than'] ) {
217 $sql .= 'AND `name` <> %s ';
218 } else {
219 $sql .= 'AND `name` = %s ';
220 }
221 $prepare[] = $conditions['condition_name'];
222 }
223
224 array_unshift( $prepare, $sql );
225 $rows = $wpdb->get_results( call_user_func_array( array( $wpdb, 'prepare' ), $prepare ), ARRAY_A );
226
227 return $rows ?? array();
228 }
229
230 /**
231 * 絞込み条件保存
232 *
233 * @param array $conditions
234 * @return void
235 */
236 public function save_conditions( $conditions ): void {
237 $this->config->set( self::KEY_CONDITIONS, $conditions );
238 $this->config->save();
239 }
240
241 /**
242 * 絞込み条件取得
243 *
244 * @return array $conditions
245 */
246 public function get_conditions(): array {
247 $conditions = $this->config->get( self::KEY_CONDITIONS ) ?? '';
248 if ( ! empty( $conditions ) ) {
249 return $conditions;
250 }
251 return array();
252 }
253
254 /**
255 * 有効化
256 *
257 * @return void
258 */
259 public function activate(): void {
260 global $wpdb;
261 $table_name = $this->get_table_name();
262 $table = $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" );
263
264 if ( is_null( $table ) ) {
265 $charset_collate = $wpdb->get_charset_collate();
266
267 $sql = "CREATE TABLE {$table_name} (
268 id BIGINT( 20 ) UNSIGNED NOT NULL AUTO_INCREMENT,
269 name VARCHAR( 60 ) NOT NULL DEFAULT '',
270 ip VARCHAR( 39 ) NOT NULL DEFAULT '',
271 status INT NOT NULL DEFAULT 0,
272 method INT NOT NULL DEFAULT 0,
273 login_at DATETIME,
274 UNIQUE KEY id ( id )
275 ) {$charset_collate}";
276
277 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
278 dbDelta( $sql );
279 }
280 }
281 }
282