New secure cookie protocol. see #5367
git-svn-id: http://svn.automattic.com/wordpress/trunk@6387 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
3225503174
commit
29ef8b6f5f
|
@ -128,7 +128,7 @@ function update_recently_edited( $file ) {
|
|||
update_option( 'recently_edited', $oldfiles );
|
||||
}
|
||||
|
||||
// If siteurl or home changed, reset cookies and flush rewrite rules.
|
||||
// If siteurl or home changed, flush rewrite rules.
|
||||
function update_home_siteurl( $old_value, $value ) {
|
||||
global $wp_rewrite, $user_login, $user_pass_md5;
|
||||
|
||||
|
@ -137,10 +137,6 @@ function update_home_siteurl( $old_value, $value ) {
|
|||
|
||||
// If home changed, write rewrite rules to new location.
|
||||
$wp_rewrite->flush_rules();
|
||||
// Clear cookies for old paths.
|
||||
wp_clearcookie();
|
||||
// Set cookies for new paths.
|
||||
wp_setcookie( $user_login, $user_pass_md5, true, get_option( 'home' ), get_option( 'siteurl' ));
|
||||
}
|
||||
|
||||
add_action( 'update_option_home', 'update_home_siteurl', 10, 2 );
|
||||
|
|
|
@ -6,6 +6,7 @@ define('DB_PASSWORD', 'yourpasswordhere'); // ...and password
|
|||
define('DB_HOST', 'localhost'); // 99% chance you won't need to change this value
|
||||
define('DB_CHARSET', 'utf8');
|
||||
define('DB_COLLATE', '');
|
||||
define('SECRET_KEY', ''); // Change this to a unique phrase.
|
||||
|
||||
// You can have multiple installations in one database if you give each a unique prefix
|
||||
$table_prefix = 'wp_'; // Only numbers, letters, and underscores please!
|
||||
|
|
|
@ -147,6 +147,27 @@ if (!function_exists('stripos')) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists('hash_hmac') ):
|
||||
function hash_hmac($algo, $data, $key, $raw_output = false) {
|
||||
$packs = array('md5' => 'H32', 'sha1' => 'H40');
|
||||
|
||||
if ( !isset($packs[$algo]) )
|
||||
return false;
|
||||
|
||||
$pack = $packs[$algo];
|
||||
|
||||
if (strlen($key) > 64)
|
||||
$key = pack($pack, $algo($key));
|
||||
else if (strlen($key) < 64)
|
||||
$key = str_pad($key, 64, chr(0));
|
||||
|
||||
$ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64));
|
||||
$opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64));
|
||||
|
||||
return $algo($opad . pack($pack, $algo($ipad . $data)));
|
||||
}
|
||||
endif;
|
||||
|
||||
// Added in PHP 4.3.0?
|
||||
if (!defined('IMAGETYPE_GIF'))
|
||||
define('IMAGETYPE_GIF', 1);
|
||||
|
|
|
@ -46,14 +46,12 @@ function get_currentuserinfo() {
|
|||
if ( ! empty($current_user) )
|
||||
return;
|
||||
|
||||
if ( empty($_COOKIE[USER_COOKIE]) || empty($_COOKIE[PASS_COOKIE]) ||
|
||||
!wp_login($_COOKIE[USER_COOKIE], $_COOKIE[PASS_COOKIE], true) ) {
|
||||
if ( ! $user = wp_validate_auth_cookie() ) {
|
||||
wp_set_current_user(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
$user_login = $_COOKIE[USER_COOKIE];
|
||||
wp_set_current_user(0, $user_login);
|
||||
wp_set_current_user($user);
|
||||
}
|
||||
endif;
|
||||
|
||||
|
@ -293,7 +291,7 @@ function wp_mail( $to, $subject, $message, $headers = '' ) {
|
|||
endif;
|
||||
|
||||
if ( !function_exists('wp_login') ) :
|
||||
function wp_login($username, $password, $already_md5 = false) {
|
||||
function wp_login($username, $password, $deprecated = false) {
|
||||
global $wpdb, $error;
|
||||
|
||||
$username = sanitize_user($username);
|
||||
|
@ -313,10 +311,11 @@ function wp_login($username, $password, $already_md5 = false) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// If the password is already_md5, it has been double hashed.
|
||||
// Otherwise, it is plain text.
|
||||
if ( !$already_md5 ) {
|
||||
if ( wp_check_password($password, $login->user_pass) ) {
|
||||
if ( !wp_check_password($password, $login->user_pass) ) {
|
||||
$error = __('<strong>ERROR</strong>: Incorrect password.');
|
||||
return false;
|
||||
}
|
||||
|
||||
// If using old md5 password, rehash.
|
||||
if ( strlen($login->user_pass) <= 32 ) {
|
||||
$hash = wp_hash_password($password);
|
||||
|
@ -326,13 +325,73 @@ function wp_login($username, $password, $already_md5 = false) {
|
|||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ( md5($login->user_pass) == $password )
|
||||
return true;
|
||||
endif;
|
||||
|
||||
if ( !function_exists('wp_validate_auth_cookie') ) :
|
||||
function wp_validate_auth_cookie($cookie = '') {
|
||||
if ( empty($cookie) ) {
|
||||
if ( empty($_COOKIE[AUTH_COOKIE]) )
|
||||
return false;
|
||||
$cookie = $_COOKIE[AUTH_COOKIE];
|
||||
}
|
||||
|
||||
$error = __('<strong>ERROR</strong>: Incorrect password.');
|
||||
list($username, $expiration, $hmac) = explode('|', $cookie);
|
||||
|
||||
$expired = $expiration;
|
||||
|
||||
// Allow a grace period for POST requests
|
||||
if ( 'POST' == $_SERVER['REQUEST_METHOD'] )
|
||||
$expired += 3600;
|
||||
|
||||
if ( $expired < time() )
|
||||
return false;
|
||||
|
||||
$key = wp_hash($username . $expiration);
|
||||
$hash = hash_hmac('md5', $username . $expiration, $key);
|
||||
|
||||
if ( $hmac != $hash )
|
||||
return false;
|
||||
|
||||
$user = get_userdatabylogin($username);
|
||||
if ( ! $user )
|
||||
return false;
|
||||
|
||||
return $user->ID;
|
||||
}
|
||||
endif;
|
||||
|
||||
if ( !function_exists('wp_set_auth_cookie') ) :
|
||||
function wp_set_auth_cookie($user_id, $remember = false) {
|
||||
$user = get_userdata($user_id);
|
||||
|
||||
if ( $remember ) {
|
||||
$expiration = $expire = time() + 1209600;
|
||||
} else {
|
||||
$expiration = time() + 172800;
|
||||
$expire = 0;
|
||||
}
|
||||
|
||||
$key = wp_hash($user->user_login . $expiration);
|
||||
$hash = hash_hmac('md5', $user->user_login . $expiration, $key);
|
||||
|
||||
$cookie = $user->user_login . '|' . $expiration . '|' . $hash;
|
||||
|
||||
setcookie(AUTH_COOKIE, $cookie, $expire, COOKIEPATH, COOKIE_DOMAIN);
|
||||
if ( COOKIEPATH != SITECOOKIEPATH )
|
||||
setcookie(AUTH_COOKIE, $cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN);
|
||||
}
|
||||
endif;
|
||||
|
||||
if ( !function_exists('wp_clear_auth_cookie') ) :
|
||||
function wp_clear_auth_cookie() {
|
||||
setcookie(AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
|
||||
setcookie(AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
|
||||
|
||||
// Old cookies
|
||||
setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
|
||||
setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
|
||||
setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
|
||||
setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
|
||||
}
|
||||
endif;
|
||||
|
||||
|
@ -350,9 +409,9 @@ endif;
|
|||
if ( !function_exists('auth_redirect') ) :
|
||||
function auth_redirect() {
|
||||
// Checks if a user is logged in, if not redirects them to the login page
|
||||
if ( (!empty($_COOKIE[USER_COOKIE]) &&
|
||||
!wp_login($_COOKIE[USER_COOKIE], $_COOKIE[PASS_COOKIE], true)) ||
|
||||
(empty($_COOKIE[USER_COOKIE])) ) {
|
||||
if ( (!empty($_COOKIE[AUTH_COOKIE]) &&
|
||||
!wp_validate_auth_cookie($_COOKIE[AUTH_COOKIE])) ||
|
||||
(empty($_COOKIE[AUTH_COOKIE])) ) {
|
||||
nocache_headers();
|
||||
|
||||
wp_redirect(get_option('siteurl') . '/wp-login.php?redirect_to=' . urlencode($_SERVER['REQUEST_URI']));
|
||||
|
@ -379,19 +438,18 @@ function check_ajax_referer( $action = -1 ) {
|
|||
if ( !wp_verify_nonce( $nonce, $action ) ) {
|
||||
$current_name = '';
|
||||
if ( ( $current = wp_get_current_user() ) && $current->ID )
|
||||
$current_name = $current->data->user_login;
|
||||
$current_name = $current->user_login;
|
||||
if ( !$current_name )
|
||||
die('-1');
|
||||
|
||||
$auth_cookie = '';
|
||||
$cookie = explode('; ', urldecode(empty($_POST['cookie']) ? $_GET['cookie'] : $_POST['cookie'])); // AJAX scripts must pass cookie=document.cookie
|
||||
foreach ( $cookie as $tasty ) {
|
||||
if ( false !== strpos($tasty, USER_COOKIE) )
|
||||
$user = substr(strstr($tasty, '='), 1);
|
||||
if ( false !== strpos($tasty, PASS_COOKIE) )
|
||||
$pass = substr(strstr($tasty, '='), 1);
|
||||
if ( false !== strpos($tasty, AUTH_COOKIE) )
|
||||
$auth_cookie = substr(strstr($tasty, '='), 1);
|
||||
}
|
||||
|
||||
if ( $current_name != $user || !wp_login( $user, $pass, true ) )
|
||||
if ( $current_name != $user || empty($auth_cookie) || !wp_validate_auth_cookie( $auth_cookie ) )
|
||||
die('-1');
|
||||
}
|
||||
do_action('check_ajax_referer');
|
||||
|
@ -472,60 +530,6 @@ function wp_safe_redirect($location, $status = 302) {
|
|||
}
|
||||
endif;
|
||||
|
||||
if ( !function_exists('wp_get_cookie_login') ):
|
||||
function wp_get_cookie_login() {
|
||||
if ( empty($_COOKIE[USER_COOKIE]) || empty($_COOKIE[PASS_COOKIE]) )
|
||||
return false;
|
||||
|
||||
return array('login' => $_COOKIE[USER_COOKIE], 'password' => $_COOKIE[PASS_COOKIE]);
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
if ( !function_exists('wp_setcookie') ) :
|
||||
function wp_setcookie($username, $password, $already_md5 = false, $home = '', $siteurl = '', $remember = false) {
|
||||
$user = get_userdatabylogin($username);
|
||||
if ( !$already_md5) {
|
||||
$password = md5($user->user_pass); // Double hash the password in the cookie.
|
||||
}
|
||||
|
||||
if ( empty($home) )
|
||||
$cookiepath = COOKIEPATH;
|
||||
else
|
||||
$cookiepath = preg_replace('|https?://[^/]+|i', '', $home . '/' );
|
||||
|
||||
if ( empty($siteurl) ) {
|
||||
$sitecookiepath = SITECOOKIEPATH;
|
||||
$cookiehash = COOKIEHASH;
|
||||
} else {
|
||||
$sitecookiepath = preg_replace('|https?://[^/]+|i', '', $siteurl . '/' );
|
||||
$cookiehash = md5($siteurl);
|
||||
}
|
||||
|
||||
if ( $remember )
|
||||
$expire = time() + 31536000;
|
||||
else
|
||||
$expire = 0;
|
||||
|
||||
setcookie(USER_COOKIE, $username, $expire, $cookiepath, COOKIE_DOMAIN);
|
||||
setcookie(PASS_COOKIE, $password, $expire, $cookiepath, COOKIE_DOMAIN);
|
||||
|
||||
if ( $cookiepath != $sitecookiepath ) {
|
||||
setcookie(USER_COOKIE, $username, $expire, $sitecookiepath, COOKIE_DOMAIN);
|
||||
setcookie(PASS_COOKIE, $password, $expire, $sitecookiepath, COOKIE_DOMAIN);
|
||||
}
|
||||
}
|
||||
endif;
|
||||
|
||||
if ( !function_exists('wp_clearcookie') ) :
|
||||
function wp_clearcookie() {
|
||||
setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
|
||||
setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
|
||||
setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
|
||||
setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
|
||||
}
|
||||
endif;
|
||||
|
||||
if ( ! function_exists('wp_notify_postauthor') ) :
|
||||
function wp_notify_postauthor($comment_id, $comment_type='') {
|
||||
$comment = get_comment($comment_id);
|
||||
|
@ -692,10 +696,17 @@ endif;
|
|||
if ( !function_exists('wp_salt') ) :
|
||||
function wp_salt() {
|
||||
$salt = get_option('secret');
|
||||
if ( empty($salt) )
|
||||
$salt = DB_PASSWORD . DB_USER . DB_NAME . DB_HOST . ABSPATH;
|
||||
if ( empty($salt) ) {
|
||||
$salt = wp_generate_password();
|
||||
update_option('secret', $salt);
|
||||
}
|
||||
|
||||
return $salt;
|
||||
if ( !defined('SECRET_KEY') || '' == SECRET_KEY )
|
||||
$secret_key = DB_PASSWORD . DB_USER . DB_NAME . DB_HOST . ABSPATH;
|
||||
else
|
||||
$secret_key = SECRET_KEY;
|
||||
|
||||
return $salt . $secret_key;
|
||||
}
|
||||
endif;
|
||||
|
||||
|
@ -758,4 +769,27 @@ function wp_generate_password() {
|
|||
return $password;
|
||||
}
|
||||
endif;
|
||||
|
||||
// Deprecated. Use wp_set_auth_cookie()
|
||||
if ( !function_exists('wp_setcookie') ) :
|
||||
function wp_setcookie($username, $password = '', $already_md5 = false, $home = '', $siteurl = '', $remember = false) {
|
||||
$user = get_userdatabylogin($username);
|
||||
wp_set_auth_cookie($user->ID, $remember);
|
||||
}
|
||||
endif;
|
||||
|
||||
// Deprecated. Use wp_clear_auth_cookie()
|
||||
if ( !function_exists('wp_clearcookie') ) :
|
||||
function wp_clearcookie() {
|
||||
wp_clear_auth_cookie();
|
||||
}
|
||||
endif;
|
||||
|
||||
// Deprecated. No alternative.
|
||||
if ( !function_exists('wp_get_cookie_login') ):
|
||||
function wp_get_cookie_login() {
|
||||
return false;
|
||||
}
|
||||
endif;
|
||||
|
||||
?>
|
||||
|
|
|
@ -167,8 +167,8 @@ function wp_update_user($userdata) {
|
|||
$current_user = wp_get_current_user();
|
||||
if ( $current_user->id == $ID ) {
|
||||
if ( isset($plaintext_pass) ) {
|
||||
wp_clearcookie();
|
||||
wp_setcookie($userdata['user_login'], $plaintext_pass);
|
||||
wp_clear_auth_cookie();
|
||||
wp_set_auth_cookie($ID);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
37
wp-login.php
37
wp-login.php
|
@ -288,7 +288,6 @@ case 'login' :
|
|||
default:
|
||||
$user_login = '';
|
||||
$user_pass = '';
|
||||
$using_cookie = FALSE;
|
||||
|
||||
if ( !isset( $_REQUEST['redirect_to'] ) || is_user_logged_in() )
|
||||
$redirect_to = 'wp-admin/';
|
||||
|
@ -296,24 +295,30 @@ default:
|
|||
$redirect_to = $_REQUEST['redirect_to'];
|
||||
|
||||
if ( $http_post ) {
|
||||
// If cookies are disabled we can't log in even with a valid user+pass
|
||||
if ( empty($_COOKIE[TEST_COOKIE]) )
|
||||
$errors['test_cookie'] = __('<strong>ERROR</strong>: WordPress requires Cookies but your browser does not support them or they are blocked.');
|
||||
|
||||
$user_login = $_POST['log'];
|
||||
$user_login = sanitize_user( $user_login );
|
||||
$user_pass = $_POST['pwd'];
|
||||
$rememberme = $_POST['rememberme'];
|
||||
} else {
|
||||
$cookie_login = wp_get_cookie_login();
|
||||
if ( ! empty($cookie_login) ) {
|
||||
$using_cookie = true;
|
||||
$user_login = $cookie_login['login'];
|
||||
$user_pass = $cookie_login['password'];
|
||||
}
|
||||
}
|
||||
|
||||
do_action_ref_array('wp_authenticate', array(&$user_login, &$user_pass));
|
||||
} else {
|
||||
$user = wp_validate_auth_cookie();
|
||||
if ( !$user ) {
|
||||
$errors['expiredsession'] = __('Your session has expired.');
|
||||
} else {
|
||||
$user = new WP_User($user);
|
||||
|
||||
// If cookies are disabled we can't log in even with a valid user+pass
|
||||
if ( $http_post && empty($_COOKIE[TEST_COOKIE]) )
|
||||
$errors['test_cookie'] = __('<strong>ERROR</strong>: WordPress requires Cookies but your browser does not support them or they are blocked.');
|
||||
// If the user can't edit posts, send them to their profile.
|
||||
if ( !$user->has_cap('edit_posts') && ( empty( $redirect_to ) || $redirect_to == 'wp-admin/' ) )
|
||||
$redirect_to = get_option('siteurl') . '/wp-admin/profile.php';
|
||||
wp_safe_redirect($redirect_to);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
if ( $user_login && $user_pass && empty( $errors ) ) {
|
||||
$user = new WP_User(0, $user_login);
|
||||
|
@ -322,15 +327,11 @@ default:
|
|||
if ( !$user->has_cap('edit_posts') && ( empty( $redirect_to ) || $redirect_to == 'wp-admin/' ) )
|
||||
$redirect_to = get_option('siteurl') . '/wp-admin/profile.php';
|
||||
|
||||
if ( wp_login($user_login, $user_pass, $using_cookie) ) {
|
||||
if ( !$using_cookie )
|
||||
wp_setcookie($user_login, $user_pass, false, '', '', $rememberme);
|
||||
if ( wp_login($user_login, $user_pass) ) {
|
||||
wp_set_auth_cookie($user->ID, $rememberme);
|
||||
do_action('wp_login', $user_login);
|
||||
wp_safe_redirect($redirect_to);
|
||||
exit();
|
||||
} else {
|
||||
if ( $using_cookie )
|
||||
$errors['expiredsession'] = __('Your session has expired.');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -189,6 +189,8 @@ if ( !defined('USER_COOKIE') )
|
|||
define('USER_COOKIE', 'wordpressuser_' . COOKIEHASH);
|
||||
if ( !defined('PASS_COOKIE') )
|
||||
define('PASS_COOKIE', 'wordpresspass_' . COOKIEHASH);
|
||||
if ( !defined('AUTH_COOKIE') )
|
||||
define('AUTH_COOKIE', 'wordpress_' . COOKIEHASH);
|
||||
if ( !defined('TEST_COOKIE') )
|
||||
define('TEST_COOKIE', 'wordpress_test_cookie');
|
||||
if ( !defined('COOKIEPATH') )
|
||||
|
|
Loading…
Reference in New Issue