mirror of
https://github.com/rustdesk/rustdesk-server.git
synced 2025-07-01 23:35:38 +00:00
Merge branch 'master' of https://github.com/open-trade/hbbs
This commit is contained in:
commit
a8d3ba56b2
53
Cargo.lock
generated
53
Cargo.lock
generated
@ -223,6 +223,12 @@ dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cryptoxide"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46212f5d1792f89c3e866fb10636139464060110c568edd7f73ab5e9f736c26d"
|
||||
|
||||
[[package]]
|
||||
name = "ct-logs"
|
||||
version = "0.6.0"
|
||||
@ -514,6 +520,7 @@ dependencies = [
|
||||
"protobuf-codegen-pure",
|
||||
"quinn",
|
||||
"rand",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
@ -530,15 +537,20 @@ dependencies = [
|
||||
name = "hbbs"
|
||||
version = "1.1.3"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"base64 0.13.0",
|
||||
"clap",
|
||||
"cryptoxide",
|
||||
"hbb_common",
|
||||
"lazy_static",
|
||||
"mac_address",
|
||||
"machine-uid",
|
||||
"minreq",
|
||||
"rocksdb",
|
||||
"rust-ini",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"whoami",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -687,12 +699,30 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "machine-uid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f1595709b0a7386bcd56ba34d250d626e5503917d05d32cdccddcd68603e212"
|
||||
dependencies = [
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
|
||||
[[package]]
|
||||
name = "minreq"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "781e56f7d29192378f0a04948b1e6aec67ce561273b2dd26ac510bbe88d7be70"
|
||||
dependencies = [
|
||||
"punycode",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.6.22"
|
||||
@ -945,6 +975,12 @@ dependencies = [
|
||||
"protobuf-codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "punycode"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9e1dcb320d6839f6edb64f7a4a59d39b30480d4d1765b56873f7c858538a5fe"
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
@ -1549,6 +1585,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7884773ab69074615cb8f8425d0e53f11710786158704fca70f53e71b0e05504"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
@ -1592,6 +1634,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ws2_32-sys"
|
||||
version = "0.2.1"
|
||||
|
@ -19,9 +19,14 @@ serde_json = "1.0"
|
||||
lazy_static = "1.4"
|
||||
clap = "2.33"
|
||||
rust-ini = "0.16"
|
||||
minreq = { version = "2.3.1", features = ["punycode"] }
|
||||
machine-uid = "0.2"
|
||||
mac_address = "1.1"
|
||||
whoami = "0.9"
|
||||
base64 = "0.13"
|
||||
cryptoxide = "0.3"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
hbb_common = { path = "libs/hbb_common" }
|
||||
|
||||
[workspace]
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 002939a1037c786d2651a779492a7c813ea4e54a
|
||||
Subproject commit 99487187a6b25380b9a412f040f43f319ece7545
|
@ -3,14 +3,17 @@ mod relay_server;
|
||||
use hbb_common::{env_logger::*, ResultType};
|
||||
use relay_server::*;
|
||||
use std::sync::{Arc, Mutex};
|
||||
mod lic;
|
||||
|
||||
fn main() -> ResultType<()> {
|
||||
init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info"));
|
||||
let args = format!(
|
||||
"-p, --port=[NUMBER(default={})] 'Sets the listening port'
|
||||
-k, --key=[KEY] 'Only allow the client with the same key'
|
||||
{}
|
||||
",
|
||||
DEFAULT_PORT
|
||||
DEFAULT_PORT,
|
||||
lic::EMAIL_ARG
|
||||
);
|
||||
let matches = App::new("hbbr")
|
||||
.version(hbbs::VERSION)
|
||||
@ -18,6 +21,9 @@ fn main() -> ResultType<()> {
|
||||
.about("RustDesk Relay Server")
|
||||
.args_from_usage(&args)
|
||||
.get_matches();
|
||||
if !lic::check_lic(matches.value_of("email").unwrap_or("")) {
|
||||
return Ok(());
|
||||
}
|
||||
let stop: Arc<Mutex<bool>> = Default::default();
|
||||
start(
|
||||
matches.value_of("port").unwrap_or(DEFAULT_PORT),
|
||||
|
110
src/lic.rs
Normal file
110
src/lic.rs
Normal file
@ -0,0 +1,110 @@
|
||||
use hbb_common::{bail, log, ResultType};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
|
||||
pub struct Machine {
|
||||
#[serde(default)]
|
||||
hostname: String,
|
||||
#[serde(default)]
|
||||
uid: String,
|
||||
#[serde(default)]
|
||||
mac: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
|
||||
pub struct Post {
|
||||
#[serde(default)]
|
||||
machine: String,
|
||||
#[serde(default)]
|
||||
email: String,
|
||||
#[serde(default)]
|
||||
status: String,
|
||||
}
|
||||
|
||||
const LICENSE_FILE: &'static str = ".license.txt";
|
||||
|
||||
pub fn check_lic(email: &str) -> bool {
|
||||
let machine = get_lic();
|
||||
let path = Path::new(LICENSE_FILE);
|
||||
if Path::is_file(&path) {
|
||||
let contents = std::fs::read_to_string(&path).unwrap_or("".to_owned());
|
||||
if verify(&contents, &machine) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if email.is_empty() {
|
||||
log::error!("Registered email required (-m option). Please visit https://rustdesk.com/server for more infomration.");
|
||||
return false;
|
||||
}
|
||||
|
||||
match check_email(machine, email.to_owned()) {
|
||||
Ok(v) => {
|
||||
return v;
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("{}", err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_lic(lic: &str) {
|
||||
if let Ok(mut f) = std::fs::File::create(LICENSE_FILE) {
|
||||
f.write_all(lic.as_bytes()).ok();
|
||||
f.sync_all().ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn check_email(machine: String, email: String) -> ResultType<bool> {
|
||||
log::info!("Checking email with the server ...");
|
||||
let resp = minreq::post("http://rustdesk.com/api/check-email")
|
||||
.with_body(
|
||||
serde_json::to_string(&Post {
|
||||
machine: machine.clone(),
|
||||
email,
|
||||
..Default::default()
|
||||
})
|
||||
.unwrap(),
|
||||
)
|
||||
.send()?;
|
||||
if resp.reason_phrase == "OK" {
|
||||
let p: Post = serde_json::from_str(&resp.as_str()?)?;
|
||||
if !p.status.is_empty() {
|
||||
bail!("{}", p.status);
|
||||
}
|
||||
if !verify(&p.machine, &machine) {
|
||||
bail!("Verification failure");
|
||||
}
|
||||
write_lic(&p.machine);
|
||||
} else {
|
||||
bail!("Server error: {}", resp.reason_phrase);
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn get_lic() -> String {
|
||||
let hostname = whoami::hostname();
|
||||
let uid = machine_uid::get().unwrap_or("".to_owned());
|
||||
let mac = if let Ok(Some(ma)) = mac_address::get_mac_address() {
|
||||
base64::encode(ma.bytes())
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
serde_json::to_string(&Machine { hostname, uid, mac }).unwrap()
|
||||
}
|
||||
|
||||
fn verify(enc_str: &str, msg: &str) -> bool {
|
||||
if let Ok(data) = base64::decode(enc_str) {
|
||||
let key =
|
||||
b"\xf1T\xc0\x1c\xffee\x86,S*\xd9.\x91\xcd\x85\x12:\xec\xa9 \x99:\x8a\xa2S\x1f Yy\x93R";
|
||||
cryptoxide::ed25519::verify(msg.as_bytes(), &key[..], &data)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub const EMAIL_ARG: &'static str =
|
||||
"-m, --email=[EMAIL] 'Sets your email address registered with RustDesk'";
|
@ -4,6 +4,7 @@
|
||||
use clap::App;
|
||||
use hbb_common::{env_logger::*, log, ResultType};
|
||||
use hbbs::*;
|
||||
mod lic;
|
||||
use ini::Ini;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
@ -16,8 +17,11 @@ fn main() -> ResultType<()> {
|
||||
-R, --rendezvous-servers=[HOSTS] 'Sets rendezvous servers, seperated by colon'
|
||||
-u, --software-url=[URL] 'Sets download url of RustDesk software of newest version'
|
||||
-r, --relay-servers=[HOST] 'Sets the default relay servers, seperated by colon'
|
||||
-C, --change-id=[BOOL(default=Y)] 'Sets if support to change id'
|
||||
{}
|
||||
-k, --key=[KEY] 'Only allow the client with the same key'",
|
||||
DEFAULT_PORT,
|
||||
lic::EMAIL_ARG
|
||||
);
|
||||
let matches = App::new("hbbs")
|
||||
.version(crate::VERSION)
|
||||
@ -43,6 +47,9 @@ fn main() -> ResultType<()> {
|
||||
}
|
||||
return default.to_owned();
|
||||
};
|
||||
if !lic::check_lic(&get_arg("email", "")) {
|
||||
return Ok(());
|
||||
}
|
||||
let port = get_arg("port", DEFAULT_PORT);
|
||||
let relay_servers: Vec<String> = get_arg("relay-servers", "")
|
||||
.split(",")
|
||||
@ -50,6 +57,7 @@ fn main() -> ResultType<()> {
|
||||
.map(|x| x.to_owned())
|
||||
.collect();
|
||||
let serial: i32 = get_arg("serial", "").parse().unwrap_or(0);
|
||||
let id_change_support: bool = get_arg("change-id", "Y").to_uppercase() == "Y";
|
||||
let rendezvous_servers: Vec<String> = get_arg("rendezvous-servers", "")
|
||||
.split(",")
|
||||
.filter(|x| !x.is_empty() && test_if_valid_server(x, "rendezvous-server").is_ok())
|
||||
@ -69,6 +77,7 @@ fn main() -> ResultType<()> {
|
||||
get_arg("software-url", ""),
|
||||
&get_arg("key", ""),
|
||||
stop,
|
||||
id_change_support,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -164,6 +164,7 @@ impl RendezvousServer {
|
||||
software_url: String,
|
||||
key: &str,
|
||||
stop: Arc<Mutex<bool>>,
|
||||
id_change_support: bool,
|
||||
) -> ResultType<()> {
|
||||
if !key.is_empty() {
|
||||
log::info!("Key: {}", key);
|
||||
@ -171,6 +172,7 @@ impl RendezvousServer {
|
||||
log::info!("Listening on tcp/udp {}", addr);
|
||||
log::info!("Listening on tcp {}, extra port for NAT test", addr2);
|
||||
log::info!("relay-servers={:?}", relay_servers);
|
||||
log::info!("change-id={:?}", id_change_support);
|
||||
let mut socket = FramedSocket::new(addr).await?;
|
||||
let (tx, mut rx) = mpsc::unbounded_channel::<(RendezvousMessage, SocketAddr)>();
|
||||
let version = hbb_common::get_version_from_url(&software_url);
|
||||
@ -202,6 +204,7 @@ impl RendezvousServer {
|
||||
&mut socket,
|
||||
key,
|
||||
stop.clone(),
|
||||
id_change_support,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
@ -215,6 +218,7 @@ impl RendezvousServer {
|
||||
socket: &mut FramedSocket,
|
||||
key: &str,
|
||||
stop: Arc<Mutex<bool>>,
|
||||
id_change_support: bool,
|
||||
) {
|
||||
let mut timer = interval(Duration::from_millis(100));
|
||||
loop {
|
||||
@ -321,6 +325,31 @@ impl RendezvousServer {
|
||||
}
|
||||
break;
|
||||
}
|
||||
Some(rendezvous_message::Union::register_pk(rk)) => {
|
||||
if rk.uuid.is_empty() {
|
||||
break;
|
||||
}
|
||||
let mut res = register_pk_response::Result::OK;
|
||||
if !id_change_support {
|
||||
res = register_pk_response::Result::NOT_SUPPORT;
|
||||
} else if !hbb_common::is_valid_custom_id(&rk.id) {
|
||||
res = register_pk_response::Result::INVALID_ID_FORMAT;
|
||||
} else if let Some(peer) = rs.pm.get(&rk.id).await {
|
||||
if peer.uuid != rk.uuid {
|
||||
res = register_pk_response::Result::ID_EXISTS;
|
||||
}
|
||||
}
|
||||
let mut msg_out = RendezvousMessage::new();
|
||||
msg_out.set_register_pk_response(RegisterPkResponse {
|
||||
result: res.into(),
|
||||
..Default::default()
|
||||
});
|
||||
if let Some(tcp) = sender.as_mut() {
|
||||
if let Ok(bytes) = msg_out.write_to_bytes() {
|
||||
allow_err!(tcp.send(Bytes::from(bytes)).await);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
break;
|
||||
}
|
||||
@ -372,7 +401,7 @@ impl RendezvousServer {
|
||||
let id = rk.id;
|
||||
let mut res = register_pk_response::Result::OK;
|
||||
if let Some(peer) = self.pm.get(&id).await {
|
||||
if !peer.uuid.is_empty() && peer.uuid != rk.uuid {
|
||||
if peer.uuid != rk.uuid {
|
||||
log::warn!(
|
||||
"Peer {} uuid mismatch: {:?} vs {:?}",
|
||||
id,
|
||||
@ -380,7 +409,7 @@ impl RendezvousServer {
|
||||
peer.uuid
|
||||
);
|
||||
res = register_pk_response::Result::UUID_MISMATCH;
|
||||
} else if peer.uuid.is_empty() || peer.pk != rk.pk {
|
||||
} else if peer.pk != rk.pk {
|
||||
self.pm.update_pk(id, addr, rk.uuid, rk.pk);
|
||||
}
|
||||
} else {
|
||||
@ -611,6 +640,17 @@ impl RendezvousServer {
|
||||
},
|
||||
};
|
||||
let socket_addr = AddrMangle::encode(addr);
|
||||
let relay_server = {
|
||||
if self.relay_servers.is_empty() {
|
||||
"".to_owned()
|
||||
} else {
|
||||
let i = unsafe {
|
||||
ROTATION_RELAY_SERVER += 1;
|
||||
ROTATION_RELAY_SERVER % self.relay_servers.len()
|
||||
};
|
||||
self.relay_servers[i].clone()
|
||||
}
|
||||
};
|
||||
if same_intranet {
|
||||
log::debug!(
|
||||
"Fetch local addr {:?} {:?} request from {:?}",
|
||||
@ -618,13 +658,9 @@ impl RendezvousServer {
|
||||
&peer.socket_addr,
|
||||
&addr
|
||||
);
|
||||
let i = unsafe {
|
||||
ROTATION_RELAY_SERVER += 1;
|
||||
ROTATION_RELAY_SERVER % self.relay_servers.len()
|
||||
};
|
||||
msg_out.set_fetch_local_addr(FetchLocalAddr {
|
||||
socket_addr,
|
||||
relay_server: self.relay_servers[i].clone(),
|
||||
relay_server,
|
||||
..Default::default()
|
||||
});
|
||||
} else {
|
||||
@ -634,14 +670,10 @@ impl RendezvousServer {
|
||||
&peer.socket_addr,
|
||||
&addr
|
||||
);
|
||||
let i = unsafe {
|
||||
ROTATION_RELAY_SERVER += 1;
|
||||
ROTATION_RELAY_SERVER % self.relay_servers.len()
|
||||
};
|
||||
msg_out.set_punch_hole(PunchHole {
|
||||
socket_addr,
|
||||
nat_type: ph.nat_type,
|
||||
relay_server: self.relay_servers[i].clone(),
|
||||
relay_server,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user