updated core to 7.80

This commit is contained in:
2021-07-12 10:11:08 +02:00
parent 7b1e954f7f
commit 5656f5a68a
236 changed files with 4149 additions and 888 deletions

View File

@@ -66,6 +66,22 @@ function user_pass() {
* @see user_pass_submit()
*/
function user_pass_validate($form, &$form_state) {
if (isset($form_state['values']['name']) && !is_scalar($form_state['values']['name'])) {
form_set_error('name', t('An illegal value has been detected. Please contact the site administrator.'));
return;
}
$user_pass_reset_ip_window = variable_get('user_pass_reset_ip_window', 3600);
// Do not allow any password reset from the current user's IP if the limit
// has been reached. Default is 50 attempts allowed in one hour. This is
// independent of the per-user limit to catch attempts from one IP to request
// resets for many different user accounts. We have a reasonably high limit
// since there may be only one apparent IP for all users at an institution.
if (!flood_is_allowed('pass_reset_ip', variable_get('user_pass_reset_ip_limit', 50), $user_pass_reset_ip_window)) {
form_set_error('name', t('Sorry, too many password reset attempts from your IP address. This IP address is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => url('user/password'))));
return;
}
// Always register an per-IP event.
flood_register_event('pass_reset_ip', $user_pass_reset_ip_window);
$name = trim($form_state['values']['name']);
// Try to load by email.
$users = user_load_multiple(array(), array('mail' => $name, 'status' => '1'));
@@ -76,6 +92,19 @@ function user_pass_validate($form, &$form_state) {
$account = reset($users);
}
if (isset($account->uid)) {
// Register user flood events based on the uid only, so they can be cleared
// when a password is reset successfully.
$identifier = $account->uid;
$user_pass_reset_user_window = variable_get('user_pass_reset_user_window', 21600);
$user_pass_reset_user_limit = variable_get('user_pass_reset_user_limit', 5);
// Don't allow password reset if the limit for this user has been reached.
// Default is to allow 5 passwords resets every 6 hours.
if (!flood_is_allowed('pass_reset_user', $user_pass_reset_user_limit, $user_pass_reset_user_window, $identifier)) {
form_set_error('name', format_plural($user_pass_reset_user_limit, 'Sorry, there has been more than one password reset attempt for this account. It is temporarily blocked. Try again later or <a href="@url">login with your password</a>.', 'Sorry, there have been more than @count password reset attempts for this account. It is temporarily blocked. Try again later or <a href="@url">login with your password</a>.', array('@url' => url('user/login'))));
return;
}
// Register a per-user event.
flood_register_event('pass_reset_user', $user_pass_reset_user_window, $identifier);
form_set_value(array('#parents' => array('account')), $account, $form_state);
}
else {
@@ -105,10 +134,25 @@ function user_pass_submit($form, &$form_state) {
/**
* Menu callback; process one time login link and redirects to the user page on success.
*
* In order to never disclose password reset hashes via referrer headers or
* web browser history, this function always issues a redirect when a valid
* password reset hash is in the URL.
*/
function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $action = NULL) {
global $user;
// Check for a reset hash in the session. Immediately remove it (to prevent it
// from being reused, for example if this page is visited again via the
// browser history) and store it for later use.
if (isset($_SESSION['pass_reset_hash'])) {
$session_reset_hash = $_SESSION['pass_reset_hash'];
unset($_SESSION['pass_reset_hash']);
}
else {
$session_reset_hash = NULL;
}
// When processing the one-time login link, we have to make sure that a user
// isn't already logged in.
if ($user->uid) {
@@ -153,7 +197,36 @@ function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $a
drupal_set_message(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'error');
drupal_goto('user/password');
}
elseif ($account->uid && $timestamp >= $account->login && $timestamp <= $current && $hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid)) {
// Validate the reset hash from the URL or from the session.
$is_valid = FALSE;
if ($account->uid && $timestamp >= $account->login && $timestamp <= $current) {
// If the reset hash in the URL is valid, put it in the session and
// redirect to the same URL but with the hash replaced by an invalid
// one ("confirm"). This prevents disclosing the hash via referrer
// headers or web browser history.
if ($hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid)) {
if ($action === 'login') {
// The 'login' action redirects directly to the user edit form.
$is_valid = TRUE;
}
else {
$_SESSION['pass_reset_hash'] = $hashed_pass;
$args = arg();
foreach ($args as &$arg) {
if ($arg == $hashed_pass) {
$arg = 'confirm';
}
}
$path = implode('/', $args);
drupal_goto($path, array('query' => drupal_get_query_parameters()));
}
}
// If the reset hash from the session is valid, use that.
elseif ($session_reset_hash && $session_reset_hash == user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid)) {
$is_valid = TRUE;
}
}
if ($is_valid) {
// First stage is a confirmation form, then login
if ($action == 'login') {
// Set the new user.
@@ -161,6 +234,8 @@ function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $a
// user_login_finalize() also updates the login timestamp of the
// user, which invalidates further use of the one-time login link.
user_login_finalize();
// Clear any password reset flood events for this user.
flood_clear_event('pass_reset_user', $account->uid);
watchdog('user', 'User %name used one-time login link at time %timestamp.', array('%name' => $account->name, '%timestamp' => $timestamp));
drupal_set_message(t('You have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password.'));
// Let the user's password be changed without the current password check.
@@ -173,7 +248,11 @@ function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $a
$form['help'] = array('#markup' => '<p>' . t('This login can be used only once.') . '</p>');
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Log in'));
$form['#action'] = url("user/reset/$uid/$timestamp/$hashed_pass/login");
$form['#action'] = url("user/reset/$uid/$timestamp/$session_reset_hash/login");
// Prevent the browser from storing this page so that the token will
// not be visible in the form action if the back button is used to
// revisit this page.
drupal_add_http_header('Cache-Control', 'no-store');
return $form;
}
}