mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-07-16 12:55:45 +03:00
Compare commits
9 Commits
revert-155
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5abf4e9724 | ||
|
|
cf2b28faf9 | ||
|
|
bdb38c4730 | ||
|
|
fa418cace6 | ||
|
|
94a2a2bb4a | ||
|
|
865fe71c46 | ||
|
|
137298e05a | ||
|
|
685a89a171 | ||
|
|
12b5cc7f72 |
32
Cargo.lock
generated
32
Cargo.lock
generated
@@ -771,6 +771,26 @@ dependencies = [
|
||||
"syn 2.0.98",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.72.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.12.1",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2 1.0.93",
|
||||
"quote 1.0.36",
|
||||
"regex",
|
||||
"rustc-hash 2.1.1",
|
||||
"shlex",
|
||||
"syn 2.0.98",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.2"
|
||||
@@ -2329,7 +2349,7 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||
dependencies = [
|
||||
"libloading 0.7.4",
|
||||
"libloading 0.8.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2694,7 +2714,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4494,7 +4514,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"windows-targets 0.48.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7434,7 +7454,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.11.0",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7491,7 +7511,7 @@ dependencies = [
|
||||
"security-framework 3.5.1",
|
||||
"security-framework-sys",
|
||||
"webpki-root-certs",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7578,7 +7598,7 @@ name = "scrap"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"bindgen 0.65.1",
|
||||
"bindgen 0.72.1",
|
||||
"block",
|
||||
"cfg-if 1.0.0",
|
||||
"dbus",
|
||||
|
||||
@@ -495,14 +495,14 @@ class _CmHeaderState extends State<_CmHeader>
|
||||
if (client.type_() == ClientType.file)
|
||||
FittedBox(
|
||||
child: Text(
|
||||
translate("File Transfer"),
|
||||
translate("Transfer file"),
|
||||
style: TextStyle(color: Colors.white70, fontSize: 12),
|
||||
),
|
||||
),
|
||||
if (client.type_() == ClientType.camera)
|
||||
FittedBox(
|
||||
child: Text(
|
||||
translate("View Camera"),
|
||||
translate("View camera"),
|
||||
style: TextStyle(color: Colors.white70, fontSize: 12),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
typedef char** (*FUNC_RUSTDESK_CORE_MAIN)(int*);
|
||||
typedef void (*FUNC_RUSTDESK_FREE_ARGS)( char**, int);
|
||||
typedef int (*FUNC_RUSTDESK_GET_APP_NAME)(wchar_t*, int);
|
||||
typedef int (*FUNC_RUSTDESK_IS_DISABLE_INSTALLATION)();
|
||||
/// Note: `--server`, `--service` are already handled in [core_main.rs].
|
||||
const std::vector<std::string> parameters_white_list = {"--install", "--cm"};
|
||||
|
||||
@@ -62,6 +63,22 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||
}
|
||||
std::vector<std::string> rust_args(c_args, c_args + args_len);
|
||||
free_c_args(c_args, args_len);
|
||||
FUNC_RUSTDESK_IS_DISABLE_INSTALLATION rustdesk_is_disable_installation =
|
||||
(FUNC_RUSTDESK_IS_DISABLE_INSTALLATION)GetProcAddress(hInstance, "rustdesk_is_disable_installation");
|
||||
bool is_disable_installation =
|
||||
rustdesk_is_disable_installation && rustdesk_is_disable_installation() != 0;
|
||||
const auto installParam = std::string("--install");
|
||||
// Flutter reads the original process command line, not only rust_args, so
|
||||
// remove the `--install` injected by the portable wrapper here as well. This
|
||||
// also lets `no-install.exe` continue as a portable app when installation is
|
||||
// disabled. See: https://github.com/rustdesk/rustdesk-server-pro/issues/991#issuecomment-4978376890
|
||||
if (is_disable_installation) {
|
||||
command_line_arguments.erase(
|
||||
std::remove(command_line_arguments.begin(),
|
||||
command_line_arguments.end(),
|
||||
installParam),
|
||||
command_line_arguments.end());
|
||||
}
|
||||
|
||||
std::wstring app_name = L"RustDesk";
|
||||
FUNC_RUSTDESK_GET_APP_NAME get_rustdesk_app_name = (FUNC_RUSTDESK_GET_APP_NAME)GetProcAddress(hInstance, "get_rustdesk_app_name");
|
||||
@@ -118,7 +135,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||
is_cm_page = true;
|
||||
}
|
||||
bool is_install_page = false;
|
||||
auto installParam = std::string("--install");
|
||||
if (!command_line_arguments.empty() && command_line_arguments.front().compare(0, installParam.size(), installParam.c_str()) == 0) {
|
||||
is_install_page = true;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ quest = "0.3"
|
||||
|
||||
[build-dependencies]
|
||||
target_build_utils = "0.3"
|
||||
bindgen = "0.65"
|
||||
bindgen = "0.72.1"
|
||||
pkg-config = { version = "0.3.27", optional = true }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
|
||||
@@ -1024,7 +1024,7 @@ pub fn get_full_name() -> String {
|
||||
}
|
||||
|
||||
pub fn is_setup(name: &str) -> bool {
|
||||
name.to_lowercase().ends_with("install.exe")
|
||||
!config::is_disable_installation() && name.to_lowercase().ends_with("install.exe")
|
||||
}
|
||||
|
||||
pub fn get_custom_rendezvous_server(custom: String) -> String {
|
||||
@@ -2623,6 +2623,20 @@ pub fn is_direct_ip_access(peer: &str) -> bool {
|
||||
hbb_common::is_ip_str(peer) || hbb_common::is_domain_port_str(peer)
|
||||
}
|
||||
|
||||
// Align the maximum length of the peer id to the maximum length of the peer id in the server.
|
||||
const MAX_UNTRUSTED_PEER_ID_LEN: usize = 253;
|
||||
const UNTRUSTED_PEER_ID_FORBIDDEN_CHARS: &[char] = &['"', '<', '>', '/', '\\', '|', '?', '*'];
|
||||
|
||||
// Shared validation for peer/connect ids that cross untrusted boundaries before
|
||||
// they are stored or written into command/script contexts.
|
||||
pub fn is_valid_untrusted_peer_id(id: &str) -> bool {
|
||||
!id.is_empty()
|
||||
&& id.len() <= MAX_UNTRUSTED_PEER_ID_LEN
|
||||
&& !id.chars().any(|ch| {
|
||||
ch.is_control() || ch.is_whitespace() || UNTRUSTED_PEER_ID_FORBIDDEN_CHARS.contains(&ch)
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -2653,6 +2667,29 @@ mod tests {
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn untrusted_peer_id_validation() {
|
||||
let cases = [
|
||||
("123456789", true),
|
||||
("m\u{00FC}nchen-pc", true),
|
||||
("192.168.1.10:21118", true),
|
||||
("9123456234@public", true),
|
||||
(
|
||||
r#"1" & oWS.Run("cmd.exe /k whoami /priv",1,False) & ""#,
|
||||
false,
|
||||
),
|
||||
("", false),
|
||||
("peer id", false),
|
||||
("peer\nid", false),
|
||||
("peer/id", false),
|
||||
("peer?id", false),
|
||||
];
|
||||
|
||||
for (id, expected) in cases {
|
||||
assert_eq!(is_valid_untrusted_peer_id(id), expected, "{id:?}");
|
||||
}
|
||||
}
|
||||
|
||||
// ThrottledInterval tick at the same time as tokio interval, if no sleeps
|
||||
#[allow(non_snake_case)]
|
||||
#[tokio::test]
|
||||
|
||||
@@ -127,6 +127,13 @@ pub fn core_main() -> Option<Vec<String>> {
|
||||
if args.contains(&"--noinstall".to_string()) {
|
||||
args.clear();
|
||||
}
|
||||
// The portable wrapper injects `--install` when its name ends with `install.exe`,
|
||||
// including `no-install.exe`. Drop the argument instead of exiting so disabled
|
||||
// clients can continue running as portable applications.
|
||||
if config::is_disable_installation() {
|
||||
args.retain(|arg| arg != "--install");
|
||||
flutter_args.retain(|arg| arg != "--install");
|
||||
}
|
||||
if args.len() > 0 {
|
||||
if args[0] == "--version" {
|
||||
println!("{}", crate::VERSION);
|
||||
|
||||
@@ -136,6 +136,12 @@ pub extern "C" fn rustdesk_core_main_args(args_len: *mut c_int) -> *mut *mut c_c
|
||||
return std::ptr::null_mut() as _;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rustdesk_is_disable_installation() -> c_int {
|
||||
hbb_common::config::is_disable_installation() as c_int
|
||||
}
|
||||
|
||||
// https://gist.github.com/iskakaushik/1c5b8aa75c77479c33c4320913eebef6
|
||||
#[cfg(windows)]
|
||||
fn rust_args_to_c_args(args: Vec<String>, outlen: *mut c_int) -> *mut *mut c_char {
|
||||
|
||||
@@ -241,6 +241,14 @@ fn wait_response(
|
||||
Some(rendezvous_message::Union::PeerDiscovery(p)) => {
|
||||
last_recv_time = Instant::now();
|
||||
if p.cmd == "pong" {
|
||||
if !crate::common::is_valid_untrusted_peer_id(&p.id) {
|
||||
log::warn!(
|
||||
"Ignoring LAN discovery response from {} with invalid peer id",
|
||||
addr
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
let local_mac = if try_get_ip_by_peer {
|
||||
if let Some(self_addr) = get_ipaddr_by_peer(&addr) {
|
||||
get_mac(&self_addr)
|
||||
|
||||
@@ -112,7 +112,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Waiting", "Aguardando"),
|
||||
("Finished", "Concluído"),
|
||||
("Speed", "Velocidade"),
|
||||
("Custom Image Quality", "Qualidade Visual Personalizada"),
|
||||
("Custom Image Quality", "Qualidade de imagem personalizada"),
|
||||
("Privacy mode", "Modo privado"),
|
||||
("Block user input", "Bloquear entrada do usuário"),
|
||||
("Unblock user input", "Desbloquear entrada do usuário"),
|
||||
@@ -122,15 +122,15 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Stretch", "Aumentar"),
|
||||
("Scrollbar", "Barra de rolagem"),
|
||||
("ScrollAuto", "Rolagem automática"),
|
||||
("Good image quality", "Boa qualidade de imagem"),
|
||||
("Good image quality", "Melhor qualidade"),
|
||||
("Balanced", "Balanceada"),
|
||||
("Optimize reaction time", "Otimizar tempo de resposta"),
|
||||
("Custom", "Personalizado"),
|
||||
("Custom", "Personalizada"),
|
||||
("Show remote cursor", "Mostrar cursor remoto"),
|
||||
("Show quality monitor", "Exibir monitor de qualidade"),
|
||||
("Disable clipboard", "Desabilitar área de transferência"),
|
||||
("Lock after session end", "Bloquear após o fim da sessão"),
|
||||
("Insert Ctrl + Alt + Del", "Enviar Ctrl + Alt + Del"),
|
||||
("Insert Ctrl + Alt + Del", "Enviar Ctrl+Alt+Del"),
|
||||
("Insert Lock", "Bloquear computador"),
|
||||
("Refresh", "Atualizar"),
|
||||
("ID does not exist", "ID não existe"),
|
||||
@@ -332,7 +332,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Relay Connection", "Conexão via Relay"),
|
||||
("Secure Connection", "Conexão Segura"),
|
||||
("Insecure Connection", "Conexão Insegura"),
|
||||
("Continue", ""),
|
||||
("Continue", "Continuar"),
|
||||
("Scale original", "Escala original"),
|
||||
("Scale adaptive", "Escala adaptada"),
|
||||
("General", "Geral"),
|
||||
|
||||
@@ -2278,6 +2278,10 @@ fn get_shortcut_icon_location(install_dir: &str, exe: &str) -> String {
|
||||
}
|
||||
|
||||
pub fn create_shortcut(id: &str) -> ResultType<()> {
|
||||
if !crate::common::is_valid_untrusted_peer_id(id) {
|
||||
bail!("Invalid peer id for shortcut");
|
||||
}
|
||||
|
||||
let exe = std::env::current_exe()?.to_str().unwrap_or("").to_owned();
|
||||
// https://github.com/rustdesk/rustdesk/issues/13735
|
||||
// Replace ':' with '_' for filename since ':' is not allowed in Windows filenames
|
||||
|
||||
Reference in New Issue
Block a user