Ticket #20276: 20276.3.diff
File 20276.3.diff, 7.6 KB (added by , 11 years ago) |
---|
-
src/wp-includes/pluggable.php
494 494 * @since 2.5.0 495 495 */ 496 496 function wp_logout() { 497 wp_destroy_current_session(); 497 498 wp_clear_auth_cookie(); 498 499 do_action('wp_logout'); 499 500 } … … 543 544 544 545 $pass_frag = substr($user->user_pass, 8, 4); 545 546 546 $key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme);547 $hash = hash_hmac('md5', $username . '|' . $expiration , $key);547 $key = wp_hash($username . '|' . $pass_frag . '|' . $expiration . '|' . $token, $scheme); 548 $hash = hash_hmac('md5', $username . '|' . $expiration . '|' . $token, $key); 548 549 549 550 if ( $hmac != $hash ) { 550 551 do_action('auth_cookie_bad_hash', $cookie_elements); … … 551 552 return false; 552 553 } 553 554 555 if ( ! wp_verify_session_token( $user->ID, $token ) ) { 556 do_action( 'auth_cookie_bad_session_token', $cookie_elements ); 557 return false; 558 } 559 554 560 if ( $expiration < time() ) // AJAX/POST grace period set above 555 561 $GLOBALS['login_grace_period'] = 1; 556 562 … … 571 577 * @param int $user_id User ID 572 578 * @param int $expiration Cookie expiration in seconds 573 579 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in 580 * @param string $token User's session token to use for this cookie 574 581 * @return string Authentication cookie contents 575 582 */ 576 function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth') { 577 $user = get_userdata($user_id); 583 function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth', $token = '') { 584 $user = new WP_User($user_id); 585 if ( ! $user->exists() ) 586 return ''; 578 587 588 if (empty($token)) 589 $token = wp_create_session_token( $user_id, $expiration ); 590 579 591 $pass_frag = substr($user->user_pass, 8, 4); 580 592 581 $key = wp_hash($user->user_login . $pass_frag . '|' . $expiration, $scheme);582 $hash = hash_hmac('md5', $user->user_login . '|' . $expiration , $key);593 $key = wp_hash($user->user_login . '|' . $pass_frag . '|' . $expiration . '|' . $token, $scheme); 594 $hash = hash_hmac('md5', $user->user_login . '|' . $expiration . '|' . $token, $key); 583 595 584 $cookie = $user->user_login . '|' . $expiration . '|' . $ hash;596 $cookie = $user->user_login . '|' . $expiration . '|' . $token . '|' . $hash; 585 597 586 598 return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme); 587 599 } … … 625 637 } 626 638 627 639 $cookie_elements = explode('|', $cookie); 628 if ( count($cookie_elements) != 3)640 if ( count($cookie_elements) != 4 ) 629 641 return false; 630 642 631 list($username, $expiration, $ hmac) = $cookie_elements;643 list($username, $expiration, $token, $hmac) = $cookie_elements; 632 644 633 return compact('username', 'expiration', ' hmac', 'scheme');645 return compact('username', 'expiration', 'token', 'hmac', 'scheme'); 634 646 } 635 647 endif; 636 648 … … 646 658 * 647 659 * @param int $user_id User ID 648 660 * @param bool $remember Whether to remember the user 661 * @param mixed $secure Whether the admin cookies should only be sent over HTTPS (defaults to is_ssl()) 649 662 */ 650 663 function wp_set_auth_cookie($user_id, $remember = false, $secure = '') { 651 664 if ( $remember ) { … … 669 682 $scheme = 'auth'; 670 683 } 671 684 672 $auth_cookie = wp_generate_auth_cookie($user_id, $expiration, $scheme); 673 $logged_in_cookie = wp_generate_auth_cookie($user_id, $expiration, 'logged_in'); 685 $token = wp_create_session_token( $user_id, $expiration ); 674 686 687 $auth_cookie = wp_generate_auth_cookie( $user_id, $expiration, $scheme, $token ); 688 $logged_in_cookie = wp_generate_auth_cookie( $user_id, $expiration, 'logged_in', $token ); 689 675 690 do_action('set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme); 676 691 do_action('set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in'); 677 692 … … 1258 1273 $uid = (int) $user->ID; 1259 1274 if ( ! $uid ) 1260 1275 $uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); 1261 1276 $token = wp_get_session_token(); 1262 1277 $i = wp_nonce_tick(); 1263 1278 1264 1279 // Nonce generated 0-12 hours ago 1265 if ( substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10) === $nonce )1280 if ( substr(wp_hash($i . '|' . $action . '|' . $uid . '|' . $token, 'nonce'), -12, 10) === $nonce ) 1266 1281 return 1; 1267 1282 // Nonce generated 12-24 hours ago 1268 if ( substr(wp_hash(($i - 1) . $action . $uid, 'nonce'), -12, 10) === $nonce )1283 if ( substr(wp_hash(($i - 1) . '|' . $action . '|' . $uid . '|' . $token, 'nonce'), -12, 10) === $nonce ) 1269 1284 return 2; 1270 1285 // Invalid nonce 1271 1286 return false; … … 1286 1301 $uid = (int) $user->ID; 1287 1302 if ( ! $uid ) 1288 1303 $uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); 1289 1304 $token = wp_get_session_token(); 1290 1305 $i = wp_nonce_tick(); 1291 1306 1292 return substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10);1307 return substr(wp_hash($i . '|' . $action . '|' . $uid . '|' . $token, 'nonce'), -12, 10); 1293 1308 } 1294 1309 endif; 1295 1310 -
src/wp-includes/user.php
1550 1550 } 1551 1551 return apply_filters( 'user_contactmethods', $user_contactmethods, $user ); 1552 1552 } 1553 1554 /** 1555 * Generate a cookie session identification token. 1556 * 1557 * A session identification token is a long, random string. It is used to 1558 * link a cookie to an expiration time and to ensure that cookies become 1559 * invalidated upon logout. This function generates a token and stores it 1560 * as user meta with the associated expiration time. 1561 * 1562 * Will also remove any expired tokens from the database. 1563 * 1564 * @since 3.7.0 1565 * 1566 * @param int $user_id User to create a token for. 1567 * @param int $expiration Session expiration timestamp. 1568 * @return string Session identification token. 1569 */ 1570 function wp_create_session_token( $user_id, $expiration ) { 1571 $sessions = get_user_meta( $user_id, 'session_tokens', true ); 1572 if ( ! $sessions ) 1573 $sessions = array(); 1574 // Expire old sessions 1575 $time = time(); 1576 foreach ( $sessions as $v => $e ) { 1577 if ( $e < $time ) 1578 unset( $sessions[ $v ] ); 1579 } 1580 1581 $token = wp_generate_password( 40, false, false ); 1582 $verifier = hash( 'sha256', $token ); 1583 $sessions[$verifier] = $expiration; 1584 1585 update_user_meta( $user_id, 'session_tokens', $sessions ); 1586 1587 return $token; 1588 } 1589 1590 /** 1591 * Validate a user's session token as authentic. 1592 * 1593 * Checks that the given token is present in the database and hasn't expired. 1594 * 1595 * @since 3.7.0 1596 * 1597 * @param int $user_id User to verify against. 1598 * @param string $token Token to verify. 1599 * @return bool Whether the token is valid for the given user. 1600 */ 1601 function wp_verify_session_token( $user_id, $token ) { 1602 $sessions = get_user_meta( $user_id, 'session_tokens', true ); 1603 $verifier = hash( 'sha256', $token ); 1604 return isset( $sessions[$verifier] ) && $sessions[$verifier] >= time(); 1605 } 1606 1607 /** 1608 * Remove the current session token from the database. 1609 * 1610 * Will also remove any expired tokens from the database. 1611 * 1612 * @since 3.7.0 1613 */ 1614 function wp_destroy_current_session() { 1615 $token = wp_get_session_token(); 1616 if ( ! empty( $token ) ) { 1617 $user_id = get_current_user_id(); 1618 $verifier = hash( 'sha256', $token ); 1619 $sessions = get_user_meta( $user_id, 'session_tokens', true ); 1620 unset( $sessions[$verifier] ); 1621 1622 // Expire old sessions 1623 $time = time(); 1624 foreach ( $sessions as $v => $e ) { 1625 if ( $e < $time ) 1626 unset( $sessions[ $v ] ); 1627 } 1628 1629 update_user_meta( $user_id, 'session_tokens', $sessions ); 1630 } 1631 } 1632 1633 /** 1634 * Retrieve the current session token from the logged_in cookie. 1635 * 1636 * @since 3.7.0 1637 * 1638 * @return string 1639 */ 1640 function wp_get_session_token() { 1641 $cookie = wp_parse_auth_cookie( '', 'logged_in' ); 1642 return ! empty( $cookie['token'] ) ? $cookie['token'] : ''; 1643 }