fix: persist RustDesk password in service profile

This commit is contained in:
Esdras Renan 2025-11-12 08:54:21 -03:00
parent ec18133a6d
commit 16ed53e24a

View file

@ -104,6 +104,14 @@ pub fn ensure_rustdesk(
log_event(&format!("Falha ao definir senha padrão: {error}")); log_event(&format!("Falha ao definir senha padrão: {error}"));
} else { } else {
log_event("Senha padrão definida com sucesso"); log_event("Senha padrão definida com sucesso");
match ensure_password_files(&password) {
Ok(_) => log_event("Senha persistida nos perfis do RustDesk"),
Err(error) => log_event(&format!("Falha ao persistir senha nos perfis: {error}")),
}
match replicate_password_artifacts() {
Ok(_) => log_event("Artefatos de senha replicados para o serviço do RustDesk"),
Err(error) => log_event(&format!("Falha ao replicar artefatos de senha: {error}")),
}
} }
let custom_id = if let Some(value) = machine_id.and_then(|raw| { let custom_id = if let Some(value) = machine_id.and_then(|raw| {
@ -429,6 +437,60 @@ fn remote_id_directories() -> Vec<PathBuf> {
dirs dirs
} }
fn ensure_password_files(secret: &str) -> Result<(), String> {
let mut errors = Vec::new();
for dir in remote_id_directories() {
let password_path = dir.join("RustDesk.toml");
if let Err(error) = write_toml_kv(&password_path, "password", secret) {
errors.push(format!("{} -> {}", password_path.display(), error));
}
let local_path = dir.join("RustDesk_local.toml");
if let Err(error) = write_toml_kv(&local_path, "verification-method", "use-both-passwords") {
log_event(&format!(
"Falha ao ajustar verification-method em {}: {error}",
local_path.display()
));
}
}
if errors.is_empty() {
Ok(())
} else {
Err(errors.join(" | "))
}
}
fn replicate_password_artifacts() -> io::Result<()> {
let Some(src) = user_appdata_config_dir() else {
return Ok(());
};
let destinations = [program_data_config_dir(), PathBuf::from(LOCAL_SERVICE_CONFIG)];
let candidates = ["password", "passwd", "passwd.txt"];
for dest in destinations {
fs::create_dir_all(&dest)?;
for name in candidates {
let source_path = src.join(name);
if !source_path.exists() {
continue;
}
let metadata = match fs::metadata(&source_path) {
Ok(data) => data,
Err(_) => continue,
};
if !metadata.is_file() || metadata.len() == 0 {
continue;
}
let target_path = dest.join(name);
fs::copy(&source_path, &target_path)?;
}
}
Ok(())
}
fn write_remote_id_value(path: &Path, id: &str) -> io::Result<()> { fn write_remote_id_value(path: &Path, id: &str) -> io::Result<()> {
if let Some(parent) = path.parent() { if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?; fs::create_dir_all(parent)?;
@ -465,6 +527,44 @@ fn write_remote_id_value(path: &Path, id: &str) -> io::Result<()> {
} }
} }
fn write_toml_kv(path: &Path, key: &str, value: &str) -> io::Result<()> {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
let sanitized = value.replace('\'', "''");
let replacement = format!("{key} = '{}'\n", sanitized);
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() {
let trimmed = line.trim_start();
if trimmed.starts_with(&format!("{key} ")) || trimmed.starts_with(&format!("{key}=")) {
buffer.push_str(&replacement);
replaced = true;
} else {
buffer.push_str(line);
buffer.push('\n');
}
}
if !replaced {
buffer.push_str(&replacement);
}
let mut file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(path)?;
file.write_all(buffer.as_bytes())
} else {
let mut file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(path)?;
file.write_all(replacement.as_bytes())
}
}
fn read_remote_id_from_profiles() -> Option<String> { fn read_remote_id_from_profiles() -> Option<String> {
for dir in remote_id_directories() { for dir in remote_id_directories() {
for candidate in [dir.join("RustDesk_local.toml"), dir.join("RustDesk.toml")] { for candidate in [dir.join("RustDesk_local.toml"), dir.join("RustDesk.toml")] {