geforkt von mirrored/vaultwarden
Merge branch 'password-hints' of https://github.com/jjlin/vaultwarden into jjlin-password-hints
Dieser Commit ist enthalten in:
Commit
d0ec410b73
3 geänderte Dateien mit 45 neuen und 21 gelöschten Zeilen
|
@ -210,8 +210,10 @@
|
||||||
## The change only applies when the password is changed
|
## The change only applies when the password is changed
|
||||||
# PASSWORD_ITERATIONS=100000
|
# PASSWORD_ITERATIONS=100000
|
||||||
|
|
||||||
## Whether password hint should be sent into the error response when the client request it
|
## Controls whether a password hint should be shown directly in the web page if
|
||||||
# SHOW_PASSWORD_HINT=true
|
## SMTP service is not configured. Not recommended for publicly-accessible instances
|
||||||
|
## as this provides unauthenticated access to potentially sensitive data.
|
||||||
|
# SHOW_PASSWORD_HINT=false
|
||||||
|
|
||||||
## Domain settings
|
## Domain settings
|
||||||
## The domain must match the address from where you access the server
|
## The domain must match the address from where you access the server
|
||||||
|
|
|
@ -576,24 +576,45 @@ struct PasswordHintData {
|
||||||
|
|
||||||
#[post("/accounts/password-hint", data = "<data>")]
|
#[post("/accounts/password-hint", data = "<data>")]
|
||||||
fn password_hint(data: JsonUpcase<PasswordHintData>, conn: DbConn) -> EmptyResult {
|
fn password_hint(data: JsonUpcase<PasswordHintData>, conn: DbConn) -> EmptyResult {
|
||||||
|
if !CONFIG.mail_enabled() && !CONFIG.show_password_hint() {
|
||||||
|
err!("This server is not configured to provide password hints.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const NO_HINT: &str = "Sorry, you have no password hint...";
|
||||||
|
|
||||||
let data: PasswordHintData = data.into_inner().data;
|
let data: PasswordHintData = data.into_inner().data;
|
||||||
|
let email = &data.Email;
|
||||||
|
|
||||||
let hint = match User::find_by_mail(&data.Email, &conn) {
|
match User::find_by_mail(email, &conn) {
|
||||||
Some(user) => user.password_hint,
|
None => {
|
||||||
None => return Ok(()),
|
// To prevent user enumeration, act as if the user exists.
|
||||||
};
|
|
||||||
|
|
||||||
if CONFIG.mail_enabled() {
|
if CONFIG.mail_enabled() {
|
||||||
mail::send_password_hint(&data.Email, hint)?;
|
// There is still a timing side channel here in that the code
|
||||||
} else if CONFIG.show_password_hint() {
|
// paths that send mail take noticeably longer than ones that
|
||||||
if let Some(hint) = hint {
|
// don't. Add a randomized sleep to mitigate this somewhat.
|
||||||
err!(format!("Your password hint is: {}", &hint));
|
use rand::{thread_rng, Rng};
|
||||||
} else {
|
let mut rng = thread_rng();
|
||||||
err!("Sorry, you have no password hint...");
|
let base = 1000;
|
||||||
}
|
let delta: i32 = 100;
|
||||||
}
|
let sleep_ms = (base + rng.gen_range(-delta..=delta)) as u64;
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(sleep_ms));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
} else {
|
||||||
|
err!(NO_HINT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(user) => {
|
||||||
|
let hint: Option<String> = user.password_hint;
|
||||||
|
if CONFIG.mail_enabled() {
|
||||||
|
mail::send_password_hint(email, hint)?;
|
||||||
|
Ok(())
|
||||||
|
} else if let Some(hint) = hint {
|
||||||
|
err!(format!("Your password hint is: {}", hint));
|
||||||
|
} else {
|
||||||
|
err!(NO_HINT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
|
|
@ -388,9 +388,10 @@ make_config! {
|
||||||
/// Password iterations |> Number of server-side passwords hashing iterations.
|
/// Password iterations |> Number of server-side passwords hashing iterations.
|
||||||
/// The changes only apply when a user changes their password. Not recommended to lower the value
|
/// The changes only apply when a user changes their password. Not recommended to lower the value
|
||||||
password_iterations: i32, true, def, 100_000;
|
password_iterations: i32, true, def, 100_000;
|
||||||
/// Show password hints |> Controls if the password hint should be shown directly in the web page.
|
/// Show password hint |> Controls whether a password hint should be shown directly in the web page
|
||||||
/// Otherwise, if email is disabled, there is no way to see the password hint
|
/// if SMTP service is not configured. Not recommended for publicly-accessible instances as this
|
||||||
show_password_hint: bool, true, def, true;
|
/// provides unauthenticated access to potentially sensitive data.
|
||||||
|
show_password_hint: bool, true, def, false;
|
||||||
|
|
||||||
/// Admin page token |> The token used to authenticate in this very same page. Changing it here won't deauthorize the current session
|
/// Admin page token |> The token used to authenticate in this very same page. Changing it here won't deauthorize the current session
|
||||||
admin_token: Pass, true, option;
|
admin_token: Pass, true, option;
|
||||||
|
|
Laden …
In neuem Issue referenzieren