mirror of
https://github.com/rustdesk/rustdesk-server.git
synced 2026-02-28 00:53:11 +08:00
Merge branch 'master' into tmp
This commit is contained in:
@@ -29,7 +29,7 @@ pub const READ_TIMEOUT: u64 = 30_000;
|
||||
pub const REG_INTERVAL: i64 = 12_000;
|
||||
pub const COMPRESS_LEVEL: i32 = 3;
|
||||
const SERIAL: i32 = 3;
|
||||
const PASSWORD_ENC_VERSION: &'static str = "00";
|
||||
const PASSWORD_ENC_VERSION: &str = "00";
|
||||
// 128x128
|
||||
#[cfg(target_os = "macos")] // 128x128 on 160x160 canvas, then shrink to 128, mac looks better with padding
|
||||
pub const ICON: &str = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAAyVBMVEUAAAAAcf8Acf8Acf8Acv8Acf8Acf8Acf8Acf8AcP8Acf8Ab/8AcP8Acf////8AaP/z+f/o8v/k7v/5/v/T5f8AYP/u9v/X6f+hx/+Kuv95pP8Aef/B1/+TwP9xoP8BdP/g6P+Irv9ZmP8Bgf/E3f98q/9sn/+01f+Es/9nm/9Jif8hhv8off/M4P+syP+avP86iP/c7f+xy/9yqf9Om/9hk/9Rjv+60P99tv9fpf88lv8yjf8Tgf8deP+kvP8BiP8NeP8hkP80gP8oj2VLAAAADXRSTlMA7o7qLvnaxZ1FOxYPjH9HWgAABHJJREFUeNrtm+tW4jAQgBfwuu7MtIUWsOUiCCioIIgLiqvr+z/UHq/LJKVkmwTcc/r9E2nzlU4mSTP9lpGRkZGR8VX5cZjfL+yCEXYL+/nDH//U/Pd8DgyTy39Xbv7oIAcWyB0cqbW/sweW2NtRaj8H1sgpGOwUIAH7Bkd7YJW9dXFwAJY5WNP/cmCZQnJvzIN18on5LwfWySXlxEPYAIcad8D6PdiHDbCfIFCADVBIENiFDbCbIACKPPXrZ+cP8E6/0znvP4EymgIEravIRcTxu8HxNSJ60a8W0AYECKrlAN+YwAthCd9wm1Ug6wKzIn5SgRduXfwkqDasCjx0XFzi9PV6zwNcIuhcWBOg+ikySq8C9UD4dEKWBCoOcspvAuLHTo9sCDQiFPHotRM48j8G5gVur1FdAN2uaYEuiz7xFsgEJ2RUoMUakXuBTHHoGxQYOBhHjeUBAefEnMAowFhaLBOKuOemBBbxLRQrH2PBCgMvNCPQGMeevTb9zLrPxz2Mo+QbEaijzPUcOOHMQZkKGRAIPem39+bypREMPTkQW/oCfk866zAkiIFG4yIKRE/aAnfiSd0WrORY6pFdXQEqi9mvAQm0RIOSnoCcZ8vJoz3diCnjRk+g8VP4/fuQDJ2Lxr6WwG0gXs9aTpDzW0vgDBlVUpixR8gYk44AD8FrUKHr8JQJGgIDnoDqoALxmWPQSi9AVVzm8gKUuEPGr/QCvptwJkbSYT/TC4S8C96DGjTj86aHtAI0x2WaBIq0eSYYpRa4EsdWVVwWu9O0Aj6f6dyBMnwEraeOgSYu0wZlauzA47QCbT7DgAQSE+hZWoEBF/BBmWOewNMK3BsSqKUW4MGcWqCSVmDkbvkXGKQOwg6PAUO9oL3xXhA20yaiCjuwYygRVQlUOTWTCf2SuNJTxeFjgaHByGuAIvd8ItdPLTDhS7IuqEE1YSKVOgbayLhSFQhMzYh8hwfBs1r7c505YVIQYEdNoKwxK06MJiyrpUFHiF0NAfCQUVHoiRclIXJIR6C2fqG37pBHvcWpgwzvAtYwkR5UGV2e42UISdBJETl3mg8ouo54Rcnti1/vaT+iuUQBt500Cgo4U10BeHSkk57FB0JjWkKRMWgLUA0lLodtImAQdaMiiri3+gIAPZQoutHNsgKF1aaDMhMyIdBf8Th+Bh8MTjGWCpl5Wv43tDmnF+IUVMrcZgRoiAxhtrloYizNkZaAnF5leglbNhj0wYCAbCDvGb0mP4nib7O7ZlcYQ2m1gPtIZgVgGNNMeaVAaWR+57TrqgtUnm3sHQ+kYeE6fufUubG1ez50FXbPnWgBlgSABmN3TTcsRl2yWkHRrwbiunvk/W2+Mg1hPZplPDeXRbZzStFH15s1QIVd3UImP5z/bHpeeQLvRJ7XLFUffQIlCvqlXETQbgN9/rlYABGosv+Vi9m2Xs639YLGrZd0br+odetlvdsvbN56abfd4vbCzv9Q3v/ygoOV21A4OPpfXvH4Ai+5ZGRkZGRkbJA/t/I0QMzoMiEAAAAASUVORK5CYII=
|
||||
@@ -43,6 +43,7 @@ lazy_static::lazy_static! {
|
||||
}
|
||||
|
||||
type Size = (i32, i32, i32, i32);
|
||||
type KeyPair = (Vec<u8>, Vec<u8>);
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref CONFIG: Arc<RwLock<Config>> = Arc::new(RwLock::new(Config::load()));
|
||||
@@ -54,7 +55,7 @@ lazy_static::lazy_static! {
|
||||
_ => "",
|
||||
}.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();
|
||||
static ref KEY_PAIR: Arc<Mutex<Option<KeyPair>>> = Default::default();
|
||||
static ref HW_CODEC_CONFIG: Arc<RwLock<HwCodecConfig>> = Arc::new(RwLock::new(HwCodecConfig::load()));
|
||||
}
|
||||
|
||||
@@ -75,12 +76,12 @@ lazy_static::lazy_static! {
|
||||
]);
|
||||
}
|
||||
|
||||
const CHARS: &'static [char] = &[
|
||||
const CHARS: &[char] = &[
|
||||
'2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
|
||||
'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
];
|
||||
|
||||
const RENDEZVOUS_SERVERS: &'static [&'static str] = &[
|
||||
pub const RENDEZVOUS_SERVERS: &[&str] = &[
|
||||
"rs-ny.rustdesk.com",
|
||||
"rs-sg.rustdesk.com",
|
||||
"rs-cn.rustdesk.com",
|
||||
@@ -131,7 +132,7 @@ pub struct Config {
|
||||
#[serde(default)]
|
||||
salt: String,
|
||||
#[serde(default)]
|
||||
key_pair: (Vec<u8>, Vec<u8>), // sk, pk
|
||||
key_pair: KeyPair, // sk, pk
|
||||
#[serde(default)]
|
||||
key_confirmed: bool,
|
||||
#[serde(default)]
|
||||
@@ -319,7 +320,7 @@ impl Config2 {
|
||||
pub fn load_path<T: serde::Serialize + serde::de::DeserializeOwned + Default + std::fmt::Debug>(
|
||||
file: PathBuf,
|
||||
) -> T {
|
||||
let cfg = match confy::load_path(&file) {
|
||||
let cfg = match confy::load_path(file) {
|
||||
Ok(config) => config,
|
||||
Err(err) => {
|
||||
log::error!("Failed to load config: {}", err);
|
||||
@@ -366,20 +367,16 @@ impl Config {
|
||||
config.id = id;
|
||||
id_valid = true;
|
||||
store |= store2;
|
||||
} else {
|
||||
if crate::get_modified_time(&Self::file_(""))
|
||||
.checked_sub(std::time::Duration::from_secs(30)) // allow modification during installation
|
||||
.unwrap_or(crate::get_exe_time())
|
||||
< crate::get_exe_time()
|
||||
{
|
||||
if !config.id.is_empty()
|
||||
&& config.enc_id.is_empty()
|
||||
&& !decrypt_str_or_original(&config.id, PASSWORD_ENC_VERSION).1
|
||||
{
|
||||
id_valid = true;
|
||||
store = true;
|
||||
}
|
||||
}
|
||||
} else if crate::get_modified_time(&Self::file_(""))
|
||||
.checked_sub(std::time::Duration::from_secs(30)) // allow modification during installation
|
||||
.unwrap_or_else(crate::get_exe_time)
|
||||
< crate::get_exe_time()
|
||||
&& !config.id.is_empty()
|
||||
&& config.enc_id.is_empty()
|
||||
&& !decrypt_str_or_original(&config.id, PASSWORD_ENC_VERSION).1
|
||||
{
|
||||
id_valid = true;
|
||||
store = true;
|
||||
}
|
||||
if !id_valid {
|
||||
for _ in 0..3 {
|
||||
@@ -444,18 +441,18 @@ impl Config {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
{
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let org = "";
|
||||
let org = "".to_owned();
|
||||
#[cfg(target_os = "macos")]
|
||||
let org = ORG.read().unwrap().clone();
|
||||
// /var/root for root
|
||||
if let Some(project) =
|
||||
directories_next::ProjectDirs::from("", &org, &*APP_NAME.read().unwrap())
|
||||
directories_next::ProjectDirs::from("", &org, &APP_NAME.read().unwrap())
|
||||
{
|
||||
let mut path = patch(project.config_dir().to_path_buf());
|
||||
path.push(p);
|
||||
return path;
|
||||
}
|
||||
return "".into();
|
||||
"".into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,9 +536,9 @@ impl Config {
|
||||
rendezvous_server = Self::get_rendezvous_servers()
|
||||
.drain(..)
|
||||
.next()
|
||||
.unwrap_or("".to_owned());
|
||||
.unwrap_or_default();
|
||||
}
|
||||
if !rendezvous_server.contains(":") {
|
||||
if !rendezvous_server.contains(':') {
|
||||
rendezvous_server = format!("{}:{}", rendezvous_server, RENDEZVOUS_PORT);
|
||||
}
|
||||
rendezvous_server
|
||||
@@ -559,8 +556,8 @@ impl Config {
|
||||
let serial_obsolute = CONFIG2.read().unwrap().serial > SERIAL;
|
||||
if serial_obsolute {
|
||||
let ss: Vec<String> = Self::get_option("rendezvous-servers")
|
||||
.split(",")
|
||||
.filter(|x| x.contains("."))
|
||||
.split(',')
|
||||
.filter(|x| x.contains('.'))
|
||||
.map(|x| x.to_owned())
|
||||
.collect();
|
||||
if !ss.is_empty() {
|
||||
@@ -580,7 +577,7 @@ impl Config {
|
||||
let mut delay = i64::MAX;
|
||||
for (tmp_host, tmp_delay) in ONLINE.lock().unwrap().iter() {
|
||||
if tmp_delay > &0 && tmp_delay < &delay {
|
||||
delay = tmp_delay.clone();
|
||||
delay = *tmp_delay;
|
||||
host = tmp_host.to_string();
|
||||
}
|
||||
}
|
||||
@@ -647,7 +644,7 @@ impl Config {
|
||||
for x in &ma.bytes()[2..] {
|
||||
id = (id << 8) | (*x as u32);
|
||||
}
|
||||
id = id & 0x1FFFFFFF;
|
||||
id &= 0x1FFFFFFF;
|
||||
Some(id.to_string())
|
||||
} else {
|
||||
None
|
||||
@@ -679,11 +676,7 @@ impl Config {
|
||||
}
|
||||
|
||||
pub fn get_host_key_confirmed(host: &str) -> bool {
|
||||
if let Some(true) = CONFIG.read().unwrap().keys_confirmed.get(host) {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
matches!(CONFIG.read().unwrap().keys_confirmed.get(host), Some(true))
|
||||
}
|
||||
|
||||
pub fn set_host_key_confirmed(host: &str, v: bool) {
|
||||
@@ -695,7 +688,7 @@ impl Config {
|
||||
config.store();
|
||||
}
|
||||
|
||||
pub fn get_key_pair() -> (Vec<u8>, Vec<u8>) {
|
||||
pub fn get_key_pair() -> KeyPair {
|
||||
// lock here to make sure no gen_keypair more than once
|
||||
// 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();
|
||||
@@ -714,7 +707,7 @@ impl Config {
|
||||
});
|
||||
}
|
||||
*lock = Some(config.key_pair.clone());
|
||||
return config.key_pair;
|
||||
config.key_pair
|
||||
}
|
||||
|
||||
pub fn get_id() -> String {
|
||||
@@ -849,7 +842,7 @@ impl Config {
|
||||
let ext = path.extension();
|
||||
if let Some(ext) = ext {
|
||||
let ext = format!("{}.toml", ext.to_string_lossy());
|
||||
path.with_extension(&ext)
|
||||
path.with_extension(ext)
|
||||
} else {
|
||||
path.with_extension("toml")
|
||||
}
|
||||
@@ -861,7 +854,7 @@ const PEERS: &str = "peers";
|
||||
impl PeerConfig {
|
||||
pub fn load(id: &str) -> PeerConfig {
|
||||
let _lock = CONFIG.read().unwrap();
|
||||
match confy::load_path(&Self::path(id)) {
|
||||
match confy::load_path(Self::path(id)) {
|
||||
Ok(config) => {
|
||||
let mut config: PeerConfig = config;
|
||||
let mut store = false;
|
||||
@@ -869,16 +862,16 @@ impl PeerConfig {
|
||||
decrypt_vec_or_original(&config.password, PASSWORD_ENC_VERSION);
|
||||
config.password = password;
|
||||
store = store || store2;
|
||||
config.options.get_mut("rdp_password").map(|v| {
|
||||
if let Some(v) = config.options.get_mut("rdp_password") {
|
||||
let (password, _, store2) = decrypt_str_or_original(v, PASSWORD_ENC_VERSION);
|
||||
*v = password;
|
||||
store = store || store2;
|
||||
});
|
||||
config.options.get_mut("os-password").map(|v| {
|
||||
}
|
||||
if let Some(v) = config.options.get_mut("os-password") {
|
||||
let (password, _, store2) = decrypt_str_or_original(v, PASSWORD_ENC_VERSION);
|
||||
*v = password;
|
||||
store = store || store2;
|
||||
});
|
||||
}
|
||||
if store {
|
||||
config.store(id);
|
||||
}
|
||||
@@ -895,34 +888,29 @@ impl PeerConfig {
|
||||
let _lock = CONFIG.read().unwrap();
|
||||
let mut config = self.clone();
|
||||
config.password = encrypt_vec_or_original(&config.password, PASSWORD_ENC_VERSION);
|
||||
config
|
||||
.options
|
||||
.get_mut("rdp_password")
|
||||
.map(|v| *v = encrypt_str_or_original(v, PASSWORD_ENC_VERSION));
|
||||
config
|
||||
.options
|
||||
.get_mut("os-password")
|
||||
.map(|v| *v = encrypt_str_or_original(v, PASSWORD_ENC_VERSION));
|
||||
if let Some(v) = config.options.get_mut("rdp_password") {
|
||||
*v = encrypt_str_or_original(v, PASSWORD_ENC_VERSION)
|
||||
}
|
||||
if let Some(v) = config.options.get_mut("os-password") {
|
||||
*v = encrypt_str_or_original(v, PASSWORD_ENC_VERSION)
|
||||
};
|
||||
if let Err(err) = store_path(Self::path(id), config) {
|
||||
log::error!("Failed to store config: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(id: &str) {
|
||||
fs::remove_file(&Self::path(id)).ok();
|
||||
fs::remove_file(Self::path(id)).ok();
|
||||
}
|
||||
|
||||
fn path(id: &str) -> PathBuf {
|
||||
let id_encoded: String;
|
||||
|
||||
//If the id contains invalid chars, encode it
|
||||
let forbidden_paths = Regex::new(r".*[<>:/\\|\?\*].*").unwrap();
|
||||
if forbidden_paths.is_match(id) {
|
||||
id_encoded =
|
||||
"base64_".to_string() + base64::encode(id, base64::Variant::Original).as_str();
|
||||
let id_encoded = if forbidden_paths.is_match(id) {
|
||||
"base64_".to_string() + base64::encode(id, base64::Variant::Original).as_str()
|
||||
} else {
|
||||
id_encoded = id.to_string();
|
||||
}
|
||||
id.to_string()
|
||||
};
|
||||
let path: PathBuf = [PEERS, id_encoded.as_str()].iter().collect();
|
||||
Config::with_extension(Config::path(path))
|
||||
}
|
||||
@@ -940,26 +928,24 @@ impl PeerConfig {
|
||||
&& p.extension().map(|p| p.to_str().unwrap_or("")) == Some("toml")
|
||||
})
|
||||
.map(|p| {
|
||||
let t = crate::get_modified_time(&p);
|
||||
let t = crate::get_modified_time(p);
|
||||
let id = p
|
||||
.file_stem()
|
||||
.map(|p| p.to_str().unwrap_or(""))
|
||||
.unwrap_or("")
|
||||
.to_owned();
|
||||
|
||||
let id_decoded_string: String;
|
||||
if id.starts_with("base64_") && id.len() != 7 {
|
||||
let id_decoded_string = if id.starts_with("base64_") && id.len() != 7 {
|
||||
let id_decoded = base64::decode(&id[7..], base64::Variant::Original)
|
||||
.unwrap_or(Vec::new());
|
||||
id_decoded_string =
|
||||
String::from_utf8_lossy(&id_decoded).as_ref().to_owned();
|
||||
.unwrap_or_default();
|
||||
String::from_utf8_lossy(&id_decoded).as_ref().to_owned()
|
||||
} else {
|
||||
id_decoded_string = id;
|
||||
}
|
||||
id
|
||||
};
|
||||
|
||||
let c = PeerConfig::load(&id_decoded_string);
|
||||
if c.info.platform.is_empty() {
|
||||
fs::remove_file(&p).ok();
|
||||
fs::remove_file(p).ok();
|
||||
}
|
||||
(id_decoded_string, t, c)
|
||||
})
|
||||
@@ -1149,7 +1135,7 @@ pub struct LanPeers {
|
||||
impl LanPeers {
|
||||
pub fn load() -> LanPeers {
|
||||
let _lock = CONFIG.read().unwrap();
|
||||
match confy::load_path(&Config::file_("_lan_peers")) {
|
||||
match confy::load_path(Config::file_("_lan_peers")) {
|
||||
Ok(peers) => peers,
|
||||
Err(err) => {
|
||||
log::error!("Failed to load lan peers: {}", err);
|
||||
@@ -1158,9 +1144,9 @@ impl LanPeers {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn store(peers: &Vec<DiscoveryPeer>) {
|
||||
pub fn store(peers: &[DiscoveryPeer]) {
|
||||
let f = LanPeers {
|
||||
peers: peers.clone(),
|
||||
peers: peers.to_owned(),
|
||||
};
|
||||
if let Err(err) = store_path(Config::file_("_lan_peers"), f) {
|
||||
log::error!("Failed to store lan peers: {}", err);
|
||||
|
||||
Reference in New Issue
Block a user