mirror of
https://github.com/rustdesk/rustdesk
synced 2026-04-21 13:27:19 +00:00
fix(security): ignore rendezvous-provided relay hosts
Signed-off-by: Vlad (Kuzmin) Erium <libalias@gmail.com> (cherry picked from commit a4b1c37f54554631c9f97200144afadc257eddee) Signed-off-by: Vlad (Kuzmin) Erium <libalias@gmail.com>
This commit is contained in:
parent
458bee228e
commit
91b153aede
3 changed files with 78 additions and 10 deletions
|
|
@ -515,7 +515,10 @@ impl Client {
|
|||
peer_nat_type = ph.nat_type();
|
||||
is_local = ph.is_local();
|
||||
signed_id_pk = ph.pk.into();
|
||||
relay_server = ph.relay_server;
|
||||
relay_server = crate::common::resolve_trusted_relay_server(
|
||||
&rendezvous_server,
|
||||
&ph.relay_server,
|
||||
);
|
||||
peer_addr = AddrMangle::decode(&ph.socket_addr);
|
||||
feedback = ph.feedback;
|
||||
let s = udp.0.take();
|
||||
|
|
@ -557,10 +560,14 @@ impl Client {
|
|||
}
|
||||
}
|
||||
signed_id_pk = rr.pk().into();
|
||||
let trusted_relay_server = crate::common::resolve_trusted_relay_server(
|
||||
&rendezvous_server,
|
||||
&rr.relay_server,
|
||||
);
|
||||
let fut = Self::create_relay(
|
||||
&peer,
|
||||
rr.uuid,
|
||||
rr.relay_server,
|
||||
trusted_relay_server,
|
||||
&key,
|
||||
conn_type,
|
||||
my_addr.is_ipv4(),
|
||||
|
|
|
|||
|
|
@ -934,6 +934,33 @@ pub fn increase_port<T: std::string::ToString>(host: T, offset: i32) -> String {
|
|||
hbb_common::socket_client::increase_port(host, offset)
|
||||
}
|
||||
|
||||
pub fn resolve_trusted_relay_server(
|
||||
rendezvous_server: &str,
|
||||
provided_by_rendezvous_server: &str,
|
||||
) -> String {
|
||||
let configured_relay_server = Config::get_option(keys::OPTION_RELAY_SERVER);
|
||||
if !configured_relay_server.is_empty() {
|
||||
return check_port(configured_relay_server, RELAY_PORT);
|
||||
}
|
||||
|
||||
let derived_relay_server = if rendezvous_server.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
increase_port(check_port(rendezvous_server, RENDEZVOUS_PORT), 1)
|
||||
};
|
||||
if !provided_by_rendezvous_server.is_empty() {
|
||||
let provided_relay_server = check_port(provided_by_rendezvous_server, RELAY_PORT);
|
||||
if !derived_relay_server.is_empty() && provided_relay_server != derived_relay_server {
|
||||
log::warn!(
|
||||
"Ignoring rendezvous-provided relay server {} in favor of derived relay {}",
|
||||
provided_relay_server,
|
||||
derived_relay_server
|
||||
);
|
||||
}
|
||||
}
|
||||
derived_relay_server
|
||||
}
|
||||
|
||||
pub const POSTFIX_SERVICE: &'static str = "_service";
|
||||
|
||||
#[inline]
|
||||
|
|
@ -3860,6 +3887,47 @@ mod tests {
|
|||
assert_eq!(get_tcp_proxy_addr(), format!("[1:2]:{RENDEZVOUS_PORT}"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_resolve_trusted_relay_server_prefers_explicit_override() {
|
||||
struct RestoreRelayServer(String);
|
||||
|
||||
impl Drop for RestoreRelayServer {
|
||||
fn drop(&mut self) {
|
||||
Config::set_option(keys::OPTION_RELAY_SERVER.to_string(), self.0.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let _restore = RestoreRelayServer(Config::get_option(keys::OPTION_RELAY_SERVER));
|
||||
Config::set_option(
|
||||
keys::OPTION_RELAY_SERVER.to_string(),
|
||||
"relay.override.example".to_string(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
resolve_trusted_relay_server("hbbs.example.com:21116", "attacker.example.com:29999"),
|
||||
format!("relay.override.example:{RELAY_PORT}")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_resolve_trusted_relay_server_ignores_server_supplied_override() {
|
||||
struct RestoreRelayServer(String);
|
||||
|
||||
impl Drop for RestoreRelayServer {
|
||||
fn drop(&mut self) {
|
||||
Config::set_option(keys::OPTION_RELAY_SERVER.to_string(), self.0.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let _restore = RestoreRelayServer(Config::get_option(keys::OPTION_RELAY_SERVER));
|
||||
Config::set_option(keys::OPTION_RELAY_SERVER.to_string(), "".to_string());
|
||||
|
||||
assert_eq!(
|
||||
resolve_trusted_relay_server("hbbs.example.com:21116", "attacker.example.com:29999"),
|
||||
"hbbs.example.com:21117"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_http_request_via_tcp_proxy_rejects_invalid_header_json() {
|
||||
let result = http_request_via_tcp_proxy("not a url", "get", None, "{").await;
|
||||
|
|
|
|||
|
|
@ -752,14 +752,7 @@ impl RendezvousMediator {
|
|||
}
|
||||
|
||||
fn get_relay_server(&self, provided_by_rendezvous_server: String) -> String {
|
||||
let mut relay_server = Config::get_option("relay-server");
|
||||
if relay_server.is_empty() {
|
||||
relay_server = provided_by_rendezvous_server;
|
||||
}
|
||||
if relay_server.is_empty() {
|
||||
relay_server = crate::increase_port(&self.host, 1);
|
||||
}
|
||||
relay_server
|
||||
crate::common::resolve_trusted_relay_server(&self.host, &provided_by_rendezvous_server)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue