diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index 3b8b3e57d..3c34324f5 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -218,7 +218,8 @@ impl Config2 { fn load() -> Config2 { let mut config = Config::load_::("2"); if let Some(mut socks) = config.socks { - let (password, store) = decrypt_str_or_original(&socks.password, PASSWORD_ENC_VERSION); + let (password, _, store) = + decrypt_str_or_original(&socks.password, PASSWORD_ENC_VERSION); socks.password = password; config.socks = Some(socks); if store { @@ -228,6 +229,13 @@ impl Config2 { config } + pub fn decrypt_password(&mut self) { + if let Some(mut socks) = self.socks.clone() { + socks.password = decrypt_str_or_original(&socks.password, PASSWORD_ENC_VERSION).0; + self.socks = Some(socks); + } + } + pub fn file() -> PathBuf { Config::file_("2") } @@ -291,7 +299,7 @@ impl Config { fn load() -> Config { let mut config = Config::load_::(""); - let (password, store) = decrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION); + let (password, _, store) = decrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION); config.password = password; if store { config.store(); @@ -299,6 +307,10 @@ impl Config { config } + pub fn decrypt_password(&mut self) { + self.password = decrypt_str_or_original(&self.password, PASSWORD_ENC_VERSION).0; + } + fn store(&self) { let mut config = self.clone(); config.password = encrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION); @@ -743,17 +755,17 @@ impl PeerConfig { Ok(config) => { let mut config: PeerConfig = config; let mut store = false; - let (password, store2) = + let (password, _, store2) = decrypt_vec_or_original(&config.password, PASSWORD_ENC_VERSION); config.password = password; store = store || store2; config.options.get_mut("rdp_password").map(|v| { - let (password, store2) = decrypt_str_or_original(v, PASSWORD_ENC_VERSION); + let (password, _, store2) = decrypt_str_or_original(v, PASSWORD_ENC_VERSION); *v = password; store = store || store2; }); config.options.get_mut("os-password").map(|v| { - let (password, store2) = decrypt_str_or_original(v, PASSWORD_ENC_VERSION); + let (password, _, store2) = decrypt_str_or_original(v, PASSWORD_ENC_VERSION); *v = password; store = store || store2; }); diff --git a/libs/hbb_common/src/password_security.rs b/libs/hbb_common/src/password_security.rs index 7be014574..413aa7c7f 100644 --- a/libs/hbb_common/src/password_security.rs +++ b/libs/hbb_common/src/password_security.rs @@ -67,6 +67,10 @@ pub mod config { const VERSION_LEN: usize = 2; pub fn encrypt_str_or_original(s: &str, version: &str) -> String { + if decrypt_str_or_original(s, version).1 { + log::error!("Duplicate encryption!"); + return s.to_owned(); + } if version.len() == VERSION_LEN { if version == "00" { if let Ok(s) = encrypt00(s.as_bytes()) { @@ -78,24 +82,31 @@ pub mod config { s.to_owned() } + // String: password + // bool: whether decryption is successful // bool: whether should store to re-encrypt when load - pub fn decrypt_str_or_original(s: &str, current_version: &str) -> (String, bool) { + pub fn decrypt_str_or_original(s: &str, current_version: &str) -> (String, bool, bool) { if s.len() > VERSION_LEN { let version = &s[..VERSION_LEN]; if version == "00" { if let Ok(v) = decrypt00(&s[VERSION_LEN..].as_bytes()) { return ( String::from_utf8_lossy(&v).to_string(), + true, version != current_version, ); } } } - (s.to_owned(), !s.is_empty()) + (s.to_owned(), false, !s.is_empty()) } pub fn encrypt_vec_or_original(v: &[u8], version: &str) -> Vec { + if decrypt_vec_or_original(v, version).1 { + log::error!("Duplicate encryption!"); + return v.to_owned(); + } if version.len() == VERSION_LEN { if version == "00" { if let Ok(s) = encrypt00(v) { @@ -109,18 +120,20 @@ pub mod config { v.to_owned() } + // String: password + // bool: whether decryption is successful // bool: whether should store to re-encrypt when load - pub fn decrypt_vec_or_original(v: &[u8], current_version: &str) -> (Vec, bool) { + pub fn decrypt_vec_or_original(v: &[u8], current_version: &str) -> (Vec, bool, bool) { if v.len() > VERSION_LEN { let version = String::from_utf8_lossy(&v[..VERSION_LEN]); if version == "00" { if let Ok(v) = decrypt00(&v[VERSION_LEN..]) { - return (v, version != current_version); + return (v, true, version != current_version); } } } - (v.to_owned(), !v.is_empty()) + (v.to_owned(), false, !v.is_empty()) } mod test { @@ -129,45 +142,58 @@ pub mod config { fn test() { use crate::password_security::config::*; + let version = "00"; + println!("test str"); let data = "Hello World"; - let encrypted = encrypt_str_or_original(data, "00"); - let (decrypted, store) = decrypt_str_or_original(&encrypted, "00"); + let encrypted = encrypt_str_or_original(data, version); + let (decrypted, succ, store) = decrypt_str_or_original(&encrypted, version); println!("data: {}", data); println!("encrypted: {}", encrypted); println!("decrypted: {}", decrypted); assert_eq!(data, decrypted); - assert_eq!("00", &encrypted[..2]); + assert_eq!(version, &encrypted[..2]); + assert_eq!(succ, true); assert_eq!(store, false); - let (_, store2) = decrypt_str_or_original(&encrypted, "01"); - assert_eq!(store2, true); + let (_, _, store) = decrypt_str_or_original(&encrypted, "99"); + assert_eq!(store, true); + assert_eq!(decrypt_str_or_original(&decrypted, version).1, false); + assert_eq!(encrypt_str_or_original(&encrypted, version), encrypted); println!("test vec"); - let data: Vec = vec![1, 2, 3, 4]; - let encrypted = encrypt_vec_or_original(&data, "00"); - let (decrypted, store) = decrypt_vec_or_original(&encrypted, "00"); + let data: Vec = vec![1, 2, 3, 4, 5, 6]; + let encrypted = encrypt_vec_or_original(&data, version); + let (decrypted, succ, store) = decrypt_vec_or_original(&encrypted, version); println!("data: {:?}", data); println!("encrypted: {:?}", encrypted); println!("decrypted: {:?}", decrypted); assert_eq!(data, decrypted); - assert_eq!("00".as_bytes(), &encrypted[..2]); + assert_eq!(version.as_bytes(), &encrypted[..2]); assert_eq!(store, false); - let (_, store2) = decrypt_vec_or_original(&encrypted, "01"); - assert_eq!(store2, true); + assert_eq!(succ, true); + let (_, _, store) = decrypt_vec_or_original(&encrypted, "99"); + assert_eq!(store, true); + assert_eq!(decrypt_vec_or_original(&decrypted, version).1, false); + assert_eq!(encrypt_vec_or_original(&encrypted, version), encrypted); - println!("test old"); - let data = "00Hello World"; - let (decrypted, store) = decrypt_str_or_original(&data, "00"); + println!("test original"); + let data = version.to_string() + "Hello World"; + let (decrypted, succ, store) = decrypt_str_or_original(&data, version); assert_eq!(data, decrypted); assert_eq!(store, true); - let data: Vec = vec!['0' as u8, '0' as u8, 1, 2, 3, 4]; - let (decrypted, store) = decrypt_vec_or_original(&data, "00"); + assert_eq!(succ, false); + let verbytes = version.as_bytes(); + let data: Vec = vec![verbytes[0] as u8, verbytes[1] as u8, 1, 2, 3, 4, 5, 6]; + let (decrypted, succ, store) = decrypt_vec_or_original(&data, version); assert_eq!(data, decrypted); assert_eq!(store, true); - let (_, store) = decrypt_str_or_original("", "00"); + assert_eq!(succ, false); + let (_, succ, store) = decrypt_str_or_original("", version); assert_eq!(store, false); - let (_, store) = decrypt_vec_or_original(&vec![], "00"); + assert_eq!(succ, false); + let (_, succ, store) = decrypt_vec_or_original(&vec![], version); assert_eq!(store, false); + assert_eq!(succ, false); } } } diff --git a/src/main.rs b/src/main.rs index be1e046a1..8a6d09e57 100644 --- a/src/main.rs +++ b/src/main.rs @@ -171,18 +171,20 @@ fn import_config(path: &str) { let path2 = std::path::Path::new(&path2); let path = std::path::Path::new(path); log::info!("import config from {:?} and {:?}", path, path2); - let config: Config = load_path(path.into()); + let mut config: Config = load_path(path.into()); if config.id.is_empty() || config.key_pair.0.is_empty() { log::info!("Empty source config, skipped"); return; } if get_modified_time(&path) > get_modified_time(&Config::file()) { + config.decrypt_password(); if Config::set(config) { log::info!("config written"); } } - let config2: Config2 = load_path(path2.into()); + let mut config2: Config2 = load_path(path2.into()); if get_modified_time(&path2) > get_modified_time(&Config2::file()) { + config2.decrypt_password(); if Config2::set(config2) { log::info!("config2 written"); }