mirror of
https://github.com/rustdesk/hbb_common.git
synced 2026-04-02 22:16:18 +00:00
fix(password): update salt in set_permanent_password()
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -1233,6 +1233,23 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut config = CONFIG.write().unwrap();
|
let mut config = CONFIG.write().unwrap();
|
||||||
|
|
||||||
|
// If the permanent password is already stored as a hashed verifier, avoid rotating salt
|
||||||
|
// when the plaintext stays the same. Rotating salt on "no-op" updates would unnecessarily
|
||||||
|
// clear trusted devices and trigger config sync churn.
|
||||||
|
if !password.is_empty()
|
||||||
|
&& !config.password.is_empty()
|
||||||
|
&& is_permanent_password_hashed_storage(&config.password)
|
||||||
|
&& !config.salt.is_empty()
|
||||||
|
{
|
||||||
|
if let Some(stored_h1) = decode_permanent_password_h1_from_storage(&config.password) {
|
||||||
|
let candidate_h1 = compute_permanent_password_h1(password, &config.salt);
|
||||||
|
if constant_time_eq_32(&candidate_h1, &stored_h1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let stored = if password.is_empty() {
|
let stored = if password.is_empty() {
|
||||||
String::new()
|
String::new()
|
||||||
} else {
|
} else {
|
||||||
@@ -1250,12 +1267,9 @@ impl Config {
|
|||||||
config: &mut Config,
|
config: &mut Config,
|
||||||
password: &str,
|
password: &str,
|
||||||
) -> String {
|
) -> String {
|
||||||
if config.salt.is_empty() {
|
// Rotate salt on permanent password updates so the verifier changes even if the user
|
||||||
// If salt is missing, we cannot keep an existing hashed verifier valid anyway.
|
// reuses a previous password. (No-op updates are handled in `set_permanent_password()`.)
|
||||||
// When updating the password, generate a new salt and store it with the new verifier.
|
|
||||||
log::warn!("Salt is empty; generating new salt for permanent password update");
|
|
||||||
config.salt = Config::get_auto_password(DEFAULT_SALT_LEN);
|
config.salt = Config::get_auto_password(DEFAULT_SALT_LEN);
|
||||||
}
|
|
||||||
let h1 = compute_permanent_password_h1(password, &config.salt);
|
let h1 = compute_permanent_password_h1(password, &config.salt);
|
||||||
encode_permanent_password_storage_from_h1(&h1)
|
encode_permanent_password_storage_from_h1(&h1)
|
||||||
}
|
}
|
||||||
@@ -1598,11 +1612,13 @@ impl Config {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once the permanent password is stored as a hashed verifier, treat salt as immutable.
|
// Once the permanent password is stored as a hashed verifier, keep salt and verifier
|
||||||
// Allow hashed verifier updates when salt is unchanged, so service->user config sync can
|
// consistent as a pair.
|
||||||
// propagate permanent password changes without plaintext.
|
// - Refuse salt-only changes (would break verification).
|
||||||
if incoming.salt != current.salt {
|
// - Allow hashed->hashed updates with salt rotation only when the verifier also changes,
|
||||||
log::error!("Refusing to change salt for hashed permanent password via Config::set");
|
// so service->user config sync can propagate password updates without plaintext.
|
||||||
|
if incoming.salt != current.salt && incoming.password == current.password {
|
||||||
|
log::error!("Refusing to change salt without updating hashed permanent password");
|
||||||
incoming.password = current.password.clone();
|
incoming.password = current.password.clone();
|
||||||
incoming.salt = current.salt.clone();
|
incoming.salt = current.salt.clone();
|
||||||
return;
|
return;
|
||||||
@@ -1616,8 +1632,10 @@ impl Config {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow hashed->hashed verifier updates when salt matches.
|
// Allow hashed->hashed verifier updates (with optional salt rotation).
|
||||||
if !incoming.password.is_empty() && is_permanent_password_hashed_storage(&incoming.password)
|
if !incoming.password.is_empty()
|
||||||
|
&& is_permanent_password_hashed_storage(&incoming.password)
|
||||||
|
&& !incoming.salt.is_empty()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user