Merge pull request #1078 from 21pages/password

Password: fix import config
This commit is contained in:
RustDesk 2022-07-28 11:16:42 +08:00 committed by GitHub
commit 295f326e7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 30 deletions

View File

@ -218,7 +218,8 @@ impl Config2 {
fn load() -> Config2 { fn load() -> Config2 {
let mut config = Config::load_::<Config2>("2"); let mut config = Config::load_::<Config2>("2");
if let Some(mut socks) = config.socks { 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; socks.password = password;
config.socks = Some(socks); config.socks = Some(socks);
if store { if store {
@ -228,6 +229,13 @@ impl Config2 {
config 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 { pub fn file() -> PathBuf {
Config::file_("2") Config::file_("2")
} }
@ -291,7 +299,7 @@ impl Config {
fn load() -> Config { fn load() -> Config {
let mut config = Config::load_::<Config>(""); let mut config = Config::load_::<Config>("");
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; config.password = password;
if store { if store {
config.store(); config.store();
@ -299,6 +307,10 @@ impl Config {
config config
} }
pub fn decrypt_password(&mut self) {
self.password = decrypt_str_or_original(&self.password, PASSWORD_ENC_VERSION).0;
}
fn store(&self) { fn store(&self) {
let mut config = self.clone(); let mut config = self.clone();
config.password = encrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION); config.password = encrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION);
@ -743,17 +755,17 @@ impl PeerConfig {
Ok(config) => { Ok(config) => {
let mut config: PeerConfig = config; let mut config: PeerConfig = config;
let mut store = false; let mut store = false;
let (password, store2) = let (password, _, store2) =
decrypt_vec_or_original(&config.password, PASSWORD_ENC_VERSION); decrypt_vec_or_original(&config.password, PASSWORD_ENC_VERSION);
config.password = password; config.password = password;
store = store || store2; store = store || store2;
config.options.get_mut("rdp_password").map(|v| { 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; *v = password;
store = store || store2; store = store || store2;
}); });
config.options.get_mut("os-password").map(|v| { 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; *v = password;
store = store || store2; store = store || store2;
}); });

View File

@ -67,6 +67,10 @@ pub mod config {
const VERSION_LEN: usize = 2; const VERSION_LEN: usize = 2;
pub fn encrypt_str_or_original(s: &str, version: &str) -> String { 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.len() == VERSION_LEN {
if version == "00" { if version == "00" {
if let Ok(s) = encrypt00(s.as_bytes()) { if let Ok(s) = encrypt00(s.as_bytes()) {
@ -78,24 +82,31 @@ pub mod config {
s.to_owned() s.to_owned()
} }
// String: password
// bool: whether decryption is successful
// bool: whether should store to re-encrypt when load // 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 { if s.len() > VERSION_LEN {
let version = &s[..VERSION_LEN]; let version = &s[..VERSION_LEN];
if version == "00" { if version == "00" {
if let Ok(v) = decrypt00(&s[VERSION_LEN..].as_bytes()) { if let Ok(v) = decrypt00(&s[VERSION_LEN..].as_bytes()) {
return ( return (
String::from_utf8_lossy(&v).to_string(), String::from_utf8_lossy(&v).to_string(),
true,
version != current_version, 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<u8> { pub fn encrypt_vec_or_original(v: &[u8], version: &str) -> Vec<u8> {
if decrypt_vec_or_original(v, version).1 {
log::error!("Duplicate encryption!");
return v.to_owned();
}
if version.len() == VERSION_LEN { if version.len() == VERSION_LEN {
if version == "00" { if version == "00" {
if let Ok(s) = encrypt00(v) { if let Ok(s) = encrypt00(v) {
@ -109,18 +120,20 @@ pub mod config {
v.to_owned() v.to_owned()
} }
// String: password
// bool: whether decryption is successful
// bool: whether should store to re-encrypt when load // bool: whether should store to re-encrypt when load
pub fn decrypt_vec_or_original(v: &[u8], current_version: &str) -> (Vec<u8>, bool) { pub fn decrypt_vec_or_original(v: &[u8], current_version: &str) -> (Vec<u8>, bool, bool) {
if v.len() > VERSION_LEN { if v.len() > VERSION_LEN {
let version = String::from_utf8_lossy(&v[..VERSION_LEN]); let version = String::from_utf8_lossy(&v[..VERSION_LEN]);
if version == "00" { if version == "00" {
if let Ok(v) = decrypt00(&v[VERSION_LEN..]) { 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 { mod test {
@ -129,45 +142,58 @@ pub mod config {
fn test() { fn test() {
use crate::password_security::config::*; use crate::password_security::config::*;
let version = "00";
println!("test str"); println!("test str");
let data = "Hello World"; let data = "Hello World";
let encrypted = encrypt_str_or_original(data, "00"); let encrypted = encrypt_str_or_original(data, version);
let (decrypted, store) = decrypt_str_or_original(&encrypted, "00"); let (decrypted, succ, store) = decrypt_str_or_original(&encrypted, version);
println!("data: {}", data); println!("data: {}", data);
println!("encrypted: {}", encrypted); println!("encrypted: {}", encrypted);
println!("decrypted: {}", decrypted); println!("decrypted: {}", decrypted);
assert_eq!(data, decrypted); assert_eq!(data, decrypted);
assert_eq!("00", &encrypted[..2]); assert_eq!(version, &encrypted[..2]);
assert_eq!(succ, true);
assert_eq!(store, false); assert_eq!(store, false);
let (_, store2) = decrypt_str_or_original(&encrypted, "01"); let (_, _, store) = decrypt_str_or_original(&encrypted, "99");
assert_eq!(store2, true); 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"); println!("test vec");
let data: Vec<u8> = vec![1, 2, 3, 4]; let data: Vec<u8> = vec![1, 2, 3, 4, 5, 6];
let encrypted = encrypt_vec_or_original(&data, "00"); let encrypted = encrypt_vec_or_original(&data, version);
let (decrypted, store) = decrypt_vec_or_original(&encrypted, "00"); let (decrypted, succ, store) = decrypt_vec_or_original(&encrypted, version);
println!("data: {:?}", data); println!("data: {:?}", data);
println!("encrypted: {:?}", encrypted); println!("encrypted: {:?}", encrypted);
println!("decrypted: {:?}", decrypted); println!("decrypted: {:?}", decrypted);
assert_eq!(data, decrypted); assert_eq!(data, decrypted);
assert_eq!("00".as_bytes(), &encrypted[..2]); assert_eq!(version.as_bytes(), &encrypted[..2]);
assert_eq!(store, false); assert_eq!(store, false);
let (_, store2) = decrypt_vec_or_original(&encrypted, "01"); assert_eq!(succ, true);
assert_eq!(store2, 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"); println!("test original");
let data = "00Hello World"; let data = version.to_string() + "Hello World";
let (decrypted, store) = decrypt_str_or_original(&data, "00"); let (decrypted, succ, store) = decrypt_str_or_original(&data, version);
assert_eq!(data, decrypted); assert_eq!(data, decrypted);
assert_eq!(store, true); assert_eq!(store, true);
let data: Vec<u8> = vec!['0' as u8, '0' as u8, 1, 2, 3, 4]; assert_eq!(succ, false);
let (decrypted, store) = decrypt_vec_or_original(&data, "00"); let verbytes = version.as_bytes();
let data: Vec<u8> = 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!(data, decrypted);
assert_eq!(store, true); 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); 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!(store, false);
assert_eq!(succ, false);
} }
} }
} }

View File

@ -171,18 +171,20 @@ fn import_config(path: &str) {
let path2 = std::path::Path::new(&path2); let path2 = std::path::Path::new(&path2);
let path = std::path::Path::new(path); let path = std::path::Path::new(path);
log::info!("import config from {:?} and {:?}", path, path2); 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() { if config.id.is_empty() || config.key_pair.0.is_empty() {
log::info!("Empty source config, skipped"); log::info!("Empty source config, skipped");
return; return;
} }
if get_modified_time(&path) > get_modified_time(&Config::file()) { if get_modified_time(&path) > get_modified_time(&Config::file()) {
config.decrypt_password();
if Config::set(config) { if Config::set(config) {
log::info!("config written"); 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()) { if get_modified_time(&path2) > get_modified_time(&Config2::file()) {
config2.decrypt_password();
if Config2::set(config2) { if Config2::set(config2) {
log::info!("config2 written"); log::info!("config2 written");
} }