8ecf05b106
Closes the M4 plan. When `OPTION_USE_RAW_TCP_FOR_API=Y` (typical in locked-down networks where direct HTTPS to port 21114 is blocked), the client wraps every /api/* request in an HttpProxyRequest protobuf and ships it over the already-encrypted rendezvous TCP channel. We now decode those messages on hbbs and dispatch them through the *same* axum Router the HTTPS listener uses — so every existing handler (login, AB, audit, TOTP, OIDC, devices/cli, plugin-sign, …) is reachable through this path with zero per-route plumbing. Components ========== - libs/hbb_common (submodule, pro-features-httpproxy branch): backports HeaderEntry / HttpProxyRequest / HttpProxyResponse + union tags 27/28 from upstream @87b11a7 onto our pinned @83419b6. Proto-only — the rest of hbb_common is unchanged so we keep the tokio 1.x / axum 0.5 / pinned reqwest fork intact (a full submodule bump risked breaking those). - src/api/http_proxy.rs: the dispatch shim. Holds a `Mutex<Option<Router>>` populated by `api::serve` before the HTTPS listener starts, builds an `http::Request<Body>` from the proto fields (sanitizing hop-by-hop headers, defaulting Content-Type: application/json), runs it through `router.oneshot(req)`, and serializes the response into HttpProxyResponse. Tower added as a direct dep with the `util` feature for ServiceExt. - src/api/mod.rs: pub mod http_proxy; install_router(app.clone()) before axum::Server::bind to share the router. - src/rendezvous_server.rs::handle_tcp: new match arm right before the catch-all that decodes HttpProxyRequest and replies with an HttpProxyResponse via the existing Sink::TcpStream(..., Encrypt) path. The reply is automatically secretbox-sealed by `send_to_sink`, so the end-to-end channel is encrypted symmetrically with secure_tcp. - examples/http_proxy_test.rs: end-to-end smoke test that opens a TCP connection, walks the secure_tcp handshake by hand (read server's signed box pubkey, derive symmetric key, send sealed reply), then ships an HttpProxyRequest GET /api/login-options and verifies the response is 200 + ["account"]. Used as the validation gate. New crate deps ============== - tower = "0.4" (features = ["util"]) — for ServiceExt::oneshot - http-body = "0.4" — for the Body trait import in dispatch Verification ============ 1. cargo build --release — clean. 2. examples/http_proxy_test against a fresh hbbs: [ok] secure_tcp handshake complete [ok] sent HttpProxyRequest GET /api/login-options [ok] response status = 200 [ok] response body = ["account"] [pass] full HTTP-over-rendezvous round trip verified 3. hbbs log confirms the secure_tcp handshake completed and the dispatch went through the standard axum router. Notes on cherry-pick vs submodule bump ====================================== The plan flagged the bump as the riskiest M4 item because newer hbb_common pulls newer tokio that breaks axum 0.5. The proto-only cherry pick keeps everything stable; the upstream-divergence cost is one extra commit in the hbb_common submodule that we own. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
85 lines
2.7 KiB
TOML
85 lines
2.7 KiB
TOML
[package]
|
|
name = "hbbs"
|
|
version = "1.1.15"
|
|
authors = ["rustdesk <info@rustdesk.com>"]
|
|
edition = "2021"
|
|
build = "build.rs"
|
|
default-run = "hbbs"
|
|
|
|
[[bin]]
|
|
name = "hbbr"
|
|
path = "src/hbbr.rs"
|
|
|
|
[[bin]]
|
|
name = "rustdesk-utils"
|
|
path = "src/utils.rs"
|
|
|
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
|
|
[dependencies]
|
|
hbb_common = { path = "libs/hbb_common" }
|
|
tokio = { version = "1", features = ["fs", "io-util"] }
|
|
totp-rs = { version = "5.4", default-features = false }
|
|
lettre = { version = "0.10", default-features = false, features = ["smtp-transport", "tokio1-rustls-tls", "builder"] }
|
|
toml = "0.7"
|
|
serde_derive = "1.0"
|
|
serde = "1.0"
|
|
serde_json = "1.0"
|
|
lazy_static = "1.4"
|
|
clap = "2"
|
|
rust-ini = "0.18"
|
|
minreq = { version = "2.4", features = ["punycode"] }
|
|
machine-uid = "0.2"
|
|
mac_address = "1.1.5"
|
|
whoami = "1.2"
|
|
base64 = "0.13"
|
|
axum = { version = "0.5", features = ["headers"] }
|
|
sqlx = { version = "0.6", features = [ "runtime-tokio-rustls", "sqlite", "macros", "chrono", "json" ] }
|
|
deadpool = "0.8"
|
|
async-trait = "0.1"
|
|
async-speed-limit = { git = "https://github.com/open-trade/async-speed-limit" }
|
|
uuid = { version = "1.0", features = ["v4"] }
|
|
bcrypt = "0.13"
|
|
chrono = "0.4"
|
|
jsonwebtoken = "8"
|
|
headers = "0.3"
|
|
once_cell = "1.8"
|
|
sodiumoxide = "0.2"
|
|
tokio-tungstenite = "0.17"
|
|
tungstenite = "0.17"
|
|
regex = "1.4"
|
|
tower-http = { version = "0.3", features = ["fs", "trace", "cors"] }
|
|
tower = { version = "0.4", features = ["util"] }
|
|
http = "0.2"
|
|
http-body = "0.4"
|
|
flexi_logger = { version = "0.22", features = ["async", "use_chrono_for_offset", "dont_minimize_extra_stacks"] }
|
|
ipnetwork = "0.20"
|
|
local-ip-address = "0.5.1"
|
|
dns-lookup = "1.0.8"
|
|
ping = "0.4.0"
|
|
flate2 = "1.0"
|
|
|
|
[target.'cfg(any(target_os = "macos", target_os = "windows"))'.dependencies]
|
|
# https://github.com/rustdesk/rustdesk-server-pro/issues/189, using native-tls for better tls support
|
|
reqwest = { git = "https://github.com/rustdesk-org/reqwest", features = ["blocking", "socks", "json", "native-tls", "gzip"], default-features=false }
|
|
|
|
[target.'cfg(not(any(target_os = "macos", target_os = "windows")))'.dependencies]
|
|
reqwest = { git = "https://github.com/rustdesk-org/reqwest", features = ["blocking", "socks", "json", "rustls-tls", "rustls-tls-native-roots", "gzip"], default-features=false }
|
|
|
|
[build-dependencies]
|
|
hbb_common = { path = "libs/hbb_common" }
|
|
|
|
[workspace]
|
|
members = ["libs/hbb_common"]
|
|
exclude = ["ui"]
|
|
|
|
#https://github.com/johnthagen/min-sized-rust
|
|
#https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles
|
|
[profile.release]
|
|
lto = true
|
|
codegen-units = 1
|
|
panic = 'abort'
|
|
strip = true
|
|
#opt-level = 'z' # only have smaller size after strip # Default is 3, better performance
|
|
#rpath = true # Not needed
|