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