Ticket #20276: 20276.diff
File 20276.diff, 6.2 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 return false; 557 } 558 554 559 if ( $expiration < time() ) // AJAX/POST grace period set above 555 560 $GLOBALS['login_grace_period'] = 1; 556 561 … … 569 574 * and expiration of cookie. 570 575 * 571 576 * @param int $user_id User ID 577 * @param string $token User's session token to use for this cookie 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 574 580 * @return string Authentication cookie contents 575 581 */ 576 function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth') { 577 $user = get_userdata($user_id); 582 function wp_generate_auth_cookie($user_id, $token, $expiration, $scheme = 'auth') { 583 $user = new WP_User($user_id); 584 if ( ! $user->exists() ) 585 return ''; 578 586 579 587 $pass_frag = substr($user->user_pass, 8, 4); 580 588 581 $key = wp_hash($user->user_login . $pass_frag . '|' . $expiration, $scheme);582 $hash = hash_hmac('md5', $user->user_login . '|' . $expiration , $key);589 $key = wp_hash($user->user_login . '|' . $pass_frag . '|' . $expiration . '|' . $token, $scheme); 590 $hash = hash_hmac('md5', $user->user_login . '|' . $expiration . '|' . $token, $key); 583 591 584 $cookie = $user->user_login . '|' . $expiration . '|' . $ hash;592 $cookie = $user->user_login . '|' . $expiration . '|' . $token . '|' . $hash; 585 593 586 594 return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme); 587 595 } … … 625 633 } 626 634 627 635 $cookie_elements = explode('|', $cookie); 628 if ( count($cookie_elements) != 3)636 if ( count($cookie_elements) != 4 ) 629 637 return false; 630 638 631 list($username, $expiration, $ hmac) = $cookie_elements;639 list($username, $expiration, $token, $hmac) = $cookie_elements; 632 640 633 return compact('username', 'expiration', ' hmac', 'scheme');641 return compact('username', 'expiration', 'token', 'hmac', 'scheme'); 634 642 } 635 643 endif; 636 644 … … 646 654 * 647 655 * @param int $user_id User ID 648 656 * @param bool $remember Whether to remember the user 657 * @param mixed $secure Whether the admin cookies should only be sent over HTTPS (defaults to is_ssl()) 649 658 */ 650 659 function wp_set_auth_cookie($user_id, $remember = false, $secure = '') { 651 660 if ( $remember ) { … … 669 678 $scheme = 'auth'; 670 679 } 671 680 672 $auth_cookie = wp_generate_auth_cookie($user_id, $expiration, $scheme); 673 $logged_in_cookie = wp_generate_auth_cookie($user_id, $expiration, 'logged_in'); 681 $token = wp_create_session_token( $user_id, $expiration ); 674 682 683 $auth_cookie = wp_generate_auth_cookie($user_id, $token, $expiration, $scheme); 684 $logged_in_cookie = wp_generate_auth_cookie($user_id, $token, $expiration, 'logged_in'); 685 675 686 do_action('set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme); 676 687 do_action('set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in'); 677 688 -
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 $sessions = array_filter( $sessions, '_session_not_expired' ); 1575 1576 $token = wp_generate_password( 40, false, false ); 1577 $verifier = hash( 'sha256', $token ); 1578 $sessions[$verifier] = $expiration; 1579 1580 update_user_meta( $user_id, 'session_tokens', $sessions ); 1581 1582 return $token; 1583 } 1584 1585 /** 1586 * Validate a user's session token as authentic. 1587 * 1588 * Checks that the given token is present in the database and hasn't expired. 1589 * 1590 * @since 3.7.0 1591 * 1592 * @param int $user_id User to verify against. 1593 * @param string $token Token to verify. 1594 * @return bool Whether the token is valid for the given user. 1595 */ 1596 function wp_verify_session_token( $user_id, $token ) { 1597 $sessions = get_user_meta( $user_id, 'session_tokens', true ); 1598 $verifier = hash( 'sha256', $token ); 1599 return isset( $sessions[$verifier] ) && $sessions[$verifier] >= time(); 1600 } 1601 1602 /** 1603 * Remove the current session token from the database. 1604 * 1605 * Will also remove any expired tokens from the database. 1606 * 1607 * @since 3.7.0 1608 */ 1609 function wp_destroy_current_session() { 1610 $user_id = get_current_user_id(); 1611 $cookie = wp_parse_auth_cookie( '', 'logged_in' ); 1612 if ( ! empty( $cookie['token'] ) ) { 1613 $verifier = hash( 'sha256', $cookie['token'] ); 1614 $sessions = get_user_meta( $user_id, 'session_tokens', true ); 1615 unset( $sessions[$verifier] ); 1616 $sessions = array_filter( $sessions, '_session_not_expired' ); 1617 update_user_meta( $user_id, 'session_tokens', $sessions ); 1618 } 1619 } 1620 1621 /** 1622 * @access private 1623 * @since 3.7.0 1624 * @param int $expiry 1625 */ 1626 function _session_not_expired( $expiry ) { 1627 return $expiry >= time(); 1628 }