refact(password): rename and comments

This commit is contained in:
fufesou
2026-05-23 15:13:16 +08:00
parent ce1f7b5f9a
commit 728b73d540
2 changed files with 19 additions and 17 deletions

View File

@@ -598,8 +598,8 @@ impl Config {
fn load() -> Config { fn load() -> Config {
let mut config = Config::load_::<Config>(""); let mut config = Config::load_::<Config>("");
let mut store = false; let mut store = false;
if let Err(err) = Self::normalize_permanent_password_storage(&mut config) { if let Err(err) = Self::validate_or_decrypt_permanent_password_storage(&mut config) {
log::error!("Failed to normalize permanent password storage: {err}"); log::error!("Failed to validate or decrypt permanent password storage: {err}");
} }
let mut id_valid = false; let mut id_valid = false;
let (id, encrypted, store2) = decrypt_str_or_original(&config.enc_id, PASSWORD_ENC_VERSION); let (id, encrypted, store2) = decrypt_str_or_original(&config.enc_id, PASSWORD_ENC_VERSION);
@@ -639,7 +639,7 @@ impl Config {
config config
} }
fn normalize_permanent_password_storage(config: &mut Config) -> Result<()> { fn validate_or_decrypt_permanent_password_storage(config: &mut Config) -> Result<()> {
if config.password.is_empty() { if config.password.is_empty() {
return Ok(()); return Ok(());
} }
@@ -686,7 +686,7 @@ impl Config {
} }
fn prepare_config_for_store(config: &mut Config) { fn prepare_config_for_store(config: &mut Config) {
match Self::normalize_permanent_password_storage(config) { match Self::validate_or_decrypt_permanent_password_storage(config) {
Ok(_) => {} Ok(_) => {}
Err(err) => { Err(err) => {
// This path is for unrecoverable permanent-password storage, such as // This path is for unrecoverable permanent-password storage, such as
@@ -3397,29 +3397,29 @@ mod tests {
} }
#[test] #[test]
fn test_normalize_keeps_plaintext_permanent_password_unchanged() { fn test_validate_or_decrypt_keeps_plaintext_permanent_password_unchanged() {
let mut cfg = Config::default(); let mut cfg = Config::default();
cfg.password = "p@ssw0rd".to_owned(); cfg.password = "p@ssw0rd".to_owned();
cfg.salt = "".to_owned(); cfg.salt = "".to_owned();
Config::normalize_permanent_password_storage(&mut cfg).unwrap(); Config::validate_or_decrypt_permanent_password_storage(&mut cfg).unwrap();
assert_eq!(cfg.password, "p@ssw0rd"); assert_eq!(cfg.password, "p@ssw0rd");
assert!(cfg.salt.is_empty()); assert!(cfg.salt.is_empty());
} }
#[test] #[test]
fn test_normalize_decrypts_00_permanent_password_without_forcing_store() { fn test_validate_or_decrypt_decrypts_00_permanent_password_without_forcing_store() {
let mut cfg = Config::default(); let mut cfg = Config::default();
let legacy_storage = let legacy_storage =
encrypt_str_or_original("legacy-secret", PASSWORD_ENC_VERSION, ENCRYPT_MAX_LEN); encrypt_str_or_original("legacy-secret", PASSWORD_ENC_VERSION, ENCRYPT_MAX_LEN);
cfg.password = legacy_storage; cfg.password = legacy_storage;
cfg.salt = "".to_owned(); cfg.salt = "".to_owned();
Config::normalize_permanent_password_storage(&mut cfg).unwrap(); Config::validate_or_decrypt_permanent_password_storage(&mut cfg).unwrap();
assert_eq!(cfg.password, "legacy-secret"); assert_eq!(cfg.password, "legacy-secret");
assert!(cfg.salt.is_empty()); assert!(cfg.salt.is_empty());
} }
#[test] #[test]
fn test_normalize_rejects_corrupted_00_permanent_password_storage() { fn test_validate_or_decrypt_rejects_corrupted_00_permanent_password_storage() {
let legacy_storage = let legacy_storage =
encrypt_str_or_original("legacy-secret", PASSWORD_ENC_VERSION, ENCRYPT_MAX_LEN); encrypt_str_or_original("legacy-secret", PASSWORD_ENC_VERSION, ENCRYPT_MAX_LEN);
let mut invalid_payload = base64::decode( let mut invalid_payload = base64::decode(
@@ -3434,23 +3434,23 @@ mod tests {
+ &base64::encode(invalid_payload, base64::Variant::Original); + &base64::encode(invalid_payload, base64::Variant::Original);
cfg.salt = "salt123".to_owned(); cfg.salt = "salt123".to_owned();
assert!(Config::normalize_permanent_password_storage(&mut cfg).is_err()); assert!(Config::validate_or_decrypt_permanent_password_storage(&mut cfg).is_err());
} }
#[test] #[test]
fn test_normalize_rejects_encrypted_hashed_permanent_password_without_salt() { fn test_validate_or_decrypt_rejects_encrypted_hashed_permanent_password_without_salt() {
let mut cfg = Config::default(); let mut cfg = Config::default();
let h1 = compute_permanent_password_h1("p@ssw0rd", "salt123"); let h1 = compute_permanent_password_h1("p@ssw0rd", "salt123");
cfg.password = encode_permanent_password_encrypted_storage_from_h1(&h1).unwrap(); cfg.password = encode_permanent_password_encrypted_storage_from_h1(&h1).unwrap();
let original_password = cfg.password.clone(); let original_password = cfg.password.clone();
assert!(Config::normalize_permanent_password_storage(&mut cfg).is_err()); assert!(Config::validate_or_decrypt_permanent_password_storage(&mut cfg).is_err());
assert_eq!(cfg.password, original_password); assert_eq!(cfg.password, original_password);
assert!(cfg.salt.is_empty()); assert!(cfg.salt.is_empty());
} }
#[test] #[test]
fn test_set_does_not_normalize_permanent_password_storage_in_memory() { fn test_set_does_not_validate_or_decrypt_permanent_password_storage_in_memory() {
let mut cfg = Config::default(); let mut cfg = Config::default();
let invalid_payload = let invalid_payload =
crate::password_security::symmetric_crypt(b"not-a-hash", true).unwrap(); crate::password_security::symmetric_crypt(b"not-a-hash", true).unwrap();
@@ -3501,13 +3501,14 @@ mod tests {
} }
#[test] #[test]
fn test_normalize_keeps_plaintext_permanent_password_with_current_prefix_and_long_base64() { fn test_validate_or_decrypt_keeps_plaintext_permanent_password_with_current_prefix_and_long_base64(
) {
let mut cfg = Config::default(); let mut cfg = Config::default();
let plain = "01".to_owned() + &base64::encode([42u8; 24], base64::Variant::Original); let plain = "01".to_owned() + &base64::encode([42u8; 24], base64::Variant::Original);
cfg.password = plain.clone(); cfg.password = plain.clone();
cfg.salt = "".to_owned(); cfg.salt = "".to_owned();
Config::normalize_permanent_password_storage(&mut cfg).unwrap(); Config::validate_or_decrypt_permanent_password_storage(&mut cfg).unwrap();
assert_eq!(cfg.password, plain); assert_eq!(cfg.password, plain);
assert!(cfg.salt.is_empty()); assert!(cfg.salt.is_empty());
} }
@@ -3520,7 +3521,7 @@ mod tests {
let encrypted_hash_storage = let encrypted_hash_storage =
encode_permanent_password_encrypted_storage_from_h1(&h1).unwrap(); encode_permanent_password_encrypted_storage_from_h1(&h1).unwrap();
cfg.password = encrypted_hash_storage.clone(); cfg.password = encrypted_hash_storage.clone();
Config::normalize_permanent_password_storage(&mut cfg).unwrap(); Config::validate_or_decrypt_permanent_password_storage(&mut cfg).unwrap();
assert!(!Config::apply_permanent_password_storage_for_sync( assert!(!Config::apply_permanent_password_storage_for_sync(
&mut cfg, &mut cfg,

View File

@@ -187,7 +187,8 @@ pub fn decode_permanent_password_h1_from_storage(
None None
} }
// If password is empty or not hashed storage, it's safe to update salt. // Salt can be updated only when the password is empty, plaintext, or decryptable
// legacy storage. Current-prefixed storage is treated as salt-bound.
pub(super) fn password_is_empty_or_not_hashed(permanent_password_storage: &str) -> bool { pub(super) fn password_is_empty_or_not_hashed(permanent_password_storage: &str) -> bool {
if permanent_password_storage.is_empty() { if permanent_password_storage.is_empty() {
return true; return true;