diff --git includes/session.inc includes/session.inc index d86d72e..5e57472 100644 --- includes/session.inc +++ includes/session.inc @@ -168,11 +168,11 @@ function _drupal_session_write($sid, $value) { $last_read = &drupal_static('drupal_session_last_read'); $is_changed = !isset($last_read) || $last_read['sid'] != $sid || $last_read['value'] !== $value; // For performance reasons, do not update the sessions table, unless // $_SESSION has changed or more than 180 has passed since the last update. - if ($is_changed || REQUEST_TIME - $user->timestamp > variable_get('session_write_interval', 180)) { + if ($is_changed || !isset($user->timestamp) || REQUEST_TIME - $user->timestamp > variable_get('session_write_interval', 180)) { // Either ssid or sid or both will be added from $key below. $fields = array( 'uid' => $user->uid, 'cache' => isset($user->cache) ? $user->cache : 0, 'hostname' => ip_address(), @@ -195,10 +195,13 @@ function _drupal_session_write($sid, $value) { if (isset($_COOKIE[$insecure_session_name])) { $key['sid'] = $_COOKIE[$insecure_session_name]; } } } + elseif (variable_get('https', FALSE)) { + unset($key['ssid']); + } db_merge('sessions') ->key($key) ->fields($fields) ->execute(); @@ -251,15 +254,21 @@ function drupal_session_initialize() { else { // Set a session identifier for this request. This is necessary because // we lazily start sessions at the end of this request, and some // processes (like drupal_get_token()) needs to know the future // session ID in advance. + $GLOBALS['lazy_session'] = TRUE; $user = drupal_anonymous_user(); // Less random sessions (which are much faster to generate) are used for // anonymous users than are generated in drupal_session_regenerate() when // a user becomes authenticated. session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE))); + if ($is_https && variable_get('https', FALSE)) { + $insecure_session_name = substr(session_name(), 1); + $session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE)); + $_COOKIE[$insecure_session_name] = $session_id; + } } date_default_timezone_set(drupal_get_user_timezone()); } /** @@ -287,11 +296,11 @@ function drupal_session_start() { * Commits the current session, if necessary. * * If an anonymous user already have an empty session, destroy it. */ function drupal_session_commit() { - global $user; + global $user, $is_https; if (!drupal_save_session()) { // We don't have anything to do if we are not allowed to save the session. return; } @@ -306,10 +315,16 @@ function drupal_session_commit() { else { // There is session data to store. Start the session if it is not already // started. if (!drupal_session_started()) { drupal_session_start(); + if ($is_https && variable_get('https', FALSE)) { + $insecure_session_name = substr(session_name(), 1); + $params = session_get_cookie_params(); + $expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0; + setcookie($insecure_session_name, $_COOKIE[$insecure_session_name], $expire, $params['path'], $params['domain'], FALSE, $params['httponly']); + } } // Write the session data. session_write_close(); } } @@ -332,11 +347,11 @@ function drupal_session_started($set = NULL) { */ function drupal_session_regenerate() { global $user, $is_https; if ($is_https && variable_get('https', FALSE)) { $insecure_session_name = substr(session_name(), 1); - if (isset($_COOKIE[$insecure_session_name])) { + if (!isset($GLOBALS['lazy_session']) && isset($_COOKIE[$insecure_session_name])) { $old_insecure_session_id = $_COOKIE[$insecure_session_name]; } $params = session_get_cookie_params(); $session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55)); // If a session cookie lifetime is set, the session will expire @@ -412,26 +427,33 @@ function _drupal_session_destroy($sid) { $user = drupal_anonymous_user(); // Unset the session cookies. _drupal_session_delete_cookie(session_name()); if ($is_https) { - _drupal_session_delete_cookie(substr(session_name(), 1), TRUE); + _drupal_session_delete_cookie(substr(session_name(), 1), FALSE); + } + elseif (variable_get('https', FALSE)) { + _drupal_session_delete_cookie('S' . session_name(), TRUE); } } /** * Deletes the session cookie. * * @param $name * Name of session cookie to delete. - * @param $force_insecure - * Force cookie to be insecure. + * @param boolean $secure + * Force the secure value of the cookie. */ -function _drupal_session_delete_cookie($name, $force_insecure = FALSE) { - if (isset($_COOKIE[$name])) { +function _drupal_session_delete_cookie($name, $secure = NULL) { + global $is_https; + if (isset($_COOKIE[$name]) || (!$is_https && $secure === TRUE)) { $params = session_get_cookie_params(); - setcookie($name, '', REQUEST_TIME - 3600, $params['path'], $params['domain'], !$force_insecure && $params['secure'], $params['httponly']); + if ($secure !== NULL) { + $params['secure'] = $secure; + } + setcookie($name, '', REQUEST_TIME - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly']); unset($_COOKIE[$name]); } } /**