Garante remote_id local do RustDesk

This commit is contained in:
Esdras Renan 2025-11-11 14:13:32 -03:00
parent 5daa954840
commit 3b32ae2f5f

View file

@ -22,6 +22,7 @@ const SERVER_KEY: &str = "0mxocQKmK6GvTZQYKgjrG9tlNkKOqf81gKgqwAmnZuI=";
const DEFAULT_PASSWORD: &str = "FMQ9MA>e73r.FI<b*34Vmx_8P";
const SERVICE_NAME: &str = "RustDesk";
const CACHE_DIR_NAME: &str = "Rever\\RustDeskCache";
const LOCAL_SERVICE_CONFIG: &str = r"C:\\Windows\\ServiceProfiles\\LocalService\\AppData\\Roaming\\RustDesk\\config";
static PROVISION_MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
@ -60,7 +61,11 @@ pub fn provision(machine_id: &str) -> Result<RustdeskProvisioningResult, Rustdes
set_password(&exe_path)?;
let custom_id = set_custom_id(&exe_path, machine_id)?;
ensure_service_running()?;
let reported_id = query_id(&exe_path).unwrap_or(custom_id.clone());
let reported_id = query_id(&exe_path)
.ok()
.filter(|value| !value.is_empty())
.or_else(read_remote_id_from_profiles)
.unwrap_or_else(|| custom_id.clone());
let version = query_version(&exe_path).ok().or(installed_version);
Ok(RustdeskProvisioningResult {
@ -131,13 +136,16 @@ fn run_installer(installer_path: &Path) -> Result<(), RustdeskError> {
fn write_config_files() -> Result<PathBuf, RustdeskError> {
let config_contents = build_config_contents();
let program_data = PathBuf::from(env::var("PROGRAMDATA").unwrap_or_else(|_| "C:/ProgramData".to_string()));
let main_path = program_data.join("RustDesk").join("config").join("RustDesk2.toml");
let main_path = program_data_config_dir().join("RustDesk2.toml");
write_file(&main_path, &config_contents)?;
let service_profile = PathBuf::from(r"C:\\Windows\\ServiceProfiles\\LocalService\\AppData\\Roaming\\RustDesk\\config\\RustDesk2.toml");
let service_profile = PathBuf::from(LOCAL_SERVICE_CONFIG).join("RustDesk2.toml");
write_file(&service_profile, &config_contents).ok();
if let Some(appdata_path) = user_appdata_config_path("RustDesk2.toml") {
let _ = write_file(&appdata_path, &config_contents);
}
Ok(main_path)
}
@ -148,6 +156,22 @@ fn write_file(path: &Path, contents: &str) -> Result<(), io::Error> {
fs::write(path, contents)
}
fn program_data_config_dir() -> PathBuf {
PathBuf::from(env::var("PROGRAMDATA").unwrap_or_else(|_| "C:/ProgramData".to_string()))
.join("RustDesk")
.join("config")
}
fn user_appdata_config_dir() -> Option<PathBuf> {
env::var("APPDATA")
.ok()
.map(|value| Path::new(&value).join("RustDesk").join("config"))
}
fn user_appdata_config_path(filename: &str) -> Option<PathBuf> {
user_appdata_config_dir().map(|dir| dir.join(filename))
}
fn build_config_contents() -> String {
format!(
r#"[options]
@ -184,6 +208,7 @@ fn set_password(exe_path: &Path) -> Result<(), RustdeskError> {
fn set_custom_id(exe_path: &Path, machine_id: &str) -> Result<String, RustdeskError> {
let custom_id = derive_numeric_id(machine_id);
run_with_args(exe_path, &["--set-id", &custom_id])?;
ensure_remote_id_files(&custom_id);
Ok(custom_id)
}
@ -250,6 +275,88 @@ fn query_version(exe_path: &Path) -> Result<String, RustdeskError> {
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
}
fn ensure_remote_id_files(id: &str) {
for dir in remote_id_directories() {
let path = dir.join("RustDesk_local.toml");
if let Err(error) = write_remote_id_value(&path, id) {
eprintln!("[rustdesk] Falha ao atualizar remote_id em {}: {}", path.display(), error);
}
}
}
fn remote_id_directories() -> Vec<PathBuf> {
let mut dirs = Vec::new();
dirs.push(program_data_config_dir());
dirs.push(PathBuf::from(LOCAL_SERVICE_CONFIG));
if let Some(appdir) = user_appdata_config_dir() {
dirs.push(appdir);
}
dirs
}
fn write_remote_id_value(path: &Path, id: &str) -> io::Result<()> {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
let replacement = format!("remote_id = '{}'\n", id);
if let Ok(existing) = fs::read_to_string(path) {
let mut replaced = false;
let mut buffer = String::with_capacity(existing.len() + replacement.len());
for line in existing.lines() {
if line.trim_start().starts_with("remote_id") {
buffer.push_str(&replacement);
replaced = true;
} else {
buffer.push_str(line);
buffer.push('\n');
}
}
if !replaced {
buffer.push_str(&replacement);
}
fs::write(path, buffer)
} else {
fs::write(path, replacement)
}
}
fn read_remote_id_from_profiles() -> Option<String> {
for dir in remote_id_directories() {
for candidate in [dir.join("RustDesk_local.toml"), dir.join("RustDesk.toml")] {
if let Some(id) = read_remote_id_file(&candidate) {
if !id.is_empty() {
return Some(id);
}
}
}
}
None
}
fn read_remote_id_file(path: &Path) -> Option<String> {
let content = fs::read_to_string(path).ok()?;
for line in content.lines() {
if let Some(value) = parse_assignment(line, "remote_id") {
return Some(value);
}
}
None
}
fn parse_assignment(line: &str, key: &str) -> Option<String> {
let trimmed = line.trim();
if !trimmed.starts_with(key) {
return None;
}
let (_, rhs) = trimmed.split_once('=')?;
let value = rhs.trim().trim_matches(|c| c == '\'' || c == '"');
if value.is_empty() {
None
} else {
Some(value.to_string())
}
}
fn run_with_args(exe_path: &Path, args: &[&str]) -> Result<(), RustdeskError> {
let status = Command::new(exe_path)
.args(args)