Browse Source

Merge branch 'master' of https://github.com/open-trade/hbbs

rustdesk 4 years ago
parent
commit
a8d3ba56b2
7 changed files with 229 additions and 16 deletions
  1. 52 1
      Cargo.lock
  2. 6 1
      Cargo.toml
  3. 1 1
      libs/hbb_common
  4. 7 1
      src/hbbr.rs
  5. 110 0
      src/lic.rs
  6. 9 0
      src/main.rs
  7. 44 12
      src/rendezvous_server.rs

+ 52 - 1
Cargo.lock

@@ -223,6 +223,12 @@ dependencies = [
223 223
  "lazy_static",
224 224
 ]
225 225
 
226
+[[package]]
227
+name = "cryptoxide"
228
+version = "0.3.2"
229
+source = "registry+https://github.com/rust-lang/crates.io-index"
230
+checksum = "46212f5d1792f89c3e866fb10636139464060110c568edd7f73ab5e9f736c26d"
231
+
226 232
 [[package]]
227 233
 name = "ct-logs"
228 234
 version = "0.6.0"
@@ -514,6 +520,7 @@ dependencies = [
514 520
  "protobuf-codegen-pure",
515 521
  "quinn",
516 522
  "rand",
523
+ "regex",
517 524
  "serde",
518 525
  "serde_derive",
519 526
  "serde_json",
@@ -530,15 +537,20 @@ dependencies = [
530 537
 name = "hbbs"
531 538
 version = "1.1.3"
532 539
 dependencies = [
533
- "cc",
540
+ "base64 0.13.0",
534 541
  "clap",
542
+ "cryptoxide",
535 543
  "hbb_common",
536 544
  "lazy_static",
545
+ "mac_address",
546
+ "machine-uid",
547
+ "minreq",
537 548
  "rocksdb",
538 549
  "rust-ini",
539 550
  "serde",
540 551
  "serde_derive",
541 552
  "serde_json",
553
+ "whoami",
542 554
 ]
543 555
 
544 556
 [[package]]
@@ -687,12 +699,30 @@ dependencies = [
687 699
  "winapi 0.3.9",
688 700
 ]
689 701
 
702
+[[package]]
703
+name = "machine-uid"
704
+version = "0.2.0"
705
+source = "registry+https://github.com/rust-lang/crates.io-index"
706
+checksum = "1f1595709b0a7386bcd56ba34d250d626e5503917d05d32cdccddcd68603e212"
707
+dependencies = [
708
+ "winreg",
709
+]
710
+
690 711
 [[package]]
691 712
 name = "memchr"
692 713
 version = "2.3.4"
693 714
 source = "registry+https://github.com/rust-lang/crates.io-index"
694 715
 checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
695 716
 
717
+[[package]]
718
+name = "minreq"
719
+version = "2.3.1"
720
+source = "registry+https://github.com/rust-lang/crates.io-index"
721
+checksum = "781e56f7d29192378f0a04948b1e6aec67ce561273b2dd26ac510bbe88d7be70"
722
+dependencies = [
723
+ "punycode",
724
+]
725
+
696 726
 [[package]]
697 727
 name = "mio"
698 728
 version = "0.6.22"
@@ -945,6 +975,12 @@ dependencies = [
945 975
  "protobuf-codegen",
946 976
 ]
947 977
 
978
+[[package]]
979
+name = "punycode"
980
+version = "0.4.1"
981
+source = "registry+https://github.com/rust-lang/crates.io-index"
982
+checksum = "e9e1dcb320d6839f6edb64f7a4a59d39b30480d4d1765b56873f7c858538a5fe"
983
+
948 984
 [[package]]
949 985
 name = "quick-error"
950 986
 version = "1.2.3"
@@ -1549,6 +1585,12 @@ dependencies = [
1549 1585
  "libc",
1550 1586
 ]
1551 1587
 
1588
+[[package]]
1589
+name = "whoami"
1590
+version = "0.9.0"
1591
+source = "registry+https://github.com/rust-lang/crates.io-index"
1592
+checksum = "7884773ab69074615cb8f8425d0e53f11710786158704fca70f53e71b0e05504"
1593
+
1552 1594
 [[package]]
1553 1595
 name = "winapi"
1554 1596
 version = "0.2.8"
@@ -1592,6 +1634,15 @@ version = "0.4.0"
1592 1634
 source = "registry+https://github.com/rust-lang/crates.io-index"
1593 1635
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1594 1636
 
1637
+[[package]]
1638
+name = "winreg"
1639
+version = "0.6.2"
1640
+source = "registry+https://github.com/rust-lang/crates.io-index"
1641
+checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
1642
+dependencies = [
1643
+ "winapi 0.3.9",
1644
+]
1645
+
1595 1646
 [[package]]
1596 1647
 name = "ws2_32-sys"
1597 1648
 version = "0.2.1"

+ 6 - 1
Cargo.toml

@@ -19,9 +19,14 @@ serde_json = "1.0"
19 19
 lazy_static = "1.4"
20 20
 clap = "2.33"
21 21
 rust-ini = "0.16"
22
+minreq = { version = "2.3.1", features = ["punycode"] }
23
+machine-uid = "0.2"
24
+mac_address = "1.1"
25
+whoami = "0.9"
26
+base64 = "0.13"
27
+cryptoxide = "0.3"
22 28
 
23 29
 [build-dependencies]
24
-cc = "1.0"
25 30
 hbb_common = { path = "libs/hbb_common" }
26 31
 
27 32
 [workspace]

+ 1 - 1
libs/hbb_common

@@ -1 +1 @@
1
-Subproject commit 002939a1037c786d2651a779492a7c813ea4e54a
1
+Subproject commit 99487187a6b25380b9a412f040f43f319ece7545

+ 7 - 1
src/hbbr.rs

@@ -3,14 +3,17 @@ mod relay_server;
3 3
 use hbb_common::{env_logger::*, ResultType};
4 4
 use relay_server::*;
5 5
 use std::sync::{Arc, Mutex};
6
+mod lic;
6 7
 
7 8
 fn main() -> ResultType<()> {
8 9
     init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info"));
9 10
     let args = format!(
10 11
         "-p, --port=[NUMBER(default={})] 'Sets the listening port'
11 12
         -k, --key=[KEY] 'Only allow the client with the same key'
13
+        {}
12 14
         ",
13
-        DEFAULT_PORT
15
+        DEFAULT_PORT,
16
+        lic::EMAIL_ARG
14 17
     );
15 18
     let matches = App::new("hbbr")
16 19
         .version(hbbs::VERSION)
@@ -18,6 +21,9 @@ fn main() -> ResultType<()> {
18 21
         .about("RustDesk Relay Server")
19 22
         .args_from_usage(&args)
20 23
         .get_matches();
24
+    if !lic::check_lic(matches.value_of("email").unwrap_or("")) {
25
+        return Ok(());
26
+    }
21 27
     let stop: Arc<Mutex<bool>> = Default::default();
22 28
     start(
23 29
         matches.value_of("port").unwrap_or(DEFAULT_PORT),

+ 110 - 0
src/lic.rs

@@ -0,0 +1,110 @@
1
+use hbb_common::{bail, log, ResultType};
2
+use serde_derive::{Deserialize, Serialize};
3
+use std::io::prelude::*;
4
+use std::path::Path;
5
+
6
+#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
7
+pub struct Machine {
8
+    #[serde(default)]
9
+    hostname: String,
10
+    #[serde(default)]
11
+    uid: String,
12
+    #[serde(default)]
13
+    mac: String,
14
+}
15
+
16
+#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
17
+pub struct Post {
18
+    #[serde(default)]
19
+    machine: String,
20
+    #[serde(default)]
21
+    email: String,
22
+    #[serde(default)]
23
+    status: String,
24
+}
25
+
26
+const LICENSE_FILE: &'static str = ".license.txt";
27
+
28
+pub fn check_lic(email: &str) -> bool {
29
+    let machine = get_lic();
30
+    let path = Path::new(LICENSE_FILE);
31
+    if Path::is_file(&path) {
32
+        let contents = std::fs::read_to_string(&path).unwrap_or("".to_owned());
33
+        if verify(&contents, &machine) {
34
+            return true;
35
+        }
36
+    }
37
+
38
+    if email.is_empty() {
39
+        log::error!("Registered email required (-m option). Please visit https://rustdesk.com/server for more infomration.");
40
+        return false;
41
+    }
42
+
43
+    match check_email(machine, email.to_owned()) {
44
+        Ok(v) => {
45
+            return v;
46
+        }
47
+        Err(err) => {
48
+            log::error!("{}", err);
49
+            return false;
50
+        }
51
+    }
52
+}
53
+
54
+fn write_lic(lic: &str) {
55
+    if let Ok(mut f) = std::fs::File::create(LICENSE_FILE) {
56
+        f.write_all(lic.as_bytes()).ok();
57
+        f.sync_all().ok();
58
+    }
59
+}
60
+
61
+fn check_email(machine: String, email: String) -> ResultType<bool> {
62
+    log::info!("Checking email with the server ...");
63
+    let resp = minreq::post("http://rustdesk.com/api/check-email")
64
+        .with_body(
65
+            serde_json::to_string(&Post {
66
+                machine: machine.clone(),
67
+                email,
68
+                ..Default::default()
69
+            })
70
+            .unwrap(),
71
+        )
72
+        .send()?;
73
+    if resp.reason_phrase == "OK" {
74
+        let p: Post = serde_json::from_str(&resp.as_str()?)?;
75
+        if !p.status.is_empty() {
76
+            bail!("{}", p.status);
77
+        }
78
+        if !verify(&p.machine, &machine) {
79
+            bail!("Verification failure");
80
+        }
81
+        write_lic(&p.machine);
82
+    } else {
83
+        bail!("Server error: {}", resp.reason_phrase);
84
+    }
85
+    Ok(true)
86
+}
87
+
88
+fn get_lic() -> String {
89
+    let hostname = whoami::hostname();
90
+    let uid = machine_uid::get().unwrap_or("".to_owned());
91
+    let mac = if let Ok(Some(ma)) = mac_address::get_mac_address() {
92
+        base64::encode(ma.bytes())
93
+    } else {
94
+        "".to_owned()
95
+    };
96
+    serde_json::to_string(&Machine { hostname, uid, mac }).unwrap()
97
+}
98
+
99
+fn verify(enc_str: &str, msg: &str) -> bool {
100
+    if let Ok(data) = base64::decode(enc_str) {
101
+        let key =
102
+            b"\xf1T\xc0\x1c\xffee\x86,S*\xd9.\x91\xcd\x85\x12:\xec\xa9 \x99:\x8a\xa2S\x1f Yy\x93R";
103
+        cryptoxide::ed25519::verify(msg.as_bytes(), &key[..], &data)
104
+    } else {
105
+        false
106
+    }
107
+}
108
+
109
+pub const EMAIL_ARG: &'static str =
110
+    "-m, --email=[EMAIL] 'Sets your email address registered with RustDesk'";

+ 9 - 0
src/main.rs

@@ -4,6 +4,7 @@
4 4
 use clap::App;
5 5
 use hbb_common::{env_logger::*, log, ResultType};
6 6
 use hbbs::*;
7
+mod lic;
7 8
 use ini::Ini;
8 9
 use std::sync::{Arc, Mutex};
9 10
 
@@ -16,8 +17,11 @@ fn main() -> ResultType<()> {
16 17
         -R, --rendezvous-servers=[HOSTS] 'Sets rendezvous servers, seperated by colon'
17 18
         -u, --software-url=[URL] 'Sets download url of RustDesk software of newest version'
18 19
         -r, --relay-servers=[HOST] 'Sets the default relay servers, seperated by colon'
20
+        -C, --change-id=[BOOL(default=Y)] 'Sets if support to change id'
21
+        {}
19 22
         -k, --key=[KEY] 'Only allow the client with the same key'",
20 23
         DEFAULT_PORT,
24
+        lic::EMAIL_ARG
21 25
     );
22 26
     let matches = App::new("hbbs")
23 27
         .version(crate::VERSION)
@@ -43,6 +47,9 @@ fn main() -> ResultType<()> {
43 47
         }
44 48
         return default.to_owned();
45 49
     };
50
+    if !lic::check_lic(&get_arg("email", "")) {
51
+        return Ok(());
52
+    }
46 53
     let port = get_arg("port", DEFAULT_PORT);
47 54
     let relay_servers: Vec<String> = get_arg("relay-servers", "")
48 55
         .split(",")
@@ -50,6 +57,7 @@ fn main() -> ResultType<()> {
50 57
         .map(|x| x.to_owned())
51 58
         .collect();
52 59
     let serial: i32 = get_arg("serial", "").parse().unwrap_or(0);
60
+    let id_change_support: bool = get_arg("change-id", "Y").to_uppercase() == "Y";
53 61
     let rendezvous_servers: Vec<String> = get_arg("rendezvous-servers", "")
54 62
         .split(",")
55 63
         .filter(|x| !x.is_empty() && test_if_valid_server(x, "rendezvous-server").is_ok())
@@ -69,6 +77,7 @@ fn main() -> ResultType<()> {
69 77
         get_arg("software-url", ""),
70 78
         &get_arg("key", ""),
71 79
         stop,
80
+        id_change_support,
72 81
     )?;
73 82
     Ok(())
74 83
 }

+ 44 - 12
src/rendezvous_server.rs

@@ -164,6 +164,7 @@ impl RendezvousServer {
164 164
         software_url: String,
165 165
         key: &str,
166 166
         stop: Arc<Mutex<bool>>,
167
+        id_change_support: bool,
167 168
     ) -> ResultType<()> {
168 169
         if !key.is_empty() {
169 170
             log::info!("Key: {}", key);
@@ -171,6 +172,7 @@ impl RendezvousServer {
171 172
         log::info!("Listening on tcp/udp {}", addr);
172 173
         log::info!("Listening on tcp {}, extra port for NAT test", addr2);
173 174
         log::info!("relay-servers={:?}", relay_servers);
175
+        log::info!("change-id={:?}", id_change_support);
174 176
         let mut socket = FramedSocket::new(addr).await?;
175 177
         let (tx, mut rx) = mpsc::unbounded_channel::<(RendezvousMessage, SocketAddr)>();
176 178
         let version = hbb_common::get_version_from_url(&software_url);
@@ -202,6 +204,7 @@ impl RendezvousServer {
202 204
                 &mut socket,
203 205
                 key,
204 206
                 stop.clone(),
207
+                id_change_support,
205 208
             )
206 209
             .await;
207 210
         }
@@ -215,6 +218,7 @@ impl RendezvousServer {
215 218
         socket: &mut FramedSocket,
216 219
         key: &str,
217 220
         stop: Arc<Mutex<bool>>,
221
+        id_change_support: bool,
218 222
     ) {
219 223
         let mut timer = interval(Duration::from_millis(100));
220 224
         loop {
@@ -321,6 +325,31 @@ impl RendezvousServer {
321 325
                                         }
322 326
                                         break;
323 327
                                     }
328
+                                    Some(rendezvous_message::Union::register_pk(rk)) => {
329
+                                        if rk.uuid.is_empty() {
330
+                                            break;
331
+                                        }
332
+                                        let mut res = register_pk_response::Result::OK;
333
+                                        if !id_change_support {
334
+                                            res = register_pk_response::Result::NOT_SUPPORT;
335
+                                        } else if !hbb_common::is_valid_custom_id(&rk.id) {
336
+                                            res = register_pk_response::Result::INVALID_ID_FORMAT;
337
+                                        } else if let Some(peer) = rs.pm.get(&rk.id).await {
338
+                                            if peer.uuid != rk.uuid {
339
+                                                res = register_pk_response::Result::ID_EXISTS;
340
+                                            }
341
+                                        }
342
+                                        let mut msg_out = RendezvousMessage::new();
343
+                                        msg_out.set_register_pk_response(RegisterPkResponse {
344
+                                            result: res.into(),
345
+                                            ..Default::default()
346
+                                        });
347
+                                        if let Some(tcp) = sender.as_mut() {
348
+                                            if let Ok(bytes) = msg_out.write_to_bytes() {
349
+                                                allow_err!(tcp.send(Bytes::from(bytes)).await);
350
+                                            }
351
+                                        }
352
+                                    }
324 353
                                     _ => {
325 354
                                         break;
326 355
                                     }
@@ -372,7 +401,7 @@ impl RendezvousServer {
372 401
                     let id = rk.id;
373 402
                     let mut res = register_pk_response::Result::OK;
374 403
                     if let Some(peer) = self.pm.get(&id).await {
375
-                        if !peer.uuid.is_empty() && peer.uuid != rk.uuid {
404
+                        if peer.uuid != rk.uuid {
376 405
                             log::warn!(
377 406
                                 "Peer {} uuid mismatch: {:?} vs {:?}",
378 407
                                 id,
@@ -380,7 +409,7 @@ impl RendezvousServer {
380 409
                                 peer.uuid
381 410
                             );
382 411
                             res = register_pk_response::Result::UUID_MISMATCH;
383
-                        } else if peer.uuid.is_empty() || peer.pk != rk.pk {
412
+                        } else if peer.pk != rk.pk {
384 413
                             self.pm.update_pk(id, addr, rk.uuid, rk.pk);
385 414
                         }
386 415
                     } else {
@@ -611,6 +640,17 @@ impl RendezvousServer {
611 640
                 },
612 641
             };
613 642
             let socket_addr = AddrMangle::encode(addr);
643
+            let relay_server = {
644
+                if self.relay_servers.is_empty() {
645
+                    "".to_owned()
646
+                } else {
647
+                    let i = unsafe {
648
+                        ROTATION_RELAY_SERVER += 1;
649
+                        ROTATION_RELAY_SERVER % self.relay_servers.len()
650
+                    };
651
+                    self.relay_servers[i].clone()
652
+                }
653
+            };
614 654
             if same_intranet {
615 655
                 log::debug!(
616 656
                     "Fetch local addr {:?} {:?} request from {:?}",
@@ -618,13 +658,9 @@ impl RendezvousServer {
618 658
                     &peer.socket_addr,
619 659
                     &addr
620 660
                 );
621
-                let i = unsafe {
622
-                    ROTATION_RELAY_SERVER += 1;
623
-                    ROTATION_RELAY_SERVER % self.relay_servers.len()
624
-                };
625 661
                 msg_out.set_fetch_local_addr(FetchLocalAddr {
626 662
                     socket_addr,
627
-                    relay_server: self.relay_servers[i].clone(),
663
+                    relay_server,
628 664
                     ..Default::default()
629 665
                 });
630 666
             } else {
@@ -634,14 +670,10 @@ impl RendezvousServer {
634 670
                     &peer.socket_addr,
635 671
                     &addr
636 672
                 );
637
-                let i = unsafe {
638
-                    ROTATION_RELAY_SERVER += 1;
639
-                    ROTATION_RELAY_SERVER % self.relay_servers.len()
640
-                };
641 673
                 msg_out.set_punch_hole(PunchHole {
642 674
                     socket_addr,
643 675
                     nat_type: ph.nat_type,
644
-                    relay_server: self.relay_servers[i].clone(),
676
+                    relay_server,
645 677
                     ..Default::default()
646 678
                 });
647 679
             }