diff --git a/core/includes/common.inc b/core/includes/common.inc index bb14e95..4ac28bc 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -4731,7 +4731,15 @@ function drupal_get_private_key() { * 'drupal_private_key' configuration variable. */ function drupal_get_token($value = '') { - return drupal_hmac_base64($value, session_id() . drupal_get_private_key() . drupal_get_hash_salt()); + // For mixed HTTP(S) sessions, use a constant identifier so that tokens can be + // shared between protocols. + if (variable_get('https', FALSE) && $GLOBALS['is_https'] && isset($_COOKIE[substr(session_name(), 1)])) { + $session_id = $_COOKIE[substr(session_name(), 1)]; + } + else { + $session_id = session_id(); + } + return drupal_hmac_base64($value, $session_id . drupal_get_private_key() . drupal_get_hash_salt()); } /** diff --git a/core/includes/form.inc b/core/includes/form.inc index 2659d06..0a83d30 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -1150,6 +1150,11 @@ function drupal_validate_form($form_id, &$form, &$form_state) { } } + // Ensure the correct protocol when #https is set. + if (!empty($form['#https']) && variable_get('https', FALSE) && !$GLOBALS['is_https']) { + form_set_error('', t('This form must be submitted over a secure connection.')); + } + _form_validate($form, $form_state, $form_id); $validated_forms[$form_id] = TRUE; diff --git a/core/modules/system/lib/Drupal/system/Tests/Session/SessionHttpsTest.php b/core/modules/system/lib/Drupal/system/Tests/Session/SessionHttpsTest.php index 0ab45a9..9424077 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Session/SessionHttpsTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Session/SessionHttpsTest.php @@ -138,13 +138,24 @@ protected function testHttpsSession() { $this->drupalGet('user'); $form = $this->xpath('//form[@id="user-login-form"]'); $this->assertEqual(substr($form[0]['action'], 0, 6), 'https:', 'Login form action is secure'); - $form[0]['action'] = $this->httpsUrl('user'); + // Change the form to submit to an insecure URL and make sure the + // submission fails. + $form[0]['action'] = $this->httpUrl('user'); $edit = array( 'name' => $user->name, 'pass' => $user->pass_raw, ); $this->drupalPost(NULL, $edit, t('Log in')); + $this->assertText(t('This form must be submitted over a secure connection.'), 'Form submission failed over HTTP.'); + + // Now try with a secure URL and make sure the submission succeeds. + $form[0]['action'] = $this->httpsUrl('user'); + $this->drupalPost(NULL, $edit, t('Log in')); + $this->assertNoText(t('This form must be submitted over a secure connection.'), 'Form submission succeeded over HTTPS.'); + // Check success the same way WebTestBase::drupalLogin() does. + $this->assertLink(t('Log out'), 0, t('User %name successfully logged in.', array('%name' => $user->name))); + // Check secure cookie on secure page. $this->assertTrue($this->cookies[$secure_session_name]['secure'], 'The secure cookie has the secure attribute'); // Check insecure cookie on secure page. @@ -200,6 +211,19 @@ protected function testHttpsSession() { // Test that the user is also authenticated on the insecure site. $this->drupalGet("user/{$user->uid}/edit"); $this->assertResponse(200); + + // Test that tokens can be shared in mixed mode. + $this->drupalGet('session-test/drupal-token'); + $matches = array(); + preg_match('/\s*drupal_get_token:(.*)\n/', $this->drupalGetContent(), $matches); + $this->assertTrue(!empty($matches[1]) , 'Found token on the HTTP URL.'); + $token_plain = $matches[1]; + $this->drupalGet($this->httpsUrl('session-test/drupal-token')); + $matches = array(); + preg_match('/\s*drupal_get_token:(.*)\n/', $this->drupalGetContent(), $matches); + $this->assertTrue(!empty($matches[1]) , 'Found token on the HTTPS URL.'); + $token_secure = $matches[1]; + $this->assertEqual($token_plain, $token_secure, 'Tokens are shared in mixed HTTPS sessions.'); } /** diff --git a/core/modules/system/tests/modules/session_test/session_test.module b/core/modules/system/tests/modules/session_test/session_test.module index 3b378ad..1d9c229 100644 --- a/core/modules/system/tests/modules/session_test/session_test.module +++ b/core/modules/system/tests/modules/session_test/session_test.module @@ -22,6 +22,12 @@ function session_test_menu() { 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); + $items['session-test/drupal-token'] = array( + 'title' => 'Display a token', + 'page callback' => '_session_test_drupal_token', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + ); $items['session-test/set/%'] = array( 'title' => 'Set session value', 'page callback' => '_session_test_set', @@ -122,6 +128,13 @@ function _session_test_id_from_cookie() { } /** + * Menu callback: display the result of drupal_get_token(). + */ +function _session_test_drupal_token() { + return 'drupal_get_token:' . drupal_get_token(); +} + +/** * Menu callback, sets a message to me displayed on the following page. */ function _session_test_set_message() {