refactor password deadlock and password_security

This commit is contained in:
rustdesk 2022-07-30 02:01:40 +08:00
parent cf88ca2bce
commit 125f6dd810
7 changed files with 225 additions and 283 deletions

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
log, log,
password_security::config::{ password_security::{
decrypt_str_or_original, decrypt_vec_or_original, encrypt_str_or_original, decrypt_str_or_original, decrypt_vec_or_original, encrypt_str_or_original,
encrypt_vec_or_original, encrypt_vec_or_original,
}, },
@ -46,6 +46,7 @@ lazy_static::lazy_static! {
pub static ref ONLINE: Arc<Mutex<HashMap<String, i64>>> = Default::default(); pub static ref ONLINE: Arc<Mutex<HashMap<String, i64>>> = Default::default();
pub static ref PROD_RENDEZVOUS_SERVER: Arc<RwLock<String>> = Default::default(); pub static ref PROD_RENDEZVOUS_SERVER: Arc<RwLock<String>> = Default::default();
pub static ref APP_NAME: Arc<RwLock<String>> = Arc::new(RwLock::new("RustDesk".to_owned())); pub static ref APP_NAME: Arc<RwLock<String>> = Arc::new(RwLock::new("RustDesk".to_owned()));
static ref KEY_PAIR: Arc<Mutex<Option<(Vec<u8>, Vec<u8>)>>> = Default::default();
} }
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
lazy_static::lazy_static! { lazy_static::lazy_static! {
@ -229,13 +230,6 @@ 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")
} }
@ -277,6 +271,11 @@ pub fn load_path<T: serde::Serialize + serde::de::DeserializeOwned + Default + s
cfg cfg
} }
#[inline]
pub fn store_path<T: serde::Serialize>(path: PathBuf, cfg: T) -> crate::ResultType<()> {
Ok(confy::store_path(path, cfg)?)
}
impl Config { impl Config {
fn load_<T: serde::Serialize + serde::de::DeserializeOwned + Default + std::fmt::Debug>( fn load_<T: serde::Serialize + serde::de::DeserializeOwned + Default + std::fmt::Debug>(
suffix: &str, suffix: &str,
@ -292,7 +291,7 @@ impl Config {
fn store_<T: serde::Serialize>(config: &T, suffix: &str) { fn store_<T: serde::Serialize>(config: &T, suffix: &str) {
let file = Self::file_(suffix); let file = Self::file_(suffix);
if let Err(err) = confy::store_path(file, config) { if let Err(err) = store_path(file, config) {
log::error!("Failed to store config: {}", err); log::error!("Failed to store config: {}", err);
} }
} }
@ -307,10 +306,6 @@ 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);
@ -587,36 +582,26 @@ impl Config {
config.store(); config.store();
} }
pub fn set_key_pair(pair: (Vec<u8>, Vec<u8>)) {
let mut config = CONFIG.write().unwrap();
if config.key_pair == pair {
return;
}
config.key_pair = pair;
config.store();
}
// * Manually make sure no gen_keypair more than once
// for uuid, avoid deadlock
pub fn get_key_pair_without_lock() -> (Vec<u8>, Vec<u8>) {
let mut config = Config::load_::<Config>("");
if config.key_pair.0.is_empty() {
let (pk, sk) = sign::gen_keypair();
config.key_pair = (sk.0.to_vec(), pk.0.into());
Config::store_(&config, "");
}
config.key_pair.clone()
}
pub fn get_key_pair() -> (Vec<u8>, Vec<u8>) { pub fn get_key_pair() -> (Vec<u8>, Vec<u8>) {
// lock here to make sure no gen_keypair more than once // lock here to make sure no gen_keypair more than once
let mut config = CONFIG.write().unwrap(); // no use of CONFIG directly here to ensure no recursive calling in Config::load because of password dec which calling this function
let mut lock = KEY_PAIR.lock().unwrap();
if let Some(p) = lock.as_ref() {
return p.clone();
}
let mut config = Config::load();
if config.key_pair.0.is_empty() { if config.key_pair.0.is_empty() {
let (pk, sk) = sign::gen_keypair(); let (pk, sk) = sign::gen_keypair();
config.key_pair = (sk.0.to_vec(), pk.0.into()); let key_pair = (sk.0.to_vec(), pk.0.into());
config.store(); config.key_pair = key_pair.clone();
std::thread::spawn(|| {
let mut config = CONFIG.write().unwrap();
config.key_pair = key_pair;
config.store();
});
} }
config.key_pair.clone() *lock = Some(config.key_pair.clone());
return config.key_pair;
} }
pub fn get_id() -> String { pub fn get_id() -> String {
@ -805,7 +790,7 @@ impl PeerConfig {
.options .options
.get_mut("os-password") .get_mut("os-password")
.map(|v| *v = encrypt_str_or_original(v, PASSWORD_ENC_VERSION)); .map(|v| *v = encrypt_str_or_original(v, PASSWORD_ENC_VERSION));
if let Err(err) = confy::store_path(Self::path(id), config) { if let Err(err) = store_path(Self::path(id), config) {
log::error!("Failed to store config: {}", err); log::error!("Failed to store config: {}", err);
} }
} }
@ -975,7 +960,7 @@ impl LanPeers {
let f = LanPeers { let f = LanPeers {
peers: peers.clone(), peers: peers.clone(),
}; };
if let Err(err) = confy::store_path(Config::file_("_lan_peers"), f) { if let Err(err) = store_path(Config::file_("_lan_peers"), f) {
log::error!("Failed to store lan peers: {}", err); log::error!("Failed to store lan peers: {}", err);
} }
} }

View File

@ -1,12 +1,12 @@
pub mod compress; pub mod compress;
pub mod protos;
pub mod platform; pub mod platform;
pub use protos::message as message_proto; pub mod protos;
pub use protos::rendezvous as rendezvous_proto;
pub use bytes; pub use bytes;
use config::Config; use config::Config;
pub use futures; pub use futures;
pub use protobuf; pub use protobuf;
pub use protos::message as message_proto;
pub use protos::rendezvous as rendezvous_proto;
use std::{ use std::{
fs::File, fs::File,
io::{self, BufRead}, io::{self, BufRead},
@ -39,10 +39,6 @@ pub use tokio_socks::IntoTargetAddr;
pub use tokio_socks::TargetAddr; pub use tokio_socks::TargetAddr;
pub mod password_security; pub mod password_security;
lazy_static::lazy_static!{
static ref UUID: Vec<u8> = gen_uuid();
}
#[cfg(feature = "quic")] #[cfg(feature = "quic")]
pub type Stream = quic::Connection; pub type Stream = quic::Connection;
#[cfg(not(feature = "quic"))] #[cfg(not(feature = "quic"))]
@ -206,23 +202,12 @@ pub fn get_modified_time(path: &std::path::Path) -> SystemTime {
.unwrap_or(UNIX_EPOCH) .unwrap_or(UNIX_EPOCH)
} }
fn gen_uuid() -> Vec<u8> { pub fn get_uuid() -> Vec<u8> {
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
if let Ok(id) = machine_uid::get() { if let Ok(id) = machine_uid::get() {
id.into() return id.into();
} else {
Config::get_key_pair().1
} }
#[cfg(any(target_os = "android", target_os = "ios"))] Config::get_key_pair().1
Config::get_key_pair_without_lock().1
}
pub fn init_uuid() {
let _ = *UUID;
}
pub fn get_uuid() -> Vec<u8> {
UUID.to_owned()
} }
#[cfg(test)] #[cfg(test)]

View File

@ -1,222 +1,143 @@
pub mod password { use crate::config::Config;
use crate::config::Config; use sodiumoxide::base64;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
lazy_static::lazy_static! { lazy_static::lazy_static! {
pub static ref TEMPORARY_PASSWORD:Arc<RwLock<String>> = Arc::new(RwLock::new(Config::get_auto_password(temporary_password_length()))); pub static ref TEMPORARY_PASSWORD:Arc<RwLock<String>> = Arc::new(RwLock::new(Config::get_auto_password(temporary_password_length())));
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum VerificationMethod { enum VerificationMethod {
OnlyUseTemporaryPassword, OnlyUseTemporaryPassword,
OnlyUsePermanentPassword, OnlyUsePermanentPassword,
UseBothPasswords, UseBothPasswords,
} }
// Should only be called in server // Should only be called in server
pub fn update_temporary_password() { pub fn update_temporary_password() {
*TEMPORARY_PASSWORD.write().unwrap() = *TEMPORARY_PASSWORD.write().unwrap() = Config::get_auto_password(temporary_password_length());
Config::get_auto_password(temporary_password_length()); }
}
// Should only be called in server // Should only be called in server
pub fn temporary_password() -> String { pub fn temporary_password() -> String {
TEMPORARY_PASSWORD.read().unwrap().clone() TEMPORARY_PASSWORD.read().unwrap().clone()
} }
fn verification_method() -> VerificationMethod { fn verification_method() -> VerificationMethod {
let method = Config::get_option("verification-method"); let method = Config::get_option("verification-method");
if method == "use-temporary-password" { if method == "use-temporary-password" {
VerificationMethod::OnlyUseTemporaryPassword VerificationMethod::OnlyUseTemporaryPassword
} else if method == "use-permanent-password" { } else if method == "use-permanent-password" {
VerificationMethod::OnlyUsePermanentPassword VerificationMethod::OnlyUsePermanentPassword
} else { } else {
VerificationMethod::UseBothPasswords // default VerificationMethod::UseBothPasswords // default
}
}
pub fn temporary_password_length() -> usize {
let length = Config::get_option("temporary-password-length");
if length == "8" {
8
} else if length == "10" {
10
} else {
6 // default
}
}
pub fn temporary_enabled() -> bool {
verification_method() != VerificationMethod::OnlyUsePermanentPassword
}
pub fn permanent_enabled() -> bool {
verification_method() != VerificationMethod::OnlyUseTemporaryPassword
}
pub fn has_valid_password() -> bool {
temporary_enabled() && !temporary_password().is_empty()
|| permanent_enabled() && !Config::get_permanent_password().is_empty()
} }
} }
pub mod config { pub fn temporary_password_length() -> usize {
use super::base64::decrypt as decrypt00; let length = Config::get_option("temporary-password-length");
use super::base64::encrypt as encrypt00; if length == "8" {
8
const VERSION_LEN: usize = 2; } else if length == "10" {
10
pub fn encrypt_str_or_original(s: &str, version: &str) -> String { } else {
if decrypt_str_or_original(s, version).1 { 6 // default
log::error!("Duplicate encryption!");
return s.to_owned();
}
if version.len() == VERSION_LEN {
if version == "00" {
if let Ok(s) = encrypt00(s.as_bytes()) {
return version.to_owned() + &s;
}
}
}
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, 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(), false, !s.is_empty())
}
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 == "00" {
if let Ok(s) = encrypt00(v) {
let mut version = version.to_owned().into_bytes();
version.append(&mut s.into_bytes());
return version;
}
}
}
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<u8>, 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, true, version != current_version);
}
}
}
(v.to_owned(), false, !v.is_empty())
}
mod test {
#[test]
fn test() {
use crate::password_security::config::*;
let version = "00";
println!("test str");
let data = "Hello World";
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!(version, &encrypted[..2]);
assert_eq!(succ, true);
assert_eq!(store, false);
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<u8> = 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!(version.as_bytes(), &encrypted[..2]);
assert_eq!(store, false);
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 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);
assert_eq!(succ, false);
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!(store, true);
assert_eq!(succ, false);
let (_, succ, store) = decrypt_str_or_original("", version);
assert_eq!(store, false);
assert_eq!(succ, false);
let (_, succ, store) = decrypt_vec_or_original(&vec![], version);
assert_eq!(store, false);
assert_eq!(succ, false);
}
} }
} }
mod base64 { pub fn temporary_enabled() -> bool {
use super::symmetric_crypt; verification_method() != VerificationMethod::OnlyUsePermanentPassword
use sodiumoxide::base64; }
pub fn encrypt(v: &[u8]) -> Result<String, ()> { pub fn permanent_enabled() -> bool {
if v.len() > 0 { verification_method() != VerificationMethod::OnlyUseTemporaryPassword
symmetric_crypt(v, true).map(|v| base64::encode(v, base64::Variant::Original)) }
} else {
Err(()) pub fn has_valid_password() -> bool {
temporary_enabled() && !temporary_password().is_empty()
|| permanent_enabled() && !Config::get_permanent_password().is_empty()
}
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 == "00" {
if let Ok(s) = encrypt(s.as_bytes()) {
return version.to_owned() + &s;
}
}
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, bool) {
if s.len() > VERSION_LEN {
let version = &s[..VERSION_LEN];
if version == "00" {
if let Ok(v) = decrypt(&s[VERSION_LEN..].as_bytes()) {
return (
String::from_utf8_lossy(&v).to_string(),
true,
version != current_version,
);
}
} }
} }
pub fn decrypt(v: &[u8]) -> Result<Vec<u8>, ()> { (s.to_owned(), false, !s.is_empty())
if v.len() > 0 { }
base64::decode(v, base64::Variant::Original).and_then(|v| symmetric_crypt(&v, false))
} else { pub fn encrypt_vec_or_original(v: &[u8], version: &str) -> Vec<u8> {
Err(()) if decrypt_vec_or_original(v, version).1 {
log::error!("Duplicate encryption!");
return v.to_owned();
}
if version == "00" {
if let Ok(s) = encrypt(v) {
let mut version = version.to_owned().into_bytes();
version.append(&mut s.into_bytes());
return version;
} }
} }
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<u8>, bool, bool) {
if v.len() > VERSION_LEN {
let version = String::from_utf8_lossy(&v[..VERSION_LEN]);
if version == "00" {
if let Ok(v) = decrypt(&v[VERSION_LEN..]) {
return (v, true, version != current_version);
}
}
}
(v.to_owned(), false, !v.is_empty())
}
fn encrypt(v: &[u8]) -> Result<String, ()> {
if v.len() > 0 {
symmetric_crypt(v, true).map(|v| base64::encode(v, base64::Variant::Original))
} else {
Err(())
}
}
fn decrypt(v: &[u8]) -> Result<Vec<u8>, ()> {
if v.len() > 0 {
base64::decode(v, base64::Variant::Original).and_then(|v| symmetric_crypt(&v, false))
} else {
Err(())
}
} }
fn symmetric_crypt(data: &[u8], encrypt: bool) -> Result<Vec<u8>, ()> { fn symmetric_crypt(data: &[u8], encrypt: bool) -> Result<Vec<u8>, ()> {
@ -234,3 +155,64 @@ fn symmetric_crypt(data: &[u8], encrypt: bool) -> Result<Vec<u8>, ()> {
secretbox::open(data, &nonce, &key) secretbox::open(data, &nonce, &key)
} }
} }
mod test {
#[test]
fn test() {
use super::*;
let version = "00";
println!("test str");
let data = "Hello World";
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!(version, &encrypted[..2]);
assert_eq!(succ, true);
assert_eq!(store, false);
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<u8> = 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!(version.as_bytes(), &encrypted[..2]);
assert_eq!(store, false);
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 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);
assert_eq!(succ, false);
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!(store, true);
assert_eq!(succ, false);
let (_, succ, store) = decrypt_str_or_original("", version);
assert_eq!(store, false);
assert_eq!(succ, false);
let (_, succ, store) = decrypt_vec_or_original(&vec![], version);
assert_eq!(store, false);
assert_eq!(succ, false);
}
}

