Lockdown WP Admin - Version 2.0

Version Description

  • Provided a system dump to help in debugging issues that may arise.
  • Fixes a issues on the 404 page under 3.5.1 (get_current_screen())
  • Cleanup, cleanup!
Download this release

Release Info

Developer sean212
Plugin Icon wp plugin Lockdown WP Admin
Version 2.0
Comparing to
See all releases

Code changes from version 1.9 to 2.0

Files changed (5) hide show
  1. README.md +87 -0
  2. admin-private-users.php +44 -51
  3. admin.php +14 -14
  4. lockdown-wp-admin.php +97 -69
  5. readme.txt +24 -17
README.md ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Lockdown WP Admin
2
+ =============
3
+
4
+ Lockdown WP Admin conceals the administration and login screen from intruders. It can hide WordPress Admin (/wp-admin/) and and login (/wp-login.php) as well as add HTTP authentication to the login system. We can also change the login URL from wp-login.php to whatever you'd like: /login, /log-in-here, etc.
5
+
6
+ ### Description
7
+ This plugin will hide WordPress Admin (/wp-admin/) when a user isn't logged in. If a user isn't logged in and they attempt to access WP Admin directly, they will be unable to and it will return a 404. It can also rename the login URL.
8
+
9
+ Also, you can add HTTP authentication directly from WP Admin and add custom username/password combinations for the HTTP auth or use the WordPress credentials.
10
+
11
+ This doesn't touch any .htaccess files or change the WordPress core files. All the CSS/Images under /wp-admin/ are still accessible, just not the .php ones.
12
+
13
+ If you enable HTTP authentication, it will add HTTP authentication to the PHP files in /wp-admin/.
14
+
15
+
16
+ ### Installation
17
+ 1. Upload `/lockdown-wp-admin/` to the `/wp-content/plugins/` directory
18
+ 2. Activate the plugin through the 'Plugins' menu in WordPress
19
+ 3. Navigate to the "Lockdown WP" menu
20
+
21
+ ### FAQ
22
+ **How can we add files to the white list to hide from the public eye? We want to have AJAX and use a custom file, but we can't because it hides it from the public.**
23
+
24
+ You can add a file using the 'no_check_files' filter. Use this:
25
+ ```php
26
+ <?php
27
+ function add_my_cool_filter($data)
28
+ {
29
+ // You have to accept the $data argument or else it will cause a system meltdown ;)
30
+ $data[] = 'my-file-name.php'; // JUST the file name.
31
+ return $data;
32
+ }
33
+ add_filter('no_check_files', 'add_my_cool_filter');
34
+ ?>
35
+ ```
36
+
37
+ Simple.
38
+
39
+ **How can I get back in if Lockdown WP Admin locked me out?**
40
+
41
+ You can create a .txt file named 'disable_auth.txt' in your `wp-content/plugins/lockdown-wp-admin/` folder (The file location would be `/wp-content/plugins/lockdown-wp-admin/disable_auth.txt`). We don't care about the content but that will disable the HTTP Auth and whatever was locking you out of your site.
42
+
43
+ ### Changelog
44
+ 1.0
45
+ * Initial release
46
+
47
+ 1.0.1
48
+ * Fixed a link to a broken file
49
+
50
+ 1.1
51
+ * Fixed a bug on activating the plugin network wide, we disabled network wide activation.
52
+ * Cleaned up the plugin and prevented a double loop of the HTTP check, unnecessary.
53
+
54
+ 1.2
55
+ * Cleaned up more code.
56
+ * Security fixes that will prevent somebody from possibly hijacking your website. (Props Jon Cave)
57
+
58
+ 1.3.1
59
+ * Added the ability to change the login URL entirely. It will disable /wp-login.php and give it whatever you want to make it.
60
+
61
+ 1.4
62
+ * Fixed a bug with user's with a index.php base
63
+ * Added stats for us to collect about about URL setup and server configuration for our users. This will let us make the plugin even better.
64
+ * Fixed bug for having private user management in WP Admin
65
+
66
+ = 1.4.2 =
67
+ * Bug fixes
68
+ * Added `admin-ajax.php` to the files that we permit to be access in wp-admin.
69
+
70
+ 1.6
71
+ * Added way to get back into WP-ADMIN if locked out (See the FAQ)
72
+
73
+ 1.7
74
+ * Removed the stats that were collected to that we could understand the issues that users were having with the plugin.
75
+
76
+ 1.8
77
+ * Finally discovered why so many users had HTTP authentication errors. Fixed it to support almost 80% of hosts out there.
78
+ * If you still have problems, shoot me an email.
79
+
80
+ 1.9
81
+
82
+ A very late update, sorry! Worked to fix many issues with the admin bar and the "get_current_screen()" error. If you still see issues, please contact me!
83
+
84
+ 2.0
85
+ * Provided a system dump to help in debugging issues that may arise.
86
+ * Fixes a issues on the 404 page under 3.5.1 (`get_current_screen()`)
87
+ * Cleanup, cleanup!
admin-private-users.php CHANGED
@@ -2,60 +2,57 @@
2
  <div class="wrap">
3
  <div id="icon-options-general" class="icon32"></div><h2>HTTP Authentication Private Users</h2>
4
 
5
- <?php if ( defined('LD_WP_ADMIN') && LD_WP_ADMIN == TRUE ) { ?>
6
  <div class="updated fade"><p>Updated!</p></div>
7
- <?php }
8
 
9
- // Error message?
10
- if ( defined('LD_ERROR') && LD_ERROR == 'delete-self') { ?>
11
  <div class="error fade"><p>You can't delete yourself!</p></div>
12
- <?php } ?>
 
 
13
 
