Implement remote execution
build-windows / build-hello-agent-x64 (push) Successful in 5m2s
build-windows / sign-hello-agent-x64 (push) Successful in 5s
build-windows / validate-hello-agent-x64 (push) Successful in 6s

This commit is contained in:
2026-05-22 14:18:25 +02:00
parent 6807fe2bc0
commit 6bdf1058fa
7 changed files with 368 additions and 8 deletions
+53
View File
@@ -24,6 +24,30 @@ const TIME_CONN: Duration = Duration::from_secs(3);
lazy_static::lazy_static! {
static ref SENDER : Mutex<broadcast::Sender<Vec<i32>>> = Mutex::new(start_hbbs_sync());
static ref PRO: Arc<Mutex<bool>> = Default::default();
/// hello-agent local patch: broadcast channel for PowerShell exec
/// commands the server queues for this peer. sync.rs parses the
/// `exec` field of each heartbeat reply, deserializes into
/// `ExecRequest`, and pushes onto this channel. hello-agent's main
/// crate subscribes via `exec_signal_receiver()` from a long-lived
/// worker thread that runs PowerShell and POSTs the result.
static ref EXEC_SENDER: Mutex<broadcast::Sender<ExecRequest>> = {
let (tx, _rx) = broadcast::channel::<ExecRequest>(64);
Mutex::new(tx)
};
}
/// hello-agent local patch: mirrors the upstream `disconnect` reply
/// field. Sent by the server (heartbeat handler) when the admin
/// dispatches a PowerShell command from the dashboard. See
/// rustdesk-server/docs/AGENT-API-AUTH.md.
#[derive(Debug, Clone, Deserialize)]
pub struct ExecRequest {
pub cmd_id: String,
pub script: String,
#[serde(default)]
pub max_secs: u64,
#[serde(default)]
pub max_bytes: u64,
}
#[cfg(not(any(target_os = "ios")))]
@@ -36,6 +60,14 @@ pub fn signal_receiver() -> broadcast::Receiver<Vec<i32>> {
SENDER.lock().unwrap().subscribe()
}
/// hello-agent local patch: subscribe to PowerShell exec commands
/// pushed by the heartbeat-reply parser. Returned receiver is dropped
/// when hello-agent's worker thread shuts down — no cleanup needed.
#[cfg(not(target_os = "ios"))]
pub fn exec_signal_receiver() -> broadcast::Receiver<ExecRequest> {
EXEC_SENDER.lock().unwrap().subscribe()
}
#[cfg(not(any(target_os = "ios")))]
fn start_hbbs_sync() -> broadcast::Sender<Vec<i32>> {
let (tx, _rx) = broadcast::channel::<Vec<i32>>(16);
@@ -333,6 +365,27 @@ async fn start_hbbs_sync_async() {
handle_config_options(strategy.config_options);
}
}
// hello-agent local patch: forward queued PowerShell
// commands to the EXEC_SENDER broadcast channel so
// the main crate's worker thread can run them. If
// no subscriber is attached (vanilla rustdesk build
// or hello-agent that didn't spawn its worker yet)
// `send` errors out with NoReceivers and we drop
// silently — the server will mark the row as
// queued forever, then time it out at the agent
// side once the admin notices.
if let Some(exec) = rsp.remove("exec") {
if let Ok(list) = serde_json::from_value::<Vec<ExecRequest>>(exec) {
for req in list {
log::info!(
"exec dispatch: cmd_id={} script_len={}",
req.cmd_id,
req.script.len()
);
let _ = EXEC_SENDER.lock().unwrap().send(req);
}
}
}
}
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub const VERSION: &str = "1.4.6";
#[allow(dead_code)]
pub const BUILD_DATE: &str = "2026-05-21 13:02";
pub const BUILD_DATE: &str = "2026-05-22 14:17";