mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-07-22 01:44:39 +03:00
fix: update download, force tls (#15529)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use crate::{common::do_check_software_update, hbbs_http::create_http_client_with_url};
|
||||
use crate::{common::do_check_software_update, hbbs_http::create_http_client_with_url_strict};
|
||||
use hbb_common::{bail, config, log, ResultType};
|
||||
use std::{
|
||||
io::Write,
|
||||
path::PathBuf,
|
||||
path::{Component, Path, PathBuf},
|
||||
sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
mpsc::{channel, Receiver, Sender},
|
||||
@@ -153,7 +153,7 @@ fn check_update(manually: bool) -> ResultType<()> {
|
||||
format!("{}/rustdesk-{}-x86-sciter.exe", download_url, version)
|
||||
};
|
||||
log::debug!("New version available: {}", &version);
|
||||
let client = create_http_client_with_url(&download_url);
|
||||
let client = create_http_client_with_url_strict(&download_url)?;
|
||||
let Some(file_path) = get_download_file_from_url(&download_url) else {
|
||||
bail!("Failed to get the file path from the URL: {}", download_url);
|
||||
};
|
||||
@@ -291,7 +291,96 @@ fn update_new_version(update_msi: bool, version: &str, file_path: &PathBuf) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_download_file_from_url(url: &str) -> Option<PathBuf> {
|
||||
let filename = url.split('/').last()?;
|
||||
pub fn get_update_download_file_from_url(url: &str) -> Option<PathBuf> {
|
||||
let parsed = url::Url::parse(url).ok()?;
|
||||
// Check the raw prefix before Url normalizes default ports.
|
||||
if !url.starts_with("https://github.com/")
|
||||
|| parsed.scheme() != "https"
|
||||
|| parsed.host_str() != Some("github.com")
|
||||
|| !parsed.username().is_empty()
|
||||
|| parsed.password().is_some()
|
||||
|| parsed.port().is_some()
|
||||
|| parsed.query().is_some()
|
||||
|| parsed.fragment().is_some()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut segments = parsed.path_segments()?;
|
||||
let owner = segments.next()?;
|
||||
let repo = segments.next()?;
|
||||
let releases = segments.next()?;
|
||||
let download = segments.next()?;
|
||||
let tag = segments.next()?;
|
||||
let filename = segments.next()?;
|
||||
|
||||
if owner != "rustdesk"
|
||||
|| repo != "rustdesk"
|
||||
|| releases != "releases"
|
||||
|| download != "download"
|
||||
|| tag.is_empty()
|
||||
|| segments.next().is_some()
|
||||
|| !is_plain_update_filename(filename)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(std::env::temp_dir().join(filename))
|
||||
}
|
||||
|
||||
fn is_plain_update_filename(filename: &str) -> bool {
|
||||
if filename.is_empty()
|
||||
|| filename.contains('/')
|
||||
|| filename.contains('\\')
|
||||
|| filename.contains(':')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut components = Path::new(filename).components();
|
||||
matches!(
|
||||
components.next(),
|
||||
Some(Component::Normal(name)) if name.to_str() == Some(filename)
|
||||
) && components.next().is_none()
|
||||
}
|
||||
|
||||
pub fn get_download_file_from_url(url: &str) -> Option<PathBuf> {
|
||||
get_update_download_file_from_url(url)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::get_download_file_from_url;
|
||||
|
||||
#[test]
|
||||
fn update_download_file_accepts_expected_github_asset_urls() {
|
||||
let file = get_download_file_from_url(
|
||||
"https://github.com/rustdesk/rustdesk/releases/download/1.4.0/rustdesk-1.4.0-x86_64.dmg",
|
||||
)
|
||||
.expect("valid GitHub release asset URL");
|
||||
|
||||
assert_eq!(
|
||||
file.file_name().and_then(|name| name.to_str()),
|
||||
Some("rustdesk-1.4.0-x86_64.dmg")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_download_file_rejects_untrusted_or_malformed_urls() {
|
||||
for url in [
|
||||
"http://github.com/rustdesk/rustdesk/releases/download/1/rustdesk.exe",
|
||||
"https://example.com/rustdesk.exe",
|
||||
"https://github.com/other/project/releases/download/1/rustdesk.exe",
|
||||
"https://github.com/rustdesk/rustdesk/releases/download/1/",
|
||||
"https://github.com/rustdesk/rustdesk/releases/download/1/nested/rustdesk.exe",
|
||||
"https://github.com/rustdesk/rustdesk/releases/download/1/C:rustdesk.exe",
|
||||
"https://user@github.com/rustdesk/rustdesk/releases/download/1/rustdesk.exe",
|
||||
"https://github.com:443/rustdesk/rustdesk/releases/download/1/rustdesk.exe",
|
||||
"https://github.com/rustdesk/rustdesk/releases/download/1/rustdesk.exe?download=1",
|
||||
"https://github.com/rustdesk/rustdesk/releases/download/1/rustdesk.exe#download",
|
||||
"not a url",
|
||||
] {
|
||||
assert!(get_download_file_from_url(url).is_none(), "{url}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user