14
  <form method="POST" action="<?php echo admin_url('admin.php?page=lockdown-private-users'); ?>">
15
-
16
- <?php
17
- // Nonces
18
- wp_nonce_field('lockdown-wp-admin');
19
- ?>
20
  <p>Adding users below will <em>only</em> work if you have "Private Usernames/Passwords" selected for HTTP Authentication.</p>
21
 
22
- <p><strong>Please note a few things:</strong>
23
- <ul>
24
- <li>1. If you are ever locked out, you can just delete the plugin files via FTP (<code>/wp-content/plugins/lockdown-wp-admin/</code>) and you will be able to login again.</li>
25
- <li>2. You cannot delete the current HTTP Authentication username you are using right now.</li>
26
-
27
- <li>3. Private user HTTP Authentication will not work if you don't have a username added below.</li>
28
- </ul>
29
- </p>
30
 
31
  <table class="widefat">
32
- <thead>
33
- <tr>
34
- <th>Username</th>
35
- <th>Action</th>
36
-
37
- </tr>
38
- </thead>
39
 
40
- <tfoot>
41
-
42
- <tr>
43
- <th>Username</th>
44
- <th>Action</th>
45
- </tr>
46
-
47
- </tfoot>
48
- <tbody>
49
- <?php if ( isset( $private_users ) && count( $private_users ) > 0 ) : ?>
50
- <?php $nonce = wp_create_nonce('lockdown-wp-admin'); ?>
51
-
52
- <?php foreach( $private_users as $key => $user ) { ?>
53
- <tr>
54
- <td><?php echo $user['user']; ?></td>
55
- <td><a href="admin.php?page=<?php echo $_GET['page']; ?>&delete=<?php echo $key; ?>&_wpnonce=<?php echo $nonce; ?>">Delete</a></td>
56
- </tr><?php } endif; ?>
57
- </tbody>
58
- </table>
59
 
60
  <h4>Add a Private User</h4>
61
  <p>To add a user, fill out the username and password below and click "Save Options" below.</p>
@@ -63,12 +60,8 @@ if ( defined('LD_ERROR') && LD_ERROR == 'delete-self') { ?>
63
  <label><input type="password" name="private_password" /> New Password</label>
64
 
65
  <div class="clear"></div><br />
66
-
67
-
68
- <input type="hidden" name="did_update" value="yes_we_did">
69
-
70
  <input class='button-primary' type='submit' name='Save' value='<?php _e('Save Options'); ?>' id='submitbutton' />
71
-
72
-
73
- </form>
74
  </div>
2
  <div class="wrap">
3
  <div id="icon-options-general" class="icon32"></div><h2>HTTP Authentication Private Users</h2>
4
 
5
+ <?php if ( defined('LD_WP_ADMIN') && LD_WP_ADMIN == TRUE ) : ?>
6
  <div class="updated fade"><p>Updated!</p></div>
7
+ <?php endif;
8
 
9
+ // Error message?
10
+ if ( defined('LD_ERROR') && LD_ERROR == 'delete-self') : ?>
11
  <div class="error fade"><p>You can't delete yourself!</p></div>
12
+ <?php elseif (defined('LD_ERROR') AND LD_ERROR == 'username-exists') : ?>
13
+ <div class="error fade"><p>Username already taken.</p></div>
14
+ <?php endif; ?>
15
 
16
  <form method="POST" action="<?php echo admin_url('admin.php?page=lockdown-private-users'); ?>">
17
+ <?php wp_nonce_field('lockdown-wp-admin'); ?>
 
 
 
 
18
  <p>Adding users below will <em>only</em> work if you have "Private Usernames/Passwords" selected for HTTP Authentication.</p>
19
 
20
+ <p><strong>Please note a few things:</strong>
21
+ <ul>
22
+ <li>1. If you are ever locked out, you can just delete the plugin files via FTP (<code>/wp-content/plugins/lockdown-wp-admin/</code>) and you will be able to login again.</li>
23
+ <li>2. You cannot delete the current HTTP Authentication username you are using right now.</li>
24
+
25
+ <li>3. Private user HTTP Authentication will not work if you don't have a username added below.</li>
26
+ </ul>
27
+ </p>
28
 
29
  <table class="widefat">
30
+ <thead>
31
+ <tr>
32
+ <th>Username</th>
33
+ <th>Action</th>
34
+ </tr>
35
+ </thead>
 
36
 
37
+ <tfoot>
38
+
39
+ <tr>
40
+ <th>Username</th>
41
+ <th>Action</th>
42
+ </tr>
43
+
44
+ </tfoot>
45
+ <tbody>
46
+ <?php if ( isset( $private_users ) && count( $private_users ) > 0 ) : ?>
47
+ <?php $nonce = wp_create_nonce('lockdown-wp-admin'); ?>
48
+
49
+ <?php foreach( $private_users as $key => $user ) : ?>
50
+ <tr>
51
+ <td><?php echo $user['user']; ?></td>
52
+ <td><a href="admin.php?page=<?php echo $_GET['page']; ?>&delete=<?php echo $key; ?>&_wpnonce=<?php echo $nonce; ?>">Delete</a></td>
53
+ </tr><?php endforeach; endif; ?>
54
+ </tbody>
55
+ </table>
56
 
57
  <h4>Add a Private User</h4>
58
  <p>To add a user, fill out the username and password below and click "Save Options" below.</p>
60
  <label><input type="password" name="private_password" /> New Password</label>
61
 
62
  <div class="clear"></div><br />
63
+ <input type="hidden" name="did_update" value="yes_we_did">
 
 
 
64
  <input class='button-primary' type='submit' name='Save' value='<?php _e('Save Options'); ?>' id='submitbutton' />
65
+
66
+ </form>
 
67
  </div>
admin.php CHANGED
@@ -2,29 +2,25 @@
2
  <div class="wrap">
3
  <div id="icon-options-general" class="icon32"></div>
4
  <h2>Lockdown WordPress Admin</h2>
5
- <?php if ( defined('LD_WP_ADMIN') && LD_WP_ADMIN == TRUE ) { ?>
6
  <div class="updated fade">
7
  <p>Options updated!</p>
8
  </div>
9
- <?php }
10
- if ( defined('LD_DIS_BASE') && LD_DIS_BASE == TRUE )
11
- {
12
- ?>
13
  <div class="updated fade">
14
  <p>You can't make that your URL Base! </p>
15
  </div>
16
- <?php
17
- }
18
- ?>
19
  <p>We are going to help make WordPress a bit more secure.</p>
20
  <p><a href="https://twitter.com/srtfisher" class="twitter-follow-button" data-show-count="false">Follow @srtfisher</a>
21
  <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script><br />
22
- I tweet a lot of cool things and often post whenever I update this plugin. <a href="http://twitter.com/srtfisher">@srtfisher</a></p>
 
23
  <form method="POST" action="<?php echo admin_url('admin.php?page=lockdown-wp-admin'); ?>">
24
- <?php
25
- // Nonces
26
- wp_nonce_field('lockdown-wp-admin');
27
- ?>
28
  <h3>Hide WP Admin</h3>
29
  <p>We can "hide" WordPress's administration interface from the public. If you enable this, when you access <code><?php echo admin_url(); ?></code> when you <strong>aren't</strong> logged in, you will recieve a <a href="http://en.wikipedia.org/wiki/HTTP_404">404 error page</a> instead of redirecting to the login page.</p>
30
  <label>
@@ -45,7 +41,11 @@ $url = wp_guess_url() . '/'. $this->login_base;
45
  <p>Your current login URL is <code><a href="<?php echo $url; ?>"><?php echo $url; ?></a></code>.</p>
46
  <blockquote>
47
  <h4>Please Note Something!</h4>
48
- <p>If you are using a cache plugin (WTC, WP Super Cache, etc), you need to enable it to not cache the above base. That means (for most caching plugins) adding whatever you enter into the box above into your plugins Caching Whitelist, that is the list of URLs that your plugin doesn't cache. If you have any questions, tweet me @talkingwithsean.</p>
 
 
 
 
49
  </blockquote>
50
  <h3>HTTP Authentication</h3>
51
  <p>Please read about HTTP Authentication on <a href="http://en.wikipedia.org/wiki/Basic_access_authentication">http://en.wikipedia.org/wiki/Basic_access_authentication</a>.</p>
2
  <div class="wrap">
3
  <div id="icon-options-general" class="icon32"></div>
4
  <h2>Lockdown WordPress Admin</h2>
5
+ <?php if ( defined('LD_WP_ADMIN') && LD_WP_ADMIN == TRUE ) : ?>
6
  <div class="updated fade">
7
  <p>Options updated!</p>
8
  </div>
9
+ <?php endif;
10
+ if ( defined('LD_DIS_BASE') && LD_DIS_BASE == TRUE ) : ?>
 
 
11
  <div class="updated fade">
12
  <p>You can't make that your URL Base! </p>
13
  </div>
14
+ <?php endif; ?>
15
+
 
16
  <p>We are going to help make WordPress a bit more secure.</p>
17
  <p><a href="https://twitter.com/srtfisher" class="twitter-follow-button" data-show-count="false">Follow @srtfisher</a>
18
  <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script><br />
19
+ I tweet a lot of things and often post whenever I update this plugin. You should follow me <a href="http://twitter.com/srtfisher">@srtfisher</a></p>
20
+
21
  <form method="POST" action="<?php echo admin_url('admin.php?page=lockdown-wp-admin'); ?>">
22
+
23
+ <?php wp_nonce_field('lockdown-wp-admin'); ?>
 
 
24
  <h3>Hide WP Admin</h3>
25
  <p>We can "hide" WordPress's administration interface from the public. If you enable this, when you access <code><?php echo admin_url(); ?></code> when you <strong>aren't</strong> logged in, you will recieve a <a href="http://en.wikipedia.org/wiki/HTTP_404">404 error page</a> instead of redirecting to the login page.</p>
26
  <label>
41
  <p>Your current login URL is <code><a href="<?php echo $url; ?>"><?php echo $url; ?></a></code>.</p>
42
  <blockquote>
43
  <h4>Please Note Something!</h4>
44
+ <p>If you are using a cache plugin (WTC, WP Super Cache, etc), you need to enable it
45
+ to not cache the above base. That means (for most caching plugins) adding
46
+ whatever you enter into the box above into your plugins Caching Whitelist, that
47
+ is the list of URLs that your plugin doesn't cache. If you have any questions, tweet
48
+ me <a href="http://twitter.com/srtfisher">@srtfisher</a>.</p>
49
  </blockquote>
50
  <h3>HTTP Authentication</h3>
51
  <p>Please read about HTTP Authentication on <a href="http://en.wikipedia.org/wiki/Basic_access_authentication">http://en.wikipedia.org/wiki/Basic_access_authentication</a>.</p>
lockdown-wp-admin.php CHANGED
@@ -1,33 +1,34 @@
1
  <?php if (! defined('ABSPATH')) exit;
2
  /*
3
- Plugin Name: Lockdown WordPress Admin
4
- Plugin URI: http://seanfisher.co/2011/01/lockdown-wp-admin/
5
- Description: Securing the WordPress Administration interface.
6
- Version: 1.9
 
7
  Author: Sean Fisher
8
  Author URI: http://seanfisher.co/
9
  License: GPL
10
  */
11
 
12
- // This file name
13
  define('LD_FILE_NAME', __FILE__ );
14
 
15
  /**
16
- * This is the plugin that will add security to our site
17
  *
18
- * @author Sean Fisher <me@seanfisher.co>
19
- * @version 1.9
20
- * @license GPL
21
  **/
22
  class WP_LockAuth
23
  {
24
  /**
25
  * The version of lockdown WP Admin
26
  *
27
- * @param string
28
  * @access private
29
  **/
30
- private $ld_admin_version = '1.9';
31
 
32
  /**
33
  * The HTTP Auth name for the protected area
@@ -36,7 +37,7 @@ class WP_LockAuth
36
  * @access public
37
  * @global string
38
  **/
39
- public $relm = "Secure Area";
40
 
41
  /**
42
  * The current user ID from our internal array
@@ -52,18 +53,19 @@ class WP_LockAuth
52
  **/
53
  private $login_base = FALSE;
54
 
55
- function WP_LockAuth()
56
  {
57
  // We don't like adding network wide WordPress plugins.
58
- require_once( dirname( __FILE__ ) .'/no-wpmu.php' );
 
59
 
60
  // Add the action to setup the menu.
61
- add_action('admin_menu', array( &$this, 'add_admin_menu'));
62
 
63
- // Setup the plugin.
64
  $this->setup_hide_admin();
65
 
66
- // Hide the login form
67
  $this->redo_login_form();
68
  }
69
 
@@ -72,11 +74,11 @@ class WP_LockAuth
72
  *
73
  * @return array|bool
74
  **/
75
- function get_http_auth_creds()
76
  {
77
  // Since PHP saves the HTTP Password in a bunch of places, we have to be able to test for all of them
78
  $username = NULL;
79
- $password = NULL;
80
 
81
  // mod_php
82
  if (isset($_SERVER['PHP_AUTH_USER']))
@@ -106,7 +108,7 @@ class WP_LockAuth
106
  *
107
  * @access private
108
  **/
109
- function update_users()
110
  {
111
  if (! isset( $_GET['page'] ) )
112
  return;
@@ -114,7 +116,7 @@ class WP_LockAuth
114
  if ( $_GET['page'] !== 'lockdown-private-users' )
115
  return;
116
 
117
- // Nonce
118
  if ( !isset( $_REQUEST['_wpnonce'] ) )
119
  return;
120
 
@@ -122,18 +124,22 @@ class WP_LockAuth
122
  if ( !wp_verify_nonce( $nonce, 'lockdown-wp-admin' ) )
123
  wp_die('Security error, please try again.');
124
 
125
- // ---------------------------------------------------
126
-
127
- // Add a user
128
  if ( isset( $_POST['private_username'] ) && isset( $_POST['private_password'] ) )
129
  {
130
  if ( $_POST['private_username'] !== '' && $_POST['private_password'] !== '' )
131
  {
132
- // Adding a user.
133
  $users = $this->get_private_users();
134
  $add['user'] = sanitize_user( $_POST['private_username'] );
135
  $add['pass'] = trim( md5( $_POST['private_password'] ) );
136
 
 
 
 
 
 
 
137
  $users[] = $add;
138
 
139
  update_option('ld_private_users', $users);
@@ -143,7 +149,7 @@ class WP_LockAuth
143
  }
144
  }
145
 
146
- // Deleting a user.
147
  if ( isset( $_GET['delete'] ) )
148
  {
149
  // Delete the user.
@@ -180,7 +186,7 @@ class WP_LockAuth
180
  *
181
  * @access private
182
  **/
183
- function update_options()
184
  {
185
  if ( !isset( $_GET['page'] ) )
186
  return;
@@ -267,7 +273,7 @@ class WP_LockAuth
267
  *
268
  * @access private
269
  **/
270
- function get_private_users()
271
  {
272
  $opt = get_option('ld_private_users');
273
  if ( !is_array( $opt ) )
@@ -281,37 +287,35 @@ class WP_LockAuth
281
  *
282
  * @access void
283
  **/
284
- function setup_hide_admin()
285
  {
286
  $opt = get_option('ld_hide_wp_admin');
287
 
288
  // Nope, they didn't enable it.
289
  if ( $opt !== 'yep' )
290
- {
291
- $this->setup_http_area();
292
- return;
293
- }
294
 
295
- // We're gonna hide it.
296
  $no_check_files = array('async-upload.php', 'admin-ajax.php', 'wp-app.php');
297
  $no_check_files = apply_filters('no_check_files', $no_check_files);
298
 
299
  $explode = explode('/', $_SERVER['SCRIPT_FILENAME'] );
300
  $file = end( $explode );
301
- if ( in_array( $file, $no_check_files ) )
302
- {
 
303
  define('INTERNAL_AUTH_PASSED', TRUE);
304
  return;
305
  }
306
 
307
- // We only will hide it if we are in admin (/wp-admin/)
308
  if ( is_admin() )
309
  {
310
  // Non logged in users.
311
  if ( ! is_user_logged_in() )
312
  $this->throw_404();
313
 
314
- // Setup HTTP auth.
315
  $this->setup_http_area();
316
  }
317
  }
@@ -321,7 +325,7 @@ class WP_LockAuth
321
  *
322
  * @return string JUST the file name
323
  **/
324
- function get_file()
325
  {
326
  // We're gonna hide it.
327
  $no_check_files = array('async-upload.php');
@@ -336,9 +340,9 @@ class WP_LockAuth
336
  *
337
  * Here, we only check if it's enabled
338
  *
339
- * @access private
340
  **/
341
- function setup_http_area()
342
  {
343
  // We save what type of auth we're doing here.
344
  $opt = get_option('ld_http_auth');
@@ -347,7 +351,7 @@ class WP_LockAuth
347
  switch( $opt )
348
  {
349
  // HTTP auth is going to ask for their WordPress creds.
350
- case('wp_creds');
351
  $creds = $this->get_http_auth_creds();
352
  if (! $creds )
353
  $this->inauth_headers(); // Invalid credentials
@@ -372,7 +376,7 @@ class WP_LockAuth
372
  return;
373
  }
374
 
375
- // Attempt to sign them in if they aren't alerady
376
  if (! is_user_logged_in() ) :
377
  // Try it via wp_signon
378
  $creds = array();
@@ -391,7 +395,7 @@ class WP_LockAuth
391
  break;
392
 
393
  // Private list of users to check
394
- case('private');
395
  $users = $this->get_private_users();
396
 
397
  // We want a user to exist.
@@ -413,38 +417,34 @@ class WP_LockAuth
413
  // Did they enter a valid user?
414
  if ( $this->user_array_check( $users, $creds['username'], $creds['password'] ) )
415
  {
416
- // Yes!!
417
  define('INTERNAL_AUTH_PASSED', TRUE);
418
  $this->set_current_user( $users, $creds['username'] );
419
  return;
420
  }
421
  else
422
  {
423
- // Nope
424
- $this->inauth_headers();
425
- return;
426
  }
427
 
428
  break;
429
 
430
  // Unknown type of auth
431
- default;
432
  return FALSE;
433
- break;
434
  }
435
 
436
  }
437
  /**
438
  * Check an internal array of users against a passed user and pass
439
  *
440
- * @access public
441
  * @return bool
442
  *
443
  * @param array $array The array of users
444
  * @param string $user The username to check for
445
  * @param string $pass The password to check for (plain text)
446
  **/
447
- public function user_array_check( $array, $user, $pass )
448
  {
449
  foreach( $array as $key => $val )
450
  {
@@ -454,11 +454,33 @@ class WP_LockAuth
454
 
455
  return FALSE;
456
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457
 
458
  /**
459
  * Set the current user
460
  *
461
  * @access private
 
 
462
  **/
463
  private function set_current_user( $array, $user )
464
  {
@@ -474,10 +496,10 @@ class WP_LockAuth
474
  *
475
  * @acces private
476
  **/
477
- function add_admin_menu()
478
  {
479
- add_menu_page('Lockdown WP', 'Lockdown WP', 'manage_options', 'lockdown-wp-admin', array( &$this, 'admin_callback'));
480
- add_submenu_page( 'lockdown-wp-admin', 'Private Users', 'Private Users', 'manage_options', 'lockdown-private-users', array( &$this, 'sub_admin_callback'));
481
  }
482
 
483
  /**
@@ -485,7 +507,7 @@ class WP_LockAuth
485
  *
486
  * You need the 'manage_options' capability to get here.
487
  **/
488
- function admin_callback()
489
  {
490
  // Update the options
491
  $this->update_options();
@@ -499,14 +521,14 @@ class WP_LockAuth
499
  *
500
  * You need the 'manage_options' capability to get here.
501
  **/
502
- function sub_admin_callback()
503
  {
504
- // Update the users options
505
  $this->update_users();
506
 
507
- // The UI
508
  $private_users = $this->get_private_users();
509
- require_once( dirname( __FILE__ ) . '/admin-private-users.php' );
510
  }
511
 
512
  /**
@@ -519,7 +541,7 @@ class WP_LockAuth
519
  $login_base = get_option('ld_login_base');
520
 
521
  // It's not enabled.
522
- if ( $login_base == NULL || !$login_base || $login_base == '' )
523
  return;
524
 
525
  $this->login_base = $login_base;
@@ -591,25 +613,30 @@ class WP_LockAuth
591
  **/
592
  public function throw_404()
593
  {
594
- // Admin Bar
595
- add_filter('show_admin_bar', '__return_false');
 
 
 
 
 
596
  remove_action( 'admin_footer', 'wp_admin_bar_render', 10);
597
  remove_action('wp_head', 'wp_admin_bar_header', 10);
598
  remove_action('wp_head', '_admin_bar_bump_cb', 10);
599
  wp_dequeue_script( 'admin-bar' );
600
  wp_dequeue_style( 'admin-bar' );
601
 
602
-
603
- status_header(404);
604
  $four_tpl = get_404_template();
605
-
606
  // Handle the admin bar
607
  @define('APP_REQUEST', TRUE);
 
608
 
609
  if ( empty($four_tpl) OR ! file_exists($four_tpl) )
610
  {
611
  // We're gonna try and get TwentyTen's one
612
- $twenty_ten_tpl = apply_filters('LD_404_FALLBACK', WP_CONTENT_DIR . '/themes/twentyten/404.php');
613
 
614
  if (file_exists($twenty_ten_tpl))
615
  require($twenty_ten_tpl);
@@ -639,8 +666,9 @@ class WP_LockAuth
639
  **/
640
  function ld_setup_auth()
641
  {
642
- // Setup the object.
643
- $auth_obj = new WP_LockAuth();
 
644
  }
645
 
646
  add_action('init', 'ld_setup_auth');
1
  <?php if (! defined('ABSPATH')) exit;
2
  /*
3
+ Plugin Name: Lockdown WP Admin
4
+ Plugin URI: http://seanfisher.co/lockdown-wp-admin/
5
+ Donate link: http://seanfisher.co/donate/
6
+ Description: Securing the WordPress Administration interface by concealing the administration dashboard and changing the login page URL.
7
+ Version: 2.0
8
  Author: Sean Fisher
9
  Author URI: http://seanfisher.co/
10
  License: GPL
11
  */
12
 
13
+ // This file name
14
  define('LD_FILE_NAME', __FILE__ );
15
 
16
  /**
17
+ * This is the plugin that will add security to our site
18
  *
19
+ * @author Sean Fisher <me@seanfisher.co>
20
+ * @version 1.9
21
+ * @license GPL
22
  **/
23
  class WP_LockAuth
24
  {
25
  /**
26
  * The version of lockdown WP Admin
27
  *
28
+ * @global string
29
  * @access private
30
  **/
31
+ private $ld_admin_version = 2.0;
32
 
33
  /**
34
  * The HTTP Auth name for the protected area
37
  * @access public
38
  * @global string
39
  **/
40
+ public $relm = 'Secure Area';
41
 
42
  /**
43
  * The current user ID from our internal array
53
  **/
54
  private $login_base = FALSE;
55
 
56
+ public function __construct()
57
  {
58
  // We don't like adding network wide WordPress plugins.
59
+ if (! class_exists('Disable_WPMS_Plugin_LD'))
60
+ require_once( dirname( __FILE__ ) .'/no-wpmu.php' );
61
 
62
  // Add the action to setup the menu.
63
+ add_action('admin_menu', array( $this, 'add_admin_menu'));
64
 
65
+ // Setup the plugin.
66
  $this->setup_hide_admin();
67
 
68
+ // Hide the login form
69
  $this->redo_login_form();
70
  }
71
 
74
  *
75
  * @return array|bool
76
  **/
77
+ public function get_http_auth_creds()
78
  {
79
  // Since PHP saves the HTTP Password in a bunch of places, we have to be able to test for all of them
80
  $username = NULL;
81
+ $password = NULL;
82
 
83
  // mod_php
84
  if (isset($_SERVER['PHP_AUTH_USER']))
108
  *
109
  * @access private
110
  **/
111
+ public function update_users()
112
  {
113
  if (! isset( $_GET['page'] ) )
114
  return;
116
  if ( $_GET['page'] !== 'lockdown-private-users' )
117
  return;
118
 
119
+ // Nonce
120
  if ( !isset( $_REQUEST['_wpnonce'] ) )
121
  return;
122
 
124
  if ( !wp_verify_nonce( $nonce, 'lockdown-wp-admin' ) )
125
  wp_die('Security error, please try again.');
126
 
127
+ // Add a user
 
 
128
  if ( isset( $_POST['private_username'] ) && isset( $_POST['private_password'] ) )
129
  {
130
  if ( $_POST['private_username'] !== '' && $_POST['private_password'] !== '' )
131
  {
132
+ // Adding a user
133
  $users = $this->get_private_users();
134
  $add['user'] = sanitize_user( $_POST['private_username'] );
135
  $add['pass'] = trim( md5( $_POST['private_password'] ) );
136
 
137
+ // See if it exists
138
+ if ($this->user_exists($users, $add['user'])) :
139
+ define('LD_ERROR', 'username-exists');
140
+ return;
141
+ endif;
142
+
143
  $users[] = $add;
144
 
145
  update_option('ld_private_users', $users);
149
  }
150
  }
151
 
152
+ // Deleting a user.
153
  if ( isset( $_GET['delete'] ) )
154
  {
155
  // Delete the user.
186
  *
187
  * @access private
188
  **/
189
+ public function update_options()
190
  {
191
  if ( !isset( $_GET['page'] ) )
192
  return;
273
  *
274
  * @access private
275
  **/
276
+ public function get_private_users()
277
  {
278
  $opt = get_option('ld_private_users');
279
  if ( !is_array( $opt ) )
287
  *
288
  * @access void
289
  **/
290
+ protected function setup_hide_admin()
291
  {
292
  $opt = get_option('ld_hide_wp_admin');
293
 
294
  // Nope, they didn't enable it.
295
  if ( $opt !== 'yep' )
296
+ return $this->setup_http_area();
 
 
 
297
 
298
+ // We're gonna hide it.
299
  $no_check_files = array('async-upload.php', 'admin-ajax.php', 'wp-app.php');
300
  $no_check_files = apply_filters('no_check_files', $no_check_files);
301
 
302
  $explode = explode('/', $_SERVER['SCRIPT_FILENAME'] );
303
  $file = end( $explode );
304
+
305
+ if ( in_array( $file, $no_check_files ) )
306
+ {
307
  define('INTERNAL_AUTH_PASSED', TRUE);
308
  return;
309
  }
310
 
311
+ // We only will hide it if we are in admin (/wp-admin/)
312
  if ( is_admin() )
313
  {
314
  // Non logged in users.
315
  if ( ! is_user_logged_in() )
316
  $this->throw_404();
317
 
318
+ // Setup HTTP auth.
319
  $this->setup_http_area();
320
  }
321
  }
325
  *
326
  * @return string JUST the file name
327
  **/
328
+ public function get_file()
329
  {
330
  // We're gonna hide it.
331
  $no_check_files = array('async-upload.php');
340
  *
341
  * Here, we only check if it's enabled
342
  *
343
+ * @access protected
344
  **/
345
+ protected function setup_http_area()
346
  {
347
  // We save what type of auth we're doing here.
348
  $opt = get_option('ld_http_auth');
351
  switch( $opt )
352
  {
353
  // HTTP auth is going to ask for their WordPress creds.
354
+ case 'wp_creds' :
355
  $creds = $this->get_http_auth_creds();
356
  if (! $creds )
357
  $this->inauth_headers(); // Invalid credentials
376
  return;
377
  }
378
 
379
+ // Attempt to sign them in if they aren't already
380
  if (! is_user_logged_in() ) :
381
  // Try it via wp_signon
382
  $creds = array();
395
  break;
396
 
397
  // Private list of users to check
398
+ case 'private' :
399
  $users = $this->get_private_users();
400
 
401
  // We want a user to exist.
417
  // Did they enter a valid user?
418
  if ( $this->user_array_check( $users, $creds['username'], $creds['password'] ) )
419
  {
 
420
  define('INTERNAL_AUTH_PASSED', TRUE);
421
  $this->set_current_user( $users, $creds['username'] );
422
  return;
423
  }
424
  else
425
  {
426
+ return $this->inauth_headers();
 
 
427
  }
428
 
429
  break;
430
 
431
  // Unknown type of auth
432
+ default :
433
  return FALSE;
 
434
  }
435
 
436
  }
437
  /**
438
  * Check an internal array of users against a passed user and pass
439
  *
440
+ * @access protected
441
  * @return bool
442
  *
443
  * @param array $array The array of users
444
  * @param string $user The username to check for
445
  * @param string $pass The password to check for (plain text)
446
  **/
447
+ protected function user_array_check( $array, $user, $pass )
448
  {
449
  foreach( $array as $key => $val )
450
  {
454
 
455
  return FALSE;
456
  }
457
+
458
+ /**
459
+ * See if a user exists in the array
460
+ *
461
+ * @access protected
462
+ * @return boolean
463
+ * @param array Array of users
464
+ * @param string
465
+ */
466
+ protected function user_exists($array, $user)
467
+ {
468
+ if (count($array) == 0) return FALSE;
469
+
470
+ foreach ($array as $k => $v) :
471
+ if ($v['user'] == $user)
472
+ return TRUE;
473
+ endforeach;
474
+
475
+ return FALSE;
476
+ }
477
 
478
  /**
479
  * Set the current user
480
  *
481
  * @access private
482
+ * @param array
483
+ * @param integer
484
  **/
485
  private function set_current_user( $array, $user )
486
  {
496
  *
497
  * @acces private
498
  **/
499
+ public function add_admin_menu()
500
  {
501
+ add_menu_page('Lockdown WP', 'Lockdown WP', 'manage_options', 'lockdown-wp-admin', array( $this, 'admin_callback'));
502
+ add_submenu_page( 'lockdown-wp-admin', 'Private Users', 'Private Users', 'manage_options', 'lockdown-private-users', array( $this, 'sub_admin_callback'));
503
  }
504
 
505
  /**
507
  *
508
  * You need the 'manage_options' capability to get here.
509
  **/
510
+ public function admin_callback()
511
  {
512
  // Update the options
513
  $this->update_options();
521
  *
522
  * You need the 'manage_options' capability to get here.
523
  **/
524
+ public function sub_admin_callback()
525
  {
526
+ // Update the users options
527
  $this->update_users();
528
 
529
+ // The UI
530
  $private_users = $this->get_private_users();
531
+ require_once( __DIR__ . '/admin-private-users.php' );
532
  }
533
 
534
  /**
541
  $login_base = get_option('ld_login_base');
542
 
543
  // It's not enabled.
544
+ if ( $login_base == NULL || ! $login_base || $login_base == '' )
545
  return;
546
 
547
  $this->login_base = $login_base;
613
  **/
614
  public function throw_404()
615
  {
616
+ // Change WP Query
617
+ global $wp_query;
618
+ $wp_query->set_404();
619
+ status_header(404);
620
+
621
+ // Disable that pesky Admin Bar
622
+ add_filter('show_admin_bar', '__return_false', 900);
623
  remove_action( 'admin_footer', 'wp_admin_bar_render', 10);
624
  remove_action('wp_head', 'wp_admin_bar_header', 10);
625
  remove_action('wp_head', '_admin_bar_bump_cb', 10);
626
  wp_dequeue_script( 'admin-bar' );
627
  wp_dequeue_style( 'admin-bar' );
628
 
629
+ // Template
 
630
  $four_tpl = get_404_template();
631
+
632
  // Handle the admin bar
633
  @define('APP_REQUEST', TRUE);
634
+ @define('DOING_AJAX', TRUE);
635
 
636
  if ( empty($four_tpl) OR ! file_exists($four_tpl) )
637
  {
638
  // We're gonna try and get TwentyTen's one
639
+ $twenty_ten_tpl = apply_filters('LD_404_FALLBACK', WP_CONTENT_DIR . '/themes/twentytwelve/404.php');
640
 
641
  if (file_exists($twenty_ten_tpl))
642
  require($twenty_ten_tpl);
666
  **/
667
  function ld_setup_auth()
668
  {
669
+ // Instantiate the object
670
+ $class = apply_filters('ld_class', 'WP_LockAuth');
671
+ $auth_obj = new $class();
672
  }
673
 
674
  add_action('init', 'ld_setup_auth');
readme.txt CHANGED
@@ -2,22 +2,24 @@
2
  Contributors: sean212
3
  Donate link: http://seanfisher.co/donate/
4
  Link: http://seanfisher.co/lockdown-wp-admin/
5
- Tags: security, wp-admin, login, hide login, rename login, http auth, 404, lockdown, srtfisher, secure
6
- Requires at least: 3.0
7
- Tested up to: 3.4.2
8
- Stable tag: 1.9
9
 
10
- This plugin will lockdown WP Admin. It can hide wp-admin and wp-login as well as add HTTP auth to the login system. It can change the login URL.
11
 
12
  == Description ==
13
 
14
- This plugin will hide /wp-admin/ when you aren't logged in. If a user isn't logged in and they attempt to access /wp-admin/ directly, they will be unable to and it will return a 404. It can also rename the login URL.
15
 
16
- Also, you can add HTTP authentication directly from WP admin and add custom username/password combinations for the HTTP auth, or use the WordPress credentials.
17
 
18
  This doesn't touch any .htaccess files or change the WordPress core files. All the CSS/Images under /wp-admin/ are still accessible, just not the .php ones.
19
 
20
- If you enable HTTP authencation, it will add HTTP auth to the PHP files in /wp-admin/
 
 
21
 
22
  == Installation ==
23
  1. Upload `/lockdown-wp-admin/` to the `/wp-content/plugins/` directory
@@ -25,13 +27,13 @@ If you enable HTTP authencation, it will add HTTP auth to the PHP files in /wp-a
25
  3. Navigate to the "Lockdown WP" menu
26
 
27
  == Frequently Asked Questions ==
28
- = How can we add files to the whitelist to hide from the public eye? We want to have AJAX and use a custom file, but we can't because it hides it from the public. =
29
 
30
  You can add a file using the 'no_check_files' filter. Use this:
31
  `
32
  function add_my_cool_filter($data)
33
  {
34
- // You have to accept the $data argument or else it will cause a system meltdown ;)
35
  $data[] = 'my-file-name.php'; // JUST the file name.
36
  return $data;
37
  }
@@ -40,9 +42,9 @@ You can add a file using the 'no_check_files' filter. Use this:
40
 
41
  Simple.
42
 
43
- = How can I get back in if the plugin locked me out? =
44
 
45
- You can create a .txt file named 'disable_auth.txt' in your wp-content/plugins/lockdown-wp-admin/ folder (The file location would be /wp-content/plugins/lockdown-wp-admin/disable_auth.txt). We don't care about the content but that will disable the HTTP Auth and whatever was locking you out of your site.
46
 
47
  == Changelog ==
48
  = 1.0 =
@@ -78,8 +80,13 @@ You can create a .txt file named 'disable_auth.txt' in your wp-content/plugins/l
78
  * Removed the stats that were collected to that we could understand the issues that users were having with the plugin.
79
 
80
  = 1.8 =
81
- * Finally discovered why so many users had HTTP auth errors. Fixed it to support almost 80% of hosts out there.
82
- * If you still have problems, shoot me an email.
83
-
84
- = 1.9 =
85
- A very late update, sorry! Worked to fix many issues with the admin bar and the "get_current_screen()" error. If you still see issues, please contact me!
 
 
 
 
 
2
  Contributors: sean212
3
  Donate link: http://seanfisher.co/donate/
4
  Link: http://seanfisher.co/lockdown-wp-admin/
5
+ Tags: security, secure, lockdown, vulnerability, website security, wp-admin, login, hide login, rename login, http auth, 404, lockdown, srtfisher, secure
6
+ Requires at least: 3.3
7
+ Tested up to: 3.5.1
8
+ Stable tag: 2.0
9
 
10
+ Lockdown WP Admin conceals the administration and login screen from intruders. It can hide WordPress Admin (/wp-admin/) and and login (/wp-login.php) as well as add HTTP authentication to the login system. We can also change the login URL from wp-login.php to whatever you'd like: /login, /log-in-here, etc.
11
 
12
  == Description ==
13
 
14
+ This plugin will hide WordPress Admin (/wp-admin/) when a user isn't logged in. If a user isn't logged in and they attempt to access WP Admin directly, they will be unable to and it will return a 404. It can also rename the login URL.
15
 
16
+ Also, you can add HTTP authentication directly from WP Admin and add custom username/password combinations for the HTTP auth or use the WordPress credentials.
17
 
18
  This doesn't touch any .htaccess files or change the WordPress core files. All the CSS/Images under /wp-admin/ are still accessible, just not the .php ones.
19
 
20
+ If you enable HTTP authentication, it will add HTTP authentication to the PHP files in /wp-admin/.
21
+
22
+ To contribute to the development, check out [the GitHub Repository](https://github.com/srtfisher/Lockdown-WPAdmin).
23
 
24
  == Installation ==
25
  1. Upload `/lockdown-wp-admin/` to the `/wp-content/plugins/` directory
27
  3. Navigate to the "Lockdown WP" menu
28
 
29
  == Frequently Asked Questions ==
30
+ = How can we add files to the white list to hide from the public eye? We want to have AJAX and use a custom file, but we can't because it hides it from the public. =
31
 
32
  You can add a file using the 'no_check_files' filter. Use this:
33
  `
34
  function add_my_cool_filter($data)
35
  {
36
+ // You have to accept the $data argument or else it will cause a system meltdown ;)
37
  $data[] = 'my-file-name.php'; // JUST the file name.
38
  return $data;
39
  }
42
 
43
  Simple.
44
 
45
+ = How can I get back in if Lockdown WP Admin locked me out? =
46
 
47
+ You can create a .txt file named 'disable_auth.txt' in your `wp-content/plugins/lockdown-wp-admin/` folder (The file location would be `/wp-content/plugins/lockdown-wp-admin/disable_auth.txt`). We don't care about the content but that will disable the HTTP Auth and whatever was locking you out of your site.
48
 
49
  == Changelog ==
50
  = 1.0 =
80
  * Removed the stats that were collected to that we could understand the issues that users were having with the plugin.
81
 
82
  = 1.8 =
83
+ * Finally discovered why so many users had HTTP authentication errors. Fixed it to support almost 80% of hosts out there.
84
+ * If you still have problems, shoot me an email.
85
+
86
+ = 1.9 =
87
+ A very late update, sorry! Worked to fix many issues with the admin bar and the "get_current_screen()" error. If you still see issues, please contact me!
88
+
89
+ = 2.0 =
90
+ * Provided a system dump to help in debugging issues that may arise.
91
+ * Fixes a issues on the 404 page under 3.5.1 (`get_current_screen()`)
92
+ * Cleanup, cleanup!