PluginProbe ʕ •ᴥ•ʔ
SiteGuard WP Plugin / trunk
SiteGuard WP Plugin vtrunk
1.8.6 1.8.6-beta1 1.8.6-beta2 1.8.4 1.8.5 1.8.3 1.8.2 1.8.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3 1.4.3 1.5.0 1.5.1 1.5.2 1.6.0 1.6.1 1.7.0 1.7.1 1.7.10 1.7.11 1.7.12 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.0-beta1 1.8.0-beta2 1.8.0-beta3 1.8.0-beta4
siteguard / siteguard.php
siteguard Last commit date
admin 2 days ago classes 2 days ago css 2 weeks ago images 2 weeks ago languages 2 days ago really-simple-captcha 1 month ago changelog.txt 2 weeks ago license.txt 11 years ago readme.txt 2 days ago siteguard.php 2 days ago uninstall.php 1 week ago
siteguard.php
362 lines
1 <?php
2 /*
3 Plugin Name: SiteGuard WP Plugin
4 Plugin URI: https://www.jp-secure.com/siteguard_wp_plugin_en/
5 Description: Adds WordPress login and admin protections, including CAPTCHA, login lock, login alerts, renamed login URLs, and SiteGuard WAF tuning support.
6 Author: JP-Secure
7 Author URI: https://www.eg-secure.co.jp/
8 Text Domain: siteguard
9 Domain Path: /languages/
10 Version: 1.8.6
11 */
12
13 /*
14 Copyright 2014 EG Secure Solutions Inc (JP-Secure Inc)
15
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License, version 2, as
18 published by the Free Software Foundation.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30 if ( ! defined( 'ABSPATH' ) ) {
31 exit;
32 }
33
34 $data = get_file_data( __FILE__, array( 'version' => 'Version' ) );
35 define( 'SITEGUARD_VERSION', $data['version'] );
36
37 define( 'SITEGUARD_PATH', plugin_dir_path( __FILE__ ) );
38 define( 'SITEGUARD_URL_PATH', plugin_dir_url( __FILE__ ) );
39
40 define( 'SITEGUARD_RENAME_MODE_HTACCESS', '0');
41 define( 'SITEGUARD_RENAME_MODE_STUB', '1');
42
43 define( 'SITEGUARD_LOGIN_NOSELECT', 4 );
44 define( 'SITEGUARD_LOGIN_SUCCESS', 0 );
45 define( 'SITEGUARD_LOGIN_FAILED', 1 );
46 define( 'SITEGUARD_LOGIN_FAIL_ONCE', 2 );
47 define( 'SITEGUARD_LOGIN_LOCKED', 3 );
48
49 define( 'SITEGUARD_LOGIN_TYPE_NOSELECT', 2 );
50 define( 'SITEGUARD_LOGIN_TYPE_NORMAL', 0 );
51 define( 'SITEGUARD_LOGIN_TYPE_XMLRPC', 1 );
52
53 require_once 'classes/siteguard-base.php';
54 require_once 'classes/siteguard-config.php';
55 require_once 'classes/siteguard-htaccess.php';
56 require_once 'classes/siteguard-admin-filter.php';
57 require_once 'classes/siteguard-rename-login.php';
58 require_once 'classes/siteguard-login-history.php';
59 require_once 'classes/siteguard-login-lock.php';
60 require_once 'classes/siteguard-login-alert.php';
61 require_once 'classes/siteguard-captcha.php';
62 require_once 'classes/siteguard-disable-xmlrpc.php';
63 require_once 'classes/siteguard-disable-pingback.php';
64 require_once 'classes/siteguard-disable-author-query.php';
65 require_once 'classes/siteguard-waf-exclude-rule.php';
66 require_once 'classes/siteguard-updates-notify.php';
67 require_once 'admin/siteguard-menu-init.php';
68
69 global $siteguard_htaccess;
70 global $siteguard_config;
71 global $siteguard_admin_filter;
72 global $siteguard_rename_login;
73 global $siteguard_loginlock;
74 global $siteguard_loginalert;
75 global $siteguard_captcha;
76 global $siteguard_login_history;
77 global $siteguard_xmlrpc;
78 global $siteguard_pingback;
79 global $siteguard_author_query;
80 global $siteguard_waf_exclude_rule;
81 global $siteguard_updates_notify;
82
83 $siteguard_htaccess = new SiteGuard_Htaccess();
84 $siteguard_config = new SiteGuard_Config();
85 $siteguard_admin_filter = new SiteGuard_AdminFilter();
86 $siteguard_rename_login = new SiteGuard_RenameLogin();
87 $siteguard_loginlock = new SiteGuard_LoginLock();
88 $siteguard_loginalert = new SiteGuard_LoginAlert();
89 $siteguard_login_history = new SiteGuard_LoginHistory();
90 $siteguard_captcha = new SiteGuard_CAPTCHA();
91 $siteguard_xmlrpc = new SiteGuard_Disable_XMLRPC();
92 $siteguard_pingback = new SiteGuard_Disable_Pingback();
93 $siteguard_author_query = new SiteGuard_Disable_Author_Query();
94 $siteguard_waf_exclude_rule = new SiteGuard_WAF_Exclude_Rule();
95 $siteguard_updates_notify = new SiteGuard_UpdatesNotify();
96
97 function siteguard_activate() {
98 global $siteguard_config, $siteguard_admin_filter, $siteguard_rename_login, $siteguard_login_history, $siteguard_captcha, $siteguard_loginlock, $siteguard_loginalert, $siteguard_xmlrpc, $siteguard_pingback, $siteguard_author_query, $siteguard_waf_exclude_rule, $siteguard_updates_notify;
99
100 load_plugin_textdomain(
101 'siteguard',
102 false,
103 dirname( plugin_basename( __FILE__ ) ) . '/languages'
104 );
105
106 $siteguard_config->set( 'show_admin_notices', '0' );
107 $siteguard_config->update();
108 $siteguard_admin_filter->init();
109 $siteguard_rename_login->init();
110 $siteguard_login_history->init();
111 $siteguard_captcha->init();
112 $siteguard_loginlock->init();
113 $siteguard_loginalert->init();
114 $siteguard_xmlrpc->init();
115 $siteguard_pingback->init();
116 $siteguard_author_query->init();
117 $siteguard_waf_exclude_rule->init();
118 $siteguard_updates_notify->init();
119 }
120 register_activation_hook( __FILE__, 'siteguard_activate' );
121
122 function siteguard_deactivate() {
123 global $siteguard_config;
124 $siteguard_config->set( 'show_admin_notices', '0' );
125 $siteguard_config->update();
126 SiteGuard_RenameLogin::feature_off();
127 SiteGuard_AdminFilter::feature_off();
128 SiteGuard_Disable_XMLRPC::feature_off();
129 SiteGuard_WAF_Exclude_Rule::feature_off();
130 SiteGuard_UpdatesNotify::feature_off();
131 }
132 register_deactivation_hook( __FILE__, 'siteguard_deactivate' );
133
134
135 class SiteGuard extends SiteGuard_Base {
136 protected $menu_init;
137 function __construct() {
138 global $siteguard_config;
139 add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
140 $this->htaccess_check();
141 // upgrade() must run on every request, not only admin_init, so that
142 // upgrades from 1.7.x can clean up legacy .htaccess blocks even when
143 // /wp-admin/ would otherwise be locked out by those very rules.
144 add_action( 'init', array( $this, 'upgrade' ), 0 );
145 if ( is_admin() ) {
146 include 'admin/siteguard-menu-login-history.php';
147 $this->menu_init = new SiteGuard_Menu_Init();
148 add_action( 'init', array( $this, 'set_cookie' ) );
149 if ( '0' === $siteguard_config->get( 'show_admin_notices' ) && '1' === $siteguard_config->get( 'renamelogin_enable' ) ) {
150 add_action( 'admin_notices', array( $this, 'admin_notices' ) );
151 $siteguard_config->set( 'show_admin_notices', '1' );
152 $siteguard_config->update();
153 }
154 }
155 }
156 function set_cookie() {
157 SiteGuard_Menu_Login_History::set_cookie();
158 }
159 function plugins_loaded() {
160 load_plugin_textdomain(
161 'siteguard',
162 false,
163 dirname( plugin_basename( __FILE__ ) ) . '/languages'
164 );
165 }
166 function htaccess_check() {
167 global $siteguard_config;
168
169 // Only check whether the SiteGuard marker block still exists in .htaccess.
170 // The actual ".htaccess effectiveness" probe (test_htaccess) is performed
171 // only when the user toggles a feature on, to avoid loopback HTTP
172 // requests on every WordPress request.
173 if ( '1' === $siteguard_config->get( 'waf_exclude_rule_enable' ) ) {
174 if ( ! SiteGuard_Htaccess::is_exists_setting( SiteGuard_WAF_Exclude_Rule::get_mark() ) ) {
175 $siteguard_config->set( 'waf_exclude_rule_enable', '0' );
176 $siteguard_config->update();
177 }
178 }
179 if ( '1' === $siteguard_config->get( 'renamelogin_enable' ) ) {
180 if ( SITEGUARD_RENAME_MODE_HTACCESS === $siteguard_config->get( 'renamelogin_stub' ) ) {
181 if ( ! SiteGuard_Htaccess::is_exists_setting( SiteGuard_RenameLogin::get_mark() ) ) {
182 $siteguard_config->set( 'renamelogin_enable', '0' );
183 $siteguard_config->update();
184 }
185 }
186 }
187 }
188 function admin_notices() {
189 global $siteguard_rename_login;
190 echo '<div class="updated" style="background-color:#719f1d;"><p><span style="border: 4px solid #def1b8;padding: 4px 4px;color:#fff;font-weight:bold;background-color:#038bc3;">';
191 echo esc_html__( 'The login page URL has been changed.', 'siteguard' ) . '</span>';
192 printf(
193 '<span style="color:#eee;">'
194 . esc_html__( 'Please bookmark the %1$s. You can change this setting %2$s.', 'siteguard' )
195 . '</span></p></div>',
196 '<a style="color:#fff;text-decoration:underline;" href="' . esc_url( wp_login_url() ) . '">' . esc_html__( 'new login URL', 'siteguard' ) . '</a>',
197 '<a style="color:#fff;text-decoration:underline;" href="' . esc_url( menu_page_url( 'siteguard_rename_login', false ) ) . '">' . esc_html__( 'here', 'siteguard' ) . '</a>'
198 );
199 $siteguard_rename_login->send_notify();
200 }
201 function upgrade() {
202 global $siteguard_config, $siteguard_rename_login, $siteguard_admin_filter, $siteguard_loginalert, $siteguard_updates_notify, $siteguard_login_history, $siteguard_xmlrpc, $siteguard_author_query, $siteguard_waf_exclude_rule;
203 $upgrade_ok = true;
204 $old_version = $siteguard_config->get( 'version' );
205 if ( '' === $old_version ) {
206 $old_version = '0.0.0';
207 }
208 if ( $old_version === SITEGUARD_VERSION ) {
209 return;
210 }
211 if ( version_compare( $old_version, '1.0.6' ) < 0 ) {
212 if ( '1' === $siteguard_config->get( 'admin_filter_enable' ) ) {
213 if ( true !== $siteguard_admin_filter->feature_on( $this->get_ip() ) ) {
214 siteguard_error_log( 'Failed to update at admin_filter from ' . $old_version . ' to ' . SITEGUARD_VERSION . '.' );
215 $upgrade_ok = false;
216 }
217 }
218 }
219 if ( version_compare( $old_version, '1.1.1' ) < 0 ) {
220 $siteguard_loginalert->init();
221 }
222 if ( version_compare( $old_version, '1.2.0' ) < 0 ) {
223 $siteguard_updates_notify->init();
224 }
225 if ( version_compare( $old_version, '1.2.5' ) < 0 ) {
226 if ( '1' === $siteguard_config->get( 'admin_filter_enable' ) ) {
227 $siteguard_admin_filter->cvt_status_for_1_2_5( $this->get_ip() );
228 }
229 if ( '1' === $siteguard_config->get( 'renamelogin_enable' ) ) {
230 if ( true !== $siteguard_rename_login->feature_on() ) {
231 siteguard_error_log( 'Failed to update at rename_login from ' . $old_version . ' to ' . SITEGUARD_VERSION . '.' );
232 $upgrade_ok = false;
233 }
234 }
235 }
236 if ( version_compare( $old_version, '1.3.0' ) < 0 ) {
237 $siteguard_login_history->init();
238 $siteguard_xmlrpc->init();
239 }
240 if ( version_compare( $old_version, '1.5.0' ) < 0 ) {
241 $admin_filter_exclude_path = $siteguard_config->get( 'admin_filter_exclude_path' );
242 if ( false === strpos( $admin_filter_exclude_path, 'site-health.php' ) ) {
243 $admin_filter_exclude_path .= ', site-health.php';
244 $siteguard_config->set( 'admin_filter_exclude_path', $admin_filter_exclude_path );
245 $siteguard_config->update();
246 }
247 }
248 if ( version_compare( $old_version, '1.5.1' ) < 0 ) {
249 if ( '1' === $siteguard_config->get( 'admin_filter_enable' ) ) {
250 if ( true !== $siteguard_admin_filter->feature_on( $this->get_ip() ) ) {
251 siteguard_error_log( 'Failed to update at admin_filter from ' . $old_version . ' to ' . SITEGUARD_VERSION . '.' );
252 $upgrade_ok = false;
253 }
254 }
255 if ( '1' === $siteguard_config->get( 'disable_xmlrpc_enable' ) ) {
256 if ( true !== $siteguard_xmlrpc->feature_on() ) {
257 siteguard_error_log( 'Failed to update at disable_xmlrpc from ' . $old_version . ' to ' . SITEGUARD_VERSION . '.' );
258 $upgrade_ok = false;
259 }
260 }
261 }
262 if ( version_compare( $old_version, '1.6.0' ) < 0 ) {
263 $siteguard_author_query->init();
264 }
265 if ( version_compare( $old_version, '1.7.0' ) < 0 ) {
266 if ( '1' === $siteguard_config->get( 'admin_filter_enable' ) ) {
267 if ( true !== $siteguard_admin_filter->feature_on( $this->get_ip() ) ) {
268 siteguard_error_log( 'Failed to update at admin_filter from ' . $old_version . ' to ' . SITEGUARD_VERSION . '.' );
269 $upgrade_ok = false;
270 }
271 }
272 }
273 if ( version_compare( $old_version, '1.8.0' ) < 0 ) {
274 // Legacy Nginx-exposure cleanup and the rescue_enable default. These
275 // are unrelated to the /wp-admin/ lockout and ran when the install
276 // first reached 1.8.0, so they stay gated on < 1.8.0. The Admin
277 // Filter / XML-RPC .htaccess blocks (which cause the lockout) are
278 // cleared in the < 1.8.3 block below.
279 if ( '' === $siteguard_config->get( 'rescue_enable' ) ) {
280 $siteguard_config->set( 'rescue_enable', '1' );
281 $siteguard_config->update();
282 }
283 // Remove legacy error.log left by previous versions; logging now
284 // uses PHP error_log() so the file would only sit web-exposed on Nginx.
285 $legacy_log = SITEGUARD_PATH . 'error.log';
286 if ( file_exists( $legacy_log ) ) {
287 @unlink( $legacy_log );
288 }
289 // Remove legacy plugin-directory tmp/ used for .htaccess rebuilds.
290 // `clear_settings()` / `update_settings()` now short-circuit on
291 // Nginx (no .htaccess in use), so this directory will not be
292 // recreated there. On Apache it will be regenerated as needed
293 // by make_tmp_dir(). Existing orphan tempnam files would be
294 // web-exposed on Nginx without the .htaccess inside the dir.
295 $legacy_tmp = SITEGUARD_PATH . 'tmp';
296 if ( is_dir( $legacy_tmp ) ) {
297 $entries = @scandir( $legacy_tmp );
298 if ( is_array( $entries ) ) {
299 foreach ( $entries as $entry ) {
300 if ( '.' === $entry || '..' === $entry ) {
301 continue;
302 }
303 $path = $legacy_tmp . DIRECTORY_SEPARATOR . $entry;
304 if ( is_file( $path ) ) {
305 if ( ! @unlink( $path ) ) {
306 @chmod( $path, 0644 );
307 @unlink( $path );
308 }
309 }
310 }
311 }
312 @rmdir( $legacy_tmp );
313 }
314 // Remove legacy CAPTCHA answer files (*.txt). Pre-1.8.0 stored
315 // them at WP_CONTENT_DIR/siteguard/ with an .htaccess block on
316 // .txt; on Nginx that block does not apply and the salt+hash
317 // would be readable. New answer files use .php with a stub
318 // prefix and live in the same directory.
319 $captcha_dir = path_join( WP_CONTENT_DIR, 'siteguard' );
320 if ( is_dir( $captcha_dir ) ) {
321 $entries = @scandir( $captcha_dir );
322 if ( is_array( $entries ) ) {
323 foreach ( $entries as $entry ) {
324 if ( preg_match( '/\.txt$/', $entry ) ) {
325 $path = $captcha_dir . DIRECTORY_SEPARATOR . $entry;
326 if ( is_file( $path ) ) {
327 if ( ! @unlink( $path ) ) {
328 @chmod( $path, 0644 );
329 @unlink( $path );
330 }
331 }
332 }
333 }
334 }
335 }
336 }
337 if ( version_compare( $old_version, '1.8.3' ) < 0 ) {
338 // Admin Page IP Filter and XML-RPC protection moved from .htaccess
339 // to PHP in 1.8.x, leaving their 1.7.x .htaccess blocks orphaned.
340 // The Admin Filter block ("RewriteRule ^wp-admin 404-siteguard")
341 // blocks /wp-admin/ at the Apache layer and can lock administrators
342 // out. clear_settings() is idempotent (a no-op when the mark is
343 // absent), so gate this on the fix release (< 1.8.3) rather than
344 // < 1.8.0: that also recovers the rare install whose stored version
345 // already advanced past 1.8.0 while the block survived (e.g. the
346 // .htaccess was briefly unwritable during the 1.8.0 upgrade).
347 //
348 // Rename Login and WAF Tuning Support still use .htaccess in 1.8.x
349 // with the same mark and block format as 1.7.x, so their blocks are
350 // the current, valid mechanism — they are intentionally NOT touched
351 // here (clearing WAF without a rebuild would drop working rules).
352 SiteGuard_Htaccess::clear_settings( $siteguard_admin_filter->get_mark() );
353 SiteGuard_Htaccess::clear_settings( $siteguard_xmlrpc->get_mark() );
354 }
355 if ( $upgrade_ok && SITEGUARD_VERSION !== $old_version ) {
356 $siteguard_config->set( 'version', SITEGUARD_VERSION );
357 $siteguard_config->update();
358 }
359 }
360 }
361 $siteguard = new SiteGuard();
362