Ticket #20276: 20276.backpress.2.diff
File 20276.backpress.2.diff, 6.1 KB (added by , 11 years ago) |
---|
-
includes/class.wp-auth.php
148 148 */ 149 149 function validate_auth_cookie( $cookie = null, $scheme = 'auth' ) 150 150 { 151 if ( empty( $cookie ) ) { 152 foreach ( $this->cookies[$scheme] as $_scheme_cookie ) { 153 // Take the first cookie of type scheme that exists 154 if ( !empty( $_COOKIE[$_scheme_cookie['name']] ) ) { 155 $cookie = $_COOKIE[$_scheme_cookie['name']]; 156 break; 157 } 158 } 159 } 160 161 if ( !$cookie ) { 151 if ( ! $cookie_elements = $this->parse_auth_cookie( $cookie, $scheme ) ) { 152 do_action( 'auth_cookie_malformed', $cookie ); 162 153 return false; 163 154 } 155 extract( $cookie_elements ); 164 156 165 $cookie_elements = explode( '|', $cookie );166 if ( count( $cookie_elements ) != 3 ) {167 do_action( 'auth_cookie_malformed', $cookie, $scheme );168 return false;169 }170 171 list( $username, $expiration, $hmac ) = $cookie_elements;172 173 157 $expired = $expiration; 174 158 175 159 // Allow a grace period for POST and AJAX requests … … 193 177 $pass_frag = substr( $user->user_pass, 8, 4 ); 194 178 } 195 179 196 $key = call_user_func( backpress_get_option( 'hash_function_name' ), $username . $pass_frag . '|' . $expiration, $scheme );197 $hash = hash_hmac( 'md5', $username . '|' . $expiration , $key );180 $key = call_user_func( backpress_get_option( 'hash_function_name' ), $username . '|' . $pass_frag . '|' . $expiration . '|' . $token, $scheme ); 181 $hash = hash_hmac( 'md5', $username . '|' . $expiration . '|' . $token, $key ); 198 182 199 183 if ( $hmac != $hash ) { 200 184 do_action( 'auth_cookie_bad_hash', $cookie_elements ); … … 201 185 return false; 202 186 } 203 187 188 if ( ! $this->verify_session_token( $user, $token ) ) { 189 do_action( 'auth_cookie_bad_session_token', $cookie_elements ); 190 return false; 191 } 192 204 193 do_action( 'auth_cookie_valid', $cookie_elements, $user ); 205 194 206 195 return $user->ID; … … 215 204 * 216 205 * @param int $user_id User ID 217 206 * @param int $expiration Cookie expiration in seconds 207 * @param string $scheme The cookie scheme to use: auth, secure_auth, or logged_in 208 * @param string $token User's session token to use for this cookie 218 209 * @return string Authentication cookie contents 219 210 */ 220 function generate_auth_cookie( $user_id, $expiration, $scheme = 'auth' )211 function generate_auth_cookie( $user_id, $expiration, $scheme = 'auth', $token = '' ) 221 212 { 222 213 $user = $this->users->get_user( $user_id ); 223 214 if ( !$user || is_wp_error( $user ) ) { … … 224 215 return $user; 225 216 } 226 217 218 if ( empty( $token ) ) 219 $token = $this->create_session_token( $user, $expiration ); 220 227 221 $pass_frag = ''; 228 222 if ( 1 < WP_AUTH_COOKIE_VERSION ) { 229 223 $pass_frag = substr( $user->user_pass, 8, 4 ); 230 224 } 231 225 232 $key = call_user_func( backpress_get_option( 'hash_function_name' ), $user->user_login . $pass_frag . '|' . $expiration, $scheme );233 $hash = hash_hmac('md5', $user->user_login . '|' . $expiration , $key);226 $key = call_user_func( backpress_get_option( 'hash_function_name' ), $user->user_login . '|' . $pass_frag . '|' . $expiration . '|' . $token, $scheme ); 227 $hash = hash_hmac('md5', $user->user_login . '|' . $expiration . '|' . $token, $key); 234 228 235 $cookie = $user->user_login . '|' . $expiration . '|' . $ hash;229 $cookie = $user->user_login . '|' . $expiration . '|' . $token . '|' . $hash; 236 230 237 231 return apply_filters( 'auth_cookie', $cookie, $user_id, $expiration, $scheme ); 238 232 } … … 264 258 265 259 $expire = absint( $expire ); 266 260 261 $token = $this->create_session_token( $user_id, $expiration ); 262 267 263 foreach ( $this->cookies[$scheme] as $_cookie ) { 268 $cookie = $this->generate_auth_cookie( $user_id, $expiration, $scheme );264 $cookie = $this->generate_auth_cookie( $user_id, $expiration, $scheme, $token ); 269 265 if ( is_wp_error( $cookie ) ) { 270 266 return $cookie; 271 267 } … … 302 298 } 303 299 unset( $_scheme, $_scheme_cookies ); 304 300 } 301 302 function create_session_token( $user, $expiration ) { 303 if ( ! is_object( $user ) ) 304 $user = $this->users->get_user( $user ); 305 306 $sessions = ! empty( $user->session_tokens ) ? $user->session_tokens : array(); 307 308 $time = time(); 309 foreach ( $sessions as $v => $e ) { 310 if ( $e < $time ) 311 unset( $sessions[ $v ] ); 312 } 313 314 $token = WP_Pass::generate_password( 40, false ); 315 $verifier = hash( 'sha256', $token ); 316 $sessions[ $verifier ] = $expiration; 317 318 $GLOBALS['wp_users_object']->update_meta( array( 'id' => $user->ID, 'meta_key' => 'session_tokens', 'meta_value' => $sessions ) ); 319 320 return $token; 321 } 322 323 function verify_session_token( $user, $token ) { 324 // Cached user may not have appropriate meta set 325 if ( ! isset( $user->session_tokens ) ) 326 $user = $GLOBALS['wp_users_object']->append_meta( $user ); 327 $verifier = hash( 'sha256', $token ); 328 return isset( $user->session_tokens[ $verifier ] ) && $user->session_tokens[ $verifier ] >= time(); 329 } 330 331 function destroy_current_session() { 332 $cookie = $this->parse_auth_cookie( '', 'logged_in' ); 333 if ( ! empty( $cookie['token'] ) ) { 334 $user = $this->get_current_user(); 335 $verifier = hash( 'sha256', $cookie['token'] ); 336 $sessions = ! empty( $user->session_tokens ) ? $user->session_tokens : array(); 337 unset( $sessions[ $verifier ] ); 338 339 $time = time(); 340 foreach ( $sessions as $v => $e ) { 341 if ( $e < $time ) 342 unset( $sessions[ $v ] ); 343 } 344 345 $GLOBALS['wp_users_object']->update_meta( array( 'id' => $user->ID, 'meta_key' => 'session_tokens', 'meta_value' => $sessions ) ); 346 } 347 } 348 349 function parse_auth_cookie( $cookie = '', $scheme = 'auth' ) { 350 if ( empty( $cookie ) ) { 351 foreach ( $this->cookies[$scheme] as $_scheme_cookie ) { 352 // Take the first cookie of type scheme that exists 353 if ( !empty( $_COOKIE[$_scheme_cookie['name']] ) ) { 354 $cookie = $_COOKIE[$_scheme_cookie['name']]; 355 break; 356 } 357 } 358 } 359 360 if ( ! $cookie ) 361 return false; 362 363 $cookie_elements = explode( '|', $cookie ); 364 if ( count( $cookie_elements ) != 4 ) 365 return false; 366 367 list( $username, $expiration, $token, $hmac ) = $cookie_elements; 368 return compact( 'username', 'expiration', 'token', 'hmac' ); 369 } 305 370 }