43a0a4f8e0
* add http(s) proxy * Add front-end translation * fix ui description * For linux platform, add rustls support * fix: Fix the proxy address test function. * add: Added default prompts for agency agreement and some multi-language translations * add: Http proxy request client * fix: add async http proxy func and format the code * add: Preliminary support for flutter front-end calling rust back-end http request * Optimize HTTP calls * Optimize HTTP calls * fix: Optimize HTTP requests, refine translations, and fix dependencies * fix: Win and macOS compilation errors * fix: web platforms * fix: Optimize import * fix: Fix web platform issues * fix: Fix web platform issues * fix: update ci * fix: test ci * test: test CI * Revert "fix: update ci" This reverts commit 2e5f247b2ed0cc63a6f6f7bbaaffd0a1223712e5. * test: test CI * test: test CI * fix: fix lock file * fix: Optimize imports
193 lines
7.2 KiB
Rust
193 lines
7.2 KiB
Rust
use hbb_common::{
|
|
bail,
|
|
base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _},
|
|
sodiumoxide::crypto::sign,
|
|
ResultType,
|
|
};
|
|
use serde_derive::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
|
|
pub struct CustomServer {
|
|
#[serde(default)]
|
|
pub key: String,
|
|
#[serde(default)]
|
|
pub host: String,
|
|
#[serde(default)]
|
|
pub api: String,
|
|
#[serde(default)]
|
|
pub relay: String,
|
|
}
|
|
|
|
fn get_custom_server_from_config_string(s: &str) -> ResultType<CustomServer> {
|
|
let tmp: String = s.chars().rev().collect();
|
|
const PK: &[u8; 32] = &[
|
|
88, 168, 68, 104, 60, 5, 163, 198, 165, 38, 12, 85, 114, 203, 96, 163, 70, 48, 0, 131, 57,
|
|
12, 46, 129, 83, 17, 84, 193, 119, 197, 130, 103,
|
|
];
|
|
let pk = sign::PublicKey(*PK);
|
|
let data = URL_SAFE_NO_PAD.decode(tmp)?;
|
|
if let Ok(lic) = serde_json::from_slice::<CustomServer>(&data) {
|
|
return Ok(lic);
|
|
}
|
|
if let Ok(data) = sign::verify(&data, &pk) {
|
|
Ok(serde_json::from_slice::<CustomServer>(&data)?)
|
|
} else {
|
|
bail!("sign:verify failed");
|
|
}
|
|
}
|
|
|
|
pub fn get_custom_server_from_string(s: &str) -> ResultType<CustomServer> {
|
|
let s = if s.to_lowercase().ends_with(".exe.exe") {
|
|
&s[0..s.len() - 8]
|
|
} else if s.to_lowercase().ends_with(".exe") {
|
|
&s[0..s.len() - 4]
|
|
} else {
|
|
s
|
|
};
|
|
/*
|
|
* The following code tokenizes the file name based on commas and
|
|
* extracts relevant parts sequentially.
|
|
*
|
|
* host= is expected to be the first part.
|
|
*
|
|
* Since Windows renames files adding (1), (2) etc. before the .exe
|
|
* in case of duplicates, which causes the host or key values to be
|
|
* garbled.
|
|
*
|
|
* This allows using a ',' (comma) symbol as a final delimiter.
|
|
*/
|
|
if s.contains("host=") {
|
|
let stripped = &s[s.find("host=").unwrap_or(0)..s.len()];
|
|
let strs: Vec<&str> = stripped.split(",").collect();
|
|
let mut host = "";
|
|
let mut key = "";
|
|
let mut api = "";
|
|
let mut relay = "";
|
|
let strs_iter = strs.iter();
|
|
for el in strs_iter {
|
|
if el.starts_with("host=") {
|
|
host = &el[5..el.len()];
|
|
}
|
|
if el.starts_with("key=") {
|
|
key = &el[4..el.len()];
|
|
}
|
|
if el.starts_with("api=") {
|
|
api = &el[4..el.len()];
|
|
}
|
|
if el.starts_with("relay=") {
|
|
relay = &el[4..el.len()];
|
|
}
|
|
}
|
|
return Ok(CustomServer {
|
|
host: host.to_owned(),
|
|
key: key.to_owned(),
|
|
api: api.to_owned(),
|
|
relay: relay.to_owned(),
|
|
});
|
|
} else {
|
|
let s = s
|
|
.replace("-licensed---", "--")
|
|
.replace("-licensed--", "--")
|
|
.replace("-licensed-", "--");
|
|
let strs = s.split("--");
|
|
for s in strs {
|
|
if let Ok(lic) = get_custom_server_from_config_string(s.trim()) {
|
|
return Ok(lic);
|
|
} else if s.contains("(") {
|
|
// https://github.com/rustdesk/rustdesk/issues/4162
|
|
for s in s.split("(") {
|
|
if let Ok(lic) = get_custom_server_from_config_string(s.trim()) {
|
|
return Ok(lic);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bail!("Failed to parse");
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_filename_license_string() {
|
|
assert!(get_custom_server_from_string("rustdesk.exe").is_err());
|
|
assert!(get_custom_server_from_string("rustdesk").is_err());
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-host=server.example.net.exe").unwrap(),
|
|
CustomServer {
|
|
host: "server.example.net".to_owned(),
|
|
key: "".to_owned(),
|
|
api: "".to_owned(),
|
|
relay: "".to_owned(),
|
|
}
|
|
);
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-host=server.example.net,.exe").unwrap(),
|
|
CustomServer {
|
|
host: "server.example.net".to_owned(),
|
|
key: "".to_owned(),
|
|
api: "".to_owned(),
|
|
relay: "".to_owned(),
|
|
}
|
|
);
|
|
// key in these tests is "foobar.,2" base64 encoded
|
|
assert_eq!(
|
|
get_custom_server_from_string(
|
|
"rustdesk-host=server.example.net,api=abc,key=Zm9vYmFyLiwyCg==.exe"
|
|
)
|
|
.unwrap(),
|
|
CustomServer {
|
|
host: "server.example.net".to_owned(),
|
|
key: "Zm9vYmFyLiwyCg==".to_owned(),
|
|
api: "abc".to_owned(),
|
|
relay: "".to_owned(),
|
|
}
|
|
);
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-host=server.example.net,key=Zm9vYmFyLiwyCg==,.exe")
|
|
.unwrap(),
|
|
CustomServer {
|
|
host: "server.example.net".to_owned(),
|
|
key: "Zm9vYmFyLiwyCg==".to_owned(),
|
|
api: "".to_owned(),
|
|
relay: "".to_owned(),
|
|
}
|
|
);
|
|
let lic = CustomServer {
|
|
host: "1.1.1.1".to_owned(),
|
|
key: "5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=".to_owned(),
|
|
api: "".to_owned(),
|
|
relay: "".to_owned(),
|
|
};
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-licensed-0nI900VsFHZVBVdIlncwpHS4V0bOZ0dtVldrpVO4JHdCp0YV5WdzUGZzdnYRVjI6ISeltmIsISMuEjLx4SMiojI0N3boJye.exe")
|
|
.unwrap(), lic);
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-licensed-0nI900VsFHZVBVdIlncwpHS4V0bOZ0dtVldrpVO4JHdCp0YV5WdzUGZzdnYRVjI6ISeltmIsISMuEjLx4SMiojI0N3boJye(1).exe")
|
|
.unwrap(), lic);
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk--0nI900VsFHZVBVdIlncwpHS4V0bOZ0dtVldrpVO4JHdCp0YV5WdzUGZzdnYRVjI6ISeltmIsISMuEjLx4SMiojI0N3boJye(1).exe")
|
|
.unwrap(), lic);
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-licensed-0nI900VsFHZVBVdIlncwpHS4V0bOZ0dtVldrpVO4JHdCp0YV5WdzUGZzdnYRVjI6ISeltmIsISMuEjLx4SMiojI0N3boJye (1).exe")
|
|
.unwrap(), lic);
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-licensed-0nI900VsFHZVBVdIlncwpHS4V0bOZ0dtVldrpVO4JHdCp0YV5WdzUGZzdnYRVjI6ISeltmIsISMuEjLx4SMiojI0N3boJye (1) (2).exe")
|
|
.unwrap(), lic);
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-licensed-0nI900VsFHZVBVdIlncwpHS4V0bOZ0dtVldrpVO4JHdCp0YV5WdzUGZzdnYRVjI6ISeltmIsISMuEjLx4SMiojI0N3boJye--abc.exe")
|
|
.unwrap(), lic);
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-licensed--0nI900VsFHZVBVdIlncwpHS4V0bOZ0dtVldrpVO4JHdCp0YV5WdzUGZzdnYRVjI6ISeltmIsISMuEjLx4SMiojI0N3boJye--.exe")
|
|
.unwrap(), lic);
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-licensed---0nI900VsFHZVBVdIlncwpHS4V0bOZ0dtVldrpVO4JHdCp0YV5WdzUGZzdnYRVjI6ISeltmIsISMuEjLx4SMiojI0N3boJye--.exe")
|
|
.unwrap(), lic);
|
|
assert_eq!(
|
|
get_custom_server_from_string("rustdesk-licensed--0nI900VsFHZVBVdIlncwpHS4V0bOZ0dtVldrpVO4JHdCp0YV5WdzUGZzdnYRVjI6ISeltmIsISMuEjLx4SMiojI0N3boJye--.exe")
|
|
.unwrap(), lic);
|
|
}
|
|
}
|