f8ead215d8
build-windows / build-hello-agent-x64 (push) Successful in 5m41s
A single-binary, Flutter-free remote-support agent that speaks the stock
RustDesk wire protocol. Designed for one-line MDM deployment against a
self-hosted rustdesk-server: a supporter using the unmodified rustdesk.exe
client connects, the controlled-side user gets a native Win32 approval
prompt, click Yes / No.
CLI surface
hello-agent.exe --install # register + start service
hello-agent.exe --uninstall # stop, delete, clean up
hello-agent.exe --config <BLOB> # admin-UI deploy string
hello-agent.exe --install --config <BLOB> # MDM one-liner
--config accepts both forms emitted by the rustdesk-server admin UI: the
reversed-base64 deploy string and the host=,key=,api=,relay= filename
form. Decoded via the upstream custom_server module, persisted via
hbb_common::config::Config::set_option.
Architecture
--service runs as a Session 0 LocalSystem service. It polls
WTSGetActiveConsoleSessionId and (re)spawns hello-agent.exe --server
into the active console session via librustdesk::platform::run_as_user,
handling the Session 0 → user-session token impersonation.
--server is the worker. It boots three concurrent components:
1. cm_popup: an IPC listener on the rustdesk `_cm` named pipe
2. librustdesk::start_server(true, false): the upstream protocol
stack — rendezvous mediator, NAT punch, IPC server, screen
capture, login validation, hbbs_http heartbeat / sysinfo sync
3. (implicit) ApproveMode::Click is pinned in config, so every
incoming connection routes through cm_popup
The popup mechanism reuses an existing upstream contract without any
patches to the protocol code: when a peer connects with no password,
Connection::start in the upstream code calls try_start_cm_ipc, which
ipc::connect-s the `_cm` pipe before falling back to spawning a Flutter
CM child. Since cm_popup is up first, step 1 succeeds; we read the
Data::Login{authorized:false} frame, show MessageBoxTimeoutW (Yes/No,
60s, top-most, system-modal), and reply Data::Authorize or Data::Close.
Source tree
src/main.rs CLI dispatcher + run_server() composition
src/cli.rs hand-rolled argv parser + unit tests
src/service.rs windows-service install/uninstall/dispatcher
src/config_import.rs --config blob decoding + persistence
src/cm_popup.rs _cm IPC listener + Win32 approval dialog
Vendoring
The upstream RustDesk crate is vendored under vendor/rustdesk/ — full
workspace including libs/{hbb_common, scrap, enigo, clipboard,
virtual_display, remote_printer}. This makes the build self-contained
(no submodules, no sibling-repo checkout in CI) and gives us freedom to
fork in a different direction later. Excluded from the vendor: .git,
target/, flutter/, appimage/, flatpak/, fastlane/, docs/, examples/,
ci/, build.py, Dockerfile, upstream README/CLAUDE/AGENTS/GEMINI.
One local divergence vs. upstream: vendor/rustdesk/src/lib.rs flips
`mod custom_server` → `pub mod custom_server` so config_import.rs can
call get_custom_server_from_string without going through the
ui_interface shim. Documented in README.md → "Re-syncing the vendored
copy".
CI
.gitea/workflows/build-windows.yml builds on a self-hosted Windows
runner with Rust 1.75, LLVM 15.0.6 (libclang for bindgen via libvpx-sys),
and a vcpkg cache. The vendored vcpkg.json drives x64-windows-static
deps. The workflow stages the resulting hello-agent.exe into
SignOutput\, reports authenticode signing status (warns on unsigned),
and uploads as artifact. ~15 min full build, faster on incremental.
Out of scope for this commit: Linux/macOS builds, code signing, MSI
packaging, coexistence with stock rustdesk on the same box (currently
shares the RustDesk APP_NAME and config dir).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
101 lines
2.8 KiB
TOML
101 lines
2.8 KiB
TOML
[package]
|
|
name = "hbb_common"
|
|
version = "0.1.0"
|
|
authors = ["open-trade <info@opentradesolutions.com>"]
|
|
edition = "2018"
|
|
|
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
|
|
[features]
|
|
default = []
|
|
webrtc = ["dep:webrtc"]
|
|
|
|
[dependencies]
|
|
# new flexi_logger failed on rustc 1.75
|
|
flexi_logger = { version = "0.27", features = ["async"] }
|
|
protobuf = { version = "3.7", features = ["with-bytes"] }
|
|
tokio = { version = "1.44", features = ["full"] }
|
|
tokio-util = { version = "0.7", features = ["full"] }
|
|
futures = "0.3"
|
|
bytes = { version = "1.10", features = ["serde"] }
|
|
log = "0.4"
|
|
env_logger = "0.11"
|
|
socket2 = { version = "0.3", features = ["reuseport"] }
|
|
zstd = "0.13"
|
|
anyhow = "1.0"
|
|
futures-util = "0.3"
|
|
directories-next = "2.0"
|
|
rand = "0.8"
|
|
serde_derive = "1.0"
|
|
serde = "1.0"
|
|
serde_json = "1.0"
|
|
lazy_static = "1.5"
|
|
confy = { git = "https://github.com/rustdesk-org/confy" }
|
|
dirs-next = "2.0"
|
|
filetime = "0.2"
|
|
sodiumoxide = "0.2"
|
|
regex = "1.11"
|
|
tokio-socks = { git = "https://github.com/rustdesk-org/tokio-socks" }
|
|
chrono = "0.4"
|
|
backtrace = "0.3"
|
|
libc = "0.2"
|
|
dlopen = "0.1"
|
|
toml = "0.7"
|
|
uuid = { version = "1.16", features = ["v4"] }
|
|
# new sysinfo issue: https://github.com/rustdesk/rustdesk/pull/6330#issuecomment-2270871442
|
|
sysinfo = { git = "https://github.com/rustdesk-org/sysinfo", branch = "rlim_max" }
|
|
# new flexi_logger failed on nightly rustc 1.75 for x86
|
|
thiserror = "1.0"
|
|
httparse = "1.10"
|
|
base64 = "0.22"
|
|
url = "2.5"
|
|
sha2 = "0.10"
|
|
whoami = "1.5"
|
|
|
|
tokio-rustls = { version = "0.26", features = [
|
|
"logging",
|
|
"tls12",
|
|
"ring",
|
|
], default-features = false }
|
|
tokio-native-tls = "0.3"
|
|
tokio-tungstenite = { version = "0.26", features = ["native-tls", "rustls-tls-native-roots", "rustls-tls-webpki-roots"] }
|
|
tungstenite = { version = "0.26", features = ["native-tls", "rustls-tls-native-roots", "rustls-tls-webpki-roots"] }
|
|
rustls-platform-verifier = "0.6"
|
|
rustls-pki-types = "1.11"
|
|
rustls-native-certs = "0.8"
|
|
webpki-roots = "1.0.4"
|
|
async-recursion = "1.1"
|
|
webrtc = { version = "0.14.0", optional = true }
|
|
libloading = "0.8"
|
|
|
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
|
mac_address = "1.1"
|
|
default_net = { git = "https://github.com/rustdesk-org/default_net" }
|
|
machine-uid = { git = "https://github.com/rustdesk-org/machine-uid" }
|
|
|
|
[build-dependencies]
|
|
protobuf-codegen = { version = "3.7" }
|
|
|
|
[dev-dependencies]
|
|
clap = "4.5.51"
|
|
webrtc = "0.14.0"
|
|
|
|
[target.'cfg(target_os = "windows")'.dependencies]
|
|
winapi = { version = "0.3", features = [
|
|
"winuser",
|
|
"synchapi",
|
|
"pdh",
|
|
"memoryapi",
|
|
"sysinfoapi",
|
|
] }
|
|
|
|
[target.'cfg(target_os = "macos")'.dependencies]
|
|
osascript = "0.3"
|
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
sctk = { package = "smithay-client-toolkit", version = "0.20.0", default-features = false, features = [
|
|
"calloop",
|
|
] }
|
|
users = { version = "0.11" }
|
|
x11 = "2.21"
|