trust this device to skip 2fa (#9012)

* trust this device to skip 2fa

Signed-off-by: 21pages <sunboeasy@gmail.com>

* Update connection.rs

---------

Signed-off-by: 21pages <sunboeasy@gmail.com>
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
This commit is contained in:
21pages
2024-08-12 18:08:33 +08:00
committed by GitHub
Unverified
parent 57834840b8
commit 1729ee337f
64 changed files with 845 additions and 22 deletions

View File

@@ -82,10 +82,12 @@ message LoginRequest {
string version = 11;
OSLogin os_login = 12;
string my_platform = 13;
bytes hwid = 14;
}
message Auth2FA {
string code = 1;
bytes hwid = 2;
}
message ChatMessage { string text = 1; }
@@ -137,6 +139,7 @@ message LoginResponse {
string error = 1;
PeerInfo peer_info = 2;
}
bool enable_trusted_devices = 3;
}
message TouchScaleUpdate {

View File

@@ -10,6 +10,7 @@ use std::{
};
use anyhow::Result;
use bytes::Bytes;
use rand::Rng;
use regex::Regex;
use serde as de;
@@ -52,6 +53,7 @@ lazy_static::lazy_static! {
static ref CONFIG: RwLock<Config> = RwLock::new(Config::load());
static ref CONFIG2: RwLock<Config2> = RwLock::new(Config2::load());
static ref LOCAL_CONFIG: RwLock<LocalConfig> = RwLock::new(LocalConfig::load());
static ref TRUSTED_DEVICES: RwLock<(Vec<TrustedDevice>, bool)> = Default::default();
static ref ONLINE: Mutex<HashMap<String, i64>> = Default::default();
pub static ref PROD_RENDEZVOUS_SERVER: RwLock<String> = RwLock::new(match option_env!("RENDEZVOUS_SERVER") {
Some(key) if !key.is_empty() => key,
@@ -210,6 +212,8 @@ pub struct Config2 {
serial: i32,
#[serde(default, deserialize_with = "deserialize_string")]
unlock_pin: String,
#[serde(default, deserialize_with = "deserialize_string")]
trusted_devices: String,
#[serde(default)]
socks: Option<Socks5Server>,
@@ -998,6 +1002,7 @@ impl Config {
}
config.password = password.into();
config.store();
Self::clear_trusted_devices();
}
pub fn get_permanent_password() -> String {
@@ -1104,6 +1109,64 @@ impl Config {
config.store();
}
pub fn get_trusted_devices_json() -> String {
serde_json::to_string(&Self::get_trusted_devices()).unwrap_or_default()
}
pub fn get_trusted_devices() -> Vec<TrustedDevice> {
let (devices, synced) = TRUSTED_DEVICES.read().unwrap().clone();
if synced {
return devices;
}
let devices = CONFIG2.read().unwrap().trusted_devices.clone();
let (devices, succ, store) = decrypt_str_or_original(&devices, PASSWORD_ENC_VERSION);
if succ {
let mut devices: Vec<TrustedDevice> =
serde_json::from_str(&devices).unwrap_or_default();
let len = devices.len();
devices.retain(|d| !d.outdate());
if store || devices.len() != len {
Self::set_trusted_devices(devices.clone());
}
*TRUSTED_DEVICES.write().unwrap() = (devices.clone(), true);
devices
} else {
Default::default()
}
}
fn set_trusted_devices(mut trusted_devices: Vec<TrustedDevice>) {
trusted_devices.retain(|d| !d.outdate());
let devices = serde_json::to_string(&trusted_devices).unwrap_or_default();
let max_len = 1024 * 1024;
if devices.bytes().len() > max_len {
log::error!("Trusted devices too large: {}", devices.bytes().len());
return;
}
let devices = encrypt_str_or_original(&devices, PASSWORD_ENC_VERSION, max_len);
let mut config = CONFIG2.write().unwrap();
config.trusted_devices = devices;
config.store();
*TRUSTED_DEVICES.write().unwrap() = (trusted_devices, true);
}
pub fn add_trusted_device(device: TrustedDevice) {
let mut devices = Self::get_trusted_devices();
devices.retain(|d| d.hwid != device.hwid);
devices.push(device);
Self::set_trusted_devices(devices);
}
pub fn remove_trusted_devices(hwids: &Vec<Bytes>) {
let mut devices = Self::get_trusted_devices();
devices.retain(|d| !hwids.contains(&d.hwid));
Self::set_trusted_devices(devices);
}
pub fn clear_trusted_devices() {
Self::set_trusted_devices(Default::default());
}
pub fn get() -> Config {
return CONFIG.read().unwrap().clone();
}
@@ -1934,6 +1997,22 @@ impl Group {
}
}
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct TrustedDevice {
pub hwid: Bytes,
pub time: i64,
pub id: String,
pub name: String,
pub platform: String,
}
impl TrustedDevice {
pub fn outdate(&self) -> bool {
const DAYS_90: i64 = 90 * 24 * 60 * 60 * 1000;
self.time + DAYS_90 < crate::get_time()
}
}
deserialize_default!(deserialize_string, String);
deserialize_default!(deserialize_bool, bool);
deserialize_default!(deserialize_i32, i32);
@@ -2123,6 +2202,7 @@ pub mod keys {
pub const OPTION_ENABLE_DIRECTX_CAPTURE: &str = "enable-directx-capture";
pub const OPTION_ENABLE_ANDROID_SOFTWARE_ENCODING_HALF_SCALE: &str =
"enable-android-software-encoding-half-scale";
pub const OPTION_ENABLE_TRUSTED_DEVICES: &str = "enable-trusted-devices";
// buildin options
pub const OPTION_DISPLAY_NAME: &str = "display-name";
@@ -2264,6 +2344,7 @@ pub mod keys {
OPTION_PRESET_ADDRESS_BOOK_TAG,
OPTION_ENABLE_DIRECTX_CAPTURE,
OPTION_ENABLE_ANDROID_SOFTWARE_ENCODING_HALF_SCALE,
OPTION_ENABLE_TRUSTED_DEVICES,
];
// BUILDIN_SETTINGS