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