View File

@ -8,9 +8,7 @@ use hbb_common::{
config::{self, Config, Config2}, config::{self, Config, Config2},
futures::StreamExt as _, futures::StreamExt as _,
futures_util::sink::SinkExt, futures_util::sink::SinkExt,
log, log, password_security as password, timeout, tokio,
password_security::password,
timeout, tokio,
tokio::io::{AsyncRead, AsyncWrite}, tokio::io::{AsyncRead, AsyncWrite},
tokio_util::codec::Framed, tokio_util::codec::Framed,
ResultType, ResultType,

View File

@ -171,21 +171,19 @@ 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 mut config: Config = load_path(path.into()); let 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 store_path(Config::file(), config).is_err() {
if Config::set(config) {
log::info!("config written"); log::info!("config written");
} }
} }
let mut config2: Config2 = load_path(path2.into()); let 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 store_path(Config2::file(), config2).is_err() {
if Config2::set(config2) {
log::info!("config2 written"); log::info!("config2 written");
} }
} }

View File

@ -1,13 +1,11 @@
use crate::client::file_trait::FileManager; use crate::client::file_trait::FileManager;
use crate::common::make_fd_to_json;
use crate::mobile::connection_manager::{self, get_clients_length, get_clients_state}; use crate::mobile::connection_manager::{self, get_clients_length, get_clients_state};
use crate::mobile::{self, Session}; use crate::mobile::{self, Session};
use crate::common::{make_fd_to_json};
use flutter_rust_bridge::{StreamSink, ZeroCopyBuffer}; use flutter_rust_bridge::{StreamSink, ZeroCopyBuffer};
use hbb_common::{ResultType, init_uuid};
use hbb_common::password_security::password;
use hbb_common::{ use hbb_common::{
config::{self, Config, LocalConfig, PeerConfig, ONLINE}, config::{self, Config, LocalConfig, PeerConfig, ONLINE},
fs, log, fs, log, password_security as password, ResultType,
}; };
use serde_json::{Number, Value}; use serde_json::{Number, Value};
use std::{ use std::{
@ -31,7 +29,6 @@ fn initialize(app_dir: &str) {
init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")); init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug"));
} }
*config::APP_DIR.write().unwrap() = app_dir.to_owned(); *config::APP_DIR.write().unwrap() = app_dir.to_owned();
init_uuid();
crate::common::test_rendezvous_server(); crate::common::test_rendezvous_server();
crate::common::test_nat_type(); crate::common::test_nat_type();
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
@ -462,9 +459,7 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) {
} }
} }
// Server Side // Server Side
"permanent_password" => { "permanent_password" => Config::set_permanent_password(value),
Config::set_permanent_password(value)
}
"temporary_password" => { "temporary_password" => {
password::update_temporary_password(); password::update_temporary_password();
} }

View File

@ -7,15 +7,14 @@ use crate::video_service;
#[cfg(any(target_os = "android", target_os = "ios"))] #[cfg(any(target_os = "android", target_os = "ios"))]
use crate::{common::MOBILE_INFO2, mobile::connection_manager::start_channel}; use crate::{common::MOBILE_INFO2, mobile::connection_manager::start_channel};
use crate::{ipc, VERSION}; use crate::{ipc, VERSION};
use hbb_common::fs::can_enable_overwrite_detection;
use hbb_common::password_security::password;
use hbb_common::{ use hbb_common::{
config::Config, config::Config,
fs, fs,
fs::can_enable_overwrite_detection,
futures::{SinkExt, StreamExt}, futures::{SinkExt, StreamExt},
get_version_number, get_version_number,
message_proto::{option_message::BoolOption, permission_info::Permission}, message_proto::{option_message::BoolOption, permission_info::Permission},
sleep, timeout, password_security as password, sleep, timeout,
tokio::{ tokio::{
net::TcpStream, net::TcpStream,
sync::mpsc, sync::mpsc,