PluginProbe
Password Protected — Lock Entire Site, Pages, Posts, Categories, and Partial Content / 1.7.1
Password Protected — Lock Entire Site, Pages, Posts, Categories, and Partial Content v1.7.1
2.8.4 2.8.3 2.8.2 2.8.1 trunk 1.0 1.1 1.2 1.2.1 1.2.2 1.3 1.4 1.5 1.6 1.6.1 1.6.2 1.7 1.7.1 1.7.2 1.8 1.9 2.0 2.0.1 2.0.2 2.0.3 All 63 releases
password-protected / password-protected.php

password-protected.php in Password Protected — Lock Entire Site, Pages, Posts, Categories, and Partial Content 1.7.1, at password-protected.php

414 lines 12.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 Plugin Name: Password Protected
5 Plugin URI: http://wordpress.org/extend/plugins/password-protected/
6 Description: A very simple way to quickly password protect your WordPress site with a single password. Integrates seamlessly into your WordPress privacy settings.
7 Version: 1.7.1
8 Author: Ben Huson
9 Text Domain: password-protected
10 Author URI: http://www.benhuson.co.uk/
11 License: GPLv2
12 */
13
14 /*
15 Copyright 2012 Ben Huson (email : ben@thewhiteroom.net)
16
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License, version 2, as
19 published by the Free Software Foundation.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31 /**
32 * @todo Use wp_hash_password() ?
33 * @todo Remember me
34 */
35
36 define( 'PASSWORD_PROTECTED_SUBDIR', '/' . str_replace( basename( __FILE__ ), '', plugin_basename( __FILE__ ) ) );
37 define( 'PASSWORD_PROTECTED_URL', plugins_url( PASSWORD_PROTECTED_SUBDIR ) );
38 define( 'PASSWORD_PROTECTED_DIR', plugin_dir_path( __FILE__ ) );
39
40 global $Password_Protected;
41 $Password_Protected = new Password_Protected();
42
43 class Password_Protected {
44
45 var $version = '1.7.1';
46 var $admin = null;
47 var $errors = null;
48
49 /**
50 * Constructor
51 */
52 function Password_Protected() {
53 $this->errors = new WP_Error();
54 register_activation_hook( __FILE__, array( &$this, 'install' ) );
55 add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
56 add_action( 'init', array( $this, 'maybe_process_login' ), 1 );
57 add_action( 'wp', array( $this, 'disable_feeds' ) );
58 add_action( 'template_redirect', array( $this, 'maybe_show_login' ), 1 );
59 add_filter( 'pre_option_password_protected_status', array( $this, 'allow_feeds' ) );
60 add_filter( 'pre_option_password_protected_status', array( $this, 'allow_administrators' ) );
61 add_filter( 'pre_option_password_protected_status', array( $this, 'allow_users' ) );
62 if ( is_admin() ) {
63 include_once( dirname( __FILE__ ) . '/admin/admin.php' );
64 $this->admin = new Password_Protected_Admin();
65 }
66 }
67
68 /**
69 * I18n
70 */
71 function load_plugin_textdomain() {
72 load_plugin_textdomain( 'password-protected', false, basename( dirname( __FILE__ ) ) . '/languages' );
73 }
74
75 /**
76 * Is Active?
77 *
78 * @return boolean Is password protection active?
79 */
80 function is_active() {
81
82 // Always allow access to robots.txt
83 if ( is_robots() )
84 return false;
85
86 if ( (bool) get_option( 'password_protected_status' ) ) {
87 if ( ! defined( 'DONOTCACHEPAGE' ) )
88 define( 'DONOTCACHEPAGE', true );
89 return true;
90 }
91 return false;
92 }
93
94 /**
95 * Disable Feeds
96 *
97 * @todo An option/filter to prevent disabling of feeds.
98 */
99 function disable_feeds() {
100 if ( $this->is_active() ) {
101 add_action( 'do_feed', array( $this, 'disable_feed' ), 1 );
102 add_action( 'do_feed_rdf', array( $this, 'disable_feed' ), 1 );
103 add_action( 'do_feed_rss', array( $this, 'disable_feed' ), 1 );
104 add_action( 'do_feed_rss2', array( $this, 'disable_feed' ), 1 );
105 add_action( 'do_feed_atom', array( $this, 'disable_feed' ), 1 );
106 }
107 }
108
109 /**
110 * Disable Feed
111 *
112 * @todo Make Translatable
113 */
114 function disable_feed() {
115 wp_die( sprintf( __( 'Feeds are not available for this site. Please visit the <a href="%s">website</a>.', 'password-protected' ), get_bloginfo( 'url' ) ) );
116 }
117
118 /**
119 * Allow Feeds
120 *
121 * @param boolean $bool Allow feeds.
122 * @return boolean True/false.
123 */
124 function allow_feeds( $bool ) {
125 if ( is_feed() && (bool) get_option( 'password_protected_feeds' ) )
126 return 0;
127 return $bool;
128 }
129
130 /**
131 * Allow Administrators
132 *
133 * @param boolean $bool Allow administrators.
134 * @return boolean True/false.
135 */
136 function allow_administrators( $bool ) {
137 if ( ! is_admin() && current_user_can( 'manage_options' ) && (bool) get_option( 'password_protected_administrators' ) )
138 return 0;
139 return $bool;
140 }
141
142 /**
143 * Allow Users
144 *
145 * @param boolean $bool Allow administrators.
146 * @return boolean True/false.
147 */
148 function allow_users( $bool ) {
149 if ( ! is_admin() && current_user_can( 'manage_options' ) && (bool) get_option( 'password_protected_users' ) )
150 return 0;
151 return $bool;
152 }
153
154 /**
155 * Encrypt Password
156 *
157 * @param string $password Password.
158 * @return string Encrypted password.
159 */
160 function encrypt_password( $password ) {
161 return md5( $password );
162 }
163
164 /**
165 * Maybe Process Login
166 */
167 function maybe_process_login() {
168 if ( $this->is_active() && isset( $_REQUEST['password_protected_pwd'] ) ) {
169 $password_protected_pwd = $_REQUEST['password_protected_pwd'];
170 $pwd = get_option( 'password_protected_password' );
171 // If correct password...
172 if ( ( $this->encrypt_password( $password_protected_pwd ) == $pwd && $pwd != '' ) || apply_filters( 'password_protected_process_login', false, $password_protected_pwd ) ) {
173 $this->set_auth_cookie();
174 if ( ! empty( $_REQUEST['redirect_to'] ) ) {
175 $this->safe_redirect( $_REQUEST['redirect_to'] );
176 exit;
177 }
178 } else {
179 // ... otherwise incorrect password
180 $this->clear_auth_cookie();
181 $this->errors->add( 'incorrect_password', __( 'Incorrect Password', 'password-protected' ) );
182 }
183 }
184
185 // Log out
186 if ( isset( $_REQUEST['password-protected'] ) && $_REQUEST['password-protected'] == 'logout' ) {
187 $this->logout();
188 if ( isset( $_REQUEST['redirect_to'] ) ) {
189 $redirect_to = esc_url_raw( $_REQUEST['redirect_to'], array( 'http', 'https' ) );
190 wp_redirect( $redirect_to );
191 exit();
192 }
193 $redirect_to = remove_query_arg( array( 'password-protected', 'redirect_to' ), ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
194 $query = array(
195 'password-protected' => 'login',
196 'redirect_to' => urlencode( $redirect_to )
197 );
198 wp_redirect( add_query_arg( $query, home_url() ) );
199 exit();
200 }
201 }
202
203 /**
204 * Maybe Show Login
205 */
206 function maybe_show_login() {
207 // Don't show login if not enabled
208 if ( ! $this->is_active() )
209 return;
210
211 // Logged in
212 if ( $this->validate_auth_cookie() )
213 return;
214
215 // Show login form
216 if ( isset( $_REQUEST['password-protected'] ) && 'login' == $_REQUEST['password-protected'] ) {
217 $default_theme_file = dirname( __FILE__ ) . '/theme/login.php';
218 $theme_file = apply_filters( 'password_protected_theme_file', $default_theme_file );
219 if ( ! file_exists( $theme_file ) ) {
220 $theme_file = $default_theme_file;
221 }
222 include( $theme_file );
223 exit();
224 } else {
225 $query = array(
226 'password-protected' => 'login',
227 'redirect_to' => urlencode( ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] )
228 );
229 wp_redirect( add_query_arg( $query, home_url() ) );
230 exit();
231 }
232 }
233
234 /**
235 * Get Site ID
236 *
237 * @return string Site ID.
238 */
239 function get_site_id() {
240 global $blog_id;
241 return 'bid_' . apply_filters( 'password_protected_blog_id', $blog_id );
242 }
243
244 /**
245 * Logout
246 */
247 function logout() {
248 $this->clear_auth_cookie();
249 do_action( 'password_protected_logout' );
250 }
251
252 /**
253 * Validate Auth Cookie
254 *
255 * @param string $cookie Cookie string.
256 * @param string $scheme Cookie scheme.
257 * @return boolean Validation successful?
258 */
259 function validate_auth_cookie( $cookie = '', $scheme = '' ) {
260 if ( ! $cookie_elements = $this->parse_auth_cookie( $cookie, $scheme ) ) {
261 do_action( 'password_protected_auth_cookie_malformed', $cookie, $scheme );
262 return false;
263 }
264 extract( $cookie_elements, EXTR_OVERWRITE );
265
266 $expired = $expiration;
267
268 // Allow a grace period for POST and AJAX requests
269 if ( defined( 'DOING_AJAX' ) || 'POST' == $_SERVER['REQUEST_METHOD'] )
270 $expired += 3600;
271
272 // Quick check to see if an honest cookie has expired
273 if ( $expired < time() ) {
274 do_action('password_protected_auth_cookie_expired', $cookie_elements);
275 return false;
276 }
277
278 $pass = md5( get_option( 'password_protected_password' ) );
279 $pass_frag = substr( $pass, 8, 4 );
280
281 $key = md5( $this->get_site_id() . $pass_frag . '|' . $expiration );
282 $hash = hash_hmac( 'md5', $this->get_site_id() . '|' . $expiration, $key);
283
284 if ( $hmac != $hash ) {
285 do_action( 'password_protected_auth_cookie_bad_hash', $cookie_elements );
286 return false;
287 }
288
289 if ( $expiration < time() ) // AJAX/POST grace period set above
290 $GLOBALS['login_grace_period'] = 1;
291
292 return true;
293 }
294
295 /**
296 * Generate Auth Cookie
297 *
298 * @param int $expiration Expiration time in seconds.
299 * @param string $scheme Cookie scheme.
300 * @return string Cookie.
301 */
302 function generate_auth_cookie( $expiration, $scheme = 'auth' ) {
303 $pass = md5( get_option( 'password_protected_password' ) );
304 $pass_frag = substr( $pass, 8, 4 );
305
306 $key = md5( $this->get_site_id() . $pass_frag . '|' . $expiration );
307 $hash = hash_hmac( 'md5', $this->get_site_id() . '|' . $expiration, $key );
308 $cookie = $this->get_site_id() . '|' . $expiration . '|' . $hash;
309
310 return $cookie;
311 }
312
313 /**
314 * Parse Auth Cookie
315 *
316 * @param string $cookie Cookie string.
317 * @param string $scheme Cookie scheme.
318 * @return string Cookie string.
319 */
320 function parse_auth_cookie( $cookie = '', $scheme = '' ) {
321 if ( empty( $cookie ) ) {
322 $cookie_name = $this->cookie_name();
323
324 if ( empty( $_COOKIE[$cookie_name] ) )
325 return false;
326 $cookie = $_COOKIE[$cookie_name];
327 }
328
329 $cookie_elements = explode( '|', $cookie );
330 if ( count( $cookie_elements ) != 3 )
331 return false;
332
333 list( $site_id, $expiration, $hmac ) = $cookie_elements;
334
335 return compact( 'site_id', 'expiration', 'hmac', 'scheme' );
336 }
337
338 /**
339 * Set Auth Cookie
340 *
341 * @todo
342 *
343 * @param boolean $remember Remember logged in.
344 * @param string $secure Secure cookie.
345 */
346 function set_auth_cookie( $remember = false, $secure = '') {
347 if ( $remember ) {
348 $expiration = $expire = time() + apply_filters( 'password_protected_auth_cookie_expiration', 1209600, $remember );
349 } else {
350 $expiration = time() + apply_filters( 'password_protected_auth_cookie_expiration', 172800, $remember );
351 $expire = 0;
352 }
353
354 if ( '' === $secure )
355 $secure = is_ssl();
356
357 $secure_password_protected_cookie = apply_filters( 'password_protected_secure_password_protected_cookie', false, $secure );
358 $password_protected_cookie = $this->generate_auth_cookie( $expiration, 'password_protected' );
359
360 setcookie( $this->cookie_name(), $password_protected_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure_password_protected_cookie, true );
361 if ( COOKIEPATH != SITECOOKIEPATH )
362 setcookie( $this->cookie_name(), $password_protected_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_password_protected_cookie, true );
363 }
364
365 /**
366 * Clear Auth Cookie
367 */
368 function clear_auth_cookie() {
369 setcookie( $this->cookie_name(), ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN );
370 setcookie( $this->cookie_name(), ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN );
371 }
372
373 /**
374 * Cookie Name
375 *
376 * @return string Cookie name.
377 */
378 function cookie_name() {
379 return $this->get_site_id() . '_password_protected_auth';
380 }
381
382 /**
383 * Install
384 */
385 function install() {
386 $old_version = get_option( 'password_protected_version' );
387
388 // 1.1 - Upgrade to MD5
389 if ( empty( $old_version ) || version_compare( '1.1', $old_version ) ) {
390 $pwd = get_option( 'password_protected_password' );
391 if ( ! empty( $pwd ) ) {
392 $new_pwd = $this->encrypt_password( $pwd );
393 update_option( 'password_protected_password', $new_pwd );
394 }
395 }
396
397 update_option( 'password_protected_version', $this->version );
398 }
399
400 /**
401 * Safe Redirect
402 *
403 * Ensure the redirect is to the same site or pluggable list of allowed domains.
404 * If invalid will redirect to ...
405 * Based on the WordPress wp_safe_redirect() function.
406 */
407 function safe_redirect( $location, $status = 302 ) {
408 $location = wp_sanitize_redirect( $location );
409 $location = wp_validate_redirect( $location, home_url() );
410 wp_redirect( $location, $status );
411 }
412
413 }
414