Просмотр исходного кода

sync rustdesk's hbb_common here

rustdesk лет назад: 3
Родитель
Сommit
17ddc89bd0

+ 5 - 2
libs/hbb_common/build.rs

@@ -1,8 +1,11 @@
1 1
 fn main() {
2
-    std::fs::create_dir_all("src/protos").unwrap();
2
+    let out_dir = format!("{}/protos", std::env::var("OUT_DIR").unwrap());
3
+
4
+    std::fs::create_dir_all(&out_dir).unwrap();
5
+    
3 6
     protobuf_codegen::Codegen::new()
4 7
         .pure()
5
-        .out_dir("src/protos")
8
+        .out_dir(out_dir)
6 9
         .inputs(&["protos/rendezvous.proto", "protos/message.proto"])
7 10
         .include("protos")
8 11
         .customize(

+ 32 - 3
libs/hbb_common/protos/message.proto

@@ -445,7 +445,7 @@ enum ImageQuality {
445 445
 }
446 446
 
447 447
 message VideoCodecState {
448
-  enum PerferCodec {
448
+  enum PreferCodec {
449 449
     Auto = 0;
450 450
     VPX = 1;
451 451
     H264 = 2;
@@ -455,7 +455,7 @@ message VideoCodecState {
455 455
   int32 score_vpx = 1;
456 456
   int32 score_h264 = 2;
457 457
   int32 score_h265 = 3;
458
-  PerferCodec perfer = 4;
458
+  PreferCodec prefer = 4;
459 459
 }
460 460
 
461 461
 message OptionMessage {
@@ -503,7 +503,7 @@ message AudioFrame {
503 503
 
504 504
 // Notify peer to show message box.
505 505
 message MessageBox {
506
-  // Message type. Refer to flutter/lib/commom.dart/msgBox().
506
+  // Message type. Refer to flutter/lib/common.dart/msgBox().
507 507
   string msgtype = 1;
508 508
   string title = 2;
509 509
   // English
@@ -552,6 +552,29 @@ message BackNotification {
552 552
   }
553 553
 }
554 554
 
555
+message ElevationRequestWithLogon {
556
+  string username = 1;
557
+  string password = 2;
558
+}
559
+
560
+message ElevationRequest {
561
+  oneof union {
562
+    bool direct = 1;
563
+    ElevationRequestWithLogon logon = 2;
564
+  }
565
+}
566
+
567
+message SwitchSidesRequest {
568
+  bytes uuid = 1;
569
+}
570
+
571
+message SwitchSidesResponse {
572
+  bytes uuid = 1;
573
+  LoginRequest lr = 2;
574
+}
575
+
576
+message SwitchBack {}
577
+
555 578
 message Misc {
556 579
   oneof union {
557 580
     ChatMessage chat_message = 4;
@@ -567,6 +590,11 @@ message Misc {
567 590
     bool uac = 15;
568 591
     bool foreground_window_elevated = 16;
569 592
     bool stop_service = 17;
593
+    ElevationRequest elevation_request = 18;
594
+    string elevation_response = 19;
595
+    bool portable_service_running = 20;
596
+    SwitchSidesRequest switch_sides_request = 21;
597
+    SwitchBack switch_back = 22;
570 598
   }
571 599
 }
572 600
 
@@ -591,5 +619,6 @@ message Message {
591 619
     Misc misc = 19;
592 620
     Cliprdr cliprdr = 20;
593 621
     MessageBox message_box = 21;
622
+    SwitchSidesResponse switch_sides_response = 22;
594 623
   }
595 624
 }

+ 11 - 3
libs/hbb_common/src/config.rs

@@ -49,7 +49,10 @@ lazy_static::lazy_static! {
49 49
     static ref CONFIG2: Arc<RwLock<Config2>> = Arc::new(RwLock::new(Config2::load()));
50 50
     static ref LOCAL_CONFIG: Arc<RwLock<LocalConfig>> = Arc::new(RwLock::new(LocalConfig::load()));
51 51
     pub static ref ONLINE: Arc<Mutex<HashMap<String, i64>>> = Default::default();
52
-    pub static ref PROD_RENDEZVOUS_SERVER: Arc<RwLock<String>> = Default::default();
52
+    pub static ref PROD_RENDEZVOUS_SERVER: Arc<RwLock<String>> = Arc::new(RwLock::new(match option_env!("RENDEZVOUS_SERVER") {
53
+        Some(key) if !key.is_empty() => key,
54
+        _ => "",
55
+    }.to_owned()));
53 56
     pub static ref APP_NAME: Arc<RwLock<String>> = Arc::new(RwLock::new("RustDesk".to_owned()));
54 57
     static ref KEY_PAIR: Arc<Mutex<Option<(Vec<u8>, Vec<u8>)>>> = Default::default();
55 58
     static ref HW_CODEC_CONFIG: Arc<RwLock<HwCodecConfig>> = Arc::new(RwLock::new(HwCodecConfig::load()));
@@ -77,12 +80,17 @@ const CHARS: &'static [char] = &[
77 80
     'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
78 81
 ];
79 82
 
80
-pub const RENDEZVOUS_SERVERS: &'static [&'static str] = &[
83
+const RENDEZVOUS_SERVERS: &'static [&'static str] = &[
81 84
     "rs-ny.rustdesk.com",
82 85
     "rs-sg.rustdesk.com",
83 86
     "rs-cn.rustdesk.com",
84 87
 ];
85
-pub const RS_PUB_KEY: &'static str = "OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw=";
88
+
89
+pub const RS_PUB_KEY: &'static str = match option_env!("RS_PUB_KEY") {
90
+    Some(key) if !key.is_empty() => key,
91
+    _ => "OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw=",
92
+};
93
+
86 94
 pub const RENDEZVOUS_PORT: i32 = 21116;
87 95
 pub const RELAY_PORT: i32 = 21117;
88 96
 

+ 39 - 0
libs/hbb_common/src/keyboard.rs

@@ -0,0 +1,39 @@
1
+use std::{fmt, slice::Iter, str::FromStr};
2
+
3
+use crate::protos::message::KeyboardMode;
4
+
5
+impl fmt::Display for KeyboardMode {
6
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7
+        match self {
8
+            KeyboardMode::Legacy => write!(f, "legacy"),
9
+            KeyboardMode::Map => write!(f, "map"),
10
+            KeyboardMode::Translate => write!(f, "translate"),
11
+            KeyboardMode::Auto => write!(f, "auto"),
12
+        }
13
+    }
14
+}
15
+
16
+impl FromStr for KeyboardMode {
17
+    type Err = ();
18
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
19
+        match s {
20
+            "legacy" => Ok(KeyboardMode::Legacy),
21
+            "map" => Ok(KeyboardMode::Map),
22
+            "translate" => Ok(KeyboardMode::Translate),
23
+            "auto" => Ok(KeyboardMode::Auto),
24
+            _ => Err(()),
25
+        }
26
+    }
27
+}
28
+
29
+impl KeyboardMode {
30
+    pub fn iter() -> Iter<'static, KeyboardMode> {
31
+        static KEYBOARD_MODES: [KeyboardMode; 4] = [
32
+            KeyboardMode::Legacy,
33
+            KeyboardMode::Map,
34
+            KeyboardMode::Translate,
35
+            KeyboardMode::Auto,
36
+        ];
37
+        KEYBOARD_MODES.iter()
38
+    }
39
+}

+ 34 - 0
libs/hbb_common/src/lib.rs

@@ -40,6 +40,7 @@ pub use tokio_socks::TargetAddr;
40 40
 pub mod password_security;
41 41
 pub use chrono;
42 42
 pub use directories_next;
43
+pub mod keyboard;
43 44
 
44 45
 #[cfg(feature = "quic")]
45 46
 pub type Stream = quic::Connection;
@@ -320,6 +321,18 @@ pub fn is_ip_str(id: &str) -> bool {
320 321
     is_ipv4_str(id) || is_ipv6_str(id)
321 322
 }
322 323
 
324
+#[inline]
325
+pub fn is_domain_port_str(id: &str) -> bool {
326
+    // modified regex for RFC1123 hostname. check https://stackoverflow.com/a/106223 for original version for hostname.
327
+    // according to [TLD List](https://data.iana.org/TLD/tlds-alpha-by-domain.txt) version 2023011700,
328
+    // there is no digits in TLD, and length is 2~63.
329
+    regex::Regex::new(
330
+        r"(?i)^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z-]{0,61}[a-z]:\d{1,5}$",
331
+    )
332
+    .unwrap()
333
+    .is_match(id)
334
+}
335
+
323 336
 #[cfg(test)]
324 337
 mod test_lib {
325 338
     use super::*;
@@ -339,4 +352,25 @@ mod test_lib {
339 352
         assert_eq!(is_ipv6_str("[1:2::0]:"), false);
340 353
         assert_eq!(is_ipv6_str("1:2::0]:1"), false);
341 354
     }
355
+
356
+    #[test]
357
+    fn test_hostname_port() {
358
+        assert_eq!(is_domain_port_str("a:12"), false);
359
+        assert_eq!(is_domain_port_str("a.b.c:12"), false);
360
+        assert_eq!(is_domain_port_str("test.com:12"), true);
361
+        assert_eq!(is_domain_port_str("test-UPPER.com:12"), true);
362
+        assert_eq!(is_domain_port_str("some-other.domain.com:12"), true);
363
+        assert_eq!(is_domain_port_str("under_score:12"), false);
364
+        assert_eq!(is_domain_port_str("a@bc:12"), false);
365
+        assert_eq!(is_domain_port_str("1.1.1.1:12"), false);
366
+        assert_eq!(is_domain_port_str("1.2.3:12"), false);
367
+        assert_eq!(is_domain_port_str("1.2.3.45:12"), false);
368
+        assert_eq!(is_domain_port_str("a.b.c:123456"), false);
369
+        assert_eq!(is_domain_port_str("---:12"), false);
370
+        assert_eq!(is_domain_port_str(".:12"), false);
371
+        // todo: should we also check for these edge cases?
372
+        // out-of-range port
373
+        assert_eq!(is_domain_port_str("test.com:0"), true);
374
+        assert_eq!(is_domain_port_str("test.com:98989"), true);
375
+    }
342 376
 }

+ 4 - 4
libs/hbb_common/src/platform/linux.rs

@@ -1,15 +1,15 @@
1 1
 use crate::ResultType;
2 2
 
3 3
 lazy_static::lazy_static! {
4
-    pub static ref DISTRO: Disto = Disto::new();
4
+    pub static ref DISTRO: Distro = Distro::new();
5 5
 }
6 6
 
7
-pub struct Disto {
7
+pub struct Distro {
8 8
     pub name: String,
9 9
     pub version_id: String,
10 10
 }
11 11
 
12
-impl Disto {
12
+impl Distro {
13 13
     fn new() -> Self {
14 14
         let name = run_cmds("awk -F'=' '/^NAME=/ {print $2}' /etc/os-release".to_owned())
15 15
             .unwrap_or_default()
@@ -74,7 +74,7 @@ fn get_display_server_of_session(session: &str) -> String {
74 74
     } else {
75 75
         "".to_owned()
76 76
     };
77
-    if display_server.is_empty() {
77
+    if display_server.is_empty() || display_server == "tty" {
78 78
         // loginctl has not given the expected output.  try something else.
79 79
         if let Ok(sestype) = std::env::var("XDG_SESSION_TYPE") {
80 80
             display_server = sestype;

+ 66 - 3
libs/hbb_common/src/socket_client.rs

@@ -9,11 +9,48 @@ use std::net::SocketAddr;
9 9
 use tokio::net::ToSocketAddrs;
10 10
 use tokio_socks::{IntoTargetAddr, TargetAddr};
11 11
 
12
-pub fn test_if_valid_server(host: &str) -> String {
13
-    let mut host = host.to_owned();
12
+#[inline]
13
+pub fn check_port<T: std::string::ToString>(host: T, port: i32) -> String {
14
+    let host = host.to_string();
15
+    if crate::is_ipv6_str(&host) {
16
+        if host.starts_with("[") {
17
+            return host;
18
+        }
19
+        return format!("[{}]:{}", host, port);
20
+    }
14 21
     if !host.contains(":") {
15
-        host = format!("{}:{}", host, 0);
22
+        return format!("{}:{}", host, port);
16 23
     }
24
+    return host;
25
+}
26
+
27
+#[inline]
28
+pub fn increase_port<T: std::string::ToString>(host: T, offset: i32) -> String {
29
+    let host = host.to_string();
30
+    if crate::is_ipv6_str(&host) {
31
+        if host.starts_with("[") {
32
+            let tmp: Vec<&str> = host.split("]:").collect();
33
+            if tmp.len() == 2 {
34
+                let port: i32 = tmp[1].parse().unwrap_or(0);
35
+                if port > 0 {
36
+                    return format!("{}]:{}", tmp[0], port + offset);
37
+                }
38
+            }
39
+        }
40
+    } else if host.contains(":") {
41
+        let tmp: Vec<&str> = host.split(":").collect();
42
+        if tmp.len() == 2 {
43
+            let port: i32 = tmp[1].parse().unwrap_or(0);
44
+            if port > 0 {
45
+                return format!("{}:{}", tmp[0], port + offset);
46
+            }
47
+        }
48
+    }
49
+    return host;
50
+}
51
+
52
+pub fn test_if_valid_server(host: &str) -> String {
53
+    let host = check_port(host, 0);
17 54
 
18 55
     use std::net::ToSocketAddrs;
19 56
     match Config::get_network_type() {
@@ -216,4 +253,30 @@ mod tests {
216 253
         }
217 254
         assert!(query_nip_io(&"1.1.1.1:80".parse().unwrap()).await.is_err());
218 255
     }
256
+
257
+    #[test]
258
+    fn test_test_if_valid_server() {
259
+        assert!(!test_if_valid_server("a").is_empty());
260
+        // on Linux, "1" is resolved to "0.0.0.1"
261
+        assert!(test_if_valid_server("1.1.1.1").is_empty());
262
+        assert!(test_if_valid_server("1.1.1.1:1").is_empty());
263
+    }
264
+
265
+    #[test]
266
+    fn test_check_port() {
267
+        assert_eq!(check_port("[1:2]:12", 32), "[1:2]:12");
268
+        assert_eq!(check_port("1:2", 32), "[1:2]:32");
269
+        assert_eq!(check_port("z1:2", 32), "z1:2");
270
+        assert_eq!(check_port("1.1.1.1", 32), "1.1.1.1:32");
271
+        assert_eq!(check_port("1.1.1.1:32", 32), "1.1.1.1:32");
272
+        assert_eq!(check_port("test.com:32", 0), "test.com:32");
273
+        assert_eq!(increase_port("[1:2]:12", 1), "[1:2]:13");
274
+        assert_eq!(increase_port("1.2.2.4:12", 1), "1.2.2.4:13");
275
+        assert_eq!(increase_port("1.2.2.4", 1), "1.2.2.4");
276
+        assert_eq!(increase_port("test.com", 1), "test.com");
277
+        assert_eq!(increase_port("test.com:13", 4), "test.com:17");
278
+        assert_eq!(increase_port("1:13", 4), "1:13");
279
+        assert_eq!(increase_port("22:1:13", 4), "22:1:13");
280
+        assert_eq!(increase_port("z1:2", 1), "z1:3");
281
+    }
219 282
 }