password: ensure encrypt only once

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2022-07-27 21:30:02 +08:00
parent 9f22f55a1f
commit 551bf5030b
2 changed files with 55 additions and 28 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 {
@ -298,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();
@ -754,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);
} }
} }
} }