From 10eddc139c3254d9183ede0c945b6ad8cf7af5f6 Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 22 Mar 2023 17:01:11 +0800 Subject: [PATCH 01/44] linux virtual display, init commit Signed-off-by: fufesou --- Cargo.lock | 54 ++ Cargo.toml | 2 + libs/hbb_common/protos/message.proto | 6 + libs/hbb_common/src/platform/linux.rs | 4 +- res/pam.d/rustdesk.debian | 5 + res/pam.d/rustdesk.suse | 5 + res/startwm.sh | 130 ++++ res/xorg.conf | 30 + src/cli.rs | 4 +- src/client.rs | 124 +++- src/client/io_loop.rs | 4 +- src/platform/linux.rs | 1 + src/platform/linux_desktop.rs | 951 ++++++++++++++++++++++++++ src/platform/mod.rs | 3 + src/port_forward.rs | 4 +- src/rendezvous_mediator.rs | 9 +- src/server.rs | 34 + src/server/connection.rs | 103 ++- src/server/service.rs | 2 + src/ui/common.css | 4 + src/ui/common.tis | 26 +- src/ui/msgbox.tis | 62 +- src/ui/remote.rs | 2 +- src/ui_session_interface.rs | 29 +- 24 files changed, 1544 insertions(+), 54 deletions(-) create mode 100644 res/pam.d/rustdesk.debian create mode 100644 res/pam.d/rustdesk.suse create mode 100755 res/startwm.sh create mode 100644 res/xorg.conf create mode 100644 src/platform/linux_desktop.rs diff --git a/Cargo.lock b/Cargo.lock index 5a4cad9f8..9d2984abe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4159,6 +4159,38 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "pam" +version = "0.7.0" +source = "git+https://github.com/fufesou/pam#10da2cbbabe32cbc9de22a66abe44738e7ec0ea0" +dependencies = [ + "libc", + "pam-macros", + "pam-sys", + "users 0.10.0", +] + +[[package]] +name = "pam-macros" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94f3b9b97df3c6d4e51a14916639b24e02c7d15d1dba686ce9b1118277cb811" +dependencies = [ + "proc-macro2 1.0.54", + "quote 1.0.26", + "syn 1.0.109", +] + +[[package]] +name = "pam-sys" +version = "1.0.0-alpha4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e9dfd42858f6a6bb1081079fd9dc259ca3e2aaece6cb689fd36b1058046c969" +dependencies = [ + "bindgen 0.59.2", + "libc", +] + [[package]] name = "pango" version = "0.16.5" @@ -5124,6 +5156,7 @@ dependencies = [ "objc", "objc_id", "os-version", + "pam", "parity-tokio-ipc", "rdev", "repng", @@ -5149,6 +5182,7 @@ dependencies = [ "tray-icon", "trayicon", "url", + "users 0.11.0", "uuid", "virtual_display", "whoami", @@ -6443,6 +6477,26 @@ dependencies = [ "serde 1.0.159", ] +[[package]] +name = "users" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486" +dependencies = [ + "libc", + "log", +] + +[[package]] +name = "users" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032" +dependencies = [ + "libc", + "log", +] + [[package]] name = "utf8parse" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index a01415837..10f90f387 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -122,6 +122,8 @@ mouce = { git="https://github.com/fufesou/mouce.git" } evdev = { git="https://github.com/fufesou/evdev" } dbus = "0.9" dbus-crossroads = "0.5" +pam = { git="https://github.com/fufesou/pam" } +users = "0.11.0" [target.'cfg(target_os = "android")'.dependencies] android_logger = "0.11" diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index a481ae6c4..c49f163a8 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -52,6 +52,11 @@ message FileTransfer { bool show_hidden = 2; } +message OSLogin { + string username = 1; + string password = 2; +} + message LoginRequest { string username = 1; bytes password = 2; @@ -65,6 +70,7 @@ message LoginRequest { bool video_ack_required = 9; uint64 session_id = 10; string version = 11; + OSLogin os_login = 12; } message ChatMessage { string text = 1; } diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index 89c96799d..1d826ea97 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -191,7 +191,7 @@ pub fn run_cmds(cmds: &str) -> ResultType { } #[cfg(not(feature = "flatpak"))] -fn run_loginctl(args: Option>) -> std::io::Result { +pub(super) fn run_loginctl(args: Option>) -> std::io::Result { let mut cmd = std::process::Command::new("loginctl"); if let Some(a) = args { return cmd.args(a).output(); @@ -200,7 +200,7 @@ fn run_loginctl(args: Option>) -> std::io::Result>) -> std::io::Result { +pub(super) fn run_loginctl(args: Option>) -> std::io::Result { let mut l_args = String::from("loginctl"); if let Some(a) = args { l_args = format!("{} {}", l_args, a.join(" ")); diff --git a/res/pam.d/rustdesk.debian b/res/pam.d/rustdesk.debian new file mode 100644 index 000000000..789ce8f7c --- /dev/null +++ b/res/pam.d/rustdesk.debian @@ -0,0 +1,5 @@ +#%PAM-1.0 +@include common-auth +@include common-account +@include common-session +@include common-password diff --git a/res/pam.d/rustdesk.suse b/res/pam.d/rustdesk.suse new file mode 100644 index 000000000..a7c7836ce --- /dev/null +++ b/res/pam.d/rustdesk.suse @@ -0,0 +1,5 @@ +#%PAM-1.0 +auth include common-auth +account include common-account +session include common-session +password include common-password diff --git a/res/startwm.sh b/res/startwm.sh new file mode 100755 index 000000000..7cdaf07ce --- /dev/null +++ b/res/startwm.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash + +# This script is derived from https://github.com/neutrinolabs/xrdp/sesman/startwm.sh. + +# +# This script is an example. You might need to edit this script +# depending on your distro if it doesn't work for you. +# +# Uncomment the following line for debug: +# exec xterm + + +# Execution sequence for interactive login shell - pseudocode +# +# IF /etc/profile is readable THEN +# execute ~/.bash_profile +# END IF +# IF ~/.bash_profile is readable THEN +# execute ~/.bash_profile +# ELSE +# IF ~/.bash_login is readable THEN +# execute ~/.bash_login +# ELSE +# IF ~/.profile is readable THEN +# execute ~/.profile +# END IF +# END IF +# END IF +pre_start() +{ + if [ -r /etc/profile ]; then + . /etc/profile + fi + if [ -r ~/.bash_profile ]; then + . ~/.bash_profile + else + if [ -r ~/.bash_login ]; then + . ~/.bash_login + else + if [ -r ~/.profile ]; then + . ~/.profile + fi + fi + fi + return 0 +} + +# When loging out from the interactive shell, the execution sequence is: +# +# IF ~/.bash_logout exists THEN +# execute ~/.bash_logout +# END IF +post_start() +{ + if [ -r ~/.bash_logout ]; then + . ~/.bash_logout + fi + return 0 +} + +#start the window manager +wm_start() +{ + if [ -r /etc/default/locale ]; then + . /etc/default/locale + export LANG LANGUAGE + fi + + # debian + if [ -r /etc/X11/Xsession ]; then + pre_start + . /etc/X11/Xsession + post_start + exit 0 + fi + + # alpine + # Don't use /etc/X11/xinit/Xsession - it doesn't work + if [ -f /etc/alpine-release ]; then + if [ -f /etc/X11/xinit/xinitrc ]; then + pre_start + /etc/X11/xinit/xinitrc + post_start + else + echo "** xinit package isn't installed" >&2 + exit 1 + fi + fi + + # el + if [ -r /etc/X11/xinit/Xsession ]; then + pre_start + . /etc/X11/xinit/Xsession + post_start + exit 0 + fi + + # suse + if [ -r /etc/X11/xdm/Xsession ]; then + # since the following script run a user login shell, + # do not execute the pseudo login shell scripts + . /etc/X11/xdm/Xsession + exit 0 + elif [ -r /usr/etc/X11/xdm/Xsession ]; then + . /usr/etc/X11/xdm/Xsession + exit 0 + fi + + pre_start + xterm + post_start +} + +#. /etc/environment +#export PATH=$PATH +#export LANG=$LANG + +# change PATH to be what your environment needs usually what is in +# /etc/environment +#PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" +#export PATH=$PATH + +# for PATH and LANG from /etc/environment +# pam will auto process the environment file if /etc/pam.d/xrdp-sesman +# includes +# auth required pam_env.so readenv=1 + +wm_start + +exit 1 diff --git a/res/xorg.conf b/res/xorg.conf new file mode 100644 index 000000000..fe1539995 --- /dev/null +++ b/res/xorg.conf @@ -0,0 +1,30 @@ +Section "Monitor" + Identifier "Dummy Monitor" + + # Default HorizSync 31.50 - 48.00 kHz + HorizSync 5.0 - 150.0 + # Default VertRefresh 50.00 - 70.00 Hz + VertRefresh 5.0 - 100.0 + + # Taken from https://www.xpra.org/xorg.conf + Modeline "1920x1080" 23.53 1920 1952 2040 2072 1080 1106 1108 1135 + Modeline "1280x720" 27.41 1280 1312 1416 1448 720 737 740 757 +EndSection + +Section "Device" + Identifier "Dummy VideoCard" + Driver "dummy" + # Default VideoRam 4096 + # (1920 * 1080 * 4) / 1024 = 8100 + VideoRam 8100 +EndSection + +Section "Screen" + Identifier "Dummy Screen" + Device "Dummy VideoCard" + Monitor "Dummy Monitor" + SubSection "Display" + Depth 24 + Modes "1920x1080" "1280x720" + EndSubSection +EndSection \ No newline at end of file diff --git a/src/cli.rs b/src/cli.rs index 454eec1ee..13e70987b 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -85,8 +85,8 @@ impl Interface for Session { handle_hash(self.lc.clone(), &pass, hash, self, peer).await; } - async fn handle_login_from_ui(&mut self, password: String, remember: bool, peer: &mut Stream) { - handle_login_from_ui(self.lc.clone(), password, remember, peer).await; + async fn handle_login_from_ui(&mut self, os_username: String, os_password: String, password: String, remember: bool, peer: &mut Stream) { + handle_login_from_ui(self.lc.clone(), os_username, os_password, password, remember, peer).await; } async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream) { diff --git a/src/client.rs b/src/client.rs index 2f745b70c..f03cb0e55 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1591,7 +1591,12 @@ impl LoginConfigHandler { } /// Create a [`Message`] for login. - fn create_login_msg(&self, password: Vec) -> Message { + fn create_login_msg( + &self, + os_username: String, + os_password: String, + password: Vec, + ) -> Message { #[cfg(any(target_os = "android", target_os = "ios"))] let my_id = Config::get_id_or(crate::common::DEVICE_ID.lock().unwrap().clone()); #[cfg(not(any(target_os = "android", target_os = "ios")))] @@ -1604,6 +1609,12 @@ impl LoginConfigHandler { option: self.get_option_message(true).into(), session_id: self.session_id, version: crate::VERSION.to_string(), + os_login: Some(OSLogin { + username: os_username, + password: os_password, + ..Default::default() + }) + .into(), ..Default::default() }; match self.conn_type { @@ -1908,10 +1919,46 @@ pub fn handle_login_error( err: &str, interface: &impl Interface, ) -> bool { - if err == "Wrong Password" { + if err == crate::server::LOGIN_MSG_PASSWORD_EMPTY { + lc.write().unwrap().password = Default::default(); + interface.msgbox("input-password", "Password Required", "", ""); + true + } else if err == crate::server::LOGIN_MSG_PASSWORD_WRONG { lc.write().unwrap().password = Default::default(); interface.msgbox("re-input-password", err, "Do you want to enter again?", ""); true + } else if err == crate::server::LOGIN_MSG_XSESSION_NOT_READY { + interface.msgbox( + "xsession-login", + "xsession is unready", + "Input linux user/password", + "", + ); + true + } else if err == crate::server::LOGIN_MSG_XSESSION_FAILED { + interface.msgbox( + "xsession-re-login", + "xsession username/password is wrong", + "Do you want to enter again?", + "", + ); + true + } else if err == crate::server::LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_EMPTY { + interface.msgbox( + "xsession-login-password", + "xsession is unready", + "Input connection password and linux user/password", + "", + ); + true + } else if err == crate::server::LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_WRONG { + interface.msgbox( + "xsession-login-re-password", + "xsession is unready and password is wrong", + "Do you want to enter again?", + "", + ); + true } else if err == "No Password Access" { lc.write().unwrap().password = Default::default(); interface.msgbox( @@ -1944,7 +1991,7 @@ pub async fn handle_hash( lc: Arc>, password_preset: &str, hash: Hash, - interface: &impl Interface, + _interface: &impl Interface, peer: &mut Stream, ) { lc.write().unwrap().hash = hash.clone(); @@ -1970,13 +2017,19 @@ pub async fn handle_hash( } if password.is_empty() { // login without password, the remote side can click accept - send_login(lc.clone(), Vec::new(), peer).await; - interface.msgbox("input-password", "Password Required", "", ""); + send_login(lc.clone(), "".to_owned(), "".to_owned(), Vec::new(), peer).await; } else { let mut hasher = Sha256::new(); hasher.update(&password); hasher.update(&hash.challenge); - send_login(lc.clone(), hasher.finalize()[..].into(), peer).await; + send_login( + lc.clone(), + "".to_owned(), + "".to_owned(), + hasher.finalize()[..].into(), + peer, + ) + .await; } lc.write().unwrap().hash = hash; } @@ -1986,10 +2039,21 @@ pub async fn handle_hash( /// # Arguments /// /// * `lc` - Login config. +/// * `os_username` - OS username. +/// * `os_password` - OS password. /// * `password` - Password. /// * `peer` - [`Stream`] for communicating with peer. -async fn send_login(lc: Arc>, password: Vec, peer: &mut Stream) { - let msg_out = lc.read().unwrap().create_login_msg(password); +async fn send_login( + lc: Arc>, + os_username: String, + os_password: String, + password: Vec, + peer: &mut Stream, +) { + let msg_out = lc + .read() + .unwrap() + .create_login_msg(os_username, os_password, password); allow_err!(peer.send(&msg_out).await); } @@ -1998,25 +2062,40 @@ async fn send_login(lc: Arc>, password: Vec, peer /// # Arguments /// /// * `lc` - Login config. +/// * `os_username` - OS username. +/// * `os_password` - OS password. /// * `password` - Password. /// * `remember` - Whether to remember password. /// * `peer` - [`Stream`] for communicating with peer. pub async fn handle_login_from_ui( lc: Arc>, + os_username: String, + os_password: String, password: String, remember: bool, peer: &mut Stream, ) { - let mut hasher = Sha256::new(); - hasher.update(password); - hasher.update(&lc.read().unwrap().hash.salt); - let res = hasher.finalize(); - lc.write().unwrap().remember = remember; - lc.write().unwrap().password = res[..].into(); + let mut hash_password = if password.is_empty() { + let mut password2 = lc.read().unwrap().password.clone(); + if password2.is_empty() { + password2 = lc.read().unwrap().config.password.clone(); + } + password2 + } else { + let mut hasher = Sha256::new(); + hasher.update(password); + hasher.update(&lc.read().unwrap().hash.salt); + let res = hasher.finalize(); + lc.write().unwrap().remember = remember; + lc.write().unwrap().password = res[..].into(); + res[..].into() + }; let mut hasher2 = Sha256::new(); - hasher2.update(&res[..]); + hasher2.update(&hash_password[..]); hasher2.update(&lc.read().unwrap().hash.challenge); - send_login(lc.clone(), hasher2.finalize()[..].into(), peer).await; + hash_password = hasher2.finalize()[..].to_vec(); + + send_login(lc.clone(), os_username, os_password, hash_password, peer).await; } async fn send_switch_login_request( @@ -2030,7 +2109,7 @@ async fn send_switch_login_request( lr: hbb_common::protobuf::MessageField::some( lc.read() .unwrap() - .create_login_msg(vec![]) + .create_login_msg("".to_owned(), "".to_owned(), vec![]) .login_request() .to_owned(), ), @@ -2051,7 +2130,14 @@ pub trait Interface: Send + Clone + 'static + Sized { self.msgbox("error", "Error", err, ""); } async fn handle_hash(&mut self, pass: &str, hash: Hash, peer: &mut Stream); - async fn handle_login_from_ui(&mut self, password: String, remember: bool, peer: &mut Stream); + async fn handle_login_from_ui( + &mut self, + os_username: String, + os_password: String, + password: String, + remember: bool, + peer: &mut Stream, + ); async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream); fn get_login_config_handler(&self) -> Arc>; @@ -2071,7 +2157,7 @@ pub trait Interface: Send + Clone + 'static + Sized { #[derive(Clone)] pub enum Data { Close, - Login((String, bool)), + Login((String, String, String, bool)), Message(Message), SendFiles((i32, String, String, i32, bool, bool)), RemoveDirAll((i32, String, bool, bool)), diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index b0bddc82e..c1c38af40 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -360,9 +360,9 @@ impl Remote { allow_err!(peer.send(&msg).await); return false; } - Data::Login((password, remember)) => { + Data::Login((os_username, os_password, password, remember)) => { self.handler - .handle_login_from_ui(password, remember, peer) + .handle_login_from_ui(os_username, os_password, password, remember, peer) .await; } Data::ToggleClipboardFile => { diff --git a/src/platform/linux.rs b/src/platform/linux.rs index dda4b115b..c1da431a4 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -1,3 +1,4 @@ +use super::linux_desktop::GNOME_SESSION_BINARY; use super::{CursorData, ResultType}; use desktop::Desktop; pub use hbb_common::platform::linux::*; diff --git a/src/platform/linux_desktop.rs b/src/platform/linux_desktop.rs new file mode 100644 index 000000000..bf9f465d0 --- /dev/null +++ b/src/platform/linux_desktop.rs @@ -0,0 +1,951 @@ +use super::{linux::*, ResultType}; +use hbb_common::{allow_err, bail, log, rand::prelude::*, tokio::time}; +use pam; +use std::{ + collections::HashMap, + os::unix::process::CommandExt, + path::Path, + process::{Child, Command}, + sync::{ + atomic::{AtomicBool, Ordering}, + mpsc::{sync_channel, SyncSender}, + Arc, Mutex, + }, + time::{Duration, Instant}, +}; +use users::{get_user_by_name, os::unix::UserExt, User}; + +lazy_static::lazy_static! { + static ref DESKTOP_RUNNING: Arc = Arc::new(AtomicBool::new(false)); + static ref DESKTOP_INST: Arc>> = Arc::new(Mutex::new(None)); +} + +pub const VIRTUAL_X11_DESKTOP: &str = "xfce4"; +pub const VIRTUAL_X11_DESKTOP_START: &str = "startxfce4"; +pub const XFCE4_PANEL: &str = "xfce4-panel"; +pub const GNOME_SESSION_BINARY: &str = "gnome-session-binary"; +pub const ENV_DESKTOP_PROTOCAL: &str = "RUSTDESK_PROTOCAL"; +pub const ENV_DESKTOP_PROTOCAL_WAYLAND: &str = "wayland"; +pub const ENV_DESKTOP_PROTOCAL__X11: &str = "x11"; +pub const ENV_DESKTOP_PROTOCAL_UNKNOWN: &str = "unknown"; + +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum Protocal { + Wayland, + X11, // Xorg + Unknown, +} + +#[derive(Debug, Clone)] +pub struct DesktopEnv { + pub protocal: Protocal, + pub username: String, + pub uid: String, + pub display: String, + pub xauth: String, +} + +#[derive(Debug)] +pub struct Desktop { + env: DesktopEnv, + child_exit: Arc, + is_child_running: Arc, +} + +fn check_update_env() { + let mut inst = DESKTOP_INST.lock().unwrap(); + if let Some(inst) = &mut (*inst) { + if !inst.is_child_running.load(Ordering::SeqCst) { + inst.child_exit.store(true, Ordering::SeqCst); + let old_env = inst.env.clone(); + allow_err!(inst.env.refresh()); + if !inst.env.is_same_env(&old_env) { + inst.env.update_env(); + log::debug!("desktop env changed, {:?}", &inst.env); + } + } + } +} + +pub fn start_xdesktop() { + std::thread::spawn(|| { + if wait_xdesktop(20) { + log::info!("Wait desktop: default"); + } else { + log::info!("Wait desktop: none"); + } + *DESKTOP_INST.lock().unwrap() = Some(Desktop::new()); + + let interval = time::Duration::from_millis(super::SERVICE_INTERVAL); + DESKTOP_RUNNING.store(true, Ordering::SeqCst); + while DESKTOP_RUNNING.load(Ordering::SeqCst) { + check_update_env(); + std::thread::sleep(interval); + } + log::info!("xdesktop update thread exit"); + }); +} + +pub fn stop_xdesktop() { + DESKTOP_RUNNING.store(false, Ordering::SeqCst); +} + +pub fn get_desktop_env() -> Option { + match &*DESKTOP_INST.lock().unwrap() { + Some(inst) => Some(inst.env.clone()), + None => None, + } +} + +pub fn try_start_x_session(username: &str, password: &str) -> ResultType { + let mut inst = DESKTOP_INST.lock().unwrap(); + if let Some(inst) = &mut (*inst) { + let _ = inst.try_start_x_session(username, password)?; + log::debug!("try_start_x_session, username: {}, {:?}", &username, &inst); + Ok(inst.env.clone()) + } else { + bail!(crate::server::LOGIN_MSG_XDESKTOP_NOT_INITED); + } +} + +fn wait_xdesktop(timeout_secs: u64) -> bool { + let wait_begin = Instant::now(); + while wait_begin.elapsed().as_secs() < timeout_secs { + let seat0 = get_values_of_seat0(&[0]); + if !seat0[0].is_empty() { + return true; + } + + if let Ok(output) = run_cmds(format!( + "ps -ef | grep -v 'grep' | grep -E 'gnome-session-binary|{}'", + XFCE4_PANEL + )) { + if !output.is_empty() { + log::info!("wait xdesktop: find xclient {}", &output); + return true; + } + } + + std::thread::sleep(Duration::from_millis(super::SERVICE_INTERVAL)); + } + + false +} + +impl DesktopEnv { + pub fn new() -> Self { + let xauth = get_env_var("XAUTHORITY"); + + Self { + protocal: Protocal::Unknown, + username: "".to_owned(), + uid: "".to_owned(), + display: "".to_owned(), + xauth: if xauth.is_empty() { + "/tmp/.Xauthority".to_owned() + } else { + xauth + }, + } + } + + fn update_env(&self) { + if self.is_ready() { + std::env::set_var("DISPLAY", &self.display); + std::env::set_var("XAUTHORITY", &self.xauth); + std::env::set_var(ENV_DESKTOP_PROTOCAL, &self.protocal.to_string()); + } else { + std::env::set_var("DISPLAY", ""); + std::env::set_var("XAUTHORITY", ""); + std::env::set_var(ENV_DESKTOP_PROTOCAL, &Protocal::Unknown.to_string()); + } + } + + pub fn is_same_env(&self, other: &Self) -> bool { + self.protocal == other.protocal + && self.uid == other.uid + && self.display == other.display + && self.xauth == other.xauth + } + + #[inline(always)] + pub fn is_ready(&self) -> bool { + self.protocal == Protocal::X11 + } + + // The logic mainly fron https://github.com/neutrinolabs/xrdp/blob/34fe9b60ebaea59e8814bbc3ca5383cabaa1b869/sesman/session.c#L334. + fn get_avail_display() -> ResultType { + let display_range = 0..51; + for i in display_range.clone() { + if Self::is_x_server_running(i) { + continue; + } + return Ok(i); + } + bail!("No avaliable display found in range {:?}", display_range) + } + + fn is_x_server_running(display: u32) -> bool { + Path::new(&format!("/tmp/.X11-unix/X{}", display)).exists() + || Path::new(&format!("/tmp/.X{}-lock", display)).exists() + } + + fn get_display(&mut self) { + self.display = get_env_tries("DISPLAY", &self.uid, GNOME_SESSION_BINARY, 10); + if self.display.is_empty() { + self.display = get_env_tries("DISPLAY", &self.uid, XFCE4_PANEL, 10); + } + if self.display.is_empty() { + self.display = Self::get_display_by_user(&self.username); + } + if self.display.is_empty() { + self.display = ":0".to_owned(); + } + self.display = self + .display + .replace(&whoami::hostname(), "") + .replace("localhost", ""); + } + + fn get_xauth(&mut self) { + self.xauth = get_env_tries("XAUTHORITY", &self.uid, GNOME_SESSION_BINARY, 10); + if self.xauth.is_empty() { + get_env_tries("XAUTHORITY", &self.uid, XFCE4_PANEL, 10); + } + + let gdm = format!("/run/user/{}/gdm/Xauthority", self.uid); + if self.xauth.is_empty() { + self.xauth = if std::path::Path::new(&gdm).exists() { + gdm + } else { + let username = &self.username; + if username == "root" { + format!("/{}/.Xauthority", username) + } else { + let tmp = format!("/home/{}/.Xauthority", username); + if std::path::Path::new(&tmp).exists() { + tmp + } else { + format!("/var/lib/{}/.Xauthority", username) + } + } + }; + } + } + + // fixme: reduce loginctl + fn get_env_seat0(&mut self) -> ResultType { + let output = Command::new("loginctl").output()?; + for line in String::from_utf8_lossy(&output.stdout).lines() { + if line.contains("seat0") { + if let Some(sid) = line.split_whitespace().nth(0) { + if Self::is_active(sid)? { + if let Some(uid) = line.split_whitespace().nth(1) { + self.uid = uid.to_owned(); + } + if let Some(u) = line.split_whitespace().nth(2) { + self.username = u.to_owned(); + } + + self.protocal = Protocal::Unknown; + let type_output = Command::new("loginctl") + .args(vec!["show-session", "-p", "Type", sid]) + .output()?; + let type_stdout = String::from_utf8_lossy(&type_output.stdout); + + if type_stdout.contains("x11") { + self.protocal = Protocal::X11; + break; + } else if type_stdout.contains("wayland") { + self.protocal = Protocal::Wayland; + } + } + } + } + } + Ok(self.is_ready()) + } + + // some case, there is no seat0 https://github.com/rustdesk/rustdesk/issues/73 + fn get_env_active(&mut self) -> ResultType { + let output = Command::new("loginctl").output()?; + + // set active Xorg session + for line in String::from_utf8_lossy(&output.stdout).lines() { + if line.contains("sessions listed.") { + continue; + } + if let Some(sid) = line.split_whitespace().nth(0) { + if Self::is_active(sid)? { + if Self::get_display_server_of_session(sid) == ENV_DESKTOP_PROTOCAL__X11 { + if let Some(uid) = line.split_whitespace().nth(1) { + self.uid = uid.to_owned(); + } + if let Some(u) = line.split_whitespace().nth(2) { + self.username = u.to_owned(); + } + + self.protocal = Protocal::X11; + } + } + } + } + // // set active xfce4 session + // for line in String::from_utf8_lossy(&output.stdout).lines() { + // if let Some(sid) = line.split_whitespace().nth(0) { + // if Self::is_active(sid)? { + // let tty_output = Command::new("loginctl") + // .args(vec!["show-session", "-p", "TTY", sid]) + // .output()?; + // let tty: String = String::from_utf8_lossy(&tty_output.stdout) + // .replace("TTY=", "") + // .trim_end() + // .into(); + + // let xfce_panel_info = + // run_cmds(format!("ps -e | grep \"{}.\\\\+{}\"", tty, XFCE4_PANEL))?; + // if xfce_panel_info.trim_end().to_string() != "" { + // if let Some(uid) = line.split_whitespace().nth(1) { + // self.uid = uid.to_owned(); + // } + // if let Some(u) = line.split_whitespace().nth(2) { + // self.username = u.to_owned(); + // } + // } + // } + // } + // } + Ok(self.is_ready()) + } + + // fixme: dup + fn get_display_server_of_session(session: &str) -> String { + if let Ok(output) = Command::new("loginctl") + .args(vec!["show-session", "-p", "Type", session]) + .output() + // Check session type of the session + { + let display_server = String::from_utf8_lossy(&output.stdout) + .replace("Type=", "") + .trim_end() + .into(); + if display_server == "tty" { + // If the type is tty... + if let Ok(output) = Command::new("loginctl") + .args(vec!["show-session", "-p", "TTY", session]) + .output() + // Get the tty number + { + let tty: String = String::from_utf8_lossy(&output.stdout) + .replace("TTY=", "") + .trim_end() + .into(); + if let Ok(xorg_results) = + run_cmds(format!("ps -e | grep \"{}.\\\\+Xorg\"", tty)) + // And check if Xorg is running on that tty + { + if xorg_results.trim_end().to_string() != "" { + // If it is, manually return "x11", otherwise return tty + ENV_DESKTOP_PROTOCAL__X11.to_owned() + } else { + display_server + } + } else { + // If any of these commands fail just fall back to the display server + display_server + } + } else { + display_server + } + } else { + // If the session is not a tty, then just return the type as usual + display_server + } + } else { + "".to_owned() + } + } + + // fixme: remove + fn is_active(sid: &str) -> ResultType { + let output = Command::new("loginctl") + .args(vec!["show-session", "-p", "State", sid]) + .output()?; + + Ok(String::from_utf8_lossy(&output.stdout).contains("active")) + } + + fn get_display_by_user(user: &str) -> String { + // log::debug!("w {}", &user); + if let Ok(output) = std::process::Command::new("w").arg(&user).output() { + for line in String::from_utf8_lossy(&output.stdout).lines() { + let mut iter = line.split_whitespace(); + let b = iter.nth(2); + if let Some(b) = b { + if b.starts_with(":") { + return b.to_owned(); + } + } + } + } + // above not work for gdm user + //log::debug!("ls -l /tmp/.X11-unix/"); + let mut last = "".to_owned(); + if let Ok(output) = std::process::Command::new("ls") + .args(vec!["-l", "/tmp/.X11-unix/"]) + .output() + { + for line in String::from_utf8_lossy(&output.stdout).lines() { + let mut iter = line.split_whitespace(); + let user_field = iter.nth(2); + if let Some(x) = iter.last() { + if x.starts_with("X") { + last = x.replace("X", ":").to_owned(); + if user_field == Some(&user) { + return last; + } + } + } + } + } + last + } + + fn add_xauth_cookie( + file: &str, + display: &str, + uid: u32, + gid: u32, + envs: &HashMap<&str, String>, + ) -> ResultType<()> { + let randstr = (0..16) + .map(|_| format!("{:02x}", random::())) + .collect::(); + let output = Command::new("xauth") + .uid(uid) + .gid(gid) + .envs(envs) + .args(vec!["-q", "-f", file, "add", display, ".", &randstr]) + .output()?; + // xauth run success, even the following error occurs. + // Ok(Output { status: ExitStatus(unix_wait_status(0)), stdout: "", stderr: "xauth: file .Xauthority does not exist\n" }) + let errmsg = String::from_utf8_lossy(&output.stderr).to_string(); + if !errmsg.is_empty() { + if !errmsg.contains("does not exist") { + bail!("Failed to launch xauth, {}", errmsg) + } + } + Ok(()) + } + + fn wait_x_server_running(pid: u32, display_num: u32, max_wait_secs: u64) -> ResultType<()> { + let wait_begin = Instant::now(); + loop { + if run_cmds(format!("ls /proc/{}", pid))?.is_empty() { + bail!("X server exit"); + } + + if Self::is_x_server_running(display_num) { + return Ok(()); + } + if wait_begin.elapsed().as_secs() > max_wait_secs { + bail!("Failed to wait xserver after {} seconds", max_wait_secs); + } + std::thread::sleep(Duration::from_millis(300)); + } + } + + fn refresh(&mut self) -> ResultType { + *self = Self::new(); + if self.get_env_seat0()? || self.get_env_active()? { + self.get_display(); + self.get_xauth(); + Ok(true) + } else { + Ok(false) + } + } +} + +impl Drop for Desktop { + fn drop(&mut self) { + self.stop_children(); + } +} + +impl Desktop { + fn fatal_exit() { + std::process::exit(0); + } + + pub fn new() -> Self { + Self { + env: DesktopEnv::new(), + child_exit: Arc::new(AtomicBool::new(true)), + is_child_running: Arc::new(AtomicBool::new(false)), + } + } + + fn try_start_x_session(&mut self, username: &str, password: &str) -> ResultType<()> { + match get_user_by_name(username) { + Some(userinfo) => { + let mut client = pam::Client::with_password(pam_get_service_name())?; + client + .conversation_mut() + .set_credentials(username, password); + match client.authenticate() { + Ok(_) => { + if self.env.is_ready() && self.env.username == username { + return Ok(()); + } + + self.env.username = username.to_string(); + self.env.uid = userinfo.uid().to_string(); + self.env.protocal = Protocal::Unknown; + match self.start_x_session(&userinfo, password) { + Ok(_) => { + log::info!("Succeeded to start x11, update env {:?}", &self.env); + self.env.update_env(); + Ok(()) + } + Err(e) => { + self.env = DesktopEnv::new(); + self.env.update_env(); + bail!("failed to start x session, {}", e); + } + } + } + Err(e) => { + bail!("failed to check user pass for {}, {}", username, e); + } + } + } + None => { + bail!("failed to get userinfo of {}", username); + } + } + } + + fn start_x_session(&mut self, userinfo: &User, password: &str) -> ResultType<()> { + self.stop_children(); + + let display_num = DesktopEnv::get_avail_display()?; + // "xServer_ip:display_num.screen_num" + self.env.display = format!(":{}", display_num); + + let uid = userinfo.uid(); + let gid = userinfo.primary_group_id(); + let envs = HashMap::from([ + ("SHELL", userinfo.shell().to_string_lossy().to_string()), + ("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin".to_owned()), + ("USER", self.env.username.clone()), + ("UID", userinfo.uid().to_string()), + ("HOME", userinfo.home_dir().to_string_lossy().to_string()), + ( + "XDG_RUNTIME_DIR", + format!("/run/user/{}", userinfo.uid().to_string()), + ), + // ("DISPLAY", self.display.clone()), + // ("XAUTHORITY", self.xauth.clone()), + // (ENV_DESKTOP_PROTOCAL, XProtocal::X11.to_string()), + ]); + let env = self.env.clone(); + self.child_exit.store(false, Ordering::SeqCst); + let is_child_running = self.is_child_running.clone(); + + let (tx_res, rx_res) = sync_channel(1); + let password = password.to_string(); + // start x11 + std::thread::spawn(move || { + match Self::start_x_session_thread( + tx_res.clone(), + is_child_running, + env, + uid, + gid, + display_num, + password, + envs, + ) { + Ok(_) => {} + Err(e) => { + log::error!("Failed to start x session thread"); + allow_err!(tx_res.send(format!("Failed to start x session thread, {}", e))); + } + } + }); + + // wait x11 + match rx_res.recv_timeout(Duration::from_millis(10_000)) { + Ok(res) => { + if res == "" { + self.env.protocal = Protocal::X11; + Ok(()) + } else { + bail!(res) + } + } + Err(e) => { + bail!("Failed to recv x11 result {}", e) + } + } + } + + fn start_x_session_thread( + tx_res: SyncSender, + is_child_running: Arc, + env: DesktopEnv, + uid: u32, + gid: u32, + display_num: u32, + password: String, + envs: HashMap<&str, String>, + ) -> ResultType<()> { + let mut client = pam::Client::with_password(pam_get_service_name())?; + client + .conversation_mut() + .set_credentials(&env.username, &password); + client.authenticate()?; + + client.set_item(pam::PamItemType::TTY, &env.display)?; + client.open_session()?; + + // fixme: FreeBSD kernel needs to login here. + // see: https://github.com/neutrinolabs/xrdp/blob/a64573b596b5fb07ca3a51590c5308d621f7214e/sesman/session.c#L556 + + let (child_xorg, child_wm) = Self::start_x11(&env, uid, gid, display_num, &envs)?; + is_child_running.store(true, Ordering::SeqCst); + + log::info!("Start xorg and wm done, notify and wait xtop x11"); + allow_err!(tx_res.send("".to_owned())); + + Self::wait_stop_x11(child_xorg, child_wm); + log::info!("Wait x11 stop done"); + Ok(()) + } + + fn wait_xorg_exit(child_xorg: &mut Child) -> ResultType { + if let Ok(_) = child_xorg.kill() { + for _ in 0..3 { + match child_xorg.try_wait() { + Ok(Some(status)) => return Ok(format!("Xorg exit with {}", status)), + Ok(None) => {} + Err(e) => { + // fatal error + log::error!("Failed to wait xorg process, {}", e); + bail!("Failed to wait xorg process, {}", e) + } + } + std::thread::sleep(std::time::Duration::from_millis(1_000)); + } + log::error!("Failed to wait xorg process, not exit"); + bail!("Failed to wait xorg process, not exit") + } else { + Ok("Xorg is already exited".to_owned()) + } + } + + fn start_x11( + env: &DesktopEnv, + uid: u32, + gid: u32, + display_num: u32, + envs: &HashMap<&str, String>, + ) -> ResultType<(Child, Child)> { + log::debug!("envs of user {}: {:?}", &env.username, &envs); + + DesktopEnv::add_xauth_cookie(&env.xauth, &env.display, uid, gid, &envs)?; + + // Start Xorg + let mut child_xorg = Self::start_x_server(&env.xauth, &env.display, uid, gid, &envs)?; + + log::info!("xorg started, wait 10 secs to ensuer x server is running"); + + let max_wait_secs = 10; + // wait x server running + if let Err(e) = + DesktopEnv::wait_x_server_running(child_xorg.id(), display_num, max_wait_secs) + { + match Self::wait_xorg_exit(&mut child_xorg) { + Ok(msg) => log::info!("{}", msg), + Err(e) => { + log::error!("{}", e); + Self::fatal_exit(); + } + } + bail!(e) + } + + log::info!( + "xorg is running, start x window manager with DISPLAY: {}, XAUTHORITY: {}", + &env.display, + &env.xauth + ); + + std::env::set_var("DISPLAY", &env.display); + std::env::set_var("XAUTHORITY", &env.xauth); + // start window manager (startwm.sh) + let child_wm = match Self::start_x_window_manager(uid, gid, &envs) { + Ok(c) => c, + Err(e) => { + match Self::wait_xorg_exit(&mut child_xorg) { + Ok(msg) => log::info!("{}", msg), + Err(e) => { + log::error!("{}", e); + Self::fatal_exit(); + } + } + bail!(e) + } + }; + log::info!("x window manager is started"); + + Ok((child_xorg, child_wm)) + } + + fn try_wait_x11_child_exit(child_xorg: &mut Child, child_wm: &mut Child) -> bool { + match child_xorg.try_wait() { + Ok(Some(status)) => { + println!( + "=============================MYDEBUG Xorg exit with {}", + status + ); + log::info!("Xorg exit with {}", status); + return true; + } + Ok(None) => {} + Err(e) => log::error!("Failed to wait xorg process, {}", e), + } + + match child_wm.try_wait() { + Ok(Some(status)) => { + println!( + "=============================MYDEBUG: wm exit with {}", + status + ); + log::info!("wm exit with {}", status); + return true; + } + Ok(None) => {} + Err(e) => log::error!("Failed to wait xorg process, {}", e), + } + false + } + + fn wait_x11_children_exit(child_xorg: &mut Child, child_wm: &mut Child) { + log::debug!("Try kill child process xorg"); + if let Ok(_) = child_xorg.kill() { + let mut exited = false; + for _ in 0..2 { + match child_xorg.try_wait() { + Ok(Some(status)) => { + println!( + "=============================MYDEBUG Xorg exit with {}", + status + ); + log::info!("Xorg exit with {}", status); + exited = true; + break; + } + Ok(None) => {} + Err(e) => { + println!( + "=============================MYDEBUG Failed to wait xorg process, {}", + &e + ); + log::error!("Failed to wait xorg process, {}", e); + Self::fatal_exit(); + } + } + std::thread::sleep(std::time::Duration::from_millis(1_000)); + } + if !exited { + println!( + "=============================MYDEBUG Failed to wait child xorg, after kill()" + ); + log::error!("Failed to wait child xorg, after kill()"); + // try kill -9? + } + } + log::debug!("Try kill child process wm"); + if let Ok(_) = child_wm.kill() { + let mut exited = false; + for _ in 0..2 { + match child_wm.try_wait() { + Ok(Some(status)) => { + println!( + "=============================MYDEBUG wm exit with {}", + status + ); + log::info!("wm exit with {}", status); + exited = true; + } + Ok(None) => {} + Err(e) => { + println!( + "=============================MYDEBUG Failed to wait wm process, {}", + &e + ); + log::error!("Failed to wait wm process, {}", e); + Self::fatal_exit(); + } + } + std::thread::sleep(std::time::Duration::from_millis(1_000)); + } + if !exited { + println!( + "=============================MYDEBUG Failed to wait child xorg, after kill()" + ); + log::error!("Failed to wait child xorg, after kill()"); + // try kill -9? + } + } + } + + fn try_wait_stop_x11(child_xorg: &mut Child, child_wm: &mut Child) -> bool { + let mut inst = DESKTOP_INST.lock().unwrap(); + let mut exited = true; + if let Some(inst) = &mut (*inst) { + if inst.child_exit.load(Ordering::SeqCst) { + exited = true; + } else { + exited = Self::try_wait_x11_child_exit(child_xorg, child_wm); + } + if exited { + println!("=============================MYDEBUG begin to wait x11 children exit"); + Self::wait_x11_children_exit(child_xorg, child_wm); + inst.is_child_running.store(false, Ordering::SeqCst); + inst.child_exit.store(true, Ordering::SeqCst); + } + } + exited + } + + fn wait_stop_x11(mut child_xorg: Child, mut child_wm: Child) { + loop { + if Self::try_wait_stop_x11(&mut child_xorg, &mut child_wm) { + break; + } + std::thread::sleep(Duration::from_millis(super::SERVICE_INTERVAL)); + } + } + + fn get_xorg() -> ResultType<&'static str> { + // Fedora 26 or later + let xorg = "/usr/libexec/Xorg"; + if Path::new(xorg).is_file() { + return Ok(xorg); + } + // Debian 9 or later + let xorg = "/usr/lib/xorg/Xorg"; + if Path::new(xorg).is_file() { + return Ok(xorg); + } + // Ubuntu 16.04 or later + let xorg = "/usr/lib/xorg/Xorg"; + if Path::new(xorg).is_file() { + return Ok(xorg); + } + // Arch Linux + let xorg = "/usr/lib/xorg-server/Xorg"; + if Path::new(xorg).is_file() { + return Ok(xorg); + } + // Arch Linux + let xorg = "/usr/lib/Xorg"; + if Path::new(xorg).is_file() { + return Ok(xorg); + } + // CentOS 7 /usr/bin/Xorg or param=Xorg + + log::warn!("Failed to find xorg, use default Xorg.\n Please add \"allowed_users=anybody\" to \"/etc/X11/Xwrapper.config\"."); + Ok("Xorg") + } + + fn start_x_server( + xauth: &str, + display: &str, + uid: u32, + gid: u32, + envs: &HashMap<&str, String>, + ) -> ResultType { + let xorg = Self::get_xorg()?; + log::info!("Use xorg: {}", &xorg); + match Command::new(xorg) + .envs(envs) + .uid(uid) + .gid(gid) + .args(vec![ + "-noreset", + "+extension", + "GLX", + "+extension", + "RANDR", + "+extension", + "RENDER", + //"-logfile", + //"/tmp/RustDesk_xorg.log", + "-config", + "rustdesk/xorg.conf", + "-auth", + xauth, + display, + ]) + .spawn() + { + Ok(c) => Ok(c), + Err(e) => { + bail!("Failed to start Xorg with display {}, {}", display, e); + } + } + } + + fn start_x_window_manager( + uid: u32, + gid: u32, + envs: &HashMap<&str, String>, + ) -> ResultType { + match Command::new("/etc/rustdesk/startwm.sh") + .envs(envs) + .uid(uid) + .gid(gid) + .spawn() + { + Ok(c) => Ok(c), + Err(e) => { + bail!("Failed to start window manager, {}", e); + } + } + } + + fn stop_children(&mut self) { + self.child_exit.store(true, Ordering::SeqCst); + for _i in 1..10 { + if !self.is_child_running.load(Ordering::SeqCst) { + break; + } + std::thread::sleep(Duration::from_millis(super::SERVICE_INTERVAL)); + } + if self.is_child_running.load(Ordering::SeqCst) { + log::warn!("xdesktop child is still running!"); + } + } +} + +fn pam_get_service_name() -> &'static str { + if Path::new("/etc/pam.d/rustdesk").is_file() { + "rustdesk" + } else { + "gdm" + } +} + +impl ToString for Protocal { + fn to_string(&self) -> String { + match self { + Protocal::X11 => ENV_DESKTOP_PROTOCAL__X11.to_owned(), + Protocal::Wayland => ENV_DESKTOP_PROTOCAL_WAYLAND.to_owned(), + Protocal::Unknown => ENV_DESKTOP_PROTOCAL_UNKNOWN.to_owned(), + } + } +} diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 777de3b01..16bcc775a 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -17,6 +17,9 @@ pub mod delegate; #[cfg(target_os = "linux")] pub mod linux; +#[cfg(target_os = "linux")] +pub mod linux_desktop; + #[cfg(not(any(target_os = "android", target_os = "ios")))] use hbb_common::{message_proto::CursorData, ResultType}; #[cfg(not(any(target_os = "macos", target_os = "android", target_os = "ios")))] diff --git a/src/port_forward.rs b/src/port_forward.rs index f50f40db8..4e05ad92f 100644 --- a/src/port_forward.rs +++ b/src/port_forward.rs @@ -199,8 +199,8 @@ async fn connect_and_login_2( }, d = ui_receiver.recv() => { match d { - Some(Data::Login((password, remember))) => { - interface.handle_login_from_ui(password, remember, &mut stream).await; + Some(Data::Login((os_username, os_password, password, remember))) => { + interface.handle_login_from_ui(os_username, os_password, password, remember, &mut stream).await; } _ => {} } diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 8b7dae1ba..339a45bf3 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -54,6 +54,8 @@ impl RendezvousMediator { pub async fn start_all() { let mut nat_tested = false; check_zombie(); + #[cfg(target_os = "linux")] + crate::server::check_xdesktop(); let server = new_server(); if Config::get_nat_type() == NatType::UNKNOWN_NAT as i32 { crate::test_nat_type(); @@ -72,7 +74,10 @@ impl RendezvousMediator { allow_err!(super::lan::start_listening()); }); } - loop { + #[cfg(target_os = "linux")] + crate::platform::linux_desktop::start_xdesktop(); + SHOULD_EXIT.store(false, Ordering::SeqCst); + while !SHOULD_EXIT.load(Ordering::SeqCst) { Config::reset_online(); if Config::get_option("stop-service").is_empty() { if !nat_tested { @@ -96,6 +101,8 @@ impl RendezvousMediator { } sleep(1.).await; } + #[cfg(target_os = "linux")] + crate::platform::linux_desktop::stop_xdesktop(); } pub async fn start(server: ServerPtr, host: String) -> ResultType<()> { diff --git a/src/server.rs b/src/server.rs index 681e7bed1..81c967ba1 100644 --- a/src/server.rs +++ b/src/server.rs @@ -356,6 +356,40 @@ pub fn check_zombie() { }); } +#[cfg(target_os = "linux")] +pub fn check_xdesktop() { + std::thread::spawn(|| { + use crate::platform::linux_desktop::{get_desktop_env, DesktopEnv}; + let mut desktop_env = DesktopEnv::new(); + loop { + let new_env = match get_desktop_env() { + Some(env) => env, + None => DesktopEnv::new(), + }; + + if new_env.is_ready() { + if !desktop_env.is_ready() { + desktop_env = new_env.clone(); + } else { + if !desktop_env.is_same_env(&new_env) { + log::info!("xdesktop env diff {:?} to {:?}", &new_env, desktop_env); + break; + } + } + } else { + if desktop_env.is_ready() { + log::info!("xdesktop env diff {:?} to {:?}", &new_env, desktop_env); + break; + } + } + + std::thread::sleep(Duration::from_millis(300)); + } + + crate::RendezvousMediator::restart(); + }); +} + /// Start the host server that allows the remote peer to control the current machine. /// /// # Arguments diff --git a/src/server/connection.rs b/src/server/connection.rs index 23e166fcf..36190485e 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -57,6 +57,16 @@ lazy_static::lazy_static! { pub static CLICK_TIME: AtomicI64 = AtomicI64::new(0); pub static MOUSE_MOVE_TIME: AtomicI64 = AtomicI64::new(0); +pub const LOGIN_MSG_XDESKTOP_NOT_INITED: &str = "xdesktop env is not inited"; +pub const LOGIN_MSG_XSESSION_NOT_READY: &str = "xsession unready"; +pub const LOGIN_MSG_XSESSION_FAILED: &str = "xsession failed"; +pub const LOGIN_MSG_XSESSION_ANOTHER_USER_READTY: &str = "xsession another user login"; +pub const LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_EMPTY: &str = "xsession unready, password empty"; +pub const LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_WRONG: &str = "xsession unready, password wrong"; +pub const LOGIN_MSG_PASSWORD_EMPTY: &str = "Empty Password"; +pub const LOGIN_MSG_PASSWORD_WRONG: &str = "Wrong Password"; +pub const LOGIN_MSG_OFFLINE: &str = "Offline"; + #[derive(Clone, Default)] pub struct ConnInner { id: i32, @@ -902,7 +912,7 @@ impl Connection { } #[cfg(not(any(target_os = "android", target_os = "ios")))] if self.file_transfer.is_some() { - if crate::platform::is_prelogin() || self.tx_to_cm.send(ipc::Data::Test).is_err() { + if !crate::platform::is_prelogin() || self.tx_to_cm.send(ipc::Data::Test).is_err() { username = "".to_owned(); } } @@ -1061,6 +1071,47 @@ impl Connection { self.tx_input.send(MessageInput::Key((msg, press))).ok(); } + fn try_start_desktop(_username: &str, _passsword: &str) -> String { + #[cfg(target_os = "linux")] + { + if _username.is_empty() { + match crate::platform::linux_desktop::get_desktop_env() { + Some(desktop_env) => { + if desktop_env.is_ready() { + "" + } else { + LOGIN_MSG_XSESSION_NOT_READY + } + } + None => LOGIN_MSG_XDESKTOP_NOT_INITED, + } + .to_owned() + } else { + match crate::platform::linux_desktop::try_start_x_session(_username, _passsword) { + Ok(desktop_env) => { + if desktop_env.is_ready() { + if _username != desktop_env.username { + LOGIN_MSG_XSESSION_ANOTHER_USER_READTY.to_owned() + } else { + "".to_owned() + } + } else { + LOGIN_MSG_XSESSION_NOT_READY.to_owned() + } + } + Err(e) => { + log::error!("Failed to start xsession {}", e); + LOGIN_MSG_XSESSION_FAILED.to_owned() + } + } + } + } + #[cfg(not(target_os = "linux"))] + { + "".to_owned() + } + } + fn validate_one_password(&self, password: String) -> bool { if password.len() == 0 { return false; @@ -1225,16 +1276,31 @@ impl Connection { } _ => {} } + + let desktop_err = match lr.os_login.as_ref() { + Some(os_login) => Self::try_start_desktop(&os_login.username, &os_login.password), + None => Self::try_start_desktop("", ""), + }; + if !desktop_err.is_empty() && desktop_err != LOGIN_MSG_XSESSION_NOT_READY { + self.send_login_error(desktop_err).await; + return true; + } + if !hbb_common::is_ipv4_str(&lr.username) && lr.username != Config::get_id() { - self.send_login_error("Offline").await; + self.send_login_error(LOGIN_MSG_OFFLINE).await; } else if password::approve_mode() == ApproveMode::Click || password::approve_mode() == ApproveMode::Both && !password::has_valid_password() { - self.try_start_cm(lr.my_id, lr.my_name, false); - if hbb_common::get_version_number(&lr.version) - >= hbb_common::get_version_number("1.2.0") - { - self.send_login_error("No Password Access").await; + if desktop_err.is_empty() { + self.try_start_cm(lr.my_id, lr.my_name, false); + if hbb_common::get_version_number(&lr.version) + >= hbb_common::get_version_number("1.2.0") + { + self.send_login_error("No Password Access").await; + } + } else { + self.send_login_error(LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_EMPTY) + .await; } return true; } else if password::approve_mode() == ApproveMode::Password @@ -1290,16 +1356,25 @@ impl Connection { .lock() .unwrap() .insert(self.ip.clone(), failure); - self.send_login_error("Wrong Password").await; - self.try_start_cm(lr.my_id, lr.my_name, false); + if desktop_err.is_empty() { + self.send_login_error(LOGIN_MSG_PASSWORD_WRONG).await; + self.try_start_cm(lr.my_id, lr.my_name, false); + } else { + self.send_login_error(LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_WRONG) + .await; + } } else { if failure.0 != 0 { LOGIN_FAILURES.lock().unwrap().remove(&self.ip); } - self.try_start_cm(lr.my_id, lr.my_name, true); - self.send_logon_response().await; - if self.port_forward_socket.is_some() { - return false; + if desktop_err.is_empty() { + self.send_logon_response().await; + self.try_start_cm(lr.my_id, lr.my_name, true); + if self.port_forward_socket.is_some() { + return false; + } + } else { + self.send_login_error(desktop_err).await; } } } @@ -2072,7 +2147,7 @@ async fn start_ipc( tx_from_cm: mpsc::UnboundedSender, ) -> ResultType<()> { loop { - if !crate::platform::is_prelogin() { + if crate::platform::is_prelogin() { break; } sleep(1.).await; diff --git a/src/server/service.rs b/src/server/service.rs index 9cc1e860c..fe038f3c0 100644 --- a/src/server/service.rs +++ b/src/server/service.rs @@ -221,6 +221,7 @@ impl> ServiceTmpl { thread::sleep(interval - elapsed); } } + log::info!("Service {} exit", sp.name()); }); self.0.write().unwrap().handle = Some(thread); } @@ -256,6 +257,7 @@ impl> ServiceTmpl { } thread::sleep(time::Duration::from_millis(HIBERNATE_TIMEOUT)); } + log::info!("Service {} exit", sp.name()); }); self.0.write().unwrap().handle = Some(thread); } diff --git a/src/ui/common.css b/src/ui/common.css index 0fb9afcb1..9845ff104 100644 --- a/src/ui/common.css +++ b/src/ui/common.css @@ -142,6 +142,10 @@ div.password input { font-size: 1.2em; } +div.username input { + font-size: 1.2em; +} + svg { background: none; } diff --git a/src/ui/common.tis b/src/ui/common.tis index b6723b131..ef6d215aa 100644 --- a/src/ui/common.tis +++ b/src/ui/common.tis @@ -252,7 +252,7 @@ function msgbox(type, title, content, link="", callback=null, height=180, width= view.close(); return; } - handler.login(res.password, res.remember); + handler.login("", "", res.password, res.remember); if (!is_port_forward) { // Specially handling file transfer for no permission hanging issue (including 60ms // timer in setPermission. @@ -262,6 +262,30 @@ function msgbox(type, title, content, link="", callback=null, height=180, width= else msgbox("connecting", "Connecting...", "Logging in..."); } }; + } else if (type == "xsession-login" || type == "xsession-re-login") { + callback = function (res) { + if (!res) { + view.close(); + return; + } + handler.login(res.osusername, res.ospassword, "", false); + if (!is_port_forward) { + if (is_file_transfer) handler.msgbox("connecting", "Connecting...", "Logging in..."); + else msgbox("connecting", "Connecting...", "Logging in..."); + } + }; + } else if (type.indexOf("xsession-login") >= 0) { + callback = function (res) { + if (!res) { + view.close(); + return; + } + handler.login(res.osusername, res.ospassword, res.password, res.remember); + if (!is_port_forward) { + if (is_file_transfer) handler.msgbox("connecting", "Connecting...", "Logging in..."); + else msgbox("connecting", "Connecting...", "Logging in..."); + } + }; } else if (type.indexOf("custom") < 0 && !is_port_forward && !callback) { callback = function() { view.close(); } } else if (type == 'wait-remote-accept-nook') { diff --git a/src/ui/msgbox.tis b/src/ui/msgbox.tis index d5c60d95c..d9a311452 100644 --- a/src/ui/msgbox.tis +++ b/src/ui/msgbox.tis @@ -32,7 +32,7 @@ class MsgboxComponent: Reactor.Component { } function getIcon(color) { - if (this.type == "input-password") { + if (this.type == "input-password" || this.type == "xsession-login" || this.type == "xsession-login-password") { return ; } if (this.type == "connecting") { @@ -41,7 +41,7 @@ class MsgboxComponent: Reactor.Component { if (this.type == "success") { return ; } - if (this.type.indexOf("error") >= 0 || this.type == "re-input-password") { + if (this.type.indexOf("error") >= 0 || this.type == "re-input-password" || this.type == "xsession-re-login" || this.type == "xsession-login-re-password") { return ; } return null; @@ -56,11 +56,36 @@ class MsgboxComponent: Reactor.Component { ; } + function getInputUserPasswordContent() { + return
+
{translate("OS Username")}
+
+
{translate("OS Password")}
+ +
+
; + } + + function getXsessionPasswordContent() { + return
+
{translate("OS Username")}
+
+
{translate("OS Password")}
+ +
{translate('Please enter your password')}
+ +
{translate('Remember password')}
+
; + } + function getContent() { if (this.type == "input-password") { return this.getInputPasswordContent(); - } - if (this.type == "custom-os-password") { + } else if (this.type == "xsession-login") { + return this.getInputUserPasswordContent(); + } else if (this.type == "xsession-login-password") { + return this.getXsessionPasswordContent(); + } else if (this.type == "custom-os-password") { var ts = this.auto_login ? { checked: true } : {}; return
@@ -71,13 +96,13 @@ class MsgboxComponent: Reactor.Component { } function getColor() { - if (this.type == "input-password" || this.type == "custom-os-password") { + if (this.type == "input-password" || this.type == "custom-os-password" || this.type == "xsession-login" || this.type == "xsession-login-password") { return "#AD448E"; } if (this.type == "success") { return "#32bea6"; } - if (this.type.indexOf("error") >= 0 || this.type == "re-input-password") { + if (this.type.indexOf("error") >= 0 || this.type == "re-input-password" || this.type == "xsession-re-login" || this.type == "xsession-login-re-password") { return "#e04f5f"; } return "#2C8CFF"; @@ -177,6 +202,16 @@ class MsgboxComponent: Reactor.Component { this.update(); return; } + if (this.type == "xsession-re-login") { + this.type = "xsession-login"; + this.update(); + return; + } + if (this.type == "xsession-login-re-password") { + this.type = "xsession-login-password"; + this.update(); + return; + } var values = this.getValues(); if (this.callback) { var self = this; @@ -238,6 +273,21 @@ class MsgboxComponent: Reactor.Component { return; } } + if (this.type == "xsession-login") { + values.osusername = (values.osusername || "").trim(); + values.ospassword = (values.ospassword || "").trim(); + if (!values.osusername || !values.ospassword) { + return; + } + } + if (this.type == "xsession-login-password") { + values.password = (values.password || "").trim(); + values.osusername = (values.osusername || "").trim(); + values.ospassword = (values.ospassword || "").trim(); + if (!values.osusername || !values.ospassword || !values.password) { + return; + } + } return values; } diff --git a/src/ui/remote.rs b/src/ui/remote.rs index 68decf955..966315a23 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -398,7 +398,7 @@ impl sciter::EventHandler for SciterSession { fn is_file_transfer(); fn is_port_forward(); fn is_rdp(); - fn login(String, bool); + fn login(String, String, String, bool); fn new_rdp(); fn send_mouse(i32, i32, i32, bool, bool, bool, bool); fn enter(); diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index f89be4879..2a0776668 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -711,8 +711,14 @@ impl Session { fs::get_string(&path) } - pub fn login(&self, password: String, remember: bool) { - self.send(Data::Login((password, remember))); + pub fn login( + &mut self, + os_username: String, + os_password: String, + password: String, + remember: bool, + ) { + self.send(Data::Login((os_username, os_password, password, remember))); } pub fn new_rdp(&self) { @@ -1005,8 +1011,23 @@ impl Interface for Session { handle_hash(self.lc.clone(), pass, hash, self, peer).await; } - async fn handle_login_from_ui(&mut self, password: String, remember: bool, peer: &mut Stream) { - handle_login_from_ui(self.lc.clone(), password, remember, peer).await; + async fn handle_login_from_ui( + &mut self, + os_username: String, + os_password: String, + password: String, + remember: bool, + peer: &mut Stream, + ) { + handle_login_from_ui( + self.lc.clone(), + os_username, + os_password, + password, + remember, + peer, + ) + .await; } async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream) { From a94052a24a15ac112d7a91ff0e6cbffc385c8080 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 23 Mar 2023 18:01:27 +0800 Subject: [PATCH 02/44] ignore seat0 on gdm Signed-off-by: fufesou --- libs/hbb_common/src/platform/linux.rs | 2 +- src/platform/linux_desktop.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index 1d826ea97..cf1cf6da5 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -135,7 +135,7 @@ pub fn get_values_of_seat0_with_gdm_wayland(indices: &[usize]) -> Vec { fn _get_values_of_seat0(indices: &[usize], ignore_gdm_wayland: bool) -> Vec { if let Ok(output) = run_loginctl(None) { for line in String::from_utf8_lossy(&output.stdout).lines() { - if line.contains("seat0") { + if !line.contains("gdm") && line.contains("seat0") { if let Some(sid) = line.split_whitespace().next() { if is_active(sid) { if ignore_gdm_wayland { diff --git a/src/platform/linux_desktop.rs b/src/platform/linux_desktop.rs index bf9f465d0..0d25b3743 100644 --- a/src/platform/linux_desktop.rs +++ b/src/platform/linux_desktop.rs @@ -237,7 +237,7 @@ impl DesktopEnv { fn get_env_seat0(&mut self) -> ResultType { let output = Command::new("loginctl").output()?; for line in String::from_utf8_lossy(&output.stdout).lines() { - if line.contains("seat0") { + if !line.contains("gdm") && line.contains("seat0") { if let Some(sid) = line.split_whitespace().nth(0) { if Self::is_active(sid)? { if let Some(uid) = line.split_whitespace().nth(1) { From c65a3b2489c76b22fb70897bad3e8632d312b660 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 23 Mar 2023 18:40:25 +0800 Subject: [PATCH 03/44] virtual display, update build script Signed-off-by: fufesou --- build.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/build.py b/build.py index 7acf97a7d..3a06c4161 100755 --- a/build.py +++ b/build.py @@ -287,6 +287,8 @@ def build_flutter_deb(version, features): system2('flutter build linux --release') system2('mkdir -p tmpdeb/usr/bin/') system2('mkdir -p tmpdeb/usr/lib/rustdesk') + system2('mkdir -p tmpdeb/etc/rustdesk/') + system2('mkdir -p tmpdeb/etc/pam.d/') system2('mkdir -p tmpdeb/usr/share/rustdesk/files/systemd/') system2('mkdir -p tmpdeb/usr/share/applications/') system2('mkdir -p tmpdeb/usr/share/polkit-1/actions') @@ -303,6 +305,12 @@ def build_flutter_deb(version, features): 'cp ../res/rustdesk-link.desktop tmpdeb/usr/share/applications/rustdesk-link.desktop') system2( 'cp ../res/com.rustdesk.RustDesk.policy tmpdeb/usr/share/polkit-1/actions/') + system2( + 'cp ../res/startwm.sh tmpdeb/etc/rustdesk/') + system2( + 'cp ../res/xorg.conf tmpdeb/etc/rustdesk/') + system2( + 'cp ../res/pam.d/rustdesk.debian tmpdeb/etc/pam.d/rustdesk') system2( "echo \"#!/bin/sh\" >> tmpdeb/usr/share/rustdesk/files/polkit && chmod a+x tmpdeb/usr/share/rustdesk/files/polkit") @@ -553,12 +561,21 @@ def main(): 'cp res/rustdesk.desktop tmpdeb/usr/share/applications/rustdesk.desktop') system2( 'cp res/rustdesk-link.desktop tmpdeb/usr/share/applications/rustdesk-link.desktop') - system2('cp -a res/DEBIAN/* tmpdeb/DEBIAN/') + os.system('mkdir -p tmpdeb/etc/rustdesk/') + os.system('cp -a res/startwm.sh tmpdeb/etc/rustdesk/') + os.system('mkdir -p tmpdeb/etc/X11/rustdesk/') + os.system('cp res/xorg.conf tmpdeb/etc/X11/rustdesk/') + os.system('cp -a DEBIAN/* tmpdeb/DEBIAN/') + os.system('mkdir -p tmpdeb/etc/pam.d/') + os.system('cp pam.d/rustdesk.debian tmpdeb/etc/pam.d/rustdesk') system2('strip tmpdeb/usr/bin/rustdesk') system2('mkdir -p tmpdeb/usr/lib/rustdesk') system2('mv tmpdeb/usr/bin/rustdesk tmpdeb/usr/lib/rustdesk/') system2('cp libsciter-gtk.so tmpdeb/usr/lib/rustdesk/') md5_file('usr/share/rustdesk/files/systemd/rustdesk.service') + md5_file('etc/rustdesk/startwm.sh') + md5_file('etc/X11/rustdesk/xorg.conf') + md5_file('etc/pam.d/rustdesk') md5_file('usr/lib/rustdesk/libsciter-gtk.so') system2('dpkg-deb -b tmpdeb rustdesk.deb; /bin/rm -rf tmpdeb/') os.rename('rustdesk.deb', 'rustdesk-%s.deb' % version) From e24e05ba5c31db9b1051bcbb2d01bafda888b900 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 23 Mar 2023 19:57:58 +0800 Subject: [PATCH 04/44] tmp commit Signed-off-by: fufesou --- flutter/lib/models/model.dart | 10 ++++++++-- src/flutter_ffi.rs | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 06bfeec45..20999f1bb 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -1631,8 +1631,14 @@ class FFI { } /// Login with [password], choose if the client should [remember] it. - void login(String id, String password, bool remember) { - bind.sessionLogin(id: id, password: password, remember: remember); + void login(String osUsername, String osPassword, String id, String password, + bool remember) { + bind.sessionLogin( + id: id, + os_username: osUsername, + os_password: osPassword, + password: password, + remember: remember); } /// Close the remote session. diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index aee486b94..c810437fb 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -136,9 +136,15 @@ pub fn session_get_option(id: String, arg: String) -> Option { } } -pub fn session_login(id: String, password: String, remember: bool) { +pub fn session_login( + id: String, + os_username: String, + os_password: String, + password: String, + remember: bool, +) { if let Some(session) = SESSIONS.read().unwrap().get(&id) { - session.login(password, remember); + session.login(os_username, os_password, password, remember); } } From 988d8dc32c093ca5e1d67d29622602b67570bc50 Mon Sep 17 00:00:00 2001 From: fufesou Date: Fri, 24 Mar 2023 11:34:00 +0800 Subject: [PATCH 05/44] test build Signed-off-by: fufesou --- src/ui_session_interface.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 2a0776668..39e614230 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -712,7 +712,7 @@ impl Session { } pub fn login( - &mut self, + &self, os_username: String, os_password: String, password: String, From 461aa622f8861322b55205db8c4d4bf0e8799c3a Mon Sep 17 00:00:00 2001 From: fufesou Date: Tue, 28 Mar 2023 08:57:19 +0800 Subject: [PATCH 06/44] fix build Signed-off-by: fufesou --- flutter/lib/common/widgets/dialog.dart | 4 ++-- flutter/lib/models/model.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index cc815c5a3..4562e519c 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -506,8 +506,8 @@ _connectDialog( final peerPassword = peerPasswordController?.text.trim() ?? ''; if (peerPasswordController != null && peerPassword.isEmpty) return; gFFI.login( - // username, - // password, + username, + password, id, peerPassword, remember, diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 20999f1bb..155956c74 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -1635,8 +1635,8 @@ class FFI { bool remember) { bind.sessionLogin( id: id, - os_username: osUsername, - os_password: osPassword, + osUsername: osUsername, + osPassword: osPassword, password: password, remember: remember); } From 5e794818601ba0a7bab881b83f19aa4a2250a442 Mon Sep 17 00:00:00 2001 From: fufesou Date: Tue, 28 Mar 2023 20:20:45 +0800 Subject: [PATCH 07/44] linux, refact desktop env Signed-off-by: fufesou --- libs/hbb_common/src/platform/linux.rs | 2 +- src/platform/linux.rs | 10 +- src/platform/linux_desktop.rs | 358 ++++++++++---------------- src/rendezvous_mediator.rs | 2 - src/server.rs | 34 --- src/server/connection.rs | 50 ++-- 6 files changed, 163 insertions(+), 293 deletions(-) diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index cf1cf6da5..1d826ea97 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -135,7 +135,7 @@ pub fn get_values_of_seat0_with_gdm_wayland(indices: &[usize]) -> Vec { fn _get_values_of_seat0(indices: &[usize], ignore_gdm_wayland: bool) -> Vec { if let Ok(output) = run_loginctl(None) { for line in String::from_utf8_lossy(&output.stdout).lines() { - if !line.contains("gdm") && line.contains("seat0") { + if line.contains("seat0") { if let Some(sid) = line.split_whitespace().next() { if is_active(sid) { if ignore_gdm_wayland { diff --git a/src/platform/linux.rs b/src/platform/linux.rs index c1da431a4..857372bd7 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -1,4 +1,4 @@ -use super::linux_desktop::GNOME_SESSION_BINARY; +use super::linux_desktop::{get_desktop_env, Desktop}; use super::{CursorData, ResultType}; use desktop::Desktop; pub use hbb_common::platform::linux::*; @@ -382,13 +382,13 @@ pub fn start_os_service() { #[inline] pub fn get_active_user_id_name() -> (String, String) { - let vec_id_name = get_values_of_seat0(&[1, 2]); - (vec_id_name[0].clone(), vec_id_name[1].clone()) + let desktop = get_desktop_env(); + (desktop.uid.clone(), desktop.username.clone()) } #[inline] pub fn get_active_userid() -> String { - get_values_of_seat0(&[1])[0].clone() + get_desktop_env().uid.clone() } fn get_cm() -> bool { @@ -434,7 +434,7 @@ fn _get_display_manager() -> String { #[inline] pub fn get_active_username() -> String { - get_values_of_seat0(&[2])[0].clone() + get_desktop_env().username.clone() } pub fn get_active_user_home() -> Option { diff --git a/src/platform/linux_desktop.rs b/src/platform/linux_desktop.rs index 0d25b3743..0cd66512a 100644 --- a/src/platform/linux_desktop.rs +++ b/src/platform/linux_desktop.rs @@ -17,7 +17,8 @@ use users::{get_user_by_name, os::unix::UserExt, User}; lazy_static::lazy_static! { static ref DESKTOP_RUNNING: Arc = Arc::new(AtomicBool::new(false)); - static ref DESKTOP_INST: Arc>> = Arc::new(Mutex::new(None)); + static ref DESKTOP_ENV: Arc> = Arc::new(Mutex::new(Desktop::new())); + static ref CHILD_FLAGS: Arc>> = Arc::new(Mutex::new(None)); } pub const VIRTUAL_X11_DESKTOP: &str = "xfce4"; @@ -37,7 +38,8 @@ pub enum Protocal { } #[derive(Debug, Clone)] -pub struct DesktopEnv { +pub struct Desktop { + pub sid: String, pub protocal: Protocal, pub username: String, pub uid: String, @@ -46,24 +48,31 @@ pub struct DesktopEnv { } #[derive(Debug)] -pub struct Desktop { - env: DesktopEnv, +struct ChildFlags { child_exit: Arc, is_child_running: Arc, } fn check_update_env() { - let mut inst = DESKTOP_INST.lock().unwrap(); - if let Some(inst) = &mut (*inst) { - if !inst.is_child_running.load(Ordering::SeqCst) { - inst.child_exit.store(true, Ordering::SeqCst); - let old_env = inst.env.clone(); - allow_err!(inst.env.refresh()); - if !inst.env.is_same_env(&old_env) { - inst.env.update_env(); - log::debug!("desktop env changed, {:?}", &inst.env); - } + let mut child_flags = CHILD_FLAGS.lock().unwrap(); + let mut desktop = DESKTOP_ENV.lock().unwrap(); + + if let Some(child_flags) = &mut (*child_flags) { + if child_flags.is_child_running.load(Ordering::SeqCst) { + return; } + child_flags.child_exit.store(true, Ordering::SeqCst); + } + + if !desktop.sid.is_empty() && is_active(&desktop.sid) { + return; + } + + let old_desktop = desktop.clone(); + desktop.refresh(); + if !desktop.is_same_env(&old_desktop) { + desktop.update_env(); + log::debug!("desktop env changed, {:?}", &desktop); } } @@ -74,7 +83,7 @@ pub fn start_xdesktop() { } else { log::info!("Wait desktop: none"); } - *DESKTOP_INST.lock().unwrap() = Some(Desktop::new()); + *CHILD_FLAGS.lock().unwrap() = Some(ChildFlags::new()); let interval = time::Duration::from_millis(super::SERVICE_INTERVAL); DESKTOP_RUNNING.store(true, Ordering::SeqCst); @@ -90,19 +99,24 @@ pub fn stop_xdesktop() { DESKTOP_RUNNING.store(false, Ordering::SeqCst); } -pub fn get_desktop_env() -> Option { - match &*DESKTOP_INST.lock().unwrap() { - Some(inst) => Some(inst.env.clone()), - None => None, - } +#[inline] +pub fn get_desktop_env() -> Desktop { + DESKTOP_ENV.lock().unwrap().clone() } -pub fn try_start_x_session(username: &str, password: &str) -> ResultType { - let mut inst = DESKTOP_INST.lock().unwrap(); - if let Some(inst) = &mut (*inst) { - let _ = inst.try_start_x_session(username, password)?; - log::debug!("try_start_x_session, username: {}, {:?}", &username, &inst); - Ok(inst.env.clone()) +pub fn try_start_x_session(username: &str, password: &str) -> ResultType { + let mut child_flags = CHILD_FLAGS.lock().unwrap(); + let mut desktop_lock = DESKTOP_ENV.lock().unwrap(); + let mut desktop = Desktop::new(); + if let Some(child_flags) = &mut (*child_flags) { + let _ = child_flags.try_start_x_session(&mut desktop, username, password)?; + log::debug!( + "try_start_x_session, username: {}, {:?}", + &username, + &child_flags + ); + *desktop_lock = desktop.clone(); + Ok(desktop) } else { bail!(crate::server::LOGIN_MSG_XDESKTOP_NOT_INITED); } @@ -111,8 +125,8 @@ pub fn try_start_x_session(username: &str, password: &str) -> ResultType bool { let wait_begin = Instant::now(); while wait_begin.elapsed().as_secs() < timeout_secs { - let seat0 = get_values_of_seat0(&[0]); - if !seat0[0].is_empty() { + let uid = &get_values_of_seat0(&[1])[0]; + if !uid.is_empty() { return true; } @@ -132,11 +146,12 @@ fn wait_xdesktop(timeout_secs: u64) -> bool { false } -impl DesktopEnv { +impl Desktop { pub fn new() -> Self { let xauth = get_env_var("XAUTHORITY"); Self { + sid: "".to_owned(), protocal: Protocal::Unknown, username: "".to_owned(), uid: "".to_owned(), @@ -150,29 +165,43 @@ impl DesktopEnv { } fn update_env(&self) { - if self.is_ready() { + if self.is_x11() { std::env::set_var("DISPLAY", &self.display); std::env::set_var("XAUTHORITY", &self.xauth); std::env::set_var(ENV_DESKTOP_PROTOCAL, &self.protocal.to_string()); } else { std::env::set_var("DISPLAY", ""); std::env::set_var("XAUTHORITY", ""); - std::env::set_var(ENV_DESKTOP_PROTOCAL, &Protocal::Unknown.to_string()); + std::env::set_var(ENV_DESKTOP_PROTOCAL, &self.protocal.to_string()); } } pub fn is_same_env(&self, other: &Self) -> bool { - self.protocal == other.protocal + self.sid == other.sid + && self.protocal == other.protocal && self.uid == other.uid && self.display == other.display && self.xauth == other.xauth } - #[inline(always)] - pub fn is_ready(&self) -> bool { + #[inline] + pub fn is_x11(&self) -> bool { self.protocal == Protocal::X11 } + #[inline] + pub fn is_wayland(&self) -> bool { + self.protocal == Protocal::Wayland + } + + #[inline] + pub fn is_ready(&self) -> bool { + match self.protocal { + Protocal::X11 | Protocal::Wayland => true, + _ => false, + } + } + // The logic mainly fron https://github.com/neutrinolabs/xrdp/blob/34fe9b60ebaea59e8814bbc3ca5383cabaa1b869/sesman/session.c#L334. fn get_avail_display() -> ResultType { let display_range = 0..51; @@ -185,6 +214,7 @@ impl DesktopEnv { bail!("No avaliable display found in range {:?}", display_range) } + #[inline] fn is_x_server_running(display: u32) -> bool { Path::new(&format!("/tmp/.X11-unix/X{}", display)).exists() || Path::new(&format!("/tmp/.X{}-lock", display)).exists() @@ -233,148 +263,6 @@ impl DesktopEnv { } } - // fixme: reduce loginctl - fn get_env_seat0(&mut self) -> ResultType { - let output = Command::new("loginctl").output()?; - for line in String::from_utf8_lossy(&output.stdout).lines() { - if !line.contains("gdm") && line.contains("seat0") { - if let Some(sid) = line.split_whitespace().nth(0) { - if Self::is_active(sid)? { - if let Some(uid) = line.split_whitespace().nth(1) { - self.uid = uid.to_owned(); - } - if let Some(u) = line.split_whitespace().nth(2) { - self.username = u.to_owned(); - } - - self.protocal = Protocal::Unknown; - let type_output = Command::new("loginctl") - .args(vec!["show-session", "-p", "Type", sid]) - .output()?; - let type_stdout = String::from_utf8_lossy(&type_output.stdout); - - if type_stdout.contains("x11") { - self.protocal = Protocal::X11; - break; - } else if type_stdout.contains("wayland") { - self.protocal = Protocal::Wayland; - } - } - } - } - } - Ok(self.is_ready()) - } - - // some case, there is no seat0 https://github.com/rustdesk/rustdesk/issues/73 - fn get_env_active(&mut self) -> ResultType { - let output = Command::new("loginctl").output()?; - - // set active Xorg session - for line in String::from_utf8_lossy(&output.stdout).lines() { - if line.contains("sessions listed.") { - continue; - } - if let Some(sid) = line.split_whitespace().nth(0) { - if Self::is_active(sid)? { - if Self::get_display_server_of_session(sid) == ENV_DESKTOP_PROTOCAL__X11 { - if let Some(uid) = line.split_whitespace().nth(1) { - self.uid = uid.to_owned(); - } - if let Some(u) = line.split_whitespace().nth(2) { - self.username = u.to_owned(); - } - - self.protocal = Protocal::X11; - } - } - } - } - // // set active xfce4 session - // for line in String::from_utf8_lossy(&output.stdout).lines() { - // if let Some(sid) = line.split_whitespace().nth(0) { - // if Self::is_active(sid)? { - // let tty_output = Command::new("loginctl") - // .args(vec!["show-session", "-p", "TTY", sid]) - // .output()?; - // let tty: String = String::from_utf8_lossy(&tty_output.stdout) - // .replace("TTY=", "") - // .trim_end() - // .into(); - - // let xfce_panel_info = - // run_cmds(format!("ps -e | grep \"{}.\\\\+{}\"", tty, XFCE4_PANEL))?; - // if xfce_panel_info.trim_end().to_string() != "" { - // if let Some(uid) = line.split_whitespace().nth(1) { - // self.uid = uid.to_owned(); - // } - // if let Some(u) = line.split_whitespace().nth(2) { - // self.username = u.to_owned(); - // } - // } - // } - // } - // } - Ok(self.is_ready()) - } - - // fixme: dup - fn get_display_server_of_session(session: &str) -> String { - if let Ok(output) = Command::new("loginctl") - .args(vec!["show-session", "-p", "Type", session]) - .output() - // Check session type of the session - { - let display_server = String::from_utf8_lossy(&output.stdout) - .replace("Type=", "") - .trim_end() - .into(); - if display_server == "tty" { - // If the type is tty... - if let Ok(output) = Command::new("loginctl") - .args(vec!["show-session", "-p", "TTY", session]) - .output() - // Get the tty number - { - let tty: String = String::from_utf8_lossy(&output.stdout) - .replace("TTY=", "") - .trim_end() - .into(); - if let Ok(xorg_results) = - run_cmds(format!("ps -e | grep \"{}.\\\\+Xorg\"", tty)) - // And check if Xorg is running on that tty - { - if xorg_results.trim_end().to_string() != "" { - // If it is, manually return "x11", otherwise return tty - ENV_DESKTOP_PROTOCAL__X11.to_owned() - } else { - display_server - } - } else { - // If any of these commands fail just fall back to the display server - display_server - } - } else { - display_server - } - } else { - // If the session is not a tty, then just return the type as usual - display_server - } - } else { - "".to_owned() - } - } - - // fixme: remove - fn is_active(sid: &str) -> ResultType { - let output = Command::new("loginctl") - .args(vec!["show-session", "-p", "State", sid]) - .output()?; - - Ok(String::from_utf8_lossy(&output.stdout).contains("active")) - } - fn get_display_by_user(user: &str) -> String { // log::debug!("w {}", &user); if let Ok(output) = std::process::Command::new("w").arg(&user).output() { @@ -455,38 +343,47 @@ impl DesktopEnv { } } - fn refresh(&mut self) -> ResultType { + fn refresh(&mut self) { *self = Self::new(); - if self.get_env_seat0()? || self.get_env_active()? { - self.get_display(); - self.get_xauth(); - Ok(true) - } else { - Ok(false) + + let seat0_values = get_values_of_seat0(&[0, 1, 2]); + if seat0_values[0].is_empty() { + return; } + + self.sid = seat0_values[0].clone(); + self.uid = seat0_values[1].clone(); + self.username = seat0_values[2].clone(); + self.protocal = get_display_server_of_session(&self.sid).into(); + self.get_display(); + self.get_xauth(); } } -impl Drop for Desktop { +impl Drop for ChildFlags { fn drop(&mut self) { self.stop_children(); } } -impl Desktop { +impl ChildFlags { fn fatal_exit() { std::process::exit(0); } pub fn new() -> Self { Self { - env: DesktopEnv::new(), child_exit: Arc::new(AtomicBool::new(true)), is_child_running: Arc::new(AtomicBool::new(false)), } } - fn try_start_x_session(&mut self, username: &str, password: &str) -> ResultType<()> { + fn try_start_x_session( + &mut self, + desktop: &mut Desktop, + username: &str, + password: &str, + ) -> ResultType<()> { match get_user_by_name(username) { Some(userinfo) => { let mut client = pam::Client::with_password(pam_get_service_name())?; @@ -495,22 +392,24 @@ impl Desktop { .set_credentials(username, password); match client.authenticate() { Ok(_) => { - if self.env.is_ready() && self.env.username == username { + if desktop.is_x11() && desktop.username == username { return Ok(()); } - self.env.username = username.to_string(); - self.env.uid = userinfo.uid().to_string(); - self.env.protocal = Protocal::Unknown; - match self.start_x_session(&userinfo, password) { + // to-do: sid is empty if xorg is managed by this process + desktop.sid = "".to_owned(); + desktop.username = username.to_string(); + desktop.uid = userinfo.uid().to_string(); + desktop.protocal = Protocal::Unknown; + match self.start_x_session(desktop, &userinfo, password) { Ok(_) => { - log::info!("Succeeded to start x11, update env {:?}", &self.env); - self.env.update_env(); + log::info!("Succeeded to start x11, update env {:?}", &desktop); + desktop.update_env(); Ok(()) } Err(e) => { - self.env = DesktopEnv::new(); - self.env.update_env(); + *desktop = Desktop::new(); + desktop.update_env(); bail!("failed to start x session, {}", e); } } @@ -526,19 +425,24 @@ impl Desktop { } } - fn start_x_session(&mut self, userinfo: &User, password: &str) -> ResultType<()> { + fn start_x_session( + &mut self, + desktop: &mut Desktop, + userinfo: &User, + password: &str, + ) -> ResultType<()> { self.stop_children(); - let display_num = DesktopEnv::get_avail_display()?; + let display_num = Desktop::get_avail_display()?; // "xServer_ip:display_num.screen_num" - self.env.display = format!(":{}", display_num); + desktop.display = format!(":{}", display_num); let uid = userinfo.uid(); let gid = userinfo.primary_group_id(); let envs = HashMap::from([ ("SHELL", userinfo.shell().to_string_lossy().to_string()), ("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin".to_owned()), - ("USER", self.env.username.clone()), + ("USER", desktop.username.clone()), ("UID", userinfo.uid().to_string()), ("HOME", userinfo.home_dir().to_string_lossy().to_string()), ( @@ -549,7 +453,7 @@ impl Desktop { // ("XAUTHORITY", self.xauth.clone()), // (ENV_DESKTOP_PROTOCAL, XProtocal::X11.to_string()), ]); - let env = self.env.clone(); + let desktop_clone = desktop.clone(); self.child_exit.store(false, Ordering::SeqCst); let is_child_running = self.is_child_running.clone(); @@ -560,7 +464,7 @@ impl Desktop { match Self::start_x_session_thread( tx_res.clone(), is_child_running, - env, + desktop_clone, uid, gid, display_num, @@ -579,7 +483,7 @@ impl Desktop { match rx_res.recv_timeout(Duration::from_millis(10_000)) { Ok(res) => { if res == "" { - self.env.protocal = Protocal::X11; + desktop.protocal = Protocal::X11; Ok(()) } else { bail!(res) @@ -594,7 +498,7 @@ impl Desktop { fn start_x_session_thread( tx_res: SyncSender, is_child_running: Arc, - env: DesktopEnv, + desktop: Desktop, uid: u32, gid: u32, display_num: u32, @@ -604,16 +508,16 @@ impl Desktop { let mut client = pam::Client::with_password(pam_get_service_name())?; client .conversation_mut() - .set_credentials(&env.username, &password); + .set_credentials(&desktop.username, &password); client.authenticate()?; - client.set_item(pam::PamItemType::TTY, &env.display)?; + client.set_item(pam::PamItemType::TTY, &desktop.display)?; client.open_session()?; // fixme: FreeBSD kernel needs to login here. // see: https://github.com/neutrinolabs/xrdp/blob/a64573b596b5fb07ca3a51590c5308d621f7214e/sesman/session.c#L556 - let (child_xorg, child_wm) = Self::start_x11(&env, uid, gid, display_num, &envs)?; + let (child_xorg, child_wm) = Self::start_x11(&desktop, uid, gid, display_num, &envs)?; is_child_running.store(true, Ordering::SeqCst); log::info!("Start xorg and wm done, notify and wait xtop x11"); @@ -646,25 +550,25 @@ impl Desktop { } fn start_x11( - env: &DesktopEnv, + desktop: &Desktop, uid: u32, gid: u32, display_num: u32, envs: &HashMap<&str, String>, ) -> ResultType<(Child, Child)> { - log::debug!("envs of user {}: {:?}", &env.username, &envs); + log::debug!("envs of user {}: {:?}", &desktop.username, &envs); - DesktopEnv::add_xauth_cookie(&env.xauth, &env.display, uid, gid, &envs)?; + Desktop::add_xauth_cookie(&desktop.xauth, &desktop.display, uid, gid, &envs)?; // Start Xorg - let mut child_xorg = Self::start_x_server(&env.xauth, &env.display, uid, gid, &envs)?; + let mut child_xorg = + Self::start_x_server(&desktop.xauth, &desktop.display, uid, gid, &envs)?; log::info!("xorg started, wait 10 secs to ensuer x server is running"); let max_wait_secs = 10; // wait x server running - if let Err(e) = - DesktopEnv::wait_x_server_running(child_xorg.id(), display_num, max_wait_secs) + if let Err(e) = Desktop::wait_x_server_running(child_xorg.id(), display_num, max_wait_secs) { match Self::wait_xorg_exit(&mut child_xorg) { Ok(msg) => log::info!("{}", msg), @@ -678,12 +582,12 @@ impl Desktop { log::info!( "xorg is running, start x window manager with DISPLAY: {}, XAUTHORITY: {}", - &env.display, - &env.xauth + &desktop.display, + &desktop.xauth ); - std::env::set_var("DISPLAY", &env.display); - std::env::set_var("XAUTHORITY", &env.xauth); + std::env::set_var("DISPLAY", &desktop.display); + std::env::set_var("XAUTHORITY", &desktop.xauth); // start window manager (startwm.sh) let child_wm = match Self::start_x_window_manager(uid, gid, &envs) { Ok(c) => c, @@ -803,10 +707,10 @@ impl Desktop { } fn try_wait_stop_x11(child_xorg: &mut Child, child_wm: &mut Child) -> bool { - let mut inst = DESKTOP_INST.lock().unwrap(); + let mut child_flags = CHILD_FLAGS.lock().unwrap(); let mut exited = true; - if let Some(inst) = &mut (*inst) { - if inst.child_exit.load(Ordering::SeqCst) { + if let Some(child_flags) = &mut (*child_flags) { + if child_flags.child_exit.load(Ordering::SeqCst) { exited = true; } else { exited = Self::try_wait_x11_child_exit(child_xorg, child_wm); @@ -814,8 +718,8 @@ impl Desktop { if exited { println!("=============================MYDEBUG begin to wait x11 children exit"); Self::wait_x11_children_exit(child_xorg, child_wm); - inst.is_child_running.store(false, Ordering::SeqCst); - inst.child_exit.store(true, Ordering::SeqCst); + child_flags.is_child_running.store(false, Ordering::SeqCst); + child_flags.child_exit.store(true, Ordering::SeqCst); } } exited @@ -949,3 +853,13 @@ impl ToString for Protocal { } } } + +impl From for Protocal { + fn from(value: String) -> Self { + match &value as &str { + ENV_DESKTOP_PROTOCAL__X11 => Protocal::X11, + ENV_DESKTOP_PROTOCAL_WAYLAND => Protocal::Wayland, + _ => Protocal::Unknown, + } + } +} diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 339a45bf3..5a68a4a03 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -54,8 +54,6 @@ impl RendezvousMediator { pub async fn start_all() { let mut nat_tested = false; check_zombie(); - #[cfg(target_os = "linux")] - crate::server::check_xdesktop(); let server = new_server(); if Config::get_nat_type() == NatType::UNKNOWN_NAT as i32 { crate::test_nat_type(); diff --git a/src/server.rs b/src/server.rs index 81c967ba1..681e7bed1 100644 --- a/src/server.rs +++ b/src/server.rs @@ -356,40 +356,6 @@ pub fn check_zombie() { }); } -#[cfg(target_os = "linux")] -pub fn check_xdesktop() { - std::thread::spawn(|| { - use crate::platform::linux_desktop::{get_desktop_env, DesktopEnv}; - let mut desktop_env = DesktopEnv::new(); - loop { - let new_env = match get_desktop_env() { - Some(env) => env, - None => DesktopEnv::new(), - }; - - if new_env.is_ready() { - if !desktop_env.is_ready() { - desktop_env = new_env.clone(); - } else { - if !desktop_env.is_same_env(&new_env) { - log::info!("xdesktop env diff {:?} to {:?}", &new_env, desktop_env); - break; - } - } - } else { - if desktop_env.is_ready() { - log::info!("xdesktop env diff {:?} to {:?}", &new_env, desktop_env); - break; - } - } - - std::thread::sleep(Duration::from_millis(300)); - } - - crate::RendezvousMediator::restart(); - }); -} - /// Start the host server that allows the remote peer to control the current machine. /// /// # Arguments diff --git a/src/server/connection.rs b/src/server/connection.rs index 36190485e..a5c63a80e 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1073,43 +1073,35 @@ impl Connection { fn try_start_desktop(_username: &str, _passsword: &str) -> String { #[cfg(target_os = "linux")] - { - if _username.is_empty() { - match crate::platform::linux_desktop::get_desktop_env() { - Some(desktop_env) => { - if desktop_env.is_ready() { - "" - } else { - LOGIN_MSG_XSESSION_NOT_READY - } - } - None => LOGIN_MSG_XDESKTOP_NOT_INITED, - } - .to_owned() + if _username.is_empty() { + let desktop = crate::platform::linux_desktop::get_desktop_env(); + if desktop.is_ready() { + "" } else { - match crate::platform::linux_desktop::try_start_x_session(_username, _passsword) { - Ok(desktop_env) => { - if desktop_env.is_ready() { - if _username != desktop_env.username { - LOGIN_MSG_XSESSION_ANOTHER_USER_READTY.to_owned() - } else { - "".to_owned() - } + LOGIN_MSG_XSESSION_NOT_READY + } + .to_owned() + } else { + match crate::platform::linux_desktop::try_start_x_session(_username, _passsword) { + Ok(desktop) => { + if desktop.is_ready() { + if _username != desktop.username { + LOGIN_MSG_XSESSION_ANOTHER_USER_READTY.to_owned() } else { - LOGIN_MSG_XSESSION_NOT_READY.to_owned() + "".to_owned() } + } else { + LOGIN_MSG_XSESSION_NOT_READY.to_owned() } - Err(e) => { - log::error!("Failed to start xsession {}", e); - LOGIN_MSG_XSESSION_FAILED.to_owned() - } + } + Err(e) => { + log::error!("Failed to start xsession {}", e); + LOGIN_MSG_XSESSION_FAILED.to_owned() } } } #[cfg(not(target_os = "linux"))] - { - "".to_owned() - } + "".to_owned() } fn validate_one_password(&self, password: String) -> bool { From 30375a98536a6b3306a605d22692587ded5f3fb2 Mon Sep 17 00:00:00 2001 From: fufesou Date: Tue, 28 Mar 2023 22:20:15 +0800 Subject: [PATCH 08/44] refact linux desktop env Signed-off-by: fufesou --- src/platform/linux.rs | 4 +- ...ux_desktop.rs => linux_desktop_manager.rs} | 672 ++++++------------ src/platform/mod.rs | 2 +- src/rendezvous_mediator.rs | 4 +- src/server/connection.rs | 17 +- 5 files changed, 250 insertions(+), 449 deletions(-) rename src/platform/{linux_desktop.rs => linux_desktop_manager.rs} (63%) diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 857372bd7..85f763ec6 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -1,4 +1,3 @@ -use super::linux_desktop::{get_desktop_env, Desktop}; use super::{CursorData, ResultType}; use desktop::Desktop; pub use hbb_common::platform::linux::*; @@ -297,6 +296,7 @@ fn force_stop_server() { pub fn start_os_service() { stop_rustdesk_servers(); start_uinput_service(); + start_check_desktop_env(); let running = Arc::new(AtomicBool::new(true)); let r = running.clone(); @@ -371,6 +371,8 @@ pub fn start_os_service() { } } + stop_check_desktop_env(); + if let Some(ps) = user_server.take().as_mut() { allow_err!(ps.kill()); } diff --git a/src/platform/linux_desktop.rs b/src/platform/linux_desktop_manager.rs similarity index 63% rename from src/platform/linux_desktop.rs rename to src/platform/linux_desktop_manager.rs index 0cd66512a..8b9e20640 100644 --- a/src/platform/linux_desktop.rs +++ b/src/platform/linux_desktop_manager.rs @@ -17,188 +17,161 @@ use users::{get_user_by_name, os::unix::UserExt, User}; lazy_static::lazy_static! { static ref DESKTOP_RUNNING: Arc = Arc::new(AtomicBool::new(false)); - static ref DESKTOP_ENV: Arc> = Arc::new(Mutex::new(Desktop::new())); - static ref CHILD_FLAGS: Arc>> = Arc::new(Mutex::new(None)); -} - -pub const VIRTUAL_X11_DESKTOP: &str = "xfce4"; -pub const VIRTUAL_X11_DESKTOP_START: &str = "startxfce4"; -pub const XFCE4_PANEL: &str = "xfce4-panel"; -pub const GNOME_SESSION_BINARY: &str = "gnome-session-binary"; -pub const ENV_DESKTOP_PROTOCAL: &str = "RUSTDESK_PROTOCAL"; -pub const ENV_DESKTOP_PROTOCAL_WAYLAND: &str = "wayland"; -pub const ENV_DESKTOP_PROTOCAL__X11: &str = "x11"; -pub const ENV_DESKTOP_PROTOCAL_UNKNOWN: &str = "unknown"; - -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum Protocal { - Wayland, - X11, // Xorg - Unknown, -} - -#[derive(Debug, Clone)] -pub struct Desktop { - pub sid: String, - pub protocal: Protocal, - pub username: String, - pub uid: String, - pub display: String, - pub xauth: String, + static ref DESKTOP_MANAGER: Arc>> = Arc::new(Mutex::new(None)); } #[derive(Debug)] -struct ChildFlags { +struct DesktopManager { + x11_username: String, + child_username: String, child_exit: Arc, is_child_running: Arc, } -fn check_update_env() { - let mut child_flags = CHILD_FLAGS.lock().unwrap(); - let mut desktop = DESKTOP_ENV.lock().unwrap(); - - if let Some(child_flags) = &mut (*child_flags) { - if child_flags.is_child_running.load(Ordering::SeqCst) { +fn check_desktop_manager() { + let mut desktop_manager = DESKTOP_MANAGER.lock().unwrap(); + if let Some(desktop_manager) = &mut (*desktop_manager) { + if desktop_manager.is_child_running.load(Ordering::SeqCst) { return; } - child_flags.child_exit.store(true, Ordering::SeqCst); - } - - if !desktop.sid.is_empty() && is_active(&desktop.sid) { - return; - } - - let old_desktop = desktop.clone(); - desktop.refresh(); - if !desktop.is_same_env(&old_desktop) { - desktop.update_env(); - log::debug!("desktop env changed, {:?}", &desktop); + desktop_manager.child_exit.store(true, Ordering::SeqCst); } } +// --server process pub fn start_xdesktop() { std::thread::spawn(|| { - if wait_xdesktop(20) { - log::info!("Wait desktop: default"); - } else { - log::info!("Wait desktop: none"); - } - *CHILD_FLAGS.lock().unwrap() = Some(ChildFlags::new()); + *DESKTOP_MANAGER.lock().unwrap() = Some(DesktopManager::new()); let interval = time::Duration::from_millis(super::SERVICE_INTERVAL); DESKTOP_RUNNING.store(true, Ordering::SeqCst); while DESKTOP_RUNNING.load(Ordering::SeqCst) { - check_update_env(); + check_desktop_manager(); std::thread::sleep(interval); } - log::info!("xdesktop update thread exit"); + log::info!("xdesktop child thread exit"); }); } pub fn stop_xdesktop() { DESKTOP_RUNNING.store(false, Ordering::SeqCst); + *DESKTOP_MANAGER.lock().unwrap() = None; } -#[inline] -pub fn get_desktop_env() -> Desktop { - DESKTOP_ENV.lock().unwrap().clone() -} +pub fn try_start_x_session(username: &str, password: &str) -> ResultType<(String, bool)> { + let mut desktop_manager = DESKTOP_MANAGER.lock().unwrap(); + if let Some(desktop_manager) = &mut (*desktop_manager) { + if !desktop_manager.x11_username.is_empty() { + return Ok((desktop_manager.x11_username.clone(), true)); + } -pub fn try_start_x_session(username: &str, password: &str) -> ResultType { - let mut child_flags = CHILD_FLAGS.lock().unwrap(); - let mut desktop_lock = DESKTOP_ENV.lock().unwrap(); - let mut desktop = Desktop::new(); - if let Some(child_flags) = &mut (*child_flags) { - let _ = child_flags.try_start_x_session(&mut desktop, username, password)?; + let _ = desktop_manager.try_start_x_session(username, password)?; log::debug!( "try_start_x_session, username: {}, {:?}", &username, - &child_flags + &desktop_manager ); - *desktop_lock = desktop.clone(); - Ok(desktop) + Ok(( + desktop_manager.child_username.clone(), + desktop_manager.is_running(), + )) } else { bail!(crate::server::LOGIN_MSG_XDESKTOP_NOT_INITED); } } -fn wait_xdesktop(timeout_secs: u64) -> bool { - let wait_begin = Instant::now(); - while wait_begin.elapsed().as_secs() < timeout_secs { - let uid = &get_values_of_seat0(&[1])[0]; - if !uid.is_empty() { - return true; +pub fn get_username() -> String { + match &*DESKTOP_MANAGER.lock().unwrap() { + Some(manager) => { + if !manager.x11_username.is_empty() { + manager.x11_username.clone() + } else { + if manager.is_running() && !manager.child_username.is_empty() { + manager.child_username.clone() + } else { + "".to_owned() + } + } } + None => "".to_owned(), + } +} - if let Ok(output) = run_cmds(format!( - "ps -ef | grep -v 'grep' | grep -E 'gnome-session-binary|{}'", - XFCE4_PANEL - )) { - if !output.is_empty() { - log::info!("wait xdesktop: find xclient {}", &output); - return true; +impl Drop for DesktopManager { + fn drop(&mut self) { + self.stop_children(); + } +} + +impl DesktopManager { + fn fatal_exit() { + std::process::exit(0); + } + + pub fn new() -> Self { + let mut x11_username = "".to_owned(); + let seat0_values = get_values_of_seat0(&[0, 1, 2]); + if !seat0_values[0].is_empty() { + if "x11" == get_display_server_of_session(&seat0_values[1]) { + x11_username = seat0_values[2].clone(); } } - std::thread::sleep(Duration::from_millis(super::SERVICE_INTERVAL)); - } - - false -} - -impl Desktop { - pub fn new() -> Self { - let xauth = get_env_var("XAUTHORITY"); - Self { - sid: "".to_owned(), - protocal: Protocal::Unknown, - username: "".to_owned(), - uid: "".to_owned(), - display: "".to_owned(), - xauth: if xauth.is_empty() { - "/tmp/.Xauthority".to_owned() - } else { - xauth - }, + x11_username, + child_username: "".to_owned(), + child_exit: Arc::new(AtomicBool::new(true)), + is_child_running: Arc::new(AtomicBool::new(false)), } } - fn update_env(&self) { - if self.is_x11() { - std::env::set_var("DISPLAY", &self.display); - std::env::set_var("XAUTHORITY", &self.xauth); - std::env::set_var(ENV_DESKTOP_PROTOCAL, &self.protocal.to_string()); + #[inline] + fn get_xauth() -> String { + let xauth = get_env_var("XAUTHORITY"); + if xauth.is_empty() { + "/tmp/.Xauthority".to_owned() } else { - std::env::set_var("DISPLAY", ""); - std::env::set_var("XAUTHORITY", ""); - std::env::set_var(ENV_DESKTOP_PROTOCAL, &self.protocal.to_string()); + xauth } } - pub fn is_same_env(&self, other: &Self) -> bool { - self.sid == other.sid - && self.protocal == other.protocal - && self.uid == other.uid - && self.display == other.display - && self.xauth == other.xauth + #[inline] + fn is_running(&self) -> bool { + self.is_child_running.load(Ordering::SeqCst) } - #[inline] - pub fn is_x11(&self) -> bool { - self.protocal == Protocal::X11 - } + fn try_start_x_session(&mut self, username: &str, password: &str) -> ResultType<()> { + match get_user_by_name(username) { + Some(userinfo) => { + let mut client = pam::Client::with_password(pam_get_service_name())?; + client + .conversation_mut() + .set_credentials(username, password); + match client.authenticate() { + Ok(_) => { + if self.is_running() { + return Ok(()); + } - #[inline] - pub fn is_wayland(&self) -> bool { - self.protocal == Protocal::Wayland - } - - #[inline] - pub fn is_ready(&self) -> bool { - match self.protocal { - Protocal::X11 | Protocal::Wayland => true, - _ => false, + match self.start_x_session(&userinfo, username, password) { + Ok(_) => { + log::info!("Succeeded to start x11"); + self.child_username = username.to_string(); + Ok(()) + } + Err(e) => { + bail!("failed to start x session, {}", e); + } + } + } + Err(e) => { + bail!("failed to check user pass for {}, {}", username, e); + } + } + } + None => { + bail!("failed to get userinfo of {}", username); + } } } @@ -220,83 +193,131 @@ impl Desktop { || Path::new(&format!("/tmp/.X{}-lock", display)).exists() } - fn get_display(&mut self) { - self.display = get_env_tries("DISPLAY", &self.uid, GNOME_SESSION_BINARY, 10); - if self.display.is_empty() { - self.display = get_env_tries("DISPLAY", &self.uid, XFCE4_PANEL, 10); - } - if self.display.is_empty() { - self.display = Self::get_display_by_user(&self.username); - } - if self.display.is_empty() { - self.display = ":0".to_owned(); - } - self.display = self - .display - .replace(&whoami::hostname(), "") - .replace("localhost", ""); - } + fn start_x_session( + &mut self, + userinfo: &User, + username: &str, + password: &str, + ) -> ResultType<()> { + self.stop_children(); - fn get_xauth(&mut self) { - self.xauth = get_env_tries("XAUTHORITY", &self.uid, GNOME_SESSION_BINARY, 10); - if self.xauth.is_empty() { - get_env_tries("XAUTHORITY", &self.uid, XFCE4_PANEL, 10); - } + let display_num = Self::get_avail_display()?; + // "xServer_ip:display_num.screen_num" - let gdm = format!("/run/user/{}/gdm/Xauthority", self.uid); - if self.xauth.is_empty() { - self.xauth = if std::path::Path::new(&gdm).exists() { - gdm - } else { - let username = &self.username; - if username == "root" { - format!("/{}/.Xauthority", username) + let uid = userinfo.uid(); + let gid = userinfo.primary_group_id(); + let envs = HashMap::from([ + ("SHELL", userinfo.shell().to_string_lossy().to_string()), + ("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin".to_owned()), + ("USER", username.to_string()), + ("UID", userinfo.uid().to_string()), + ("HOME", userinfo.home_dir().to_string_lossy().to_string()), + ( + "XDG_RUNTIME_DIR", + format!("/run/user/{}", userinfo.uid().to_string()), + ), + // ("DISPLAY", self.display.clone()), + // ("XAUTHORITY", self.xauth.clone()), + // (ENV_DESKTOP_PROTOCAL, XProtocal::X11.to_string()), + ]); + self.child_exit.store(false, Ordering::SeqCst); + let is_child_running = self.is_child_running.clone(); + + let (tx_res, rx_res) = sync_channel(1); + let password = password.to_string(); + let username = username.to_string(); + // start x11 + std::thread::spawn(move || { + match Self::start_x_session_thread( + tx_res.clone(), + is_child_running, + uid, + gid, + display_num, + username, + password, + envs, + ) { + Ok(_) => {} + Err(e) => { + log::error!("Failed to start x session thread"); + allow_err!(tx_res.send(format!("Failed to start x session thread, {}", e))); + } + } + }); + + // wait x11 + match rx_res.recv_timeout(Duration::from_millis(10_000)) { + Ok(res) => { + if res == "" { + Ok(()) } else { - let tmp = format!("/home/{}/.Xauthority", username); - if std::path::Path::new(&tmp).exists() { - tmp - } else { - format!("/var/lib/{}/.Xauthority", username) - } + bail!(res) } - }; + } + Err(e) => { + bail!("Failed to recv x11 result {}", e) + } } } - fn get_display_by_user(user: &str) -> String { - // log::debug!("w {}", &user); - if let Ok(output) = std::process::Command::new("w").arg(&user).output() { - for line in String::from_utf8_lossy(&output.stdout).lines() { - let mut iter = line.split_whitespace(); - let b = iter.nth(2); - if let Some(b) = b { - if b.starts_with(":") { - return b.to_owned(); + #[inline] + fn display_from_num(num: u32) -> String { + format!(":{num}") + } + + fn start_x_session_thread( + tx_res: SyncSender, + is_child_running: Arc, + uid: u32, + gid: u32, + display_num: u32, + username: String, + password: String, + envs: HashMap<&str, String>, + ) -> ResultType<()> { + let mut client = pam::Client::with_password(pam_get_service_name())?; + client + .conversation_mut() + .set_credentials(&username, &password); + client.authenticate()?; + + client.set_item(pam::PamItemType::TTY, &Self::display_from_num(display_num))?; + client.open_session()?; + + // fixme: FreeBSD kernel needs to login here. + // see: https://github.com/neutrinolabs/xrdp/blob/a64573b596b5fb07ca3a51590c5308d621f7214e/sesman/session.c#L556 + + let (child_xorg, child_wm) = Self::start_x11(uid, gid, username, display_num, &envs)?; + is_child_running.store(true, Ordering::SeqCst); + + log::info!("Start xorg and wm done, notify and wait xtop x11"); + allow_err!(tx_res.send("".to_owned())); + + Self::wait_stop_x11(child_xorg, child_wm); + log::info!("Wait x11 stop done"); + Ok(()) + } + + fn wait_xorg_exit(child_xorg: &mut Child) -> ResultType { + if let Ok(_) = child_xorg.kill() { + for _ in 0..3 { + match child_xorg.try_wait() { + Ok(Some(status)) => return Ok(format!("Xorg exit with {}", status)), + Ok(None) => {} + Err(e) => { + // fatal error + log::error!("Failed to wait xorg process, {}", e); + bail!("Failed to wait xorg process, {}", e) } } + std::thread::sleep(std::time::Duration::from_millis(1_000)); } + log::error!("Failed to wait xorg process, not exit"); + bail!("Failed to wait xorg process, not exit") + } else { + Ok("Xorg is already exited".to_owned()) } - // above not work for gdm user - //log::debug!("ls -l /tmp/.X11-unix/"); - let mut last = "".to_owned(); - if let Ok(output) = std::process::Command::new("ls") - .args(vec!["-l", "/tmp/.X11-unix/"]) - .output() - { - for line in String::from_utf8_lossy(&output.stdout).lines() { - let mut iter = line.split_whitespace(); - let user_field = iter.nth(2); - if let Some(x) = iter.last() { - if x.starts_with("X") { - last = x.replace("X", ":").to_owned(); - if user_field == Some(&user) { - return last; - } - } - } - } - } - last } fn add_xauth_cookie( @@ -343,233 +364,28 @@ impl Desktop { } } - fn refresh(&mut self) { - *self = Self::new(); - - let seat0_values = get_values_of_seat0(&[0, 1, 2]); - if seat0_values[0].is_empty() { - return; - } - - self.sid = seat0_values[0].clone(); - self.uid = seat0_values[1].clone(); - self.username = seat0_values[2].clone(); - self.protocal = get_display_server_of_session(&self.sid).into(); - self.get_display(); - self.get_xauth(); - } -} - -impl Drop for ChildFlags { - fn drop(&mut self) { - self.stop_children(); - } -} - -impl ChildFlags { - fn fatal_exit() { - std::process::exit(0); - } - - pub fn new() -> Self { - Self { - child_exit: Arc::new(AtomicBool::new(true)), - is_child_running: Arc::new(AtomicBool::new(false)), - } - } - - fn try_start_x_session( - &mut self, - desktop: &mut Desktop, - username: &str, - password: &str, - ) -> ResultType<()> { - match get_user_by_name(username) { - Some(userinfo) => { - let mut client = pam::Client::with_password(pam_get_service_name())?; - client - .conversation_mut() - .set_credentials(username, password); - match client.authenticate() { - Ok(_) => { - if desktop.is_x11() && desktop.username == username { - return Ok(()); - } - - // to-do: sid is empty if xorg is managed by this process - desktop.sid = "".to_owned(); - desktop.username = username.to_string(); - desktop.uid = userinfo.uid().to_string(); - desktop.protocal = Protocal::Unknown; - match self.start_x_session(desktop, &userinfo, password) { - Ok(_) => { - log::info!("Succeeded to start x11, update env {:?}", &desktop); - desktop.update_env(); - Ok(()) - } - Err(e) => { - *desktop = Desktop::new(); - desktop.update_env(); - bail!("failed to start x session, {}", e); - } - } - } - Err(e) => { - bail!("failed to check user pass for {}, {}", username, e); - } - } - } - None => { - bail!("failed to get userinfo of {}", username); - } - } - } - - fn start_x_session( - &mut self, - desktop: &mut Desktop, - userinfo: &User, - password: &str, - ) -> ResultType<()> { - self.stop_children(); - - let display_num = Desktop::get_avail_display()?; - // "xServer_ip:display_num.screen_num" - desktop.display = format!(":{}", display_num); - - let uid = userinfo.uid(); - let gid = userinfo.primary_group_id(); - let envs = HashMap::from([ - ("SHELL", userinfo.shell().to_string_lossy().to_string()), - ("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin".to_owned()), - ("USER", desktop.username.clone()), - ("UID", userinfo.uid().to_string()), - ("HOME", userinfo.home_dir().to_string_lossy().to_string()), - ( - "XDG_RUNTIME_DIR", - format!("/run/user/{}", userinfo.uid().to_string()), - ), - // ("DISPLAY", self.display.clone()), - // ("XAUTHORITY", self.xauth.clone()), - // (ENV_DESKTOP_PROTOCAL, XProtocal::X11.to_string()), - ]); - let desktop_clone = desktop.clone(); - self.child_exit.store(false, Ordering::SeqCst); - let is_child_running = self.is_child_running.clone(); - - let (tx_res, rx_res) = sync_channel(1); - let password = password.to_string(); - // start x11 - std::thread::spawn(move || { - match Self::start_x_session_thread( - tx_res.clone(), - is_child_running, - desktop_clone, - uid, - gid, - display_num, - password, - envs, - ) { - Ok(_) => {} - Err(e) => { - log::error!("Failed to start x session thread"); - allow_err!(tx_res.send(format!("Failed to start x session thread, {}", e))); - } - } - }); - - // wait x11 - match rx_res.recv_timeout(Duration::from_millis(10_000)) { - Ok(res) => { - if res == "" { - desktop.protocal = Protocal::X11; - Ok(()) - } else { - bail!(res) - } - } - Err(e) => { - bail!("Failed to recv x11 result {}", e) - } - } - } - - fn start_x_session_thread( - tx_res: SyncSender, - is_child_running: Arc, - desktop: Desktop, - uid: u32, - gid: u32, - display_num: u32, - password: String, - envs: HashMap<&str, String>, - ) -> ResultType<()> { - let mut client = pam::Client::with_password(pam_get_service_name())?; - client - .conversation_mut() - .set_credentials(&desktop.username, &password); - client.authenticate()?; - - client.set_item(pam::PamItemType::TTY, &desktop.display)?; - client.open_session()?; - - // fixme: FreeBSD kernel needs to login here. - // see: https://github.com/neutrinolabs/xrdp/blob/a64573b596b5fb07ca3a51590c5308d621f7214e/sesman/session.c#L556 - - let (child_xorg, child_wm) = Self::start_x11(&desktop, uid, gid, display_num, &envs)?; - is_child_running.store(true, Ordering::SeqCst); - - log::info!("Start xorg and wm done, notify and wait xtop x11"); - allow_err!(tx_res.send("".to_owned())); - - Self::wait_stop_x11(child_xorg, child_wm); - log::info!("Wait x11 stop done"); - Ok(()) - } - - fn wait_xorg_exit(child_xorg: &mut Child) -> ResultType { - if let Ok(_) = child_xorg.kill() { - for _ in 0..3 { - match child_xorg.try_wait() { - Ok(Some(status)) => return Ok(format!("Xorg exit with {}", status)), - Ok(None) => {} - Err(e) => { - // fatal error - log::error!("Failed to wait xorg process, {}", e); - bail!("Failed to wait xorg process, {}", e) - } - } - std::thread::sleep(std::time::Duration::from_millis(1_000)); - } - log::error!("Failed to wait xorg process, not exit"); - bail!("Failed to wait xorg process, not exit") - } else { - Ok("Xorg is already exited".to_owned()) - } - } - fn start_x11( - desktop: &Desktop, uid: u32, gid: u32, + username: String, display_num: u32, envs: &HashMap<&str, String>, ) -> ResultType<(Child, Child)> { - log::debug!("envs of user {}: {:?}", &desktop.username, &envs); + log::debug!("envs of user {}: {:?}", &username, &envs); - Desktop::add_xauth_cookie(&desktop.xauth, &desktop.display, uid, gid, &envs)?; + let xauth = Self::get_xauth(); + let display = Self::display_from_num(display_num); + + Self::add_xauth_cookie(&xauth, &display, uid, gid, &envs)?; // Start Xorg - let mut child_xorg = - Self::start_x_server(&desktop.xauth, &desktop.display, uid, gid, &envs)?; + let mut child_xorg = Self::start_x_server(&xauth, &display, uid, gid, &envs)?; log::info!("xorg started, wait 10 secs to ensuer x server is running"); let max_wait_secs = 10; // wait x server running - if let Err(e) = Desktop::wait_x_server_running(child_xorg.id(), display_num, max_wait_secs) - { + if let Err(e) = Self::wait_x_server_running(child_xorg.id(), display_num, max_wait_secs) { match Self::wait_xorg_exit(&mut child_xorg) { Ok(msg) => log::info!("{}", msg), Err(e) => { @@ -582,12 +398,12 @@ impl ChildFlags { log::info!( "xorg is running, start x window manager with DISPLAY: {}, XAUTHORITY: {}", - &desktop.display, - &desktop.xauth + &display, + &xauth ); - std::env::set_var("DISPLAY", &desktop.display); - std::env::set_var("XAUTHORITY", &desktop.xauth); + std::env::set_var("DISPLAY", &display); + std::env::set_var("XAUTHORITY", &xauth); // start window manager (startwm.sh) let child_wm = match Self::start_x_window_manager(uid, gid, &envs) { Ok(c) => c, @@ -707,10 +523,10 @@ impl ChildFlags { } fn try_wait_stop_x11(child_xorg: &mut Child, child_wm: &mut Child) -> bool { - let mut child_flags = CHILD_FLAGS.lock().unwrap(); + let mut desktop_manager = DESKTOP_MANAGER.lock().unwrap(); let mut exited = true; - if let Some(child_flags) = &mut (*child_flags) { - if child_flags.child_exit.load(Ordering::SeqCst) { + if let Some(desktop_manager) = &mut (*desktop_manager) { + if desktop_manager.child_exit.load(Ordering::SeqCst) { exited = true; } else { exited = Self::try_wait_x11_child_exit(child_xorg, child_wm); @@ -718,8 +534,10 @@ impl ChildFlags { if exited { println!("=============================MYDEBUG begin to wait x11 children exit"); Self::wait_x11_children_exit(child_xorg, child_wm); - child_flags.is_child_running.store(false, Ordering::SeqCst); - child_flags.child_exit.store(true, Ordering::SeqCst); + desktop_manager + .is_child_running + .store(false, Ordering::SeqCst); + desktop_manager.child_exit.store(true, Ordering::SeqCst); } } exited @@ -843,23 +661,3 @@ fn pam_get_service_name() -> &'static str { "gdm" } } - -impl ToString for Protocal { - fn to_string(&self) -> String { - match self { - Protocal::X11 => ENV_DESKTOP_PROTOCAL__X11.to_owned(), - Protocal::Wayland => ENV_DESKTOP_PROTOCAL_WAYLAND.to_owned(), - Protocal::Unknown => ENV_DESKTOP_PROTOCAL_UNKNOWN.to_owned(), - } - } -} - -impl From for Protocal { - fn from(value: String) -> Self { - match &value as &str { - ENV_DESKTOP_PROTOCAL__X11 => Protocal::X11, - ENV_DESKTOP_PROTOCAL_WAYLAND => Protocal::Wayland, - _ => Protocal::Unknown, - } - } -} diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 16bcc775a..7c9b2f0b0 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -18,7 +18,7 @@ pub mod delegate; pub mod linux; #[cfg(target_os = "linux")] -pub mod linux_desktop; +pub mod linux_desktop_manager; #[cfg(not(any(target_os = "android", target_os = "ios")))] use hbb_common::{message_proto::CursorData, ResultType}; diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 5a68a4a03..3fef9747b 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -73,7 +73,7 @@ impl RendezvousMediator { }); } #[cfg(target_os = "linux")] - crate::platform::linux_desktop::start_xdesktop(); + crate::platform::linux_desktop_manager::start_xdesktop(); SHOULD_EXIT.store(false, Ordering::SeqCst); while !SHOULD_EXIT.load(Ordering::SeqCst) { Config::reset_online(); @@ -100,7 +100,7 @@ impl RendezvousMediator { sleep(1.).await; } #[cfg(target_os = "linux")] - crate::platform::linux_desktop::stop_xdesktop(); + crate::platform::linux_desktop_manager::stop_xdesktop(); } pub async fn start(server: ServerPtr, host: String) -> ResultType<()> { diff --git a/src/server/connection.rs b/src/server/connection.rs index a5c63a80e..2d9e60f04 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1074,18 +1074,19 @@ impl Connection { fn try_start_desktop(_username: &str, _passsword: &str) -> String { #[cfg(target_os = "linux")] if _username.is_empty() { - let desktop = crate::platform::linux_desktop::get_desktop_env(); - if desktop.is_ready() { - "" - } else { + let username = crate::platform::linux_desktop_manager::get_username(); + if username.is_empty() { LOGIN_MSG_XSESSION_NOT_READY + } else { + "" } .to_owned() } else { - match crate::platform::linux_desktop::try_start_x_session(_username, _passsword) { - Ok(desktop) => { - if desktop.is_ready() { - if _username != desktop.username { + match crate::platform::linux_desktop_manager::try_start_x_session(_username, _passsword) + { + Ok((username, x11_ready)) => { + if x11_ready { + if _username != username { LOGIN_MSG_XSESSION_ANOTHER_USER_READTY.to_owned() } else { "".to_owned() From e4c2e9af00f4dda2ae18e898a196b848687ab744 Mon Sep 17 00:00:00 2001 From: fufesou Date: Tue, 28 Mar 2023 22:47:29 +0800 Subject: [PATCH 09/44] refact linux desktop Signed-off-by: fufesou --- src/platform/linux.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 85f763ec6..dda4b115b 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -296,7 +296,6 @@ fn force_stop_server() { pub fn start_os_service() { stop_rustdesk_servers(); start_uinput_service(); - start_check_desktop_env(); let running = Arc::new(AtomicBool::new(true)); let r = running.clone(); @@ -371,8 +370,6 @@ pub fn start_os_service() { } } - stop_check_desktop_env(); - if let Some(ps) = user_server.take().as_mut() { allow_err!(ps.kill()); } @@ -384,13 +381,13 @@ pub fn start_os_service() { #[inline] pub fn get_active_user_id_name() -> (String, String) { - let desktop = get_desktop_env(); - (desktop.uid.clone(), desktop.username.clone()) + let vec_id_name = get_values_of_seat0(&[1, 2]); + (vec_id_name[0].clone(), vec_id_name[1].clone()) } #[inline] pub fn get_active_userid() -> String { - get_desktop_env().uid.clone() + get_values_of_seat0(&[1])[0].clone() } fn get_cm() -> bool { @@ -436,7 +433,7 @@ fn _get_display_manager() -> String { #[inline] pub fn get_active_username() -> String { - get_desktop_env().username.clone() + get_values_of_seat0(&[2])[0].clone() } pub fn get_active_user_home() -> Option { From 6149c7f4777fe1f5a83188fd38a41487b5a90354 Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 29 Mar 2023 12:08:24 +0800 Subject: [PATCH 10/44] refact linux desktop env Signed-off-by: fufesou --- src/platform/linux.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/platform/linux.rs b/src/platform/linux.rs index dda4b115b..28c4d9252 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -769,6 +769,7 @@ mod desktop { pub protocal: String, pub display: String, pub xauth: String, + pub is_rustdesk_subprocess: bool, } impl Desktop { @@ -787,6 +788,11 @@ mod desktop { self.sid.is_empty() } + #[inline] + pub fn is_headless(&self) -> bool { + self.sid.is_empty() || self.is_rustdesk_subprocess + } + fn get_display(&mut self) { self.display = get_env_tries("DISPLAY", &self.uid, GNOME_SESSION_BINARY, 10); if self.display.is_empty() { @@ -901,6 +907,16 @@ mod desktop { last } + fn set_is_subprocess(&mut self) { + self.is_rustdesk_subprocess = false; + let cmd = "ps -ef | grep 'rustdesk/xorg.conf' | grep -v grep | wc -l"; + if let Ok(res) = run_cmds(cmd) { + if res.trim() != "0" { + self.is_rustdesk_subprocess = true; + } + } + } + pub fn refresh(&mut self) { if !self.sid.is_empty() && is_active(&self.sid) { return; @@ -909,6 +925,7 @@ mod desktop { let seat0_values = get_values_of_seat0(&[0, 1, 2]); if seat0_values[0].is_empty() { *self = Self::default(); + self.is_rustdesk_subprocess = false; return; } @@ -924,6 +941,9 @@ mod desktop { self.get_display(); self.get_xauth(); + self.set_is_subprocess(); + + println!("REMOVE ME ======================================= desktop: {:?}", self); } } } From b82207f20bb13428c781df8edb0dee4c65a40a65 Mon Sep 17 00:00:00 2001 From: qcloud Date: Wed, 29 Mar 2023 17:39:16 +0800 Subject: [PATCH 11/44] virtual display, linux, debug Signed-off-by: qcloud --- libs/hbb_common/src/platform/mod.rs | 2 +- src/platform/linux.rs | 12 +++- src/platform/linux_desktop_manager.rs | 3 +- src/server/connection.rs | 83 ++++++--------------------- 4 files changed, 31 insertions(+), 69 deletions(-) diff --git a/libs/hbb_common/src/platform/mod.rs b/libs/hbb_common/src/platform/mod.rs index c37c8aaf5..f4a1122e5 100644 --- a/libs/hbb_common/src/platform/mod.rs +++ b/libs/hbb_common/src/platform/mod.rs @@ -57,6 +57,6 @@ where { unsafe { GLOBAL_CALLBACK = Some(Box::new(callback)); - libc::signal(libc::SIGSEGV, breakdown_signal_handler as _); + // libc::signal(libc::SIGSEGV, breakdown_signal_handler as _); } } diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 28c4d9252..b166f1531 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -225,6 +225,13 @@ fn stop_rustdesk_servers() { )); } +#[inline] +fn stop_xorg_subprocess() { + let _ = run_cmds(format!( + r##"ps -ef | grep '/etc/rustdesk/xorg.conf' | grep -v grep | awk '{{printf("kill -9 %d\n", $2)}}' | bash"##, + )); +} + fn should_start_server( try_x11: bool, uid: &mut String, @@ -295,6 +302,7 @@ fn force_stop_server() { pub fn start_os_service() { stop_rustdesk_servers(); + stop_xorg_subprocess(); start_uinput_service(); let running = Arc::new(AtomicBool::new(true)); @@ -329,6 +337,7 @@ pub fn start_os_service() { &mut last_restart, &mut server, ) { + stop_xorg_subprocess(); force_stop_server(); start_server(None, &mut server); } @@ -921,7 +930,6 @@ mod desktop { if !self.sid.is_empty() && is_active(&self.sid) { return; } - let seat0_values = get_values_of_seat0(&[0, 1, 2]); if seat0_values[0].is_empty() { *self = Self::default(); @@ -942,8 +950,6 @@ mod desktop { self.get_display(); self.get_xauth(); self.set_is_subprocess(); - - println!("REMOVE ME ======================================= desktop: {:?}", self); } } } diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index 8b9e20640..ea7189b82 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -111,6 +111,7 @@ impl DesktopManager { pub fn new() -> Self { let mut x11_username = "".to_owned(); let seat0_values = get_values_of_seat0(&[0, 1, 2]); + println!("REMOVE ME ======================== DesktopManager seato values {:?}", &seat0_values); if !seat0_values[0].is_empty() { if "x11" == get_display_server_of_session(&seat0_values[1]) { x11_username = seat0_values[2].clone(); @@ -608,7 +609,7 @@ impl DesktopManager { //"-logfile", //"/tmp/RustDesk_xorg.log", "-config", - "rustdesk/xorg.conf", + "/etc/rustdesk/xorg.conf", "-auth", xauth, display, diff --git a/src/server/connection.rs b/src/server/connection.rs index 2d9e60f04..beefaac1a 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1075,6 +1075,7 @@ impl Connection { #[cfg(target_os = "linux")] if _username.is_empty() { let username = crate::platform::linux_desktop_manager::get_username(); + println!("REMOVE ME ===================================== try_start_desktop username '{}'", &username); if username.is_empty() { LOGIN_MSG_XSESSION_NOT_READY } else { @@ -1274,6 +1275,7 @@ impl Connection { Some(os_login) => Self::try_start_desktop(&os_login.username, &os_login.password), None => Self::try_start_desktop("", ""), }; + // If err is LOGIN_MSG_XSESSION_NOT_READY, just keep this msg and go on checking password. if !desktop_err.is_empty() && desktop_err != LOGIN_MSG_XSESSION_NOT_READY { self.send_login_error(desktop_err).await; return true; @@ -1302,73 +1304,26 @@ impl Connection { self.send_login_error("Connection not allowed").await; return false; } else if self.is_recent_session() { - self.try_start_cm(lr.my_id, lr.my_name, true); - self.send_logon_response().await; - if self.port_forward_socket.is_some() { - return false; - } - } else if lr.password.is_empty() { - self.try_start_cm(lr.my_id, lr.my_name, false); - } else { - let mut failure = LOGIN_FAILURES - .lock() - .unwrap() - .get(&self.ip) - .map(|x| x.clone()) - .unwrap_or((0, 0, 0)); - let time = (get_time() / 60_000) as i32; - if failure.2 > 30 { - self.send_login_error("Too many wrong password attempts") - .await; - Self::post_alarm_audit( - AlarmAuditType::ManyWrongPassword, - true, - json!({ - "ip":self.ip, - }), - ); - } else if time == failure.0 && failure.1 > 6 { - self.send_login_error("Please try 1 minute later").await; - Self::post_alarm_audit( - AlarmAuditType::FrequentAttempt, - true, - json!({ - "ip":self.ip, - }), - ); - } else if !self.validate_password() { - if failure.0 == time { - failure.1 += 1; - failure.2 += 1; - } else { - failure.0 = time; - failure.1 = 1; - failure.2 += 1; - } - LOGIN_FAILURES - .lock() - .unwrap() - .insert(self.ip.clone(), failure); - if desktop_err.is_empty() { - self.send_login_error(LOGIN_MSG_PASSWORD_WRONG).await; - self.try_start_cm(lr.my_id, lr.my_name, false); - } else { - self.send_login_error(LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_WRONG) - .await; + if desktop_err.is_empty() { + self.try_start_cm(lr.my_id, lr.my_name, true); + self.send_logon_response().await; + if self.port_forward_socket.is_some() { + return false; } } else { - if failure.0 != 0 { - LOGIN_FAILURES.lock().unwrap().remove(&self.ip); - } - if desktop_err.is_empty() { - self.send_logon_response().await; - self.try_start_cm(lr.my_id, lr.my_name, true); - if self.port_forward_socket.is_some() { - return false; - } - } else { - self.send_login_error(desktop_err).await; + self.send_login_error(desktop_err).await; + } + } else { + if desktop_err.is_empty() { + println!("REMOVE ME =============================== send logon response"); + self.send_logon_response().await; + self.try_start_cm(lr.my_id, lr.my_name, true); + if self.port_forward_socket.is_some() { + return false; } + } else { + println!("REMOVE ME =============================== send login error {}", &desktop_err); + self.send_login_error(desktop_err).await; } } } else if let Some(message::Union::TestDelay(t)) = msg.union { From bcf08ba26d7adadb8a1f7777d3c173a334bbf357 Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 29 Mar 2023 18:31:42 +0800 Subject: [PATCH 12/44] virtual display, linux, debug Signed-off-by: fufesou --- src/platform/linux.rs | 2 +- src/platform/linux_desktop_manager.rs | 35 +++------------------------ src/server/connection.rs | 3 --- 3 files changed, 4 insertions(+), 36 deletions(-) diff --git a/src/platform/linux.rs b/src/platform/linux.rs index b166f1531..8c4a68848 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -227,7 +227,7 @@ fn stop_rustdesk_servers() { #[inline] fn stop_xorg_subprocess() { - let _ = run_cmds(format!( + let _ = run_cmds(&format!( r##"ps -ef | grep '/etc/rustdesk/xorg.conf' | grep -v grep | awk '{{printf("kill -9 %d\n", $2)}}' | bash"##, )); } diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index ea7189b82..b21b2d5b1 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -111,7 +111,6 @@ impl DesktopManager { pub fn new() -> Self { let mut x11_username = "".to_owned(); let seat0_values = get_values_of_seat0(&[0, 1, 2]); - println!("REMOVE ME ======================== DesktopManager seato values {:?}", &seat0_values); if !seat0_values[0].is_empty() { if "x11" == get_display_server_of_session(&seat0_values[1]) { x11_username = seat0_values[2].clone(); @@ -427,10 +426,6 @@ impl DesktopManager { fn try_wait_x11_child_exit(child_xorg: &mut Child, child_wm: &mut Child) -> bool { match child_xorg.try_wait() { Ok(Some(status)) => { - println!( - "=============================MYDEBUG Xorg exit with {}", - status - ); log::info!("Xorg exit with {}", status); return true; } @@ -440,10 +435,7 @@ impl DesktopManager { match child_wm.try_wait() { Ok(Some(status)) => { - println!( - "=============================MYDEBUG: wm exit with {}", - status - ); + // Logout may result "wm exit with signal: 11 (SIGSEGV) (core dumped)" log::info!("wm exit with {}", status); return true; } @@ -460,20 +452,12 @@ impl DesktopManager { for _ in 0..2 { match child_xorg.try_wait() { Ok(Some(status)) => { - println!( - "=============================MYDEBUG Xorg exit with {}", - status - ); log::info!("Xorg exit with {}", status); exited = true; break; } Ok(None) => {} Err(e) => { - println!( - "=============================MYDEBUG Failed to wait xorg process, {}", - &e - ); log::error!("Failed to wait xorg process, {}", e); Self::fatal_exit(); } @@ -481,9 +465,6 @@ impl DesktopManager { std::thread::sleep(std::time::Duration::from_millis(1_000)); } if !exited { - println!( - "=============================MYDEBUG Failed to wait child xorg, after kill()" - ); log::error!("Failed to wait child xorg, after kill()"); // try kill -9? } @@ -494,19 +475,12 @@ impl DesktopManager { for _ in 0..2 { match child_wm.try_wait() { Ok(Some(status)) => { - println!( - "=============================MYDEBUG wm exit with {}", - status - ); + // Logout may result "wm exit with signal: 11 (SIGSEGV) (core dumped)" log::info!("wm exit with {}", status); exited = true; } Ok(None) => {} Err(e) => { - println!( - "=============================MYDEBUG Failed to wait wm process, {}", - &e - ); log::error!("Failed to wait wm process, {}", e); Self::fatal_exit(); } @@ -514,9 +488,6 @@ impl DesktopManager { std::thread::sleep(std::time::Duration::from_millis(1_000)); } if !exited { - println!( - "=============================MYDEBUG Failed to wait child xorg, after kill()" - ); log::error!("Failed to wait child xorg, after kill()"); // try kill -9? } @@ -533,7 +504,7 @@ impl DesktopManager { exited = Self::try_wait_x11_child_exit(child_xorg, child_wm); } if exited { - println!("=============================MYDEBUG begin to wait x11 children exit"); + log::debug!("Wait x11 children exiting"); Self::wait_x11_children_exit(child_xorg, child_wm); desktop_manager .is_child_running diff --git a/src/server/connection.rs b/src/server/connection.rs index beefaac1a..6bbbffefc 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1075,7 +1075,6 @@ impl Connection { #[cfg(target_os = "linux")] if _username.is_empty() { let username = crate::platform::linux_desktop_manager::get_username(); - println!("REMOVE ME ===================================== try_start_desktop username '{}'", &username); if username.is_empty() { LOGIN_MSG_XSESSION_NOT_READY } else { @@ -1315,14 +1314,12 @@ impl Connection { } } else { if desktop_err.is_empty() { - println!("REMOVE ME =============================== send logon response"); self.send_logon_response().await; self.try_start_cm(lr.my_id, lr.my_name, true); if self.port_forward_socket.is_some() { return false; } } else { - println!("REMOVE ME =============================== send login error {}", &desktop_err); self.send_login_error(desktop_err).await; } } From c944d6093d0487bd6a2a995a6e3f031c8dab86a8 Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 29 Mar 2023 20:25:41 +0800 Subject: [PATCH 13/44] virtual display, linux, debug Signed-off-by: fufesou --- flutter/lib/models/model.dart | 4 +- libs/hbb_common/src/platform/mod.rs | 2 +- src/server/connection.rs | 85 +++++++++++++++++++++++------ 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 155956c74..470bb47c3 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -294,10 +294,10 @@ class FfiModel with ChangeNotifier { } else if (type == 'input-password') { enterPasswordDialog(id, dialogManager); } else if (type == 'xsession-login' || type == 'xsession-re-login') { - // to-do + enterUserLoginDialog(id, dialogManager); } else if (type == 'xsession-login-password' || type == 'xsession-login-password') { - // to-do + enterUserLoginAndPasswordDialog(id, dialogManager); } else if (type == 'restarting') { showMsgBox(id, type, title, text, link, false, dialogManager, hasCancel: false); diff --git a/libs/hbb_common/src/platform/mod.rs b/libs/hbb_common/src/platform/mod.rs index f4a1122e5..c37c8aaf5 100644 --- a/libs/hbb_common/src/platform/mod.rs +++ b/libs/hbb_common/src/platform/mod.rs @@ -57,6 +57,6 @@ where { unsafe { GLOBAL_CALLBACK = Some(Box::new(callback)); - // libc::signal(libc::SIGSEGV, breakdown_signal_handler as _); + libc::signal(libc::SIGSEGV, breakdown_signal_handler as _); } } diff --git a/src/server/connection.rs b/src/server/connection.rs index 6bbbffefc..2f86ca5f0 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1285,16 +1285,11 @@ impl Connection { } else if password::approve_mode() == ApproveMode::Click || password::approve_mode() == ApproveMode::Both && !password::has_valid_password() { - if desktop_err.is_empty() { - self.try_start_cm(lr.my_id, lr.my_name, false); - if hbb_common::get_version_number(&lr.version) - >= hbb_common::get_version_number("1.2.0") - { - self.send_login_error("No Password Access").await; - } - } else { - self.send_login_error(LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_EMPTY) - .await; + self.try_start_cm(lr.my_id, lr.my_name, false); + if hbb_common::get_version_number(&lr.version) + >= hbb_common::get_version_number("1.2.0") + { + self.send_login_error("No Password Access").await; } return true; } else if password::approve_mode() == ApproveMode::Password @@ -1312,15 +1307,73 @@ impl Connection { } else { self.send_login_error(desktop_err).await; } - } else { + } else if lr.password.is_empty() { if desktop_err.is_empty() { - self.send_logon_response().await; - self.try_start_cm(lr.my_id, lr.my_name, true); - if self.port_forward_socket.is_some() { - return false; + self.try_start_cm(lr.my_id, lr.my_name, false); + } else { + self.send_login_error(LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_EMPTY) + .await; + } + } else { + let mut failure = LOGIN_FAILURES + .lock() + .unwrap() + .get(&self.ip) + .map(|x| x.clone()) + .unwrap_or((0, 0, 0)); + let time = (get_time() / 60_000) as i32; + if failure.2 > 30 { + self.send_login_error("Too many wrong password attempts") + .await; + Self::post_alarm_audit( + AlarmAuditType::ManyWrongPassword, + true, + json!({ + "ip":self.ip, + }), + ); + } else if time == failure.0 && failure.1 > 6 { + self.send_login_error("Please try 1 minute later").await; + Self::post_alarm_audit( + AlarmAuditType::FrequentAttempt, + true, + json!({ + "ip":self.ip, + }), + ); + } else if !self.validate_password() { + if failure.0 == time { + failure.1 += 1; + failure.2 += 1; + } else { + failure.0 = time; + failure.1 = 1; + failure.2 += 1; + } + LOGIN_FAILURES + .lock() + .unwrap() + .insert(self.ip.clone(), failure); + if desktop_err.is_empty() { + self.send_login_error(LOGIN_MSG_PASSWORD_WRONG).await; + self.try_start_cm(lr.my_id, lr.my_name, false); + } else { + self.send_login_error(LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_WRONG) + .await; } } else { - self.send_login_error(desktop_err).await; + if failure.0 != 0 { + LOGIN_FAILURES.lock().unwrap().remove(&self.ip); + } + if desktop_err.is_empty() { + self.send_logon_response().await; + self.try_start_cm(lr.my_id, lr.my_name, true); + if self.port_forward_socket.is_some() { + return false; + } + } else { + self.send_login_error(desktop_err).await; + } } } } else if let Some(message::Union::TestDelay(t)) = msg.union { From 9448e35b461691d57d418c3c0d381eecff902ae2 Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 29 Mar 2023 23:18:27 +0800 Subject: [PATCH 14/44] update dialog style Signed-off-by: fufesou --- flutter/lib/common/widgets/dialog.dart | 177 ++-- .../lib/desktop/pages/connection_page.dart | 7 +- src/lang/ca.rs | 6 +- src/lang/cn.rs | 7 +- src/lang/cs.rs | 6 +- src/lang/da.rs | 6 +- src/lang/de.rs | 5 +- src/lang/el.rs | 5 +- src/lang/en.rs | 5 +- src/lang/eo.rs | 6 +- src/lang/es.rs | 6 +- src/lang/fa.rs | 6 +- src/lang/fr.rs | 2 +- src/lang/hu.rs | 6 +- src/lang/id.rs | 6 +- src/lang/it.rs | 6 +- src/lang/ja.rs | 6 +- src/lang/ko.rs | 6 +- src/lang/kz.rs | 6 +- src/lang/nl.rs | 6 +- src/lang/pl.rs | 2 +- src/lang/pt_PT.rs | 6 +- src/lang/ptbr.rs | 6 +- src/lang/ro.rs | 6 +- src/lang/ru.rs | 5 +- src/lang/sk.rs | 6 +- src/lang/sl.rs | 6 +- src/lang/sq.rs | 6 +- src/lang/sr.rs | 6 +- src/lang/sv.rs | 6 +- src/lang/template.rs | 4 +- src/lang/th.rs | 6 +- src/lang/tr.rs | 6 +- src/lang/tw.rs | 979 +++++++++--------- src/lang/ua.rs | 6 +- src/lang/vn.rs | 6 +- 36 files changed, 764 insertions(+), 584 deletions(-) diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index 4562e519c..569d64428 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -456,7 +456,7 @@ void enterPasswordDialog(String id, OverlayDialogManager dialogManager) async { await _connectDialog( id, dialogManager, - peerPasswordController: TextEditingController(), + passwordController: TextEditingController(), ); } @@ -464,8 +464,8 @@ void enterUserLoginDialog(String id, OverlayDialogManager dialogManager) async { await _connectDialog( id, dialogManager, - usernameController: TextEditingController(), - passwordController: TextEditingController(), + osUsernameController: TextEditingController(), + osPasswordController: TextEditingController(), ); } @@ -474,20 +474,27 @@ void enterUserLoginAndPasswordDialog( await _connectDialog( id, dialogManager, - usernameController: TextEditingController(), + osUsernameController: TextEditingController(), + osPasswordController: TextEditingController(), passwordController: TextEditingController(), - peerPasswordController: TextEditingController(), ); } _connectDialog( String id, OverlayDialogManager dialogManager, { - TextEditingController? usernameController, + TextEditingController? osUsernameController, + TextEditingController? osPasswordController, TextEditingController? passwordController, - TextEditingController? peerPasswordController, }) async { - var remember = await bind.sessionGetRemember(id: id) ?? false; + var rememberPassword = false; + if (passwordController != null) { + rememberPassword = await bind.sessionGetRemember(id: id) ?? false; + } + var rememberAccount = false; + if (osUsernameController != null) { + rememberAccount = await bind.sessionGetRemember(id: id) ?? false; + } dialogManager.dismissAll(); dialogManager.show((setState, close) { cancel() { @@ -501,77 +508,125 @@ _connectDialog( // If the remote side is headless. // The client side should login to remote OS account, to enable X desktop session. // `username` and `password` will be used in the near future. - final username = usernameController?.text.trim() ?? ''; + final osUsername = osUsernameController?.text.trim() ?? ''; + final osPassword = osPasswordController?.text.trim() ?? ''; final password = passwordController?.text.trim() ?? ''; - final peerPassword = peerPasswordController?.text.trim() ?? ''; - if (peerPasswordController != null && peerPassword.isEmpty) return; + if (passwordController != null && password.isEmpty) return; gFFI.login( - username, - password, + osUsername, + osPassword, id, - peerPassword, - remember, + password, + rememberPassword, ); close(); dialogManager.showLoading(translate('Logging in...'), onCancel: closeConnection); } + descWidget(String text) { + return Column( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + text, + maxLines: 3, + softWrap: true, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 16), + ), + ), + Container( + height: 8, + ), + ], + ); + } + + rememberWidget( + String desc, + bool remember, + ValueChanged? onChanged, + ) { + return CheckboxListTile( + contentPadding: const EdgeInsets.all(0), + dense: true, + controlAffinity: ListTileControlAffinity.leading, + title: Text(desc), + value: remember, + onChanged: onChanged, + ); + } + + osAccountWidget() { + if (osUsernameController == null || osPasswordController == null) { + return Offstage(); + } + return Column( + children: [ + descWidget(translate('login_linux_tooltip_tip')), + DialogTextField( + title: translate(DialogTextField.kUsernameTitle), + controller: osUsernameController, + prefixIcon: DialogTextField.kUsernameIcon, + errorText: null, + ), + PasswordWidget( + controller: osPasswordController, + autoFocus: false, + ), + rememberWidget( + translate('remember_account_tip'), + rememberAccount, + (v) { + if (v != null) { + setState(() => rememberAccount = v); + } + }, + ), + ], + ); + } + + passwdWidget() { + if (passwordController == null) { + return Offstage(); + } + return Column( + children: [ + descWidget(translate('verify_rustdesk_password_tip')), + PasswordWidget( + controller: passwordController, + autoFocus: osUsernameController == null, + ), + rememberWidget( + translate('remember_password_tip'), + rememberPassword, + (v) { + if (v != null) { + setState(() => rememberPassword = v); + } + }, + ), + ], + ); + } + return CustomAlertDialog( title: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.password_rounded, color: MyTheme.accent), - (usernameController == null - ? Text(translate('Password Required')) - : Tooltip( - message: translate('login_linux_tooltip_tip'), - child: Text(translate('login_linux_tip')), - )) - .paddingOnly(left: 10), + Text(translate('Password Required')).paddingOnly(left: 10), ], ), content: Column(mainAxisSize: MainAxisSize.min, children: [ - usernameController == null + osAccountWidget(), + osUsernameController == null || passwordController == null ? Offstage() - : DialogTextField( - title: translate(DialogTextField.kUsernameTitle), - controller: usernameController, - prefixIcon: DialogTextField.kUsernameIcon, - errorText: null, - ), - passwordController == null - ? Offstage() - : PasswordWidget( - controller: passwordController, - autoFocus: false, - ), - usernameController == null || peerPasswordController == null - ? Offstage() - : const Divider(), - peerPasswordController == null - ? Offstage() - : PasswordWidget( - controller: peerPasswordController, - autoFocus: usernameController == null, - hintText: 'enter_rustdesk_passwd_tip', - ), - peerPasswordController == null - ? Offstage() - : CheckboxListTile( - contentPadding: const EdgeInsets.all(0), - dense: true, - controlAffinity: ListTileControlAffinity.leading, - title: Text( - translate('remember_rustdesk_passwd_tip'), - ), - value: remember, - onChanged: (v) { - if (v != null) { - setState(() => remember = v); - } - }, - ), + : Container(height: 10), + passwdWidget(), ]), actions: [ dialogButton( diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index a593810fd..63d6b9c7b 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -233,7 +233,12 @@ class _ConnectionPageState extends State const SizedBox( width: 17, ), - Button(onTap: onConnect, text: "Connect"), + Button( + onTap: () => enterUserLoginAndPasswordDialog( + 'fdsfd', + gFFI.dialogManager, + ), + text: "Connect"), ], ), ) diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 162a48883..af744d153 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Tancar"), ("Retry", "Reintentar"), ("OK", ""), - ("Password Required", "Es necessita la contrasenya"), + ("remember_password_tip", "Es necessita la contrasenya"), ("Please enter your password", "Si us plau, introdueixi la seva contrasenya"), ("Remember password", "Recordar contrasenya"), ("Wrong Password", "Contrasenya incorrecta"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 250f9a5b6..584be4333 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "关闭"), ("Retry", "再试"), ("OK", "确认"), - ("Password Required", "需要密码"), + ("remember_password_tip", "需要密码"), ("Please enter your password", "请输入密码"), ("Remember password", "记住密码"), ("Wrong Password", "密码错误"), @@ -483,6 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", "请输入 RustDesk 密码"), ("remember_rustdesk_passwd_tip", "记住 RustDesk 密码"), ("login_linux_tip", "登录被控端的 Linux 账户"), - ("login_linux_tooltip_tip", "登录被控端的 Linux 账户,才能启用 X 桌面"), + ("login_linux_tooltip_tip", "登录被控端的 Linux 账户,才能启用 X 桌面。"), + ("verify_rustdesk_password_tip", "验证 RustDesk 密码"), + ("remember_account_tip", "记住此账户"), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 2f9e52f6c..cb882277e 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zavřít"), ("Retry", "Zkusit znovu"), ("OK", "OK"), - ("Password Required", "Vyžadováno heslo"), + ("remember_password_tip", "Vyžadováno heslo"), ("Please enter your password", "Zadejte své heslo"), ("Remember password", "Zapamatovat heslo"), ("Wrong Password", "Nesprávné heslo"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index a9ca8e8a6..ad6ddfc48 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Luk"), ("Retry", "Prøv igen"), ("OK", "OK"), - ("Password Required", "Adgangskode påkrævet"), + ("remember_password_tip", "Adgangskode påkrævet"), ("Please enter your password", "Indtast venligst dit kodeord"), ("Remember password", "Husk kodeord"), ("Wrong Password", "Forkert kodeord"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index b70e9f872..263664d4c 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Schließen"), ("Retry", "Erneut versuchen"), ("OK", "OK"), - ("Password Required", "Passwort erforderlich"), + ("remember_password_tip", "Passwort erforderlich"), ("Please enter your password", "Bitte geben Sie Ihr Passwort ein"), ("Remember password", "Passwort merken"), ("Wrong Password", "Falsches Passwort"), @@ -484,5 +484,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_rustdesk_passwd_tip", "RustDesk-Passwort merken."), ("login_linux_tip", "Anmeldung am entfernten Linux-Konto"), ("login_linux_tooltip_tip", "Sie müssen sich an einem entfernten Linux-Konto anmelden, um eine X-Desktop-Sitzung zu eröffnen."), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index 85c269d29..9597ae158 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Κλείσιμο"), ("Retry", "Δοκίμασε ξανά"), ("OK", "ΟΚ"), - ("Password Required", "Απαιτείται κωδικός πρόσβασης"), + ("remember_password_tip", "Απαιτείται κωδικός πρόσβασης"), ("Please enter your password", "Παρακαλώ εισάγετε τον κωδικό πρόσβασης"), ("Remember password", "Απομνημόνευση κωδικού πρόσβασης"), ("Wrong Password", "Λάθος κωδικός πρόσβασης"), @@ -484,5 +484,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_rustdesk_passwd_tip", "Να θυμάσαι τον κωδικό του RustDesk."), ("login_linux_tip", "Είσοδος σε απομακρυσμένο λογαριασμό Linux"), ("login_linux_tooltip_tip", "Απαιτείται είσοδος σε απομακρυσμένο λογαριασμό Linux για την ενεργοποίηση του περιβάλλον εργασίας Χ."), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index 8a981564b..95186325f 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -56,7 +56,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("show_monitors_tip", "Show monitors in toolbar."), ("enter_rustdesk_passwd_tip", "Enter RustDesk password."), ("remember_rustdesk_passwd_tip", "Remember RustDesk password."), - ("login_linux_tip", "Login to remote Linux account"), + ("login_linux_tip", "Login to remote Linux account."), ("login_linux_tooltip_tip", "You need to login to remote Linux account to enable a X desktop session."), + ("verify_rustdesk_password_tip", "Veryfy RustDesk password."), + ("remember_account_tip", "Remember this account."), + ("remember_password_tip", "Remember password."), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index e430f8f67..aeee842f7 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fermi"), ("Retry", "Reprovi"), ("OK", "Konfermi"), - ("Password Required", "Pasvorto deviga"), + ("remember_password_tip", "Pasvorto deviga"), ("Please enter your password", "Bonvolu tajpi vian pasvorton"), ("Remember password", "Memori pasvorton"), ("Wrong Password", "Erara pasvorto"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index a85a5e491..3b998ae7d 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Cerrar"), ("Retry", "Reintentar"), ("OK", ""), - ("Password Required", "Se requiere contraseña"), + ("remember_password_tip", "Se requiere contraseña"), ("Please enter your password", "Por favor, introduzca su contraseña"), ("Remember password", "Recordar contraseña"), ("Wrong Password", "Contraseña incorrecta"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", "Introduzca la contraseña de RustDesk"), ("remember_rustdesk_passwd_tip", "Recordar la contraseña de RustDesk"), ("login_linux_tip", "Iniciar sesión para la cuenta remota de Linux"), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index e4d026586..e2137c3e2 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "بستن"), ("Retry", "تلاش مجدد"), ("OK", "قبول"), - ("Password Required", "رمز عبور لازم است"), + ("remember_password_tip", "رمز عبور لازم است"), ("Please enter your password", "رمز عبور خود را وارد کنید"), ("Remember password", "رمز عبور را به خاطر بسپار"), ("Wrong Password", "رمز عبور اشتباه است"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 3279b9175..71c0f6728 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fermer"), ("Retry", "Réessayer"), ("OK", "Valider"), - ("Password Required", "Mot de passe requis"), + ("remember_password_tip", "Mot de passe requis"), ("Please enter your password", "Veuillez saisir votre mot de passe"), ("Remember password", "Mémoriser le mot de passe"), ("Wrong Password", "Mauvais mot de passe"), diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 2e6a20b56..7c7fb2468 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Bezárás"), ("Retry", "Újra"), ("OK", "OK"), - ("Password Required", "Jelszó megadása kötelező"), + ("remember_password_tip", "Jelszó megadása kötelező"), ("Please enter your password", "Kérem írja be a jelszavát"), ("Remember password", "Jelszó megjegyzése"), ("Wrong Password", "Hibás jelszó"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index cca4ba6c1..174d970b6 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Tutup"), ("Retry", "Ulangi"), ("OK", "Oke"), - ("Password Required", "Kata sandi dibutuhkan"), + ("remember_password_tip", "Kata sandi dibutuhkan"), ("Please enter your password", "Silahkan masukkan kata sandi anda"), ("Remember password", "Ingat Password"), ("Wrong Password", "Kata sandi Salah"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 3c5973053..94b7d10a9 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Chiudi"), ("Retry", "Riprova"), ("OK", "OK"), - ("Password Required", "Password Richiesta"), + ("remember_password_tip", "Password Richiesta"), ("Please enter your password", "Inserisci la tua password"), ("Remember password", "Ricorda password"), ("Wrong Password", "Password Errata"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", "Inserisci la password di RustDesk."), ("remember_rustdesk_passwd_tip", "Ricorda la passowrd di RustDesk."), ("login_linux_tip", "Effettua l'accesso sul tuo account Linux"), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 29bf3c346..95395c516 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "閉じる"), ("Retry", "再試行"), ("OK", "OK"), - ("Password Required", "パスワードが必要"), + ("remember_password_tip", "パスワードが必要"), ("Please enter your password", "パスワードを入力してください"), ("Remember password", "パスワードを記憶する"), ("Wrong Password", "パスワードが間違っています"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 929934016..4e3b52ea2 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "닫기"), ("Retry", "재시도"), ("OK", "확인"), - ("Password Required", "비밀번호 입력"), + ("remember_password_tip", "비밀번호 입력"), ("Please enter your password", "비밀번호를 입력해주세요"), ("Remember password", "이 비밀번호 기억하기"), ("Wrong Password", "틀린 비밀번호"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index a2c7c5983..bfe312e02 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Жабу"), ("Retry", "Қайтадан көру"), ("OK", "OK"), - ("Password Required", "Құпия сөз Қажет"), + ("remember_password_tip", "Құпия сөз Қажет"), ("Please enter your password", "Құпия сөзіңізді еңгізуді өтінеміз"), ("Remember password", "Құпия сөзді есте сақтау"), ("Wrong Password", "Бұрыс Құпия сөз"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index f31135c6c..4a3c9c062 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Sluit"), ("Retry", "Probeer opnieuw"), ("OK", "OK"), - ("Password Required", "Wachtwoord vereist"), + ("remember_password_tip", "Wachtwoord vereist"), ("Please enter your password", "Geef uw wachtwoord in"), ("Remember password", "Wachtwoord onthouden"), ("Wrong Password", "Verkeerd wachtwoord"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", "Geef het RustDesk-wachtwoord op."), ("remember_rustdesk_passwd_tip", "RustDesk Wachtwoord onthouden."), ("login_linux_tip", "Je moet inloggen op een Linux Account op afstand om een X desktop sessie te openen."), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 852aa520d..f68d37866 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zamknij"), ("Retry", "Ponów"), ("OK", "OK"), - ("Password Required", "Wymagane jest hasło"), + ("remember_password_tip", "Wymagane jest hasło"), ("Please enter your password", "Wpisz proszę twoje hasło"), ("Remember password", "Zapamiętaj hasło"), ("Wrong Password", "Błędne hasło"), diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 45226dec6..04689f713 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fechar"), ("Retry", "Tentar novamente"), ("OK", "Confirmar"), - ("Password Required", "Palavra-chave Necessária"), + ("remember_password_tip", "Palavra-chave Necessária"), ("Please enter your password", "Por favor introduza a sua palavra-chave"), ("Remember password", "Memorizar palavra-chave"), ("Wrong Password", "Palavra-chave inválida"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 8cf8ca6ef..6f6302a59 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fechar"), ("Retry", "Tentar novamente"), ("OK", "OK"), - ("Password Required", "Senha necessária"), + ("remember_password_tip", "Senha necessária"), ("Please enter your password", "Por favor informe sua senha"), ("Remember password", "Lembrar senha"), ("Wrong Password", "Senha incorreta"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index e81fa0cfd..ade2e3c36 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Închide"), ("Retry", "Reîncearcă"), ("OK", "OK"), - ("Password Required", "Parolă necesară"), + ("remember_password_tip", "Parolă necesară"), ("Please enter your password", "Introdu parola"), ("Remember password", "Memorează parola"), ("Wrong Password", "Parolă incorectă"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 12c3dfb34..c85582e86 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Закрыть"), ("Retry", "Повторить"), ("OK", "ОК"), - ("Password Required", "Требуется пароль"), + ("remember_password_tip", "Требуется пароль"), ("Please enter your password", "Введите пароль"), ("Remember password", "Запомнить пароль"), ("Wrong Password", "Неправильный пароль"), @@ -484,5 +484,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_rustdesk_passwd_tip", "Запомнить пароль RustDesk"), ("login_linux_tip", "Вход в удалённый аккаунт Linux"), ("login_linux_tooltip_tip", "Чтобы включить сеанс рабочего стола X, необходимо войти в удалённый аккаунт Linux."), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 7d28cfb72..e7c108a8c 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zatvoriť"), ("Retry", "Zopakovať"), ("OK", "OK"), - ("Password Required", "Vyžaduje sa heslo"), + ("remember_password_tip", "Vyžaduje sa heslo"), ("Please enter your password", "Zadajte vaše heslo"), ("Remember password", "Zapamätať heslo"), ("Wrong Password", "Chybné heslo"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 544e544f7..0e5265b87 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zapri"), ("Retry", "Ponovi"), ("OK", "V redu"), - ("Password Required", "Potrebno je geslo"), + ("remember_password_tip", "Potrebno je geslo"), ("Please enter your password", "Vnesite vaše geslo"), ("Remember password", "Zapomni si geslo"), ("Wrong Password", "Napačno geslo"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index afd5c2c2d..68ef47be9 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Mbyll"), ("Retry", "Riprovo"), ("OK", "OK"), - ("Password Required", "Fjalëkalimi i detyrueshëm"), + ("remember_password_tip", "Fjalëkalimi i detyrueshëm"), ("Please enter your password", "Ju lutem vendosni fjalëkalimin tuaj"), ("Remember password", "Mbani mend fjalëkalimin"), ("Wrong Password", "Fjalëkalim i gabuar"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 05204f728..ccb328e3e 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zatvori"), ("Retry", "Ponovi"), ("OK", "Ok"), - ("Password Required", "Potrebna lozinka"), + ("remember_password_tip", "Potrebna lozinka"), ("Please enter your password", "Molimo unesite svoju lozinku"), ("Remember password", "Zapamti lozinku"), ("Wrong Password", "Pogrešna lozinka"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 7941c2f58..496c882bc 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Stäng"), ("Retry", "Försök igen"), ("OK", "OK"), - ("Password Required", "Lösenord krävs"), + ("remember_password_tip", "Lösenord krävs"), ("Please enter your password", "Skriv in ditt lösenord"), ("Remember password", "Kom ihåg lösenord"), ("Wrong Password", "Fel lösenord"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 56508d80a..6ec149289 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", ""), ("Retry", ""), ("OK", ""), - ("Password Required", ""), + ("remember_password_tip", ""), ("Please enter your password", ""), ("Remember password", ""), ("Wrong Password", ""), @@ -484,5 +484,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 4f178bf1d..92ae279c9 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "ปิด"), ("Retry", "ลองใหม่อีกครั้ง"), ("OK", "ตกลง"), - ("Password Required", "ต้องใช้รหัสผ่าน"), + ("remember_password_tip", "ต้องใช้รหัสผ่าน"), ("Please enter your password", "กรุณาใส่รหัสผ่านของคุณ"), ("Remember password", "จดจำรหัสผ่าน"), ("Wrong Password", "รหัสผ่านไม่ถูกต้อง"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index f5209129b..b423a021b 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Kapat"), ("Retry", "Tekrar Dene"), ("OK", "Tamam"), - ("Password Required", "Şifre Gerekli"), + ("remember_password_tip", "Şifre Gerekli"), ("Please enter your password", "Lütfen şifrenizi giriniz"), ("Remember password", "Şifreyi hatırla"), ("Wrong Password", "Hatalı şifre"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 870105b09..e8685747e 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -1,488 +1,491 @@ -lazy_static::lazy_static! { -pub static ref T: std::collections::HashMap<&'static str, &'static str> = - [ - ("Status", "狀態"), - ("Your Desktop", "您的桌面"), - ("desk_tip", "您可以透過此 ID 及密碼存取您的桌面"), - ("Password", "密碼"), - ("Ready", "就緒"), - ("Established", "已建立"), - ("connecting_status", "正在連線到 RustDesk 網路 ..."), - ("Enable Service", "啟用服務"), - ("Start Service", "啟動服務"), - ("Service is running", "服務正在執行"), - ("Service is not running", "服務尚未執行"), - ("not_ready_status", "尚未就緒,請檢查您的網路連線。"), - ("Control Remote Desktop", "控制遠端桌面"), - ("Transfer File", "傳輸檔案"), - ("Connect", "連線"), - ("Recent Sessions", "近期的工作階段"), - ("Address Book", "通訊錄"), - ("Confirmation", "確認"), - ("TCP Tunneling", "TCP 通道"), - ("Remove", "移除"), - ("Refresh random password", "重新產生隨機密碼"), - ("Set your own password", "自行設定密碼"), - ("Enable Keyboard/Mouse", "啟用鍵盤和滑鼠"), - ("Enable Clipboard", "啟用剪貼簿"), - ("Enable File Transfer", "啟用檔案傳輸"), - ("Enable TCP Tunneling", "啟用 TCP 通道"), - ("IP Whitelisting", "IP 白名單"), - ("ID/Relay Server", "ID / 轉送伺服器"), - ("Import Server Config", "匯入伺服器設定"), - ("Export Server Config", "匯出伺服器設定"), - ("Import server configuration successfully", "匯入伺服器設定成功"), - ("Export server configuration successfully", "匯出伺服器設定成功"), - ("Invalid server configuration", "無效的伺服器設定"), - ("Clipboard is empty", "剪貼簿是空的"), - ("Stop service", "停止服務"), - ("Change ID", "更改 ID"), - ("Your new ID", "您的新 ID"), - ("length %min% to %max%", "長度在 %min% 與 %max% 之間"), - ("starts with a letter", "以字母開頭"), - ("allowed characters", "使用允許的字元"), - ("id_change_tip", "僅能使用以下字元:a-z、A-Z、0-9、_ (底線)。首字元必須為 a-z 或 A-Z。長度介於 6 到 16 之間。"), - ("Website", "網站"), - ("About", "關於"), - ("Slogan_tip", ""), - ("Privacy Statement", "隱私權聲明"), - ("Mute", "靜音"), - ("Build Date", "構建日期"), - ("Version", "版本"), - ("Home", "首頁"), - ("Audio Input", "音訊輸入"), - ("Enhancements", "增強功能"), - ("Hardware Codec", "硬體編解碼器"), - ("Adaptive Bitrate", "自適應位元速率"), - ("ID Server", "ID 伺服器"), - ("Relay Server", "轉送伺服器"), - ("API Server", "API 伺服器"), - ("invalid_http", "開頭必須為 http:// 或 https://"), - ("Invalid IP", "IP 無效"), - ("Invalid format", "格式無效"), - ("server_not_support", "伺服器暫不支持"), - ("Not available", "無法使用"), - ("Too frequent", "修改過於頻繁,請稍後再試。"), - ("Cancel", "取消"), - ("Skip", "跳過"), - ("Close", "關閉"), - ("Retry", "重試"), - ("OK", "確定"), - ("Password Required", "需要密碼"), - ("Please enter your password", "請輸入您的密碼"), - ("Remember password", "記住密碼"), - ("Wrong Password", "密碼錯誤"), - ("Do you want to enter again?", "您要重新輸入嗎?"), - ("Connection Error", "連線錯誤"), - ("Error", "錯誤"), - ("Reset by the peer", "對方重設了連線"), - ("Connecting...", "正在連線 ..."), - ("Connection in progress. Please wait.", "正在連線,請稍候。"), - ("Please try 1 minute later", "請於 1 分鐘後再試"), - ("Login Error", "登入錯誤"), - ("Successful", "成功"), - ("Connected, waiting for image...", "已連線,等待畫面傳輸 ..."), - ("Name", "名稱"), - ("Type", "類型"), - ("Modified", "修改時間"), - ("Size", "大小"), - ("Show Hidden Files", "顯示隱藏檔案"), - ("Receive", "接收"), - ("Send", "傳送"), - ("Refresh File", "重新整理檔案"), - ("Local", "本地"), - ("Remote", "遠端"), - ("Remote Computer", "遠端電腦"), - ("Local Computer", "本地電腦"), - ("Confirm Delete", "確認刪除"), - ("Delete", "刪除"), - ("Properties", "屬性"), - ("Multi Select", "多選"), - ("Select All", "全選"), - ("Unselect All", "取消全選"), - ("Empty Directory", "空資料夾"), - ("Not an empty directory", "不是一個空資料夾"), - ("Are you sure you want to delete this file?", "您確定要刪除此檔案嗎?"), - ("Are you sure you want to delete this empty directory?", "您確定要刪除此空資料夾嗎?"), - ("Are you sure you want to delete the file of this directory?", "您確定要刪除此資料夾中的檔案嗎?"), - ("Do this for all conflicts", "套用到其他衝突"), - ("This is irreversible!", "此操作不可逆!"), - ("Deleting", "正在刪除 ..."), - ("files", "檔案"), - ("Waiting", "正在等候 ..."), - ("Finished", "已完成"), - ("Speed", "速度"), - ("Custom Image Quality", "自訂畫面品質"), - ("Privacy mode", "隱私模式"), - ("Block user input", "封鎖使用者輸入"), - ("Unblock user input", "取消封鎖使用者輸入"), - ("Adjust Window", "調整視窗"), - ("Original", "原始"), - ("Shrink", "縮減"), - ("Stretch", "延展"), - ("Scrollbar", "滾動條"), - ("ScrollAuto", "自動滾動"), - ("Good image quality", "最佳化畫面品質"), - ("Balanced", "平衡"), - ("Optimize reaction time", "最佳化反應時間"), - ("Custom", "自訂"), - ("Show remote cursor", "顯示遠端游標"), - ("Show quality monitor", "顯示質量監測"), - ("Disable clipboard", "停用剪貼簿"), - ("Lock after session end", "工作階段結束後鎖定電腦"), - ("Insert", "插入"), - ("Insert Lock", "鎖定遠端電腦"), - ("Refresh", "重新載入"), - ("ID does not exist", "ID 不存在"), - ("Failed to connect to rendezvous server", "無法連線到 rendezvous 伺服器"), - ("Please try later", "請稍候再試"), - ("Remote desktop is offline", "遠端桌面已離線"), - ("Key mismatch", "金鑰不符"), - ("Timeout", "逾時"), - ("Failed to connect to relay server", "無法連線到轉送伺服器"), - ("Failed to connect via rendezvous server", "無法透過 rendezvous 伺服器連線"), - ("Failed to connect via relay server", "無法透過轉送伺服器連線"), - ("Failed to make direct connection to remote desktop", "無法直接連線到遠端桌面"), - ("Set Password", "設定密碼"), - ("OS Password", "作業系統密碼"), - ("install_tip", "UAC 會導致 RustDesk 在某些情況下無法正常以遠端電腦執行。若要避開 UAC,請點擊下方按鈕將 RustDesk 安裝到系統中。"), - ("Click to upgrade", "點擊以升級"), - ("Click to download", "點擊以下載"), - ("Click to update", "點擊以更新"), - ("Configure", "設定"), - ("config_acc", "您需要授予 RustDesk「協助工具」權限才能存取遠端電腦。"), - ("config_screen", "您需要授予 RustDesk「畫面錄製」權限才能存取遠端電腦。"), - ("Installing ...", "正在安裝 ..."), - ("Install", "安裝"), - ("Installation", "安裝"), - ("Installation Path", "安裝路徑"), - ("Create start menu shortcuts", "新增開始功能表捷徑"), - ("Create desktop icon", "新增桌面捷徑"), - ("agreement_tip", "開始安裝即表示接受許可協議"), - ("Accept and Install", "接受並安裝"), - ("End-user license agreement", "使用者授權合約"), - ("Generating ...", "正在產生 ..."), - ("Your installation is lower version.", "您安裝的版本過舊。"), - ("not_close_tcp_tip", "使用通道時請不要關閉此視窗"), - ("Listening ...", "正在等待通道連線 ..."), - ("Remote Host", "遠端主機"), - ("Remote Port", "遠端連線端口"), - ("Action", "操作"), - ("Add", "新增"), - ("Local Port", "本機連線端口"), - ("Local Address", "本機地址"), - ("Change Local Port", "修改本機連線端口"), - ("setup_server_tip", "若您需要更快的連線速度,可以選擇自行建立伺服器"), - ("Too short, at least 6 characters.", "過短,至少需要 6 個字元。"), - ("The confirmation is not identical.", "兩次輸入不相符"), - ("Permissions", "權限"), - ("Accept", "接受"), - ("Dismiss", "關閉"), - ("Disconnect", "中斷連線"), - ("Allow using keyboard and mouse", "允許使用鍵盤和滑鼠"), - ("Allow using clipboard", "允許使用剪貼簿"), - ("Allow hearing sound", "允許分享音訊"), - ("Allow file copy and paste", "允許檔案複製和貼上"), - ("Connected", "已連線"), - ("Direct and encrypted connection", "加密直接連線"), - ("Relayed and encrypted connection", "加密轉送連線"), - ("Direct and unencrypted connection", "未加密直接連線"), - ("Relayed and unencrypted connection", "未加密轉送連線"), - ("Enter Remote ID", "輸入遠端 ID"), - ("Enter your password", "輸入您的密碼"), - ("Logging in...", "正在登入 ..."), - ("Enable RDP session sharing", "啟用 RDP 工作階段共享"), - ("Auto Login", "自動登入 (鎖定將在設定關閉後套用)"), - ("Enable Direct IP Access", "允許 IP 直接存取"), - ("Rename", "重新命名"), - ("Space", "空白"), - ("Create Desktop Shortcut", "新增桌面捷徑"), - ("Change Path", "更改路徑"), - ("Create Folder", "新增資料夾"), - ("Please enter the folder name", "請輸入資料夾名稱"), - ("Fix it", "修復"), - ("Warning", "警告"), - ("Login screen using Wayland is not supported", "不支援使用 Wayland 的登入畫面"), - ("Reboot required", "需要重新啟動"), - ("Unsupported display server", "不支援顯示伺服器"), - ("x11 expected", "預期 x11"), - ("Port", "端口"), - ("Settings", "設定"), - ("Username", "使用者名稱"), - ("Invalid port", "連線端口無效"), - ("Closed manually by the peer", "遠端使用者關閉了工作階段"), - ("Enable remote configuration modification", "允許遠端使用者更改設定"), - ("Run without install", "跳過安裝直接執行"), - ("Connect via relay", "中繼連線"), - ("Always connect via relay", "一律透過轉送連線"), - ("whitelist_tip", "只有白名單中的 IP 可以存取"), - ("Login", "登入"), - ("Verify", "驗證"), - ("Remember me", "記住我"), - ("Trust this device", "信任此裝置"), - ("Verification code", "驗證碼"), - ("verification_tip", "檢測到新裝置登入,已向註冊電子信箱發送了登入驗證碼,請輸入驗證碼以繼續登入"), - ("Logout", "登出"), - ("Tags", "標籤"), - ("Search ID", "搜尋 ID"), - ("whitelist_sep", "使用逗號、分號、空白,或是換行來分隔"), - ("Add ID", "新增 ID"), - ("Add Tag", "新增標籤"), - ("Unselect all tags", "取消選取所有標籤"), - ("Network error", "網路錯誤"), - ("Username missed", "缺少使用者名稱"), - ("Password missed", "缺少密碼"), - ("Wrong credentials", "提供的登入資訊有誤"), - ("Edit Tag", "編輯標籤"), - ("Unremember Password", "忘掉密碼"), - ("Favorites", "我的最愛"), - ("Add to Favorites", "新增到我的最愛"), - ("Remove from Favorites", "從我的最愛中刪除"), - ("Empty", "空空如也"), - ("Invalid folder name", "資料夾名稱無效"), - ("Socks5 Proxy", "Socks5 代理"), - ("Hostname", "主機名稱"), - ("Discovered", "已探索"), - ("install_daemon_tip", "為了能夠開機時自動啟動,請先安裝系統服務。"), - ("Remote ID", "遠端 ID"), - ("Paste", "貼上"), - ("Paste here?", "貼上到這裡?"), - ("Are you sure to close the connection?", "您確定要關閉連線嗎?"), - ("Download new version", "下載新版本"), - ("Touch mode", "觸控模式"), - ("Mouse mode", "滑鼠模式"), - ("One-Finger Tap", "單指輕觸"), - ("Left Mouse", "滑鼠左鍵"), - ("One-Long Tap", "單指長按"), - ("Two-Finger Tap", "雙指輕觸"), - ("Right Mouse", "滑鼠右鍵"), - ("One-Finger Move", "單指移動"), - ("Double Tap & Move", "雙擊並移動"), - ("Mouse Drag", "滑鼠選中拖動"), - ("Three-Finger vertically", "三指垂直滑動"), - ("Mouse Wheel", "滑鼠滾輪"), - ("Two-Finger Move", "雙指移動"), - ("Canvas Move", "移動畫布"), - ("Pinch to Zoom", "雙指縮放"), - ("Canvas Zoom", "縮放畫布"), - ("Reset canvas", "重設畫布"), - ("No permission of file transfer", "沒有檔案傳輸權限"), - ("Note", "備註"), - ("Connection", "連線"), - ("Share Screen", "共享螢幕畫面"), - ("Chat", "聊天訊息"), - ("Total", "總計"), - ("items", "個項目"), - ("Selected", "已選擇"), - ("Screen Capture", "畫面錄製"), - ("Input Control", "輸入控制"), - ("Audio Capture", "音訊錄製"), - ("File Connection", "檔案連線"), - ("Screen Connection", "畫面連線"), - ("Do you accept?", "是否接受?"), - ("Open System Setting", "開啟系統設定"), - ("How to get Android input permission?", "如何獲取 Android 的輸入權限?"), - ("android_input_permission_tip1", "取得輸入權限後可以讓遠端裝置透過滑鼠控制此 Android 裝置"), - ("android_input_permission_tip2", "請在接下來的系統設定頁面中,找到並進入「已安裝的服務」頁面,並將「RustDesk Input」服務開啟"), - ("android_new_connection_tip", "收到新的連線控制請求,對方想要控制您目前的裝置"), - ("android_service_will_start_tip", "開啟畫面錄製權限將自動開啟服務,允許其他裝置向此裝置請求建立連線。"), - ("android_stop_service_tip", "關閉服務將自動關閉所有已建立的連線。"), - ("android_version_audio_tip", "目前的 Android 版本不支援音訊錄製,請升級到 Android 10 或以上版本。"), - ("android_start_service_tip", "點擊「啟動服務」或啟用「螢幕錄製」權限,以啟動螢幕共享服務。"), - ("android_permission_may_not_change_tip", "對於已經建立的連線,權限可能不會立即發生改變,除非重新建立連線。"), - ("Account", "帳號"), - ("Overwrite", "取代"), - ("This file exists, skip or overwrite this file?", "此檔案/資料夾已存在,要略過或是取代此檔案嗎?"), - ("Quit", "退出"), - ("doc_mac_permission", "https://rustdesk.com/docs/zh-tw/manual/mac/#啟用權限"), - ("Help", "幫助"), - ("Failed", "失敗"), - ("Succeeded", "成功"), - ("Someone turns on privacy mode, exit", "其他使用者開啟隱私模式,退出"), - ("Unsupported", "不支援"), - ("Peer denied", "被控端拒絕"), - ("Please install plugins", "請安裝插件"), - ("Peer exit", "被控端退出"), - ("Failed to turn off", "退出失敗"), - ("Turned off", "退出"), - ("In privacy mode", "開啟隱私模式"), - ("Out privacy mode", "退出隱私模式"), - ("Language", "語言"), - ("Keep RustDesk background service", "保持 RustDesk 後台服務"), - ("Ignore Battery Optimizations", "忽略電池最佳化"), - ("android_open_battery_optimizations_tip", "如需關閉此功能,請在接下來的 RustDesk 應用設定頁面中,找到並進入 [電源] 頁面,取消勾選 [不受限制]"), - ("Start on Boot", "開機自動啟動"), - ("Start the screen sharing service on boot, requires special permissions", "開機自動啟動螢幕共享服務,此功能需要一些特殊權限。"), - ("Connection not allowed", "對方不允許連線"), - ("Legacy mode", "傳統模式"), - ("Map mode", "1:1 傳輸模式"), - ("Translate mode", "翻譯模式"), - ("Use permanent password", "使用固定密碼"), - ("Use both passwords", "同時使用兩種密碼"), - ("Set permanent password", "設定固定密碼"), - ("Enable Remote Restart", "啟用遠端重新啟動"), - ("Allow remote restart", "允許遠端重新啟動"), - ("Restart Remote Device", "重新啟動遠端電腦"), - ("Are you sure you want to restart", "確定要重新啟動"), - ("Restarting Remote Device", "正在重新啟動遠端裝置"), - ("remote_restarting_tip", "遠端裝置正在重新啟動,請關閉當前提示框,並在一段時間後使用永久密碼重新連線"), - ("Copied", "已複製"), - ("Exit Fullscreen", "退出全螢幕"), - ("Fullscreen", "全螢幕"), - ("Mobile Actions", "手機操作"), - ("Select Monitor", "選擇顯示器"), - ("Control Actions", "控制操作"), - ("Display Settings", "顯示設定"), - ("Ratio", "比例"), - ("Image Quality", "畫質"), - ("Scroll Style", "滾動樣式"), - ("Show Menubar", "顯示選單欄"), - ("Hide Menubar", "隱藏選單欄"), - ("Direct Connection", "直接連線"), - ("Relay Connection", "中繼連線"), - ("Secure Connection", "安全連線"), - ("Insecure Connection", "非安全連線"), - ("Scale original", "原始尺寸"), - ("Scale adaptive", "適應視窗"), - ("General", "通用"), - ("Security", "安全"), - ("Theme", "主題"), - ("Dark Theme", "黑暗主題"), - ("Light Theme", "明亮主題"), - ("Dark", "黑暗"), - ("Light", "明亮"), - ("Follow System", "跟隨系統"), - ("Enable hardware codec", "使用硬體編解碼器"), - ("Unlock Security Settings", "解鎖安全設定"), - ("Enable Audio", "允許傳輸音訊"), - ("Unlock Network Settings", "解鎖網路設定"), - ("Server", "伺服器"), - ("Direct IP Access", "IP 直接連線"), - ("Proxy", "代理"), - ("Apply", "應用"), - ("Disconnect all devices?", "中斷所有遠端連線?"), - ("Clear", "清空"), - ("Audio Input Device", "音訊輸入裝置"), - ("Deny remote access", "拒絕遠端存取"), - ("Use IP Whitelisting", "只允許白名單上的 IP 進行連線"), - ("Network", "網路"), - ("Enable RDP", "允許 RDP 訪問"), - ("Pin menubar", "固定選單欄"), - ("Unpin menubar", "取消固定選單欄"), - ("Recording", "錄製"), - ("Directory", "路徑"), - ("Automatically record incoming sessions", "自動錄製連入的工作階段"), - ("Change", "變更"), - ("Start session recording", "開始錄影"), - ("Stop session recording", "停止錄影"), - ("Enable Recording Session", "啟用錄製工作階段"), - ("Allow recording session", "允許錄製工作階段"), - ("Enable LAN Discovery", "允許區域網路探索"), - ("Deny LAN Discovery", "拒絕區域網路探索"), - ("Write a message", "輸入聊天訊息"), - ("Prompt", "提示"), - ("Please wait for confirmation of UAC...", "請等待對方確認 UAC ..."), - ("elevated_foreground_window_tip", "目前的遠端桌面視窗需要更高的權限才能繼續操作,暫時無法使用滑鼠、鍵盤,可以請求對方最小化目前視窗,或者在連線管理視窗點擊提升權限。為了避免這個問題,建議在遠端裝置上安裝本軟體。"), - ("Disconnected", "斷開連線"), - ("Other", "其他"), - ("Confirm before closing multiple tabs", "關閉多個分頁前詢問我"), - ("Keyboard Settings", "鍵盤設定"), - ("Full Access", "完全訪問"), - ("Screen Share", "僅分享螢幕畫面"), - ("Wayland requires Ubuntu 21.04 or higher version.", "Wayland 需要 Ubuntu 21.04 或更高版本。"), - ("Wayland requires higher version of linux distro. Please try X11 desktop or change your OS.", "Wayland 需要更高版本的 Linux 發行版。請嘗試使用 X11 桌面或更改您的作業系統。"), - ("JumpLink", "查看"), - ("Please Select the screen to be shared(Operate on the peer side).", "請選擇要分享的螢幕畫面(在對端操作)。"), - ("Show RustDesk", "顯示 RustDesk"), - ("This PC", "此電腦"), - ("or", "或"), - ("Continue with", "繼續"), - ("Elevate", "提升權限"), - ("Zoom cursor", "縮放游標"), - ("Accept sessions via password", "只允許透過輸入密碼進行連線"), - ("Accept sessions via click", "只允許透過點擊接受進行連線"), - ("Accept sessions via both", "允許輸入密碼或點擊接受進行連線"), - ("Please wait for the remote side to accept your session request...", "請等待對方接受您的連線請求 ..."), - ("One-time Password", "一次性密碼"), - ("Use one-time password", "使用一次性密碼"), - ("One-time password length", "一次性密碼長度"), - ("Request access to your device", "請求訪問您的裝置"), - ("Hide connection management window", "隱藏連線管理視窗"), - ("hide_cm_tip", "在只允許密碼連線並且只用固定密碼的情況下才允許隱藏"), - ("wayland_experiment_tip", "Wayland 支援處於實驗階段,如果您需要使用無人值守訪問,請使用 X11。"), - ("Right click to select tabs", "右鍵選擇分頁"), - ("Skipped", "已略過"), - ("Add to Address Book", "新增到通訊錄"), - ("Group", "群組"), - ("Search", "搜尋"), - ("Closed manually by web console", "被 Web 控制台手動關閉"), - ("Local keyboard type", "本地鍵盤類型"), - ("Select local keyboard type", "請選擇本地鍵盤類型"), - ("software_render_tip", "如果您使用 NVIDIA 顯示卡,並且遠端視窗在建立連線後會立刻關閉,那麼請安裝 nouveau 顯示卡驅動程式並且選擇使用軟體渲染可能會有幫助。重新啟動軟體後生效。"), - ("Always use software rendering", "使用軟體渲染"), - ("config_input", "為了能夠透過鍵盤控制遠端桌面,請給予 RustDesk \"輸入監控\" 權限。"), - ("config_microphone", "為了支援透過麥克風進行音訊傳輸,請給予 RustDesk \"錄音\"權限。"), - ("request_elevation_tip", "如果遠端使用者可以操作電腦,也可以請求提升權限。"), - ("Wait", "等待"), - ("Elevation Error", "權限提升失敗"), - ("Ask the remote user for authentication", "請求遠端使用者進行身分驗證"), - ("Choose this if the remote account is administrator", "當遠端使用者帳戶是管理員時,請選擇此選項"), - ("Transmit the username and password of administrator", "發送管理員的使用者名稱和密碼"), - ("still_click_uac_tip", "依然需要遠端使用者在 UAC 視窗點擊確認。"), - ("Request Elevation", "請求權限提升"), - ("wait_accept_uac_tip", "請等待遠端使用者確認 UAC 對話框。"), - ("Elevate successfully", "權限提升成功"), - ("uppercase", "大寫字母"), - ("lowercase", "小寫字母"), - ("digit", "數字"), - ("special character", "特殊字元"), - ("length>=8", "長度不能小於 8"), - ("Weak", "弱"), - ("Medium", "中"), - ("Strong", "強"), - ("Switch Sides", "反轉存取方向"), - ("Please confirm if you want to share your desktop?", "請確認是否要讓對方存取您的桌面?"), - ("Display", "顯示"), - ("Default View Style", "預設顯示方式"), - ("Default Scroll Style", "預設滾動方式"), - ("Default Image Quality", "預設圖像質量"), - ("Default Codec", "預設編解碼器"), - ("Bitrate", "位元速率"), - ("FPS", "幀率"), - ("Auto", "自動"), - ("Other Default Options", "其他預設選項"), - ("Voice call", "語音通話"), - ("Text chat", "文字聊天"), - ("Stop voice call", "停止語音通話"), - ("relay_hint_tip", "可能無法直接連線,可以嘗試中繼連線。\n另外,如果想要直接使用中繼連線,可以在 ID 後面新增/r,或者在卡片選項裡選擇強制走中繼連線。"), - ("Reconnect", "重新連線"), - ("Codec", "編解碼器"), - ("Resolution", "解析度"), - ("No transfers in progress", "沒有正在進行的傳輸"), - ("Set one-time password length", "設定一次性密碼長度"), - ("idd_driver_tip", "安裝虛擬顯示器驅動程式,以便在沒有連接顯示器的情況下啟動虛擬顯示器進行控制。"), - ("confirm_idd_driver_tip", "安裝虛擬顯示器驅動程式的選項已勾選。請注意,測試證書將被安裝以信任虛擬顯示器驅動。測試證書僅會用於信任 RustDesk 的驅動程式。"), - ("RDP Settings", "RDP 設定"), - ("Sort by", "排序方式"), - ("New Connection", "新連線"), - ("Restore", "還原"), - ("Minimize", "最小化"), - ("Maximize", "最大化"), - ("Your Device", "您的裝置"), - ("empty_recent_tip", "空空如也"), - ("empty_favorite_tip", "空空如也"), - ("empty_lan_tip", "空空如也"), - ("empty_address_book_tip", "空空如也"), - ("eg: admin", "例如:admin"), - ("Empty Username", "空使用者帳號"), - ("Empty Password", "空密碼"), - ("Me", "我"), - ("identical_file_tip", "此檔案與對方的檔案一致"), - ("show_monitors_tip", "在工具列中顯示顯示器"), - ("View Mode", "瀏覽模式"), - ("enter_rustdesk_passwd_tip", "輸入 RustDesk 密碼"), - ("remember_rustdesk_passwd_tip", "記住 RustDesk 密碼"), - ("login_linux_tip", "登入到遠端 Linux 使用者帳戶"), - ("login_linux_tooltip_tip", "需要登入到遠端 Linux 使用者帳戶才能啟用 X 介面。"), - ].iter().cloned().collect(); -} +lazy_static::lazy_static! { +pub static ref T: std::collections::HashMap<&'static str, &'static str> = + [ + ("Status", "狀態"), + ("Your Desktop", "您的桌面"), + ("desk_tip", "您可以透過此 ID 及密碼存取您的桌面"), + ("Password", "密碼"), + ("Ready", "就緒"), + ("Established", "已建立"), + ("connecting_status", "正在連線到 RustDesk 網路 ..."), + ("Enable Service", "啟用服務"), + ("Start Service", "啟動服務"), + ("Service is running", "服務正在執行"), + ("Service is not running", "服務尚未執行"), + ("not_ready_status", "尚未就緒,請檢查您的網路連線。"), + ("Control Remote Desktop", "控制遠端桌面"), + ("Transfer File", "傳輸檔案"), + ("Connect", "連線"), + ("Recent Sessions", "近期的工作階段"), + ("Address Book", "通訊錄"), + ("Confirmation", "確認"), + ("TCP Tunneling", "TCP 通道"), + ("Remove", "移除"), + ("Refresh random password", "重新產生隨機密碼"), + ("Set your own password", "自行設定密碼"), + ("Enable Keyboard/Mouse", "啟用鍵盤和滑鼠"), + ("Enable Clipboard", "啟用剪貼簿"), + ("Enable File Transfer", "啟用檔案傳輸"), + ("Enable TCP Tunneling", "啟用 TCP 通道"), + ("IP Whitelisting", "IP 白名單"), + ("ID/Relay Server", "ID / 轉送伺服器"), + ("Import Server Config", "匯入伺服器設定"), + ("Export Server Config", "匯出伺服器設定"), + ("Import server configuration successfully", "匯入伺服器設定成功"), + ("Export server configuration successfully", "匯出伺服器設定成功"), + ("Invalid server configuration", "無效的伺服器設定"), + ("Clipboard is empty", "剪貼簿是空的"), + ("Stop service", "停止服務"), + ("Change ID", "更改 ID"), + ("Your new ID", "您的新 ID"), + ("length %min% to %max%", "長度在 %min% 與 %max% 之間"), + ("starts with a letter", "以字母開頭"), + ("allowed characters", "使用允許的字元"), + ("id_change_tip", "僅能使用以下字元:a-z、A-Z、0-9、_ (底線)。首字元必須為 a-z 或 A-Z。長度介於 6 到 16 之間。"), + ("Website", "網站"), + ("About", "關於"), + ("Slogan_tip", ""), + ("Privacy Statement", "隱私權聲明"), + ("Mute", "靜音"), + ("Build Date", "構建日期"), + ("Version", "版本"), + ("Home", "首頁"), + ("Audio Input", "音訊輸入"), + ("Enhancements", "增強功能"), + ("Hardware Codec", "硬體編解碼器"), + ("Adaptive Bitrate", "自適應位元速率"), + ("ID Server", "ID 伺服器"), + ("Relay Server", "轉送伺服器"), + ("API Server", "API 伺服器"), + ("invalid_http", "開頭必須為 http:// 或 https://"), + ("Invalid IP", "IP 無效"), + ("Invalid format", "格式無效"), + ("server_not_support", "伺服器暫不支持"), + ("Not available", "無法使用"), + ("Too frequent", "修改過於頻繁,請稍後再試。"), + ("Cancel", "取消"), + ("Skip", "跳過"), + ("Close", "關閉"), + ("Retry", "重試"), + ("OK", "確定"), + ("remember_password_tip", "需要密碼"), + ("Please enter your password", "請輸入您的密碼"), + ("Remember password", "記住密碼"), + ("Wrong Password", "密碼錯誤"), + ("Do you want to enter again?", "您要重新輸入嗎?"), + ("Connection Error", "連線錯誤"), + ("Error", "錯誤"), + ("Reset by the peer", "對方重設了連線"), + ("Connecting...", "正在連線 ..."), + ("Connection in progress. Please wait.", "正在連線,請稍候。"), + ("Please try 1 minute later", "請於 1 分鐘後再試"), + ("Login Error", "登入錯誤"), + ("Successful", "成功"), + ("Connected, waiting for image...", "已連線,等待畫面傳輸 ..."), + ("Name", "名稱"), + ("Type", "類型"), + ("Modified", "修改時間"), + ("Size", "大小"), + ("Show Hidden Files", "顯示隱藏檔案"), + ("Receive", "接收"), + ("Send", "傳送"), + ("Refresh File", "重新整理檔案"), + ("Local", "本地"), + ("Remote", "遠端"), + ("Remote Computer", "遠端電腦"), + ("Local Computer", "本地電腦"), + ("Confirm Delete", "確認刪除"), + ("Delete", "刪除"), + ("Properties", "屬性"), + ("Multi Select", "多選"), + ("Select All", "全選"), + ("Unselect All", "取消全選"), + ("Empty Directory", "空資料夾"), + ("Not an empty directory", "不是一個空資料夾"), + ("Are you sure you want to delete this file?", "您確定要刪除此檔案嗎?"), + ("Are you sure you want to delete this empty directory?", "您確定要刪除此空資料夾嗎?"), + ("Are you sure you want to delete the file of this directory?", "您確定要刪除此資料夾中的檔案嗎?"), + ("Do this for all conflicts", "套用到其他衝突"), + ("This is irreversible!", "此操作不可逆!"), + ("Deleting", "正在刪除 ..."), + ("files", "檔案"), + ("Waiting", "正在等候 ..."), + ("Finished", "已完成"), + ("Speed", "速度"), + ("Custom Image Quality", "自訂畫面品質"), + ("Privacy mode", "隱私模式"), + ("Block user input", "封鎖使用者輸入"), + ("Unblock user input", "取消封鎖使用者輸入"), + ("Adjust Window", "調整視窗"), + ("Original", "原始"), + ("Shrink", "縮減"), + ("Stretch", "延展"), + ("Scrollbar", "滾動條"), + ("ScrollAuto", "自動滾動"), + ("Good image quality", "最佳化畫面品質"), + ("Balanced", "平衡"), + ("Optimize reaction time", "最佳化反應時間"), + ("Custom", "自訂"), + ("Show remote cursor", "顯示遠端游標"), + ("Show quality monitor", "顯示質量監測"), + ("Disable clipboard", "停用剪貼簿"), + ("Lock after session end", "工作階段結束後鎖定電腦"), + ("Insert", "插入"), + ("Insert Lock", "鎖定遠端電腦"), + ("Refresh", "重新載入"), + ("ID does not exist", "ID 不存在"), + ("Failed to connect to rendezvous server", "無法連線到 rendezvous 伺服器"), + ("Please try later", "請稍候再試"), + ("Remote desktop is offline", "遠端桌面已離線"), + ("Key mismatch", "金鑰不符"), + ("Timeout", "逾時"), + ("Failed to connect to relay server", "無法連線到轉送伺服器"), + ("Failed to connect via rendezvous server", "無法透過 rendezvous 伺服器連線"), + ("Failed to connect via relay server", "無法透過轉送伺服器連線"), + ("Failed to make direct connection to remote desktop", "無法直接連線到遠端桌面"), + ("Set Password", "設定密碼"), + ("OS Password", "作業系統密碼"), + ("install_tip", "UAC 會導致 RustDesk 在某些情況下無法正常以遠端電腦執行。若要避開 UAC,請點擊下方按鈕將 RustDesk 安裝到系統中。"), + ("Click to upgrade", "點擊以升級"), + ("Click to download", "點擊以下載"), + ("Click to update", "點擊以更新"), + ("Configure", "設定"), + ("config_acc", "您需要授予 RustDesk「協助工具」權限才能存取遠端電腦。"), + ("config_screen", "您需要授予 RustDesk「畫面錄製」權限才能存取遠端電腦。"), + ("Installing ...", "正在安裝 ..."), + ("Install", "安裝"), + ("Installation", "安裝"), + ("Installation Path", "安裝路徑"), + ("Create start menu shortcuts", "新增開始功能表捷徑"), + ("Create desktop icon", "新增桌面捷徑"), + ("agreement_tip", "開始安裝即表示接受許可協議"), + ("Accept and Install", "接受並安裝"), + ("End-user license agreement", "使用者授權合約"), + ("Generating ...", "正在產生 ..."), + ("Your installation is lower version.", "您安裝的版本過舊。"), + ("not_close_tcp_tip", "使用通道時請不要關閉此視窗"), + ("Listening ...", "正在等待通道連線 ..."), + ("Remote Host", "遠端主機"), + ("Remote Port", "遠端連線端口"), + ("Action", "操作"), + ("Add", "新增"), + ("Local Port", "本機連線端口"), + ("Local Address", "本機地址"), + ("Change Local Port", "修改本機連線端口"), + ("setup_server_tip", "若您需要更快的連線速度,可以選擇自行建立伺服器"), + ("Too short, at least 6 characters.", "過短,至少需要 6 個字元。"), + ("The confirmation is not identical.", "兩次輸入不相符"), + ("Permissions", "權限"), + ("Accept", "接受"), + ("Dismiss", "關閉"), + ("Disconnect", "中斷連線"), + ("Allow using keyboard and mouse", "允許使用鍵盤和滑鼠"), + ("Allow using clipboard", "允許使用剪貼簿"), + ("Allow hearing sound", "允許分享音訊"), + ("Allow file copy and paste", "允許檔案複製和貼上"), + ("Connected", "已連線"), + ("Direct and encrypted connection", "加密直接連線"), + ("Relayed and encrypted connection", "加密轉送連線"), + ("Direct and unencrypted connection", "未加密直接連線"), + ("Relayed and unencrypted connection", "未加密轉送連線"), + ("Enter Remote ID", "輸入遠端 ID"), + ("Enter your password", "輸入您的密碼"), + ("Logging in...", "正在登入 ..."), + ("Enable RDP session sharing", "啟用 RDP 工作階段共享"), + ("Auto Login", "自動登入 (鎖定將在設定關閉後套用)"), + ("Enable Direct IP Access", "允許 IP 直接存取"), + ("Rename", "重新命名"), + ("Space", "空白"), + ("Create Desktop Shortcut", "新增桌面捷徑"), + ("Change Path", "更改路徑"), + ("Create Folder", "新增資料夾"), + ("Please enter the folder name", "請輸入資料夾名稱"), + ("Fix it", "修復"), + ("Warning", "警告"), + ("Login screen using Wayland is not supported", "不支援使用 Wayland 的登入畫面"), + ("Reboot required", "需要重新啟動"), + ("Unsupported display server", "不支援顯示伺服器"), + ("x11 expected", "預期 x11"), + ("Port", "端口"), + ("Settings", "設定"), + ("Username", "使用者名稱"), + ("Invalid port", "連線端口無效"), + ("Closed manually by the peer", "遠端使用者關閉了工作階段"), + ("Enable remote configuration modification", "允許遠端使用者更改設定"), + ("Run without install", "跳過安裝直接執行"), + ("Connect via relay", "中繼連線"), + ("Always connect via relay", "一律透過轉送連線"), + ("whitelist_tip", "只有白名單中的 IP 可以存取"), + ("Login", "登入"), + ("Verify", "驗證"), + ("Remember me", "記住我"), + ("Trust this device", "信任此裝置"), + ("Verification code", "驗證碼"), + ("verification_tip", "檢測到新裝置登入,已向註冊電子信箱發送了登入驗證碼,請輸入驗證碼以繼續登入"), + ("Logout", "登出"), + ("Tags", "標籤"), + ("Search ID", "搜尋 ID"), + ("whitelist_sep", "使用逗號、分號、空白,或是換行來分隔"), + ("Add ID", "新增 ID"), + ("Add Tag", "新增標籤"), + ("Unselect all tags", "取消選取所有標籤"), + ("Network error", "網路錯誤"), + ("Username missed", "缺少使用者名稱"), + ("Password missed", "缺少密碼"), + ("Wrong credentials", "提供的登入資訊有誤"), + ("Edit Tag", "編輯標籤"), + ("Unremember Password", "忘掉密碼"), + ("Favorites", "我的最愛"), + ("Add to Favorites", "新增到我的最愛"), + ("Remove from Favorites", "從我的最愛中刪除"), + ("Empty", "空空如也"), + ("Invalid folder name", "資料夾名稱無效"), + ("Socks5 Proxy", "Socks5 代理"), + ("Hostname", "主機名稱"), + ("Discovered", "已探索"), + ("install_daemon_tip", "為了能夠開機時自動啟動,請先安裝系統服務。"), + ("Remote ID", "遠端 ID"), + ("Paste", "貼上"), + ("Paste here?", "貼上到這裡?"), + ("Are you sure to close the connection?", "您確定要關閉連線嗎?"), + ("Download new version", "下載新版本"), + ("Touch mode", "觸控模式"), + ("Mouse mode", "滑鼠模式"), + ("One-Finger Tap", "單指輕觸"), + ("Left Mouse", "滑鼠左鍵"), + ("One-Long Tap", "單指長按"), + ("Two-Finger Tap", "雙指輕觸"), + ("Right Mouse", "滑鼠右鍵"), + ("One-Finger Move", "單指移動"), + ("Double Tap & Move", "雙擊並移動"), + ("Mouse Drag", "滑鼠選中拖動"), + ("Three-Finger vertically", "三指垂直滑動"), + ("Mouse Wheel", "滑鼠滾輪"), + ("Two-Finger Move", "雙指移動"), + ("Canvas Move", "移動畫布"), + ("Pinch to Zoom", "雙指縮放"), + ("Canvas Zoom", "縮放畫布"), + ("Reset canvas", "重設畫布"), + ("No permission of file transfer", "沒有檔案傳輸權限"), + ("Note", "備註"), + ("Connection", "連線"), + ("Share Screen", "共享螢幕畫面"), + ("Chat", "聊天訊息"), + ("Total", "總計"), + ("items", "個項目"), + ("Selected", "已選擇"), + ("Screen Capture", "畫面錄製"), + ("Input Control", "輸入控制"), + ("Audio Capture", "音訊錄製"), + ("File Connection", "檔案連線"), + ("Screen Connection", "畫面連線"), + ("Do you accept?", "是否接受?"), + ("Open System Setting", "開啟系統設定"), + ("How to get Android input permission?", "如何獲取 Android 的輸入權限?"), + ("android_input_permission_tip1", "取得輸入權限後可以讓遠端裝置透過滑鼠控制此 Android 裝置"), + ("android_input_permission_tip2", "請在接下來的系統設定頁面中,找到並進入「已安裝的服務」頁面,並將「RustDesk Input」服務開啟"), + ("android_new_connection_tip", "收到新的連線控制請求,對方想要控制您目前的裝置"), + ("android_service_will_start_tip", "開啟畫面錄製權限將自動開啟服務,允許其他裝置向此裝置請求建立連線。"), + ("android_stop_service_tip", "關閉服務將自動關閉所有已建立的連線。"), + ("android_version_audio_tip", "目前的 Android 版本不支援音訊錄製,請升級到 Android 10 或以上版本。"), + ("android_start_service_tip", "點擊「啟動服務」或啟用「螢幕錄製」權限,以啟動螢幕共享服務。"), + ("android_permission_may_not_change_tip", "對於已經建立的連線,權限可能不會立即發生改變,除非重新建立連線。"), + ("Account", "帳號"), + ("Overwrite", "取代"), + ("This file exists, skip or overwrite this file?", "此檔案/資料夾已存在,要略過或是取代此檔案嗎?"), + ("Quit", "退出"), + ("doc_mac_permission", "https://rustdesk.com/docs/zh-tw/manual/mac/#啟用權限"), + ("Help", "幫助"), + ("Failed", "失敗"), + ("Succeeded", "成功"), + ("Someone turns on privacy mode, exit", "其他使用者開啟隱私模式,退出"), + ("Unsupported", "不支援"), + ("Peer denied", "被控端拒絕"), + ("Please install plugins", "請安裝插件"), + ("Peer exit", "被控端退出"), + ("Failed to turn off", "退出失敗"), + ("Turned off", "退出"), + ("In privacy mode", "開啟隱私模式"), + ("Out privacy mode", "退出隱私模式"), + ("Language", "語言"), + ("Keep RustDesk background service", "保持 RustDesk 後台服務"), + ("Ignore Battery Optimizations", "忽略電池最佳化"), + ("android_open_battery_optimizations_tip", "如需關閉此功能,請在接下來的 RustDesk 應用設定頁面中,找到並進入 [電源] 頁面,取消勾選 [不受限制]"), + ("Start on Boot", "開機自動啟動"), + ("Start the screen sharing service on boot, requires special permissions", "開機自動啟動螢幕共享服務,此功能需要一些特殊權限。"), + ("Connection not allowed", "對方不允許連線"), + ("Legacy mode", "傳統模式"), + ("Map mode", "1:1 傳輸模式"), + ("Translate mode", "翻譯模式"), + ("Use permanent password", "使用固定密碼"), + ("Use both passwords", "同時使用兩種密碼"), + ("Set permanent password", "設定固定密碼"), + ("Enable Remote Restart", "啟用遠端重新啟動"), + ("Allow remote restart", "允許遠端重新啟動"), + ("Restart Remote Device", "重新啟動遠端電腦"), + ("Are you sure you want to restart", "確定要重新啟動"), + ("Restarting Remote Device", "正在重新啟動遠端裝置"), + ("remote_restarting_tip", "遠端裝置正在重新啟動,請關閉當前提示框,並在一段時間後使用永久密碼重新連線"), + ("Copied", "已複製"), + ("Exit Fullscreen", "退出全螢幕"), + ("Fullscreen", "全螢幕"), + ("Mobile Actions", "手機操作"), + ("Select Monitor", "選擇顯示器"), + ("Control Actions", "控制操作"), + ("Display Settings", "顯示設定"), + ("Ratio", "比例"), + ("Image Quality", "畫質"), + ("Scroll Style", "滾動樣式"), + ("Show Menubar", "顯示選單欄"), + ("Hide Menubar", "隱藏選單欄"), + ("Direct Connection", "直接連線"), + ("Relay Connection", "中繼連線"), + ("Secure Connection", "安全連線"), + ("Insecure Connection", "非安全連線"), + ("Scale original", "原始尺寸"), + ("Scale adaptive", "適應視窗"), + ("General", "通用"), + ("Security", "安全"), + ("Theme", "主題"), + ("Dark Theme", "黑暗主題"), + ("Light Theme", "明亮主題"), + ("Dark", "黑暗"), + ("Light", "明亮"), + ("Follow System", "跟隨系統"), + ("Enable hardware codec", "使用硬體編解碼器"), + ("Unlock Security Settings", "解鎖安全設定"), + ("Enable Audio", "允許傳輸音訊"), + ("Unlock Network Settings", "解鎖網路設定"), + ("Server", "伺服器"), + ("Direct IP Access", "IP 直接連線"), + ("Proxy", "代理"), + ("Apply", "應用"), + ("Disconnect all devices?", "中斷所有遠端連線?"), + ("Clear", "清空"), + ("Audio Input Device", "音訊輸入裝置"), + ("Deny remote access", "拒絕遠端存取"), + ("Use IP Whitelisting", "只允許白名單上的 IP 進行連線"), + ("Network", "網路"), + ("Enable RDP", "允許 RDP 訪問"), + ("Pin menubar", "固定選單欄"), + ("Unpin menubar", "取消固定選單欄"), + ("Recording", "錄製"), + ("Directory", "路徑"), + ("Automatically record incoming sessions", "自動錄製連入的工作階段"), + ("Change", "變更"), + ("Start session recording", "開始錄影"), + ("Stop session recording", "停止錄影"), + ("Enable Recording Session", "啟用錄製工作階段"), + ("Allow recording session", "允許錄製工作階段"), + ("Enable LAN Discovery", "允許區域網路探索"), + ("Deny LAN Discovery", "拒絕區域網路探索"), + ("Write a message", "輸入聊天訊息"), + ("Prompt", "提示"), + ("Please wait for confirmation of UAC...", "請等待對方確認 UAC ..."), + ("elevated_foreground_window_tip", "目前的遠端桌面視窗需要更高的權限才能繼續操作,暫時無法使用滑鼠、鍵盤,可以請求對方最小化目前視窗,或者在連線管理視窗點擊提升權限。為了避免這個問題,建議在遠端裝置上安裝本軟體。"), + ("Disconnected", "斷開連線"), + ("Other", "其他"), + ("Confirm before closing multiple tabs", "關閉多個分頁前詢問我"), + ("Keyboard Settings", "鍵盤設定"), + ("Full Access", "完全訪問"), + ("Screen Share", "僅分享螢幕畫面"), + ("Wayland requires Ubuntu 21.04 or higher version.", "Wayland 需要 Ubuntu 21.04 或更高版本。"), + ("Wayland requires higher version of linux distro. Please try X11 desktop or change your OS.", "Wayland 需要更高版本的 Linux 發行版。請嘗試使用 X11 桌面或更改您的作業系統。"), + ("JumpLink", "查看"), + ("Please Select the screen to be shared(Operate on the peer side).", "請選擇要分享的螢幕畫面(在對端操作)。"), + ("Show RustDesk", "顯示 RustDesk"), + ("This PC", "此電腦"), + ("or", "或"), + ("Continue with", "繼續"), + ("Elevate", "提升權限"), + ("Zoom cursor", "縮放游標"), + ("Accept sessions via password", "只允許透過輸入密碼進行連線"), + ("Accept sessions via click", "只允許透過點擊接受進行連線"), + ("Accept sessions via both", "允許輸入密碼或點擊接受進行連線"), + ("Please wait for the remote side to accept your session request...", "請等待對方接受您的連線請求 ..."), + ("One-time Password", "一次性密碼"), + ("Use one-time password", "使用一次性密碼"), + ("One-time password length", "一次性密碼長度"), + ("Request access to your device", "請求訪問您的裝置"), + ("Hide connection management window", "隱藏連線管理視窗"), + ("hide_cm_tip", "在只允許密碼連線並且只用固定密碼的情況下才允許隱藏"), + ("wayland_experiment_tip", "Wayland 支援處於實驗階段,如果您需要使用無人值守訪問,請使用 X11。"), + ("Right click to select tabs", "右鍵選擇分頁"), + ("Skipped", "已略過"), + ("Add to Address Book", "新增到通訊錄"), + ("Group", "群組"), + ("Search", "搜尋"), + ("Closed manually by web console", "被 Web 控制台手動關閉"), + ("Local keyboard type", "本地鍵盤類型"), + ("Select local keyboard type", "請選擇本地鍵盤類型"), + ("software_render_tip", "如果您使用 NVIDIA 顯示卡,並且遠端視窗在建立連線後會立刻關閉,那麼請安裝 nouveau 顯示卡驅動程式並且選擇使用軟體渲染可能會有幫助。重新啟動軟體後生效。"), + ("Always use software rendering", "使用軟體渲染"), + ("config_input", "為了能夠透過鍵盤控制遠端桌面,請給予 RustDesk \"輸入監控\" 權限。"), + ("config_microphone", "為了支援透過麥克風進行音訊傳輸,請給予 RustDesk \"錄音\"權限。"), + ("request_elevation_tip", "如果遠端使用者可以操作電腦,也可以請求提升權限。"), + ("Wait", "等待"), + ("Elevation Error", "權限提升失敗"), + ("Ask the remote user for authentication", "請求遠端使用者進行身分驗證"), + ("Choose this if the remote account is administrator", "當遠端使用者帳戶是管理員時,請選擇此選項"), + ("Transmit the username and password of administrator", "發送管理員的使用者名稱和密碼"), + ("still_click_uac_tip", "依然需要遠端使用者在 UAC 視窗點擊確認。"), + ("Request Elevation", "請求權限提升"), + ("wait_accept_uac_tip", "請等待遠端使用者確認 UAC 對話框。"), + ("Elevate successfully", "權限提升成功"), + ("uppercase", "大寫字母"), + ("lowercase", "小寫字母"), + ("digit", "數字"), + ("special character", "特殊字元"), + ("length>=8", "長度不能小於 8"), + ("Weak", "弱"), + ("Medium", "中"), + ("Strong", "強"), + ("Switch Sides", "反轉存取方向"), + ("Please confirm if you want to share your desktop?", "請確認是否要讓對方存取您的桌面?"), + ("Display", "顯示"), + ("Default View Style", "預設顯示方式"), + ("Default Scroll Style", "預設滾動方式"), + ("Default Image Quality", "預設圖像質量"), + ("Default Codec", "預設編解碼器"), + ("Bitrate", "位元速率"), + ("FPS", "幀率"), + ("Auto", "自動"), + ("Other Default Options", "其他預設選項"), + ("Voice call", "語音通話"), + ("Text chat", "文字聊天"), + ("Stop voice call", "停止語音通話"), + ("relay_hint_tip", "可能無法直接連線,可以嘗試中繼連線。\n另外,如果想要直接使用中繼連線,可以在 ID 後面新增/r,或者在卡片選項裡選擇強制走中繼連線。"), + ("Reconnect", "重新連線"), + ("Codec", "編解碼器"), + ("Resolution", "解析度"), + ("No transfers in progress", "沒有正在進行的傳輸"), + ("Set one-time password length", "設定一次性密碼長度"), + ("idd_driver_tip", "安裝虛擬顯示器驅動程式,以便在沒有連接顯示器的情況下啟動虛擬顯示器進行控制。"), + ("confirm_idd_driver_tip", "安裝虛擬顯示器驅動程式的選項已勾選。請注意,測試證書將被安裝以信任虛擬顯示器驅動。測試證書僅會用於信任 RustDesk 的驅動程式。"), + ("RDP Settings", "RDP 設定"), + ("Sort by", "排序方式"), + ("New Connection", "新連線"), + ("Restore", "還原"), + ("Minimize", "最小化"), + ("Maximize", "最大化"), + ("Your Device", "您的裝置"), + ("empty_recent_tip", "空空如也"), + ("empty_favorite_tip", "空空如也"), + ("empty_lan_tip", "空空如也"), + ("empty_address_book_tip", "空空如也"), + ("eg: admin", "例如:admin"), + ("Empty Username", "空使用者帳號"), + ("Empty Password", "空密碼"), + ("Me", "我"), + ("identical_file_tip", "此檔案與對方的檔案一致"), + ("show_monitors_tip", "在工具列中顯示顯示器"), + ("View Mode", "瀏覽模式"), + ("enter_rustdesk_passwd_tip", "輸入 RustDesk 密碼"), + ("remember_rustdesk_passwd_tip", "記住 RustDesk 密碼"), + ("login_linux_tip", "登入到遠端 Linux 使用者帳戶"), + ("login_linux_tooltip_tip", "需要登入到遠端 Linux 使用者帳戶才能啟用 X 介面。"), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), + ].iter().cloned().collect(); +} diff --git a/src/lang/ua.rs b/src/lang/ua.rs index e21cd88df..952c36b13 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Закрити"), ("Retry", "Спробувати знову"), ("OK", "ОК"), - ("Password Required", "Потрібен пароль"), + ("remember_password_tip", "Потрібен пароль"), ("Please enter your password", "Будь ласка, введіть ваш пароль"), ("Remember password", "Запам'ятати пароль"), ("Wrong Password", "Невірний пароль"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index f716bd536..ab1aa2820 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Đóng"), ("Retry", "Thử lại"), ("OK", "OK"), - ("Password Required", "Yêu cầu mật khẩu"), + ("remember_password_tip", "Yêu cầu mật khẩu"), ("Please enter your password", "Mời nhập mật khẩu"), ("Remember password", "Nhớ mật khẩu"), ("Wrong Password", "Sai mật khẩu"), @@ -483,5 +483,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", ""), ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), + ("login_linux_tooltip_tip", ""), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("remember_password_tip", ""), ].iter().cloned().collect(); } From 3fd1da05f4d9fc1bd6f8c866998888eae0d58e4c Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 10:48:18 +0800 Subject: [PATCH 15/44] tmp commit Signed-off-by: fufesou --- flutter/lib/common/widgets/dialog.dart | 2 +- .../lib/desktop/widgets/remote_toolbar.dart | 68 ++++++++++++++++++- flutter/lib/models/model.dart | 1 + src/lang/en.rs | 14 ++-- src/platform/linux_desktop_manager.rs | 9 +++ src/server/connection.rs | 10 ++- 6 files changed, 92 insertions(+), 12 deletions(-) diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index 569d64428..0fdd17a4b 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -625,7 +625,7 @@ _connectDialog( osAccountWidget(), osUsernameController == null || passwordController == null ? Offstage() - : Container(height: 10), + : Container(height: 12), passwdWidget(), ]), actions: [ diff --git a/flutter/lib/desktop/widgets/remote_toolbar.dart b/flutter/lib/desktop/widgets/remote_toolbar.dart index 703ed6db9..467cd69b0 100644 --- a/flutter/lib/desktop/widgets/remote_toolbar.dart +++ b/flutter/lib/desktop/widgets/remote_toolbar.dart @@ -639,7 +639,7 @@ class _ControlMenu extends StatelessWidget { ffi: ffi, menuChildren: [ requestElevation(), - osPassword(), + ffi.ffiModel.pi.is_headless ? osAccount() : osPassword(), transferFile(context), tcpTunneling(context), note(), @@ -662,6 +662,72 @@ class _ControlMenu extends StatelessWidget { onPressed: () => showRequestElevationDialog(id, ffi.dialogManager)); } + osAccount() { + return _MenuItemButton( + child: Text(translate('OS Account')), + trailingIcon: Transform.scale(scale: 0.8, child: Icon(Icons.edit)), + ffi: ffi, + onPressed: () => _showSetOSAccount(id, false, ffi.dialogManager)); + } + + _showSetOSAccount( + String id, bool login, OverlayDialogManager dialogManager) async { + final usernameController = TextEditingController(); + final passwdController = TextEditingController(); + var username = + await bind.sessionGetOption(id: id, arg: 'os-username') ?? ''; + var password = + await bind.sessionGetOption(id: id, arg: 'os-password') ?? ''; + usernameController.text = username; + passwdController.text = password; + dialogManager.show((setState, close) { + submit() { + final username = usernameController.text.trim(); + final password = usernameController.text.trim(); + bind.sessionPeerOption(id: id, name: 'os-username', value: username); + bind.sessionPeerOption(id: id, name: 'os-password', value: password); + close(); + } + + return CustomAlertDialog( + title: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.password_rounded, color: MyTheme.accent), + Text(translate('OS Password')).paddingOnly(left: 10), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + DialogTextField( + title: translate(DialogTextField.kUsernameTitle), + controller: usernameController, + prefixIcon: DialogTextField.kUsernameIcon, + errorText: null, + ), + PasswordWidget(controller: passwdController), + ], + ), + actions: [ + dialogButton( + "Cancel", + icon: Icon(Icons.close_rounded), + onPressed: close, + isOutline: true, + ), + dialogButton( + "OK", + icon: Icon(Icons.done_rounded), + onPressed: submit, + ), + ], + onSubmit: submit, + onCancel: close, + ); + }); + } + osPassword() { return _MenuItemButton( child: Text(translate('OS Password')), diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 470bb47c3..7d1249906 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -1725,6 +1725,7 @@ class PeerInfo { Map platform_additions = {}; bool get is_wayland => platform_additions['is_wayland'] == true; + bool get is_headless => platform_additions['headless'] == true; } const canvasKey = 'canvas'; diff --git a/src/lang/en.rs b/src/lang/en.rs index 95186325f..79f18ebc5 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -54,12 +54,12 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("empty_address_book_tip", "Oh dear, it appears that there are currently no peers listed in your address book."), ("identical_file_tip", "This file is identical with the peer's one."), ("show_monitors_tip", "Show monitors in toolbar."), - ("enter_rustdesk_passwd_tip", "Enter RustDesk password."), - ("remember_rustdesk_passwd_tip", "Remember RustDesk password."), - ("login_linux_tip", "Login to remote Linux account."), - ("login_linux_tooltip_tip", "You need to login to remote Linux account to enable a X desktop session."), - ("verify_rustdesk_password_tip", "Veryfy RustDesk password."), - ("remember_account_tip", "Remember this account."), - ("remember_password_tip", "Remember password."), + ("enter_rustdesk_passwd_tip", "Enter RustDesk password"), + ("remember_rustdesk_passwd_tip", "Remember RustDesk password"), + ("login_linux_tip", "Login to remote Linux account"), + ("login_linux_tooltip_tip", "You need to login to remote Linux account to enable a X desktop session"), + ("verify_rustdesk_password_tip", "Veryfy RustDesk password"), + ("remember_account_tip", "Remember this account"), + ("remember_password_tip", "Remember password"), ].iter().cloned().collect(); } diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index b21b2d5b1..a957e045e 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -80,6 +80,15 @@ pub fn try_start_x_session(username: &str, password: &str) -> ResultType<(String } } +#[inline] +pub fn is_headless() -> bool { + DESKTOP_MANAGER + .lock() + .unwrap() + .as_ref() + .map_or(false, |manager| manager.x11_username.is_empty()) +} + pub fn get_username() -> String { match &*DESKTOP_MANAGER.lock().unwrap() { Some(manager) => { diff --git a/src/server/connection.rs b/src/server/connection.rs index 2f86ca5f0..ee4bdda35 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -3,6 +3,8 @@ use super::{input_service::*, *}; use crate::clipboard_file::*; #[cfg(not(any(target_os = "android", target_os = "ios")))] use crate::common::update_clipboard; +#[cfg(target_os = "linux")] +use crate::platform::linux_desktop_manager; #[cfg(windows)] use crate::portable_service::client as portable_client; use crate::{ @@ -866,6 +868,9 @@ impl Connection { if crate::platform::current_is_wayland() { platform_additions.insert("is_wayland".into(), json!(true)); } + if linux_desktop_manager::is_headless() { + platform_additions.insert("headless".into(), json!(true)); + } if !platform_additions.is_empty() { pi.platform_additions = serde_json::to_string(&platform_additions).unwrap_or("".into()); @@ -1074,7 +1079,7 @@ impl Connection { fn try_start_desktop(_username: &str, _passsword: &str) -> String { #[cfg(target_os = "linux")] if _username.is_empty() { - let username = crate::platform::linux_desktop_manager::get_username(); + let username = linux_desktop_manager::get_username(); if username.is_empty() { LOGIN_MSG_XSESSION_NOT_READY } else { @@ -1082,8 +1087,7 @@ impl Connection { } .to_owned() } else { - match crate::platform::linux_desktop_manager::try_start_x_session(_username, _passsword) - { + match linux_desktop_manager::try_start_x_session(_username, _passsword) { Ok((username, x11_ready)) => { if x11_ready { if _username != username { From 888c8511671bac9e649b6bc3a28de912e63155ac Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 11:17:24 +0800 Subject: [PATCH 16/44] desktop, remote toolbar, os account Signed-off-by: fufesou --- flutter/lib/common/widgets/dialog.dart | 7 +------ .../lib/desktop/pages/connection_page.dart | 14 +++++-------- .../lib/desktop/widgets/remote_toolbar.dart | 21 +++++++++++++++++++ libs/hbb_common/src/config.rs | 4 ++-- src/lang/ca.rs | 8 +++---- src/lang/cn.rs | 10 ++++----- src/lang/cs.rs | 8 +++---- src/lang/da.rs | 8 +++---- src/lang/de.rs | 10 ++++----- src/lang/el.rs | 10 ++++----- src/lang/en.rs | 4 ++-- src/lang/eo.rs | 8 +++---- src/lang/es.rs | 10 ++++----- src/lang/fa.rs | 8 +++---- src/lang/fr.rs | 2 +- src/lang/hu.rs | 8 +++---- src/lang/id.rs | 8 +++---- src/lang/it.rs | 10 ++++----- src/lang/ja.rs | 8 +++---- src/lang/ko.rs | 8 +++---- src/lang/kz.rs | 8 +++---- src/lang/nl.rs | 10 ++++----- src/lang/pl.rs | 2 +- src/lang/pt_PT.rs | 8 +++---- src/lang/ptbr.rs | 8 +++---- src/lang/ro.rs | 8 +++---- src/lang/ru.rs | 10 ++++----- src/lang/sk.rs | 8 +++---- src/lang/sl.rs | 8 +++---- src/lang/sq.rs | 8 +++---- src/lang/sr.rs | 8 +++---- src/lang/sv.rs | 8 +++---- src/lang/template.rs | 5 ++--- src/lang/th.rs | 8 +++---- src/lang/tr.rs | 8 +++---- src/lang/tw.rs | 10 ++++----- src/lang/ua.rs | 8 +++---- src/lang/vn.rs | 8 +++---- 38 files changed, 133 insertions(+), 182 deletions(-) diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index 0fdd17a4b..86611cd8a 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -503,11 +503,6 @@ _connectDialog( } submit() { - // to-do: - // username and password are about remote OS account. - // If the remote side is headless. - // The client side should login to remote OS account, to enable X desktop session. - // `username` and `password` will be used in the near future. final osUsername = osUsernameController?.text.trim() ?? ''; final osPassword = osPasswordController?.text.trim() ?? ''; final password = passwordController?.text.trim() ?? ''; @@ -565,7 +560,7 @@ _connectDialog( } return Column( children: [ - descWidget(translate('login_linux_tooltip_tip')), + descWidget(translate('login_linux_tip')), DialogTextField( title: translate(DialogTextField.kUsernameTitle), controller: osUsernameController, diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 63d6b9c7b..480ea75ff 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -225,20 +225,16 @@ class _ConnectionPageState extends State children: [ Button( isOutline: true, - onTap: () { - onConnect(isFileTransfer: true); - }, + onTap: () => enterUserLoginAndPasswordDialog( + 'fdsfd', + gFFI.dialogManager, + ), text: "Transfer File", ), const SizedBox( width: 17, ), - Button( - onTap: () => enterUserLoginAndPasswordDialog( - 'fdsfd', - gFFI.dialogManager, - ), - text: "Connect"), + Button(onTap: onConnect, text: "Connect"), ], ), ) diff --git a/flutter/lib/desktop/widgets/remote_toolbar.dart b/flutter/lib/desktop/widgets/remote_toolbar.dart index 467cd69b0..ec4d32ee0 100644 --- a/flutter/lib/desktop/widgets/remote_toolbar.dart +++ b/flutter/lib/desktop/widgets/remote_toolbar.dart @@ -689,6 +689,26 @@ class _ControlMenu extends StatelessWidget { close(); } + descWidget(String text) { + return Column( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + text, + maxLines: 3, + softWrap: true, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 16), + ), + ), + Container( + height: 8, + ), + ], + ); + } + return CustomAlertDialog( title: Row( mainAxisAlignment: MainAxisAlignment.center, @@ -700,6 +720,7 @@ class _ControlMenu extends StatelessWidget { content: Column( mainAxisSize: MainAxisSize.min, children: [ + descWidget(translate("os_account_desk_tip")), DialogTextField( title: translate(DialogTextField.kUsernameTitle), controller: usernameController, diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index 6a823c7b7..3841bf976 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -915,7 +915,7 @@ impl PeerConfig { decrypt_vec_or_original(&config.password, PASSWORD_ENC_VERSION); config.password = password; store = store || store2; - for opt in ["rdp_password", "os-password"] { + for opt in ["rdp_password", "os-username", "os-password"] { if let Some(v) = config.options.get_mut(opt) { let (encrypted, _, store2) = decrypt_str_or_original(v, PASSWORD_ENC_VERSION); *v = encrypted; @@ -938,7 +938,7 @@ impl PeerConfig { let _lock = CONFIG.read().unwrap(); let mut config = self.clone(); config.password = encrypt_vec_or_original(&config.password, PASSWORD_ENC_VERSION); - for opt in ["rdp_password", "os-password"] { + for opt in ["rdp_password", "os-username", "os-password"] { if let Some(v) = config.options.get_mut(opt) { *v = encrypt_str_or_original(v, PASSWORD_ENC_VERSION) } diff --git a/src/lang/ca.rs b/src/lang/ca.rs index af744d153..6f4ce9543 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Tancar"), ("Retry", "Reintentar"), ("OK", ""), - ("remember_password_tip", "Es necessita la contrasenya"), + ("remember_password_tip", ""), ("Please enter your password", "Si us plau, introdueixi la seva contrasenya"), ("Remember password", "Recordar contrasenya"), ("Wrong Password", "Contrasenya incorrecta"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 584be4333..5262db44c 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "关闭"), ("Retry", "再试"), ("OK", "确认"), - ("remember_password_tip", "需要密码"), + ("remember_password_tip", ""), ("Please enter your password", "请输入密码"), ("Remember password", "记住密码"), ("Wrong Password", "密码错误"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "此文件与对方的一致"), ("show_monitors_tip", ""), ("View Mode", "浏览模式"), - ("enter_rustdesk_passwd_tip", "请输入 RustDesk 密码"), - ("remember_rustdesk_passwd_tip", "记住 RustDesk 密码"), - ("login_linux_tip", "登录被控端的 Linux 账户"), - ("login_linux_tooltip_tip", "登录被控端的 Linux 账户,才能启用 X 桌面。"), + ("login_linux_tip", "登录被控端的 Linux 账户,才能启用 X 桌面"), ("verify_rustdesk_password_tip", "验证 RustDesk 密码"), ("remember_account_tip", "记住此账户"), - ("remember_password_tip", ""), + ("os_account_desk_tip", "在无显示器的环境下,此账户用于登录被控系统,并启用桌面"), + ("OS Account", "系统账户"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index cb882277e..58d10b5ee 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zavřít"), ("Retry", "Zkusit znovu"), ("OK", "OK"), - ("remember_password_tip", "Vyžadováno heslo"), + ("remember_password_tip", ""), ("Please enter your password", "Zadejte své heslo"), ("Remember password", "Zapamatovat heslo"), ("Wrong Password", "Nesprávné heslo"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index ad6ddfc48..7e6888239 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Luk"), ("Retry", "Prøv igen"), ("OK", "OK"), - ("remember_password_tip", "Adgangskode påkrævet"), + ("remember_password_tip", ""), ("Please enter your password", "Indtast venligst dit kodeord"), ("Remember password", "Husk kodeord"), ("Wrong Password", "Forkert kodeord"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 263664d4c..ad9196785 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Schließen"), ("Retry", "Erneut versuchen"), ("OK", "OK"), - ("remember_password_tip", "Passwort erforderlich"), + ("remember_password_tip", ""), ("Please enter your password", "Bitte geben Sie Ihr Passwort ein"), ("Remember password", "Passwort merken"), ("Wrong Password", "Falsches Passwort"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "Diese Datei ist identisch mit der Datei der Gegenstelle."), ("show_monitors_tip", "Monitore in der Symbolleiste anzeigen"), ("View Mode", "Ansichtsmodus"), - ("enter_rustdesk_passwd_tip", "RustDesk-Passwort eingeben."), - ("remember_rustdesk_passwd_tip", "RustDesk-Passwort merken."), - ("login_linux_tip", "Anmeldung am entfernten Linux-Konto"), - ("login_linux_tooltip_tip", "Sie müssen sich an einem entfernten Linux-Konto anmelden, um eine X-Desktop-Sitzung zu eröffnen."), + ("login_linux_tip", "Sie müssen sich an einem entfernten Linux-Konto anmelden, um eine X-Desktop-Sitzung zu eröffnen."), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index 9597ae158..50778f4c4 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Κλείσιμο"), ("Retry", "Δοκίμασε ξανά"), ("OK", "ΟΚ"), - ("remember_password_tip", "Απαιτείται κωδικός πρόσβασης"), + ("remember_password_tip", ""), ("Please enter your password", "Παρακαλώ εισάγετε τον κωδικό πρόσβασης"), ("Remember password", "Απομνημόνευση κωδικού πρόσβασης"), ("Wrong Password", "Λάθος κωδικός πρόσβασης"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "Το αρχείο είναι πανομοιότυπο με αυτό του άλλου υπολογιστή."), ("show_monitors_tip", "Εμφάνιση οθονών στη γραμμή εργαλείων"), ("View Mode", "Λειτουργία προβολής"), - ("enter_rustdesk_passwd_tip", "Εισαγωγή του κωδικού RustDesk."), - ("remember_rustdesk_passwd_tip", "Να θυμάσαι τον κωδικό του RustDesk."), - ("login_linux_tip", "Είσοδος σε απομακρυσμένο λογαριασμό Linux"), - ("login_linux_tooltip_tip", "Απαιτείται είσοδος σε απομακρυσμένο λογαριασμό Linux για την ενεργοποίηση του περιβάλλον εργασίας Χ."), + ("login_linux_tip", "Απαιτείται είσοδος σε απομακρυσμένο λογαριασμό Linux για την ενεργοποίηση του περιβάλλον εργασίας Χ."), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index 79f18ebc5..2ea65b05f 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -56,10 +56,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("show_monitors_tip", "Show monitors in toolbar."), ("enter_rustdesk_passwd_tip", "Enter RustDesk password"), ("remember_rustdesk_passwd_tip", "Remember RustDesk password"), - ("login_linux_tip", "Login to remote Linux account"), - ("login_linux_tooltip_tip", "You need to login to remote Linux account to enable a X desktop session"), + ("login_linux_tip", "You need to login to remote Linux account to enable a X desktop session"), ("verify_rustdesk_password_tip", "Veryfy RustDesk password"), ("remember_account_tip", "Remember this account"), ("remember_password_tip", "Remember password"), + ("os_account_desk_tip", "This account is used to login the remote OS and enable the desktop session in headless"), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index aeee842f7..9fcc2b451 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fermi"), ("Retry", "Reprovi"), ("OK", "Konfermi"), - ("remember_password_tip", "Pasvorto deviga"), + ("remember_password_tip", ""), ("Please enter your password", "Bonvolu tajpi vian pasvorton"), ("Remember password", "Memori pasvorton"), ("Wrong Password", "Erara pasvorto"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index 3b998ae7d..c8120de49 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Cerrar"), ("Retry", "Reintentar"), ("OK", ""), - ("remember_password_tip", "Se requiere contraseña"), + ("remember_password_tip", ""), ("Please enter your password", "Por favor, introduzca su contraseña"), ("Remember password", "Recordar contraseña"), ("Wrong Password", "Contraseña incorrecta"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "Este archivo es idéntico al del par."), ("show_monitors_tip", "Mostrar monitores en la barra de herramientas"), ("View Mode", "Modo Vista"), - ("enter_rustdesk_passwd_tip", "Introduzca la contraseña de RustDesk"), - ("remember_rustdesk_passwd_tip", "Recordar la contraseña de RustDesk"), - ("login_linux_tip", "Iniciar sesión para la cuenta remota de Linux"), - ("login_linux_tooltip_tip", ""), + ("login_linux_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index e2137c3e2..ccf2a670a 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "بستن"), ("Retry", "تلاش مجدد"), ("OK", "قبول"), - ("remember_password_tip", "رمز عبور لازم است"), + ("remember_password_tip", ""), ("Please enter your password", "رمز عبور خود را وارد کنید"), ("Remember password", "رمز عبور را به خاطر بسپار"), ("Wrong Password", "رمز عبور اشتباه است"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "این فایل با فایل همتا یکسان است."), ("show_monitors_tip", "نمایش مانیتورها در نوار ابزار"), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 71c0f6728..2ff02d8f9 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fermer"), ("Retry", "Réessayer"), ("OK", "Valider"), - ("remember_password_tip", "Mot de passe requis"), + ("remember_password_tip", ""), ("Please enter your password", "Veuillez saisir votre mot de passe"), ("Remember password", "Mémoriser le mot de passe"), ("Wrong Password", "Mauvais mot de passe"), diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 7c7fb2468..49e767b84 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Bezárás"), ("Retry", "Újra"), ("OK", "OK"), - ("remember_password_tip", "Jelszó megadása kötelező"), + ("remember_password_tip", ""), ("Please enter your password", "Kérem írja be a jelszavát"), ("Remember password", "Jelszó megjegyzése"), ("Wrong Password", "Hibás jelszó"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 174d970b6..2c410c0ec 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Tutup"), ("Retry", "Ulangi"), ("OK", "Oke"), - ("remember_password_tip", "Kata sandi dibutuhkan"), + ("remember_password_tip", ""), ("Please enter your password", "Silahkan masukkan kata sandi anda"), ("Remember password", "Ingat Password"), ("Wrong Password", "Kata sandi Salah"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 94b7d10a9..4427743f1 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Chiudi"), ("Retry", "Riprova"), ("OK", "OK"), - ("remember_password_tip", "Password Richiesta"), + ("remember_password_tip", ""), ("Please enter your password", "Inserisci la tua password"), ("Remember password", "Ricorda password"), ("Wrong Password", "Password Errata"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "Questo file è identico a quello del peer."), ("show_monitors_tip", "Mostra schermi nella barra degli strumenti"), ("View Mode", "Modalità di visualizzazione"), - ("enter_rustdesk_passwd_tip", "Inserisci la password di RustDesk."), - ("remember_rustdesk_passwd_tip", "Ricorda la passowrd di RustDesk."), - ("login_linux_tip", "Effettua l'accesso sul tuo account Linux"), - ("login_linux_tooltip_tip", ""), + ("login_linux_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 95395c516..dba70c1e1 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "閉じる"), ("Retry", "再試行"), ("OK", "OK"), - ("remember_password_tip", "パスワードが必要"), + ("remember_password_tip", ""), ("Please enter your password", "パスワードを入力してください"), ("Remember password", "パスワードを記憶する"), ("Wrong Password", "パスワードが間違っています"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 4e3b52ea2..ab7714190 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "닫기"), ("Retry", "재시도"), ("OK", "확인"), - ("remember_password_tip", "비밀번호 입력"), + ("remember_password_tip", ""), ("Please enter your password", "비밀번호를 입력해주세요"), ("Remember password", "이 비밀번호 기억하기"), ("Wrong Password", "틀린 비밀번호"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index bfe312e02..7fe2719cc 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Жабу"), ("Retry", "Қайтадан көру"), ("OK", "OK"), - ("remember_password_tip", "Құпия сөз Қажет"), + ("remember_password_tip", ""), ("Please enter your password", "Құпия сөзіңізді еңгізуді өтінеміз"), ("Remember password", "Құпия сөзді есте сақтау"), ("Wrong Password", "Бұрыс Құпия сөз"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 4a3c9c062..360166e50 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Sluit"), ("Retry", "Probeer opnieuw"), ("OK", "OK"), - ("remember_password_tip", "Wachtwoord vereist"), + ("remember_password_tip", ""), ("Please enter your password", "Geef uw wachtwoord in"), ("Remember password", "Wachtwoord onthouden"), ("Wrong Password", "Verkeerd wachtwoord"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "Dit bestand is identiek aan het bestand van het externe station."), ("show_monitors_tip", "Monitoren weergeven in de werkbalk"), ("View Mode", "Weergave Mode"), - ("enter_rustdesk_passwd_tip", "Geef het RustDesk-wachtwoord op."), - ("remember_rustdesk_passwd_tip", "RustDesk Wachtwoord onthouden."), - ("login_linux_tip", "Je moet inloggen op een Linux Account op afstand om een X desktop sessie te openen."), - ("login_linux_tooltip_tip", ""), + ("login_linux_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index f68d37866..d89b6f763 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zamknij"), ("Retry", "Ponów"), ("OK", "OK"), - ("remember_password_tip", "Wymagane jest hasło"), + ("remember_password_tip", ""), ("Please enter your password", "Wpisz proszę twoje hasło"), ("Remember password", "Zapamiętaj hasło"), ("Wrong Password", "Błędne hasło"), diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 04689f713..c23aa1e46 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fechar"), ("Retry", "Tentar novamente"), ("OK", "Confirmar"), - ("remember_password_tip", "Palavra-chave Necessária"), + ("remember_password_tip", ""), ("Please enter your password", "Por favor introduza a sua palavra-chave"), ("Remember password", "Memorizar palavra-chave"), ("Wrong Password", "Palavra-chave inválida"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 6f6302a59..c741944a1 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fechar"), ("Retry", "Tentar novamente"), ("OK", "OK"), - ("remember_password_tip", "Senha necessária"), + ("remember_password_tip", ""), ("Please enter your password", "Por favor informe sua senha"), ("Remember password", "Lembrar senha"), ("Wrong Password", "Senha incorreta"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index ade2e3c36..d77345356 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Închide"), ("Retry", "Reîncearcă"), ("OK", "OK"), - ("remember_password_tip", "Parolă necesară"), + ("remember_password_tip", ""), ("Please enter your password", "Introdu parola"), ("Remember password", "Memorează parola"), ("Wrong Password", "Parolă incorectă"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index c85582e86..fbd1c4c62 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Закрыть"), ("Retry", "Повторить"), ("OK", "ОК"), - ("remember_password_tip", "Требуется пароль"), + ("remember_password_tip", ""), ("Please enter your password", "Введите пароль"), ("Remember password", "Запомнить пароль"), ("Wrong Password", "Неправильный пароль"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "Файл идентичен файлу на удалённом узле."), ("show_monitors_tip", "Показывать мониторы на панели инструментов"), ("View Mode", "Режим просмотра"), - ("enter_rustdesk_passwd_tip", "Введите пароль RustDesk"), - ("remember_rustdesk_passwd_tip", "Запомнить пароль RustDesk"), - ("login_linux_tip", "Вход в удалённый аккаунт Linux"), - ("login_linux_tooltip_tip", "Чтобы включить сеанс рабочего стола X, необходимо войти в удалённый аккаунт Linux."), + ("login_linux_tip", "Чтобы включить сеанс рабочего стола X, необходимо войти в удалённый аккаунт Linux."), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index e7c108a8c..efa66f7ae 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zatvoriť"), ("Retry", "Zopakovať"), ("OK", "OK"), - ("remember_password_tip", "Vyžaduje sa heslo"), + ("remember_password_tip", ""), ("Please enter your password", "Zadajte vaše heslo"), ("Remember password", "Zapamätať heslo"), ("Wrong Password", "Chybné heslo"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 0e5265b87..d897e4755 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zapri"), ("Retry", "Ponovi"), ("OK", "V redu"), - ("remember_password_tip", "Potrebno je geslo"), + ("remember_password_tip", ""), ("Please enter your password", "Vnesite vaše geslo"), ("Remember password", "Zapomni si geslo"), ("Wrong Password", "Napačno geslo"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index 68ef47be9..88d678ed3 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Mbyll"), ("Retry", "Riprovo"), ("OK", "OK"), - ("remember_password_tip", "Fjalëkalimi i detyrueshëm"), + ("remember_password_tip", ""), ("Please enter your password", "Ju lutem vendosni fjalëkalimin tuaj"), ("Remember password", "Mbani mend fjalëkalimin"), ("Wrong Password", "Fjalëkalim i gabuar"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index ccb328e3e..078d9ba29 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zatvori"), ("Retry", "Ponovi"), ("OK", "Ok"), - ("remember_password_tip", "Potrebna lozinka"), + ("remember_password_tip", ""), ("Please enter your password", "Molimo unesite svoju lozinku"), ("Remember password", "Zapamti lozinku"), ("Wrong Password", "Pogrešna lozinka"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 496c882bc..df5caee28 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Stäng"), ("Retry", "Försök igen"), ("OK", "OK"), - ("remember_password_tip", "Lösenord krävs"), + ("remember_password_tip", ""), ("Please enter your password", "Skriv in ditt lösenord"), ("Remember password", "Kom ihåg lösenord"), ("Wrong Password", "Fel lösenord"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 6ec149289..1b8bf69c2 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -480,11 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 92ae279c9..a152eb7b1 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "ปิด"), ("Retry", "ลองใหม่อีกครั้ง"), ("OK", "ตกลง"), - ("remember_password_tip", "ต้องใช้รหัสผ่าน"), + ("remember_password_tip", ""), ("Please enter your password", "กรุณาใส่รหัสผ่านของคุณ"), ("Remember password", "จดจำรหัสผ่าน"), ("Wrong Password", "รหัสผ่านไม่ถูกต้อง"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index b423a021b..c5d21460a 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Kapat"), ("Retry", "Tekrar Dene"), ("OK", "Tamam"), - ("remember_password_tip", "Şifre Gerekli"), + ("remember_password_tip", ""), ("Please enter your password", "Lütfen şifrenizi giriniz"), ("Remember password", "Şifreyi hatırla"), ("Wrong Password", "Hatalı şifre"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index e8685747e..d2156f4b7 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "關閉"), ("Retry", "重試"), ("OK", "確定"), - ("remember_password_tip", "需要密碼"), + ("remember_password_tip", ""), ("Please enter your password", "請輸入您的密碼"), ("Remember password", "記住密碼"), ("Wrong Password", "密碼錯誤"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "此檔案與對方的檔案一致"), ("show_monitors_tip", "在工具列中顯示顯示器"), ("View Mode", "瀏覽模式"), - ("enter_rustdesk_passwd_tip", "輸入 RustDesk 密碼"), - ("remember_rustdesk_passwd_tip", "記住 RustDesk 密碼"), - ("login_linux_tip", "登入到遠端 Linux 使用者帳戶"), - ("login_linux_tooltip_tip", "需要登入到遠端 Linux 使用者帳戶才能啟用 X 介面。"), + ("login_linux_tip", "需要登入到遠端 Linux 使用者帳戶才能啟用 X 介面。"), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 952c36b13..1a91bb879 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Закрити"), ("Retry", "Спробувати знову"), ("OK", "ОК"), - ("remember_password_tip", "Потрібен пароль"), + ("remember_password_tip", ""), ("Please enter your password", "Будь ласка, введіть ваш пароль"), ("Remember password", "Запам'ятати пароль"), ("Wrong Password", "Невірний пароль"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index ab1aa2820..eeafcfa54 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Đóng"), ("Retry", "Thử lại"), ("OK", "OK"), - ("remember_password_tip", "Yêu cầu mật khẩu"), + ("remember_password_tip", ""), ("Please enter your password", "Mời nhập mật khẩu"), ("Remember password", "Nhớ mật khẩu"), ("Wrong Password", "Sai mật khẩu"), @@ -480,12 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", ""), ("show_monitors_tip", ""), ("View Mode", ""), - ("enter_rustdesk_passwd_tip", ""), - ("remember_rustdesk_passwd_tip", ""), ("login_linux_tip", ""), - ("login_linux_tooltip_tip", ""), ("verify_rustdesk_password_tip", ""), ("remember_account_tip", ""), - ("remember_password_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } From 8aa5f3a2a7382f1050195612e89140247058d416 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 11:47:32 +0800 Subject: [PATCH 17/44] mobile, edit os account Signed-off-by: fufesou --- flutter/lib/common/widgets/dialog.dart | 146 +++++++++++++++++ .../lib/desktop/pages/connection_page.dart | 5 +- .../lib/desktop/widgets/remote_toolbar.dart | 149 +----------------- flutter/lib/mobile/pages/remote_page.dart | 92 ++++------- 4 files changed, 184 insertions(+), 208 deletions(-) diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index 86611cd8a..0c61abb0d 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -897,3 +897,149 @@ void showRestartRemoteDevice( )); if (res == true) bind.sessionRestartRemoteDevice(id: id); } + +showSetOSPassword( + String id, + bool login, + OverlayDialogManager dialogManager, +) async { + final controller = TextEditingController(); + var password = await bind.sessionGetOption(id: id, arg: 'os-password') ?? ''; + var autoLogin = await bind.sessionGetOption(id: id, arg: 'auto-login') != ''; + controller.text = password; + dialogManager.show((setState, close) { + submit() { + var text = controller.text.trim(); + bind.sessionPeerOption(id: id, name: 'os-password', value: text); + bind.sessionPeerOption( + id: id, name: 'auto-login', value: autoLogin ? 'Y' : ''); + if (text != '' && login) { + bind.sessionInputOsPassword(id: id, value: text); + } + close(); + } + + return CustomAlertDialog( + title: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.password_rounded, color: MyTheme.accent), + Text(translate('OS Password')).paddingOnly(left: 10), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + PasswordWidget(controller: controller), + CheckboxListTile( + contentPadding: const EdgeInsets.all(0), + dense: true, + controlAffinity: ListTileControlAffinity.leading, + title: Text( + translate('Auto Login'), + ), + value: autoLogin, + onChanged: (v) { + if (v == null) return; + setState(() => autoLogin = v); + }, + ), + ], + ), + actions: [ + dialogButton( + "Cancel", + icon: Icon(Icons.close_rounded), + onPressed: close, + isOutline: true, + ), + dialogButton( + "OK", + icon: Icon(Icons.done_rounded), + onPressed: submit, + ), + ], + onSubmit: submit, + onCancel: close, + ); + }); +} + +showSetOSAccount( + String id, + OverlayDialogManager dialogManager, +) async { + final usernameController = TextEditingController(); + final passwdController = TextEditingController(); + var username = await bind.sessionGetOption(id: id, arg: 'os-username') ?? ''; + var password = await bind.sessionGetOption(id: id, arg: 'os-password') ?? ''; + usernameController.text = username; + passwdController.text = password; + dialogManager.show((setState, close) { + submit() { + final username = usernameController.text.trim(); + final password = usernameController.text.trim(); + bind.sessionPeerOption(id: id, name: 'os-username', value: username); + bind.sessionPeerOption(id: id, name: 'os-password', value: password); + close(); + } + + descWidget(String text) { + return Column( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + text, + maxLines: 3, + softWrap: true, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 16), + ), + ), + Container( + height: 8, + ), + ], + ); + } + + return CustomAlertDialog( + title: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.password_rounded, color: MyTheme.accent), + Text(translate('OS Account')).paddingOnly(left: 10), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + descWidget(translate("os_account_desk_tip")), + DialogTextField( + title: translate(DialogTextField.kUsernameTitle), + controller: usernameController, + prefixIcon: DialogTextField.kUsernameIcon, + errorText: null, + ), + PasswordWidget(controller: passwdController), + ], + ), + actions: [ + dialogButton( + "Cancel", + icon: Icon(Icons.close_rounded), + onPressed: close, + isOutline: true, + ), + dialogButton( + "OK", + icon: Icon(Icons.done_rounded), + onPressed: submit, + ), + ], + onSubmit: submit, + onCancel: close, + ); + }); +} diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 480ea75ff..3f6bb7d16 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -225,10 +225,7 @@ class _ConnectionPageState extends State children: [ Button( isOutline: true, - onTap: () => enterUserLoginAndPasswordDialog( - 'fdsfd', - gFFI.dialogManager, - ), + onTap: () => onConnect(isFileTransfer: true), text: "Transfer File", ), const SizedBox( diff --git a/flutter/lib/desktop/widgets/remote_toolbar.dart b/flutter/lib/desktop/widgets/remote_toolbar.dart index ec4d32ee0..b6f97790e 100644 --- a/flutter/lib/desktop/widgets/remote_toolbar.dart +++ b/flutter/lib/desktop/widgets/remote_toolbar.dart @@ -667,86 +667,7 @@ class _ControlMenu extends StatelessWidget { child: Text(translate('OS Account')), trailingIcon: Transform.scale(scale: 0.8, child: Icon(Icons.edit)), ffi: ffi, - onPressed: () => _showSetOSAccount(id, false, ffi.dialogManager)); - } - - _showSetOSAccount( - String id, bool login, OverlayDialogManager dialogManager) async { - final usernameController = TextEditingController(); - final passwdController = TextEditingController(); - var username = - await bind.sessionGetOption(id: id, arg: 'os-username') ?? ''; - var password = - await bind.sessionGetOption(id: id, arg: 'os-password') ?? ''; - usernameController.text = username; - passwdController.text = password; - dialogManager.show((setState, close) { - submit() { - final username = usernameController.text.trim(); - final password = usernameController.text.trim(); - bind.sessionPeerOption(id: id, name: 'os-username', value: username); - bind.sessionPeerOption(id: id, name: 'os-password', value: password); - close(); - } - - descWidget(String text) { - return Column( - children: [ - Align( - alignment: Alignment.centerLeft, - child: Text( - text, - maxLines: 3, - softWrap: true, - overflow: TextOverflow.ellipsis, - style: TextStyle(fontSize: 16), - ), - ), - Container( - height: 8, - ), - ], - ); - } - - return CustomAlertDialog( - title: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.password_rounded, color: MyTheme.accent), - Text(translate('OS Password')).paddingOnly(left: 10), - ], - ), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - descWidget(translate("os_account_desk_tip")), - DialogTextField( - title: translate(DialogTextField.kUsernameTitle), - controller: usernameController, - prefixIcon: DialogTextField.kUsernameIcon, - errorText: null, - ), - PasswordWidget(controller: passwdController), - ], - ), - actions: [ - dialogButton( - "Cancel", - icon: Icon(Icons.close_rounded), - onPressed: close, - isOutline: true, - ), - dialogButton( - "OK", - icon: Icon(Icons.done_rounded), - onPressed: submit, - ), - ], - onSubmit: submit, - onCancel: close, - ); - }); + onPressed: () => showSetOSAccount(id, ffi.dialogManager)); } osPassword() { @@ -754,73 +675,7 @@ class _ControlMenu extends StatelessWidget { child: Text(translate('OS Password')), trailingIcon: Transform.scale(scale: 0.8, child: Icon(Icons.edit)), ffi: ffi, - onPressed: () => _showSetOSPassword(id, false, ffi.dialogManager)); - } - - _showSetOSPassword( - String id, bool login, OverlayDialogManager dialogManager) async { - final controller = TextEditingController(); - var password = - await bind.sessionGetOption(id: id, arg: 'os-password') ?? ''; - var autoLogin = - await bind.sessionGetOption(id: id, arg: 'auto-login') != ''; - controller.text = password; - dialogManager.show((setState, close) { - submit() { - var text = controller.text.trim(); - bind.sessionPeerOption(id: id, name: 'os-password', value: text); - bind.sessionPeerOption( - id: id, name: 'auto-login', value: autoLogin ? 'Y' : ''); - if (text != '' && login) { - bind.sessionInputOsPassword(id: id, value: text); - } - close(); - } - - return CustomAlertDialog( - title: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.password_rounded, color: MyTheme.accent), - Text(translate('OS Password')).paddingOnly(left: 10), - ], - ), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - PasswordWidget(controller: controller), - CheckboxListTile( - contentPadding: const EdgeInsets.all(0), - dense: true, - controlAffinity: ListTileControlAffinity.leading, - title: Text( - translate('Auto Login'), - ), - value: autoLogin, - onChanged: (v) { - if (v == null) return; - setState(() => autoLogin = v); - }, - ), - ], - ), - actions: [ - dialogButton( - "Cancel", - icon: Icon(Icons.close_rounded), - onPressed: close, - isOutline: true, - ), - dialogButton( - "OK", - icon: Icon(Icons.done_rounded), - onPressed: submit, - ), - ], - onSubmit: submit, - onCancel: close, - ); - }); + onPressed: () => showSetOSPassword(id, false, ffi.dialogManager)); } transferFile(BuildContext context) { diff --git a/flutter/lib/mobile/pages/remote_page.dart b/flutter/lib/mobile/pages/remote_page.dart index 083cdcd1c..1a7452dd7 100644 --- a/flutter/lib/mobile/pages/remote_page.dart +++ b/flutter/lib/mobile/pages/remote_page.dart @@ -548,19 +548,39 @@ class _RemotePageState extends State { more.add(PopupMenuItem( child: Text(translate('Refresh')), value: 'refresh')); } - more.add(PopupMenuItem( - child: Row( - children: ([ - Text(translate('OS Password')), - TextButton( - style: flatButtonStyle, - onPressed: () { - showSetOSPassword(id, false, gFFI.dialogManager); - }, - child: Icon(Icons.edit, color: MyTheme.accent), - ) - ])), - value: 'enter_os_password')); + if (gFFI.ffiModel.pi.is_headless) { + more.add( + PopupMenuItem( + child: Row( + children: ([ + Text(translate('OS Account')), + TextButton( + style: flatButtonStyle, + onPressed: () { + showSetOSAccount(id, gFFI.dialogManager); + }, + child: Icon(Icons.edit, color: MyTheme.accent), + ) + ])), + value: 'enter_os_account'), + ); + } else { + more.add( + PopupMenuItem( + child: Row( + children: ([ + Text(translate('OS Password')), + TextButton( + style: flatButtonStyle, + onPressed: () { + showSetOSPassword(id, false, gFFI.dialogManager); + }, + child: Icon(Icons.edit, color: MyTheme.accent), + ) + ])), + value: 'enter_os_password'), + ); + } if (!isWebDesktop) { if (perms['keyboard'] != false && perms['clipboard'] != false) { more.add(PopupMenuItem( @@ -657,6 +677,8 @@ class _RemotePageState extends State { } else { showSetOSPassword(id, true, gFFI.dialogManager); } + } else if (value == 'enter_os_account') { + showSetOSAccount(id, gFFI.dialogManager); } else if (value == 'reset_canvas') { gFFI.cursorModel.reset(); } else if (value == 'restart') { @@ -1071,50 +1093,6 @@ void showOptions( }, clickMaskDismiss: true, backDismiss: true); } -void showSetOSPassword( - String id, bool login, OverlayDialogManager dialogManager) async { - final controller = TextEditingController(); - var password = await bind.sessionGetOption(id: id, arg: "os-password") ?? ""; - var autoLogin = await bind.sessionGetOption(id: id, arg: "auto-login") != ""; - controller.text = password; - dialogManager.show((setState, close) { - return CustomAlertDialog( - title: Text(translate('OS Password')), - content: Column(mainAxisSize: MainAxisSize.min, children: [ - PasswordWidget(controller: controller), - CheckboxListTile( - contentPadding: const EdgeInsets.all(0), - dense: true, - controlAffinity: ListTileControlAffinity.leading, - title: Text( - translate('Auto Login'), - ), - value: autoLogin, - onChanged: (v) { - if (v == null) return; - setState(() => autoLogin = v); - }, - ), - ]), - actions: [ - dialogButton('Cancel', onPressed: close, isOutline: true), - dialogButton( - 'OK', - onPressed: () { - var text = controller.text.trim(); - bind.sessionPeerOption(id: id, name: "os-password", value: text); - bind.sessionPeerOption( - id: id, name: "auto-login", value: autoLogin ? 'Y' : ''); - if (text != "" && login) { - bind.sessionInputOsPassword(id: id, value: text); - } - close(); - }, - ), - ]); - }); -} - void sendPrompt(bool isMac, String key) { final old = isMac ? gFFI.inputModel.command : gFFI.inputModel.ctrl; if (isMac) { From 127ab57d62539949be82ed330f41a9a53cbc79b5 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 14:11:56 +0800 Subject: [PATCH 18/44] ignore 'gdm' on loginctl Signed-off-by: fufesou --- flutter/lib/models/model.dart | 6 ++--- libs/hbb_common/src/platform/linux.rs | 2 +- src/client.rs | 22 ++++++++-------- src/lang/en.rs | 2 +- src/platform/linux.rs | 10 ++++++++ src/platform/linux_desktop_manager.rs | 29 +++++++++++++-------- src/server/connection.rs | 36 ++++++++++++++++----------- src/ui/common.tis | 4 +-- src/ui/msgbox.tis | 24 +++++++++--------- 9 files changed, 80 insertions(+), 55 deletions(-) diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 7d1249906..77e1b8fbf 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -293,10 +293,10 @@ class FfiModel with ChangeNotifier { wrongPasswordDialog(id, dialogManager, type, title, text); } else if (type == 'input-password') { enterPasswordDialog(id, dialogManager); - } else if (type == 'xsession-login' || type == 'xsession-re-login') { + } else if (type == 'session-login' || type == 'session-re-login') { enterUserLoginDialog(id, dialogManager); - } else if (type == 'xsession-login-password' || - type == 'xsession-login-password') { + } else if (type == 'session-login-password' || + type == 'session-login-password') { enterUserLoginAndPasswordDialog(id, dialogManager); } else if (type == 'restarting') { showMsgBox(id, type, title, text, link, false, dialogManager, diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index 1d826ea97..cf1cf6da5 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -135,7 +135,7 @@ pub fn get_values_of_seat0_with_gdm_wayland(indices: &[usize]) -> Vec { fn _get_values_of_seat0(indices: &[usize], ignore_gdm_wayland: bool) -> Vec { if let Ok(output) = run_loginctl(None) { for line in String::from_utf8_lossy(&output.stdout).lines() { - if line.contains("seat0") { + if !line.contains("gdm") && line.contains("seat0") { if let Some(sid) = line.split_whitespace().next() { if is_active(sid) { if ignore_gdm_wayland { diff --git a/src/client.rs b/src/client.rs index f03cb0e55..3819ed382 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1927,34 +1927,34 @@ pub fn handle_login_error( lc.write().unwrap().password = Default::default(); interface.msgbox("re-input-password", err, "Do you want to enter again?", ""); true - } else if err == crate::server::LOGIN_MSG_XSESSION_NOT_READY { + } else if err == crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY { interface.msgbox( - "xsession-login", - "xsession is unready", + "session-login", + "session is unready", "Input linux user/password", "", ); true - } else if err == crate::server::LOGIN_MSG_XSESSION_FAILED { + } else if err == crate::server::LOGIN_MSG_DESKTOP_XSESSION_FAILED { interface.msgbox( - "xsession-re-login", + "session-re-login", "xsession username/password is wrong", "Do you want to enter again?", "", ); true - } else if err == crate::server::LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_EMPTY { + } else if err == crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY { interface.msgbox( - "xsession-login-password", - "xsession is unready", + "session-login-password", + "session is unready", "Input connection password and linux user/password", "", ); true - } else if err == crate::server::LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_WRONG { + } else if err == crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG { interface.msgbox( - "xsession-login-re-password", - "xsession is unready and password is wrong", + "session-login-re-password", + "session is unready and password is wrong", "Do you want to enter again?", "", ); diff --git a/src/lang/en.rs b/src/lang/en.rs index 2ea65b05f..11ad719ab 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -56,7 +56,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("show_monitors_tip", "Show monitors in toolbar."), ("enter_rustdesk_passwd_tip", "Enter RustDesk password"), ("remember_rustdesk_passwd_tip", "Remember RustDesk password"), - ("login_linux_tip", "You need to login to remote Linux account to enable a X desktop session"), + ("login_linux_tip", "Remote desktop is unready. Please \n 1. Login on remote side and then try again\n 2. Or input remote account to login and start a X desktop session"), ("verify_rustdesk_password_tip", "Veryfy RustDesk password"), ("remember_account_tip", "Remember this account"), ("remember_password_tip", "Remember password"), diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 8c4a68848..fa83fdc1f 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -21,6 +21,9 @@ use std::{ type Xdo = *const c_void; +pub const ENV_DESKTOP_PROTOCAL_WAYLAND: &str = "wayland"; +pub const ENV_DESKTOP_PROTOCAL_X11: &str = "x11"; + pub const PA_SAMPLE_RATE: u32 = 48000; static mut UNMODIFIED: bool = true; @@ -930,6 +933,8 @@ mod desktop { if !self.sid.is_empty() && is_active(&self.sid) { return; } + + println!("REMOVE ME ================================== desktop: refresh"); let seat0_values = get_values_of_seat0(&[0, 1, 2]); if seat0_values[0].is_empty() { *self = Self::default(); @@ -950,6 +955,11 @@ mod desktop { self.get_display(); self.get_xauth(); self.set_is_subprocess(); + + println!( + "REMOVE ME ================================== desktop: {:?}", + self + ); } } } diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index a957e045e..f1ddec58e 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -22,7 +22,7 @@ lazy_static::lazy_static! { #[derive(Debug)] struct DesktopManager { - x11_username: String, + seat0_username: String, child_username: String, child_exit: Arc, is_child_running: Arc, @@ -61,8 +61,8 @@ pub fn stop_xdesktop() { pub fn try_start_x_session(username: &str, password: &str) -> ResultType<(String, bool)> { let mut desktop_manager = DESKTOP_MANAGER.lock().unwrap(); if let Some(desktop_manager) = &mut (*desktop_manager) { - if !desktop_manager.x11_username.is_empty() { - return Ok((desktop_manager.x11_username.clone(), true)); + if !desktop_manager.seat0_username.is_empty() { + return Ok((desktop_manager.seat0_username.clone(), true)); } let _ = desktop_manager.try_start_x_session(username, password)?; @@ -76,7 +76,7 @@ pub fn try_start_x_session(username: &str, password: &str) -> ResultType<(String desktop_manager.is_running(), )) } else { - bail!(crate::server::LOGIN_MSG_XDESKTOP_NOT_INITED); + bail!(crate::server::LOGIN_MSG_DESKTOP_NOT_INITED); } } @@ -86,14 +86,14 @@ pub fn is_headless() -> bool { .lock() .unwrap() .as_ref() - .map_or(false, |manager| manager.x11_username.is_empty()) + .map_or(false, |manager| manager.seat0_username.is_empty()) } pub fn get_username() -> String { match &*DESKTOP_MANAGER.lock().unwrap() { Some(manager) => { - if !manager.x11_username.is_empty() { - manager.x11_username.clone() + if !manager.seat0_username.is_empty() { + manager.seat0_username.clone() } else { if manager.is_running() && !manager.child_username.is_empty() { manager.child_username.clone() @@ -118,16 +118,23 @@ impl DesktopManager { } pub fn new() -> Self { - let mut x11_username = "".to_owned(); + let mut seat0_username = "".to_owned(); let seat0_values = get_values_of_seat0(&[0, 1, 2]); + println!( + "REMOVE ME ================================== DesktopManager: {:?}", + &seat0_values + ); if !seat0_values[0].is_empty() { - if "x11" == get_display_server_of_session(&seat0_values[1]) { - x11_username = seat0_values[2].clone(); + let display_server = get_display_server_of_session(&seat0_values[1]); + if display_server == ENV_DESKTOP_PROTOCAL_X11 + || display_server == ENV_DESKTOP_PROTOCAL_WAYLAND + { + seat0_username = seat0_values[2].clone(); } } Self { - x11_username, + seat0_username, child_username: "".to_owned(), child_exit: Arc::new(AtomicBool::new(true)), is_child_running: Arc::new(AtomicBool::new(false)), diff --git a/src/server/connection.rs b/src/server/connection.rs index ee4bdda35..f9c64378e 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -59,12 +59,14 @@ lazy_static::lazy_static! { pub static CLICK_TIME: AtomicI64 = AtomicI64::new(0); pub static MOUSE_MOVE_TIME: AtomicI64 = AtomicI64::new(0); -pub const LOGIN_MSG_XDESKTOP_NOT_INITED: &str = "xdesktop env is not inited"; -pub const LOGIN_MSG_XSESSION_NOT_READY: &str = "xsession unready"; -pub const LOGIN_MSG_XSESSION_FAILED: &str = "xsession failed"; -pub const LOGIN_MSG_XSESSION_ANOTHER_USER_READTY: &str = "xsession another user login"; -pub const LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_EMPTY: &str = "xsession unready, password empty"; -pub const LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_WRONG: &str = "xsession unready, password wrong"; +pub const LOGIN_MSG_DESKTOP_NOT_INITED: &str = "Desktop env is not inited"; +pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY: &str = "Desktop session unready"; +pub const LOGIN_MSG_DESKTOP_XSESSION_FAILED: &str = "Desktop xsession failed"; +pub const LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER: &str = "Desktop session another user login"; +pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY: &str = + "Desktop session unready, password empty"; +pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG: &str = + "Desktop session unready, password wrong"; pub const LOGIN_MSG_PASSWORD_EMPTY: &str = "Empty Password"; pub const LOGIN_MSG_PASSWORD_WRONG: &str = "Wrong Password"; pub const LOGIN_MSG_OFFLINE: &str = "Offline"; @@ -1081,27 +1083,33 @@ impl Connection { if _username.is_empty() { let username = linux_desktop_manager::get_username(); if username.is_empty() { - LOGIN_MSG_XSESSION_NOT_READY + LOGIN_MSG_DESKTOP_SESSION_NOT_READY } else { "" } .to_owned() } else { + let username = linux_desktop_manager::get_username(); + if username == _username { + // No need to verify password here. + return "".to_owned(); + } + match linux_desktop_manager::try_start_x_session(_username, _passsword) { Ok((username, x11_ready)) => { if x11_ready { if _username != username { - LOGIN_MSG_XSESSION_ANOTHER_USER_READTY.to_owned() + LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER.to_owned() } else { "".to_owned() } } else { - LOGIN_MSG_XSESSION_NOT_READY.to_owned() + LOGIN_MSG_DESKTOP_SESSION_NOT_READY.to_owned() } } Err(e) => { log::error!("Failed to start xsession {}", e); - LOGIN_MSG_XSESSION_FAILED.to_owned() + LOGIN_MSG_DESKTOP_XSESSION_FAILED.to_owned() } } } @@ -1278,8 +1286,8 @@ impl Connection { Some(os_login) => Self::try_start_desktop(&os_login.username, &os_login.password), None => Self::try_start_desktop("", ""), }; - // If err is LOGIN_MSG_XSESSION_NOT_READY, just keep this msg and go on checking password. - if !desktop_err.is_empty() && desktop_err != LOGIN_MSG_XSESSION_NOT_READY { + // If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password. + if !desktop_err.is_empty() && desktop_err != LOGIN_MSG_DESKTOP_SESSION_NOT_READY { self.send_login_error(desktop_err).await; return true; } @@ -1315,7 +1323,7 @@ impl Connection { if desktop_err.is_empty() { self.try_start_cm(lr.my_id, lr.my_name, false); } else { - self.send_login_error(LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_EMPTY) + self.send_login_error(LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY) .await; } } else { @@ -1362,7 +1370,7 @@ impl Connection { self.send_login_error(LOGIN_MSG_PASSWORD_WRONG).await; self.try_start_cm(lr.my_id, lr.my_name, false); } else { - self.send_login_error(LOGIN_MSG_XSESSION_NOT_READY_PASSWORD_WRONG) + self.send_login_error(LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG) .await; } } else { diff --git a/src/ui/common.tis b/src/ui/common.tis index ef6d215aa..92e704052 100644 --- a/src/ui/common.tis +++ b/src/ui/common.tis @@ -262,7 +262,7 @@ function msgbox(type, title, content, link="", callback=null, height=180, width= else msgbox("connecting", "Connecting...", "Logging in..."); } }; - } else if (type == "xsession-login" || type == "xsession-re-login") { + } else if (type == "session-login" || type == "session-re-login") { callback = function (res) { if (!res) { view.close(); @@ -274,7 +274,7 @@ function msgbox(type, title, content, link="", callback=null, height=180, width= else msgbox("connecting", "Connecting...", "Logging in..."); } }; - } else if (type.indexOf("xsession-login") >= 0) { + } else if (type.indexOf("session-login") >= 0) { callback = function (res) { if (!res) { view.close(); diff --git a/src/ui/msgbox.tis b/src/ui/msgbox.tis index d9a311452..2099a8e7b 100644 --- a/src/ui/msgbox.tis +++ b/src/ui/msgbox.tis @@ -32,7 +32,7 @@ class MsgboxComponent: Reactor.Component { } function getIcon(color) { - if (this.type == "input-password" || this.type == "xsession-login" || this.type == "xsession-login-password") { + if (this.type == "input-password" || this.type == "session-login" || this.type == "session-login-password") { return ; } if (this.type == "connecting") { @@ -41,7 +41,7 @@ class MsgboxComponent: Reactor.Component { if (this.type == "success") { return ; } - if (this.type.indexOf("error") >= 0 || this.type == "re-input-password" || this.type == "xsession-re-login" || this.type == "xsession-login-re-password") { + if (this.type.indexOf("error") >= 0 || this.type == "re-input-password" || this.type == "session-re-login" || this.type == "session-login-re-password") { return ; } return null; @@ -81,9 +81,9 @@ class MsgboxComponent: Reactor.Component { function getContent() { if (this.type == "input-password") { return this.getInputPasswordContent(); - } else if (this.type == "xsession-login") { + } else if (this.type == "session-login") { return this.getInputUserPasswordContent(); - } else if (this.type == "xsession-login-password") { + } else if (this.type == "session-login-password") { return this.getXsessionPasswordContent(); } else if (this.type == "custom-os-password") { var ts = this.auto_login ? { checked: true } : {}; @@ -96,13 +96,13 @@ class MsgboxComponent: Reactor.Component { } function getColor() { - if (this.type == "input-password" || this.type == "custom-os-password" || this.type == "xsession-login" || this.type == "xsession-login-password") { + if (this.type == "input-password" || this.type == "custom-os-password" || this.type == "session-login" || this.type == "session-login-password") { return "#AD448E"; } if (this.type == "success") { return "#32bea6"; } - if (this.type.indexOf("error") >= 0 || this.type == "re-input-password" || this.type == "xsession-re-login" || this.type == "xsession-login-re-password") { + if (this.type.indexOf("error") >= 0 || this.type == "re-input-password" || this.type == "session-re-login" || this.type == "session-login-re-password") { return "#e04f5f"; } return "#2C8CFF"; @@ -202,13 +202,13 @@ class MsgboxComponent: Reactor.Component { this.update(); return; } - if (this.type == "xsession-re-login") { - this.type = "xsession-login"; + if (this.type == "session-re-login") { + this.type = "session-login"; this.update(); return; } - if (this.type == "xsession-login-re-password") { - this.type = "xsession-login-password"; + if (this.type == "session-login-re-password") { + this.type = "session-login-password"; this.update(); return; } @@ -273,14 +273,14 @@ class MsgboxComponent: Reactor.Component { return; } } - if (this.type == "xsession-login") { + if (this.type == "session-login") { values.osusername = (values.osusername || "").trim(); values.ospassword = (values.ospassword || "").trim(); if (!values.osusername || !values.ospassword) { return; } } - if (this.type == "xsession-login-password") { + if (this.type == "session-login-password") { values.password = (values.password || "").trim(); values.osusername = (values.osusername || "").trim(); values.ospassword = (values.ospassword || "").trim(); From 9ef4f4c1dea28b2c32b5697f0e394008f46a8405 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 15:36:03 +0800 Subject: [PATCH 19/44] handle_hash empty password Signed-off-by: fufesou --- src/client.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/client.rs b/src/client.rs index 3819ed382..741c45416 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1991,7 +1991,7 @@ pub async fn handle_hash( lc: Arc>, password_preset: &str, hash: Hash, - _interface: &impl Interface, + interface: &impl Interface, peer: &mut Stream, ) { lc.write().unwrap().hash = hash.clone(); @@ -2015,22 +2015,21 @@ pub async fn handle_hash( if password.is_empty() { password = lc.read().unwrap().config.password.clone(); } - if password.is_empty() { + let password = if password.is_empty() { // login without password, the remote side can click accept - send_login(lc.clone(), "".to_owned(), "".to_owned(), Vec::new(), peer).await; + interface.msgbox("input-password", "Password Required", "", ""); + Vec::new() } else { let mut hasher = Sha256::new(); hasher.update(&password); hasher.update(&hash.challenge); - send_login( - lc.clone(), - "".to_owned(), - "".to_owned(), - hasher.finalize()[..].into(), - peer, - ) - .await; - } + hasher.finalize()[..].into() + }; + + let os_username = lc.read().unwrap().get_option("os-username"); + let os_password = lc.read().unwrap().get_option("os-password"); + + send_login(lc.clone(), os_username, os_password, password, peer).await; lc.write().unwrap().hash = hash; } From 34c36153201aa4103b20c488784d24c356d5b7d3 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 16:17:24 +0800 Subject: [PATCH 20/44] get values of seat0, do not filter gdm Signed-off-by: fufesou --- libs/hbb_common/src/platform/linux.rs | 2 +- src/lang/en.rs | 2 +- src/platform/linux.rs | 12 +++++++++ src/platform/linux_desktop_manager.rs | 37 +++++++++++++++++++-------- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index cf1cf6da5..1d826ea97 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -135,7 +135,7 @@ pub fn get_values_of_seat0_with_gdm_wayland(indices: &[usize]) -> Vec { fn _get_values_of_seat0(indices: &[usize], ignore_gdm_wayland: bool) -> Vec { if let Ok(output) = run_loginctl(None) { for line in String::from_utf8_lossy(&output.stdout).lines() { - if !line.contains("gdm") && line.contains("seat0") { + if line.contains("seat0") { if let Some(sid) = line.split_whitespace().next() { if is_active(sid) { if ignore_gdm_wayland { diff --git a/src/lang/en.rs b/src/lang/en.rs index 11ad719ab..2ea65b05f 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -56,7 +56,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("show_monitors_tip", "Show monitors in toolbar."), ("enter_rustdesk_passwd_tip", "Enter RustDesk password"), ("remember_rustdesk_passwd_tip", "Remember RustDesk password"), - ("login_linux_tip", "Remote desktop is unready. Please \n 1. Login on remote side and then try again\n 2. Or input remote account to login and start a X desktop session"), + ("login_linux_tip", "You need to login to remote Linux account to enable a X desktop session"), ("verify_rustdesk_password_tip", "Veryfy RustDesk password"), ("remember_account_tip", "Remember this account"), ("remember_password_tip", "Remember password"), diff --git a/src/platform/linux.rs b/src/platform/linux.rs index fa83fdc1f..800875a61 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -357,6 +357,7 @@ pub fn start_os_service() { &mut last_restart, &mut user_server, ) { + stop_xorg_subprocess(); force_stop_server(); start_server( Some((desktop.uid.clone(), desktop.username.clone())), @@ -402,6 +403,12 @@ pub fn get_active_userid() -> String { get_values_of_seat0(&[1])[0].clone() } +#[inline] +pub fn is_gdm_user(username: &str) -> bool { + username == "gdm" + // || username == "lightgdm" +} + fn get_cm() -> bool { if let Ok(output) = Command::new("ps").args(vec!["aux"]).output() { for line in String::from_utf8_lossy(&output.stdout).lines() { @@ -800,6 +807,11 @@ mod desktop { self.sid.is_empty() } + #[inline] + pub fn is_login_wayland(&self) -> bool { + super::is_gdm_user(&self.username) && self.protocal == ENV_DESKTOP_PROTOCAL_WAYLAND + } + #[inline] pub fn is_headless(&self) -> bool { self.sid.is_empty() || self.is_rustdesk_subprocess diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index f1ddec58e..f1f098c69 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -23,6 +23,7 @@ lazy_static::lazy_static! { #[derive(Debug)] struct DesktopManager { seat0_username: String, + seat0_display_server: String, child_username: String, child_exit: Arc, is_child_running: Arc, @@ -61,8 +62,8 @@ pub fn stop_xdesktop() { pub fn try_start_x_session(username: &str, password: &str) -> ResultType<(String, bool)> { let mut desktop_manager = DESKTOP_MANAGER.lock().unwrap(); if let Some(desktop_manager) = &mut (*desktop_manager) { - if !desktop_manager.seat0_username.is_empty() { - return Ok((desktop_manager.seat0_username.clone(), true)); + if let Some(seat0_username) = desktop_manager.get_supported_display_seat0_username() { + return Ok((seat0_username, true)); } let _ = desktop_manager.try_start_x_session(username, password)?; @@ -86,14 +87,16 @@ pub fn is_headless() -> bool { .lock() .unwrap() .as_ref() - .map_or(false, |manager| manager.seat0_username.is_empty()) + .map_or(false, |manager| { + manager.get_supported_display_seat0_username().is_none() + }) } pub fn get_username() -> String { match &*DESKTOP_MANAGER.lock().unwrap() { Some(manager) => { - if !manager.seat0_username.is_empty() { - manager.seat0_username.clone() + if let Some(seat0_username) = manager.get_supported_display_seat0_username() { + seat0_username } else { if manager.is_running() && !manager.child_username.is_empty() { manager.child_username.clone() @@ -119,28 +122,40 @@ impl DesktopManager { pub fn new() -> Self { let mut seat0_username = "".to_owned(); + let mut seat0_display_server = "".to_owned(); let seat0_values = get_values_of_seat0(&[0, 1, 2]); println!( "REMOVE ME ================================== DesktopManager: {:?}", &seat0_values ); if !seat0_values[0].is_empty() { - let display_server = get_display_server_of_session(&seat0_values[1]); - if display_server == ENV_DESKTOP_PROTOCAL_X11 - || display_server == ENV_DESKTOP_PROTOCAL_WAYLAND - { - seat0_username = seat0_values[2].clone(); - } + seat0_username = seat0_values[2].clone(); + seat0_display_server = get_display_server_of_session(&seat0_values[1]); } Self { seat0_username, + seat0_display_server, child_username: "".to_owned(), child_exit: Arc::new(AtomicBool::new(true)), is_child_running: Arc::new(AtomicBool::new(false)), } } + fn get_supported_display_seat0_username(&self) -> Option { + if is_gdm_user(&self.seat0_username) + && self.seat0_display_server == ENV_DESKTOP_PROTOCAL_WAYLAND + { + None + } else { + if self.seat0_username.is_empty() { + None + } else { + Some(self.seat0_username.clone()) + } + } + } + #[inline] fn get_xauth() -> String { let xauth = get_env_var("XAUTHORITY"); From d82d2471d752633bc170e2d1c250a202d2c42384 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 18:16:48 +0800 Subject: [PATCH 21/44] temp commit Signed-off-by: fufesou --- libs/hbb_common/src/platform/linux.rs | 22 ++++++++++++++++++++-- src/core_main.rs | 5 +++++ src/flutter.rs | 17 ++++++++++++++++- src/platform/linux.rs | 12 ++---------- src/platform/linux_desktop_manager.rs | 16 ++++++++-------- src/server/connection.rs | 17 +++++++++++++++-- src/ui_interface.rs | 8 +++++--- 7 files changed, 71 insertions(+), 26 deletions(-) diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index 1d826ea97..30ceaa760 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -35,6 +35,7 @@ pub fn is_gdm_user(username: &str) -> bool { // || username == "lightgdm" } +<<<<<<< HEAD #[inline] pub fn is_desktop_wayland() -> bool { get_display_server() == DISPLAY_SERVER_WAYLAND @@ -43,12 +44,23 @@ pub fn is_desktop_wayland() -> bool { #[inline] pub fn is_x11_or_headless() -> bool { !is_desktop_wayland() +======= +pub fn is_x11_or_headless() -> bool { + let (username, display_server) = get_user_and_display_server(); + display_server == DISPLAY_SERVER_WAYLAND && is_gdm_user(&username) + || display_server != DISPLAY_SERVER_WAYLAND +} + +pub fn is_desktop_wayland() -> bool { + let (username, display_server) = get_user_and_display_server(); + display_server == DISPLAY_SERVER_WAYLAND && !is_gdm_user(&username) +>>>>>>> temp commit } // -1 const INVALID_SESSION: &str = "4294967295"; -pub fn get_display_server() -> String { +pub fn get_user_and_display_server() -> (String, String) { let mut session = get_values_of_seat0(&[0])[0].clone(); if session.is_empty() { // loginctl has not given the expected output. try something else. @@ -63,11 +75,17 @@ pub fn get_display_server() -> String { } } } +<<<<<<< HEAD if session.is_empty() { +======= + + let display_server = if session.is_empty() { +>>>>>>> temp commit "".to_owned() } else { get_display_server_of_session(&session) - } + }; + (session, display_server) } pub fn get_display_server_of_session(session: &str) -> String { diff --git a/src/core_main.rs b/src/core_main.rs index e5eb64136..05a5ad769 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -224,6 +224,11 @@ pub fn core_main() -> Option> { // call connection manager to establish connections // meanwhile, return true to call flutter window to show control panel crate::ui_interface::start_option_status_sync(); + } else if args[0] == "--cm-no-ui" { + #[cfg(feature = "flutter")] + #[cfg(not(any(target_os = "android", target_os = "ios")))] + crate::flutter::connection_manager::start_cm_no_ui(); + return None; } } //_async_logger_holder.map(|x| x.flush()); diff --git a/src/flutter.rs b/src/flutter.rs index b293059d0..3d49dcf03 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -815,8 +815,19 @@ pub mod connection_manager { } } + #[inline] + #[cfg(not(any(target_os = "android", target_os = "ios")))] + pub fn start_cm_no_ui() { + start_listen_ipc(false); + } + + #[inline] #[cfg(not(any(target_os = "android", target_os = "ios")))] pub fn start_listen_ipc_thread() { + start_listen_ipc(true); + } + + fn start_listen_ipc(new_thread: bool) { use crate::ui_cm_interface::{start_ipc, ConnectionManager}; #[cfg(target_os = "linux")] @@ -825,7 +836,11 @@ pub mod connection_manager { let cm = ConnectionManager { ui_handler: FlutterHandler {}, }; - std::thread::spawn(move || start_ipc(cm)); + if new_thread { + std::thread::spawn(move || start_ipc(cm)); + } else { + start_ipc(cm); + } } #[cfg(target_os = "android")] diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 800875a61..745464a58 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -21,9 +21,6 @@ use std::{ type Xdo = *const c_void; -pub const ENV_DESKTOP_PROTOCAL_WAYLAND: &str = "wayland"; -pub const ENV_DESKTOP_PROTOCAL_X11: &str = "x11"; - pub const PA_SAMPLE_RATE: u32 = 48000; static mut UNMODIFIED: bool = true; @@ -403,12 +400,6 @@ pub fn get_active_userid() -> String { get_values_of_seat0(&[1])[0].clone() } -#[inline] -pub fn is_gdm_user(username: &str) -> bool { - username == "gdm" - // || username == "lightgdm" -} - fn get_cm() -> bool { if let Ok(output) = Command::new("ps").args(vec!["aux"]).output() { for line in String::from_utf8_lossy(&output.stdout).lines() { @@ -809,7 +800,7 @@ mod desktop { #[inline] pub fn is_login_wayland(&self) -> bool { - super::is_gdm_user(&self.username) && self.protocal == ENV_DESKTOP_PROTOCAL_WAYLAND + super::is_gdm_user(&self.username) && self.protocal == DISPLAY_SERVER_WAYLAND } #[inline] @@ -961,6 +952,7 @@ mod desktop { if self.is_login_wayland() { self.display = "".to_owned(); self.xauth = "".to_owned(); + self.is_rustdesk_subprocess = false; return; } diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index f1f098c69..1896060fe 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -123,15 +123,15 @@ impl DesktopManager { pub fn new() -> Self { let mut seat0_username = "".to_owned(); let mut seat0_display_server = "".to_owned(); - let seat0_values = get_values_of_seat0(&[0, 1, 2]); - println!( - "REMOVE ME ================================== DesktopManager: {:?}", - &seat0_values - ); + let seat0_values = get_values_of_seat0(&[0, 2]); if !seat0_values[0].is_empty() { - seat0_username = seat0_values[2].clone(); - seat0_display_server = get_display_server_of_session(&seat0_values[1]); + seat0_username = seat0_values[1].clone(); + seat0_display_server = get_display_server_of_session(&seat0_values[0]); } + println!( + "REMOVE ME ================================== DesktopManager: {:?}, display server: {}", + &seat0_values, &seat0_display_server + ); Self { seat0_username, @@ -144,7 +144,7 @@ impl DesktopManager { fn get_supported_display_seat0_username(&self) -> Option { if is_gdm_user(&self.seat0_username) - && self.seat0_display_server == ENV_DESKTOP_PROTOCAL_WAYLAND + && self.seat0_display_server == DISPLAY_SERVER_WAYLAND { None } else { diff --git a/src/server/connection.rs b/src/server/connection.rs index f9c64378e..2777824df 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -899,8 +899,10 @@ impl Connection { } #[cfg(target_os = "linux")] if !self.file_transfer.is_some() && !self.port_forward_socket.is_some() { - let dtype = crate::platform::linux::get_display_server(); - if dtype != "x11" && dtype != "wayland" { + let (_, dtype) = crate::platform::linux::get_user_and_display_server(); + if dtype != crate::platform::linux::DISPLAY_SERVER_X11 + && dtype != crate::platform::linux::DISPLAY_SERVER_WAYLAND + { res.set_error(format!( "Unsupported display server type \"{}\", x11 or wayland expected", dtype @@ -1131,6 +1133,7 @@ impl Connection { } fn validate_password(&mut self) -> bool { + return true; if password::temporary_enabled() { let password = password::temporary_password(); if self.validate_one_password(password.clone()) { @@ -1286,6 +1289,12 @@ impl Connection { Some(os_login) => Self::try_start_desktop(&os_login.username, &os_login.password), None => Self::try_start_desktop("", ""), }; + + println!( + "REMOVE ME =================================== try_start_desktop '{}'", + &desktop_err + ); + // If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password. if !desktop_err.is_empty() && desktop_err != LOGIN_MSG_DESKTOP_SESSION_NOT_READY { self.send_login_error(desktop_err).await; @@ -2170,6 +2179,10 @@ async fn start_ipc( if password::hide_cm() { args.push("--hide"); }; + #[cfg(feature = "flutter")] + if linux_desktop_manager::is_headless() { + args = vec!["--cm-no-ui"]; + } let run_done; if crate::platform::is_root() { let mut res = Ok(None); diff --git a/src/ui_interface.rs b/src/ui_interface.rs index 11357be4a..1181598a6 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -511,11 +511,13 @@ pub fn get_error() -> String { #[cfg(not(any(feature = "cli")))] #[cfg(target_os = "linux")] { - let dtype = crate::platform::linux::get_display_server(); - if "wayland" == dtype { + let (username, dtype) = crate::platform::linux::get_user_and_display_server(); + if crate::platform::linux::DISPLAY_SERVER_WAYLAND == dtype + && !crate::platform::linux::is_gdm_user(&username) + { return crate::server::wayland::common_get_error(); } - if dtype != "x11" { + if dtype != crate::platform::linux::DISPLAY_SERVER_X11 { return format!( "{} {}, {}", crate::client::translate("Unsupported display server".to_owned()), From d86ef4a86ebeafdf3e20b438aebb6413257ec141 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 18:39:21 +0800 Subject: [PATCH 22/44] headless, linux, debug Signed-off-by: fufesou --- libs/hbb_common/src/platform/linux.rs | 6 ++++-- src/platform/linux.rs | 1 + src/server/video_service.rs | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index 30ceaa760..ce0782a61 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -61,7 +61,9 @@ pub fn is_desktop_wayland() -> bool { const INVALID_SESSION: &str = "4294967295"; pub fn get_user_and_display_server() -> (String, String) { - let mut session = get_values_of_seat0(&[0])[0].clone(); + let seat0_values = get_values_of_seat0(&[0, 2]); + let mut session = seat0_values[0].clone(); + let username = seat0_values[1].clone(); if session.is_empty() { // loginctl has not given the expected output. try something else. if let Ok(sid) = std::env::var("XDG_SESSION_ID") { @@ -85,7 +87,7 @@ pub fn get_user_and_display_server() -> (String, String) { } else { get_display_server_of_session(&session) }; - (session, display_server) + (username, display_server) } pub fn get_display_server_of_session(session: &str) -> String { diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 745464a58..5bfa6a9df 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -464,6 +464,7 @@ pub fn get_env_var(k: &str) -> String { } } +// Headless is enabled, no need to wait prelogin. pub fn is_prelogin() -> bool { let n = get_active_userid().len(); n < 4 && n > 1 diff --git a/src/server/video_service.rs b/src/server/video_service.rs index 205d0584c..483c29cfa 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -450,6 +450,8 @@ fn run(sp: GenericService) -> ResultType<()> { #[cfg(windows)] ensure_close_virtual_device()?; + println!("REMOVE ME ================================= run 111"); + // ensure_inited() is needed because release_resource() may be called. #[cfg(target_os = "linux")] super::wayland::ensure_inited()?; From 4ed6681bfdd554aba284bcca2d32f0d629ac84ed Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 18:52:47 +0800 Subject: [PATCH 23/44] run cm as user Signed-off-by: fufesou --- src/server/connection.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/server/connection.rs b/src/server/connection.rs index 2777824df..1a83cfed6 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2165,6 +2165,8 @@ async fn start_ipc( mut rx_to_cm: mpsc::UnboundedReceiver, tx_from_cm: mpsc::UnboundedSender, ) -> ResultType<()> { + use hbb_common::platform::linux::run_cmds; + loop { if crate::platform::is_prelogin() { break; @@ -2179,8 +2181,21 @@ async fn start_ipc( if password::hide_cm() { args.push("--hide"); }; + #[cfg(not(feature = "flutter"))] + let user = None; + let mut user = None; #[cfg(feature = "flutter")] if linux_desktop_manager::is_headless() { + let username = linux_desktop_manager::get_username(); + let uid = { + let output = run_cmds(format!("id -u {}", &username))?; + let output = output.trim(); + if output.is_empty() || !output.parse::().is_ok() { + bail!("Invalid username {}", &username); + } + output.to_string() + }; + user = Some((username, uid)); args = vec!["--cm-no-ui"]; } let run_done; @@ -2195,7 +2210,7 @@ async fn start_ipc( #[cfg(target_os = "linux")] { log::debug!("Start cm"); - res = crate::platform::run_as_user(args.clone(), None); + res = crate::platform::run_as_user(args.clone(), user); } if res.is_ok() { break; From b33ae6ec64085d5690622bbf073c099b123f2ac0 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 18:55:03 +0800 Subject: [PATCH 24/44] fix build Signed-off-by: fufesou --- src/server/connection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/connection.rs b/src/server/connection.rs index 1a83cfed6..24e3af5b1 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2210,7 +2210,7 @@ async fn start_ipc( #[cfg(target_os = "linux")] { log::debug!("Start cm"); - res = crate::platform::run_as_user(args.clone(), user); + res = crate::platform::run_as_user(args.clone(), user.clone()); } if res.is_ok() { break; From 6238098cd0defe4529f58360d3383047e5924172 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 21:17:33 +0800 Subject: [PATCH 25/44] start cm, tmp commit Signed-off-by: fufesou --- src/server/connection.rs | 63 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/src/server/connection.rs b/src/server/connection.rs index 24e3af5b1..28c661537 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -18,6 +18,8 @@ use crate::{ use crate::{common::DEVICE_NAME, flutter::connection_manager::start_channel}; use crate::{ipc, VERSION}; use cidr_utils::cidr::IpCidr; +#[cfg(all(target_os = "linux", feature = "flutter"))] +use hbb_common::platform::linux::run_cmds; use hbb_common::{ config::Config, fs, @@ -148,6 +150,8 @@ pub struct Connection { audio_input_device_before_voice_call: Option, options_in_login: Option, pressed_modifiers: HashSet, + rx_cm_stream_ready: mpsc::Receiver<()>, + tx_desktop_ready: mpsc::Sender<()>, } impl ConnInner { @@ -208,6 +212,8 @@ impl Connection { let (tx_video, mut rx_video) = mpsc::unbounded_channel::<(Instant, Arc)>(); let (tx_input, _rx_input) = std_mpsc::channel(); let mut hbbs_rx = crate::hbbs_http::sync::signal_receiver(); + let (tx_cm_stream_ready, rx_cm_stream_ready) = mpsc::channel(1); + let (tx_desktop_ready, rx_desktop_ready) = mpsc::channel(1); #[cfg(not(any(target_os = "android", target_os = "ios")))] let tx_cloned = tx.clone(); @@ -260,10 +266,14 @@ impl Connection { audio_input_device_before_voice_call: None, options_in_login: None, pressed_modifiers: Default::default(), + rx_cm_stream_ready, + tx_desktop_ready, }; #[cfg(not(any(target_os = "android", target_os = "ios")))] tokio::spawn(async move { - if let Err(err) = start_ipc(rx_to_cm, tx_from_cm).await { + if let Err(err) = + start_ipc(rx_to_cm, tx_from_cm, rx_desktop_ready, tx_cm_stream_ready).await + { log::error!("ipc to connection manager exit: {}", err); } }); @@ -1289,6 +1299,9 @@ impl Connection { Some(os_login) => Self::try_start_desktop(&os_login.username, &os_login.password), None => Self::try_start_desktop("", ""), }; + #[cfg(target_os = "linux")] + let is_headless = linux_desktop_manager::is_headless(); + let wait_ipc_timeout = 10_000; println!( "REMOVE ME =================================== try_start_desktop '{}'", @@ -1320,6 +1333,11 @@ impl Connection { return false; } else if self.is_recent_session() { if desktop_err.is_empty() { + #[cfg(target_os = "linux")] + if is_headless { + self.tx_desktop_ready.send(()).await.ok(); + let _res = timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; + } self.try_start_cm(lr.my_id, lr.my_name, true); self.send_logon_response().await; if self.port_forward_socket.is_some() { @@ -1387,6 +1405,12 @@ impl Connection { LOGIN_FAILURES.lock().unwrap().remove(&self.ip); } if desktop_err.is_empty() { + #[cfg(target_os = "linux")] + if is_headless { + self.tx_desktop_ready.send(()).await.ok(); + let _res = + timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; + } self.send_logon_response().await; self.try_start_cm(lr.my_id, lr.my_name, true); if self.port_forward_socket.is_some() { @@ -2164,9 +2188,9 @@ pub fn insert_switch_sides_uuid(id: String, uuid: uuid::Uuid) { async fn start_ipc( mut rx_to_cm: mpsc::UnboundedReceiver, tx_from_cm: mpsc::UnboundedSender, + mut _rx_desktop_ready: mpsc::Receiver<()>, + tx_stream_ready: mpsc::Sender<()>, ) -> ResultType<()> { - use hbb_common::platform::linux::run_cmds; - loop { if crate::platform::is_prelogin() { break; @@ -2181,12 +2205,25 @@ async fn start_ipc( if password::hide_cm() { args.push("--hide"); }; - #[cfg(not(feature = "flutter"))] + + #[cfg(all(target_os = "linux", not(feature = "flutter")))] let user = None; + #[cfg(all(target_os = "linux", feature = "flutter"))] let mut user = None; - #[cfg(feature = "flutter")] + #[cfg(all(target_os = "linux", feature = "flutter"))] if linux_desktop_manager::is_headless() { - let username = linux_desktop_manager::get_username(); + let mut username = linux_desktop_manager::get_username(); + loop { + if !username.is_empty() { + break; + } + let _res = timeout(500, _rx_desktop_ready.recv()).await; + username = linux_desktop_manager::get_username(); + } + println!( + "REMOVE ME =================================== headless username '{}' ", + &username + ); let uid = { let output = run_cmds(format!("id -u {}", &username))?; let output = output.trim(); @@ -2196,6 +2233,10 @@ async fn start_ipc( output.to_string() }; user = Some((username, uid)); + println!( + "REMOVE ME =================================== headless user '{:?}' ", + &user + ); args = vec!["--cm-no-ui"]; } let run_done; @@ -2210,6 +2251,10 @@ async fn start_ipc( #[cfg(target_os = "linux")] { log::debug!("Start cm"); + println!( + "REMOVE ME =================================== start_ipc 222 '{}' ", + linux_desktop_manager::is_headless() + ); res = crate::platform::run_as_user(args.clone(), user.clone()); } if res.is_ok() { @@ -2224,6 +2269,10 @@ async fn start_ipc( } else { run_done = false; } + println!( + "REMOVE ME =================================== start_ipc 333 '{}' ", + run_done + ); if !run_done { log::debug!("Start cm"); super::CHILD_PROCESS @@ -2242,6 +2291,8 @@ async fn start_ipc( bail!("Failed to connect to connection manager"); } } + + let _res = tx_stream_ready.send(()).await; let mut stream = stream.unwrap(); loop { tokio::select! { From f91514e164f73f494b103db01dcffb7886d76d8f Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 21:35:47 +0800 Subject: [PATCH 26/44] cm-no-ui, debug Signed-off-by: fufesou --- src/platform/linux_desktop_manager.rs | 11 ++++------- src/server/connection.rs | 20 ++------------------ src/server/video_service.rs | 2 -- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index 1896060fe..7b87b9b02 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -143,16 +143,13 @@ impl DesktopManager { } fn get_supported_display_seat0_username(&self) -> Option { - if is_gdm_user(&self.seat0_username) - && self.seat0_display_server == DISPLAY_SERVER_WAYLAND + if is_gdm_user(&self.seat0_username) && self.seat0_display_server == DISPLAY_SERVER_WAYLAND { None + } else if self.seat0_username.is_empty() { + None } else { - if self.seat0_username.is_empty() { - None - } else { - Some(self.seat0_username.clone()) - } + Some(self.seat0_username.clone()) } } diff --git a/src/server/connection.rs b/src/server/connection.rs index 28c661537..e629fa93a 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2217,13 +2217,9 @@ async fn start_ipc( if !username.is_empty() { break; } - let _res = timeout(500, _rx_desktop_ready.recv()).await; + let _res = timeout(1_000, _rx_desktop_ready.recv()).await; username = linux_desktop_manager::get_username(); } - println!( - "REMOVE ME =================================== headless username '{}' ", - &username - ); let uid = { let output = run_cmds(format!("id -u {}", &username))?; let output = output.trim(); @@ -2232,11 +2228,7 @@ async fn start_ipc( } output.to_string() }; - user = Some((username, uid)); - println!( - "REMOVE ME =================================== headless user '{:?}' ", - &user - ); + user = Some((uid, username)); args = vec!["--cm-no-ui"]; } let run_done; @@ -2251,10 +2243,6 @@ async fn start_ipc( #[cfg(target_os = "linux")] { log::debug!("Start cm"); - println!( - "REMOVE ME =================================== start_ipc 222 '{}' ", - linux_desktop_manager::is_headless() - ); res = crate::platform::run_as_user(args.clone(), user.clone()); } if res.is_ok() { @@ -2269,10 +2257,6 @@ async fn start_ipc( } else { run_done = false; } - println!( - "REMOVE ME =================================== start_ipc 333 '{}' ", - run_done - ); if !run_done { log::debug!("Start cm"); super::CHILD_PROCESS diff --git a/src/server/video_service.rs b/src/server/video_service.rs index 483c29cfa..205d0584c 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -450,8 +450,6 @@ fn run(sp: GenericService) -> ResultType<()> { #[cfg(windows)] ensure_close_virtual_device()?; - println!("REMOVE ME ================================= run 111"); - // ensure_inited() is needed because release_resource() may be called. #[cfg(target_os = "linux")] super::wayland::ensure_inited()?; From 39917c174a2b6eb592e6ab19311e42b857b0f275 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 21:54:20 +0800 Subject: [PATCH 27/44] kill --cm-no-ui Signed-off-by: fufesou --- src/platform/linux.rs | 15 ++++++--------- src/platform/linux_desktop_manager.rs | 5 ----- src/server/connection.rs | 5 ----- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 5bfa6a9df..27c0fde48 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -230,6 +230,9 @@ fn stop_xorg_subprocess() { let _ = run_cmds(&format!( r##"ps -ef | grep '/etc/rustdesk/xorg.conf' | grep -v grep | awk '{{printf("kill -9 %d\n", $2)}}' | bash"##, )); + let _ = run_cmds(format!( + r##"ps -ef | grep -E 'rustdesk +--cm-no-ui' | grep -v grep | awk '{{printf("kill -9 %d\n", $2)}}' | bash"##, + )); } fn should_start_server( @@ -302,7 +305,7 @@ fn force_stop_server() { pub fn start_os_service() { stop_rustdesk_servers(); - stop_xorg_subprocess(); + stop_subprocess(); start_uinput_service(); let running = Arc::new(AtomicBool::new(true)); @@ -337,7 +340,7 @@ pub fn start_os_service() { &mut last_restart, &mut server, ) { - stop_xorg_subprocess(); + stop_subprocess(); force_stop_server(); start_server(None, &mut server); } @@ -354,7 +357,7 @@ pub fn start_os_service() { &mut last_restart, &mut user_server, ) { - stop_xorg_subprocess(); + stop_subprocess(); force_stop_server(); start_server( Some((desktop.uid.clone(), desktop.username.clone())), @@ -938,7 +941,6 @@ mod desktop { return; } - println!("REMOVE ME ================================== desktop: refresh"); let seat0_values = get_values_of_seat0(&[0, 1, 2]); if seat0_values[0].is_empty() { *self = Self::default(); @@ -960,11 +962,6 @@ mod desktop { self.get_display(); self.get_xauth(); self.set_is_subprocess(); - - println!( - "REMOVE ME ================================== desktop: {:?}", - self - ); } } } diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index 7b87b9b02..c70724a5e 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -128,11 +128,6 @@ impl DesktopManager { seat0_username = seat0_values[1].clone(); seat0_display_server = get_display_server_of_session(&seat0_values[0]); } - println!( - "REMOVE ME ================================== DesktopManager: {:?}, display server: {}", - &seat0_values, &seat0_display_server - ); - Self { seat0_username, seat0_display_server, diff --git a/src/server/connection.rs b/src/server/connection.rs index e629fa93a..7a9ab86c2 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1303,11 +1303,6 @@ impl Connection { let is_headless = linux_desktop_manager::is_headless(); let wait_ipc_timeout = 10_000; - println!( - "REMOVE ME =================================== try_start_desktop '{}'", - &desktop_err - ); - // If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password. if !desktop_err.is_empty() && desktop_err != LOGIN_MSG_DESKTOP_SESSION_NOT_READY { self.send_login_error(desktop_err).await; From 86c063eecbf4d5d8672c4ff7f32049c0ed71887e Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 22:01:43 +0800 Subject: [PATCH 28/44] remember os account Signed-off-by: fufesou --- flutter/lib/common/widgets/dialog.dart | 4 ++++ src/server/connection.rs | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index 0c61abb0d..6b24c9d28 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -507,6 +507,10 @@ _connectDialog( final osPassword = osPasswordController?.text.trim() ?? ''; final password = passwordController?.text.trim() ?? ''; if (passwordController != null && password.isEmpty) return; + if (rememberAccount) { + bind.sessionPeerOption(id: id, name: 'os-username', value: osUsername); + bind.sessionPeerOption(id: id, name: 'os-password', value: osPassword); + } gFFI.login( osUsername, osPassword, diff --git a/src/server/connection.rs b/src/server/connection.rs index 7a9ab86c2..1a8d807bc 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1143,7 +1143,6 @@ impl Connection { } fn validate_password(&mut self) -> bool { - return true; if password::temporary_enabled() { let password = password::temporary_password(); if self.validate_one_password(password.clone()) { From 8373c5994127f4aba27c3f824090a3a41247fcfa Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 22:44:05 +0800 Subject: [PATCH 29/44] update lang Signed-off-by: fufesou --- src/lang/pl.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lang/pl.rs b/src/lang/pl.rs index d89b6f763..f8c853026 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -480,8 +480,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "Ten plik jest identyczny jak plik na drugim komputerze."), ("show_monitors_tip", "Pokaż monitory w zasobniku."), ("View Mode", "Tryb widoku"), - ("enter_rustdesk_passwd_tip", "Podaj hasło RustDesk."), - ("remember_rustdesk_passwd_tip", "Zapamiętaj hasło RustDesk."), ("login_linux_tip", "Zaloguj do zdalnego konta Linux"), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), ].iter().cloned().collect(); } From 41573a94b4dc90dcfef95e2d2ab900b125afc936 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 23:18:09 +0800 Subject: [PATCH 30/44] win, remove build warnings Signed-off-by: fufesou --- src/server/connection.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/server/connection.rs b/src/server/connection.rs index 1a8d807bc..125800040 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -150,7 +150,9 @@ pub struct Connection { audio_input_device_before_voice_call: Option, options_in_login: Option, pressed_modifiers: HashSet, + #[cfg(target_os = "linux")] rx_cm_stream_ready: mpsc::Receiver<()>, + #[cfg(target_os = "linux")] tx_desktop_ready: mpsc::Sender<()>, } @@ -212,8 +214,8 @@ impl Connection { let (tx_video, mut rx_video) = mpsc::unbounded_channel::<(Instant, Arc)>(); let (tx_input, _rx_input) = std_mpsc::channel(); let mut hbbs_rx = crate::hbbs_http::sync::signal_receiver(); - let (tx_cm_stream_ready, rx_cm_stream_ready) = mpsc::channel(1); - let (tx_desktop_ready, rx_desktop_ready) = mpsc::channel(1); + let (tx_cm_stream_ready, _rx_cm_stream_ready) = mpsc::channel(1); + let (_tx_desktop_ready, rx_desktop_ready) = mpsc::channel(1); #[cfg(not(any(target_os = "android", target_os = "ios")))] let tx_cloned = tx.clone(); @@ -266,8 +268,10 @@ impl Connection { audio_input_device_before_voice_call: None, options_in_login: None, pressed_modifiers: Default::default(), - rx_cm_stream_ready, - tx_desktop_ready, + #[cfg(target_os = "linux")] + rx_cm_stream_ready: _rx_cm_stream_ready, + #[cfg(target_os = "linux")] + tx_desktop_ready: _tx_desktop_ready, }; #[cfg(not(any(target_os = "android", target_os = "ios")))] tokio::spawn(async move { @@ -1300,6 +1304,7 @@ impl Connection { }; #[cfg(target_os = "linux")] let is_headless = linux_desktop_manager::is_headless(); + #[cfg(target_os = "linux")] let wait_ipc_timeout = 10_000; // If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password. From 5fcb30d3c736c91436da04ccb03adba9648388d7 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 23:26:03 +0800 Subject: [PATCH 31/44] restore lang Signed-off-by: fufesou --- flutter/lib/common/widgets/dialog.dart | 2 +- src/lang/ca.rs | 2 +- src/lang/cn.rs | 2 +- src/lang/cs.rs | 2 +- src/lang/da.rs | 2 +- src/lang/de.rs | 2 +- src/lang/el.rs | 2 +- src/lang/en.rs | 1 - src/lang/eo.rs | 2 +- src/lang/es.rs | 2 +- src/lang/fa.rs | 2 +- src/lang/fr.rs | 2 +- src/lang/hu.rs | 2 +- src/lang/id.rs | 2 +- src/lang/it.rs | 2 +- src/lang/ja.rs | 2 +- src/lang/ko.rs | 2 +- src/lang/kz.rs | 2 +- src/lang/nl.rs | 2 +- src/lang/pl.rs | 2 +- src/lang/pt_PT.rs | 2 +- src/lang/ptbr.rs | 2 +- src/lang/ro.rs | 2 +- src/lang/ru.rs | 2 +- src/lang/sk.rs | 2 +- src/lang/sl.rs | 2 +- src/lang/sq.rs | 2 +- src/lang/sr.rs | 2 +- src/lang/sv.rs | 2 +- src/lang/template.rs | 2 +- src/lang/th.rs | 2 +- src/lang/tr.rs | 2 +- src/lang/tw.rs | 2 +- src/lang/ua.rs | 2 +- src/lang/vn.rs | 2 +- 35 files changed, 34 insertions(+), 35 deletions(-) diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index 6b24c9d28..cf1ced92f 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -600,7 +600,7 @@ _connectDialog( autoFocus: osUsernameController == null, ), rememberWidget( - translate('remember_password_tip'), + translate('Remember password'), rememberPassword, (v) { if (v != null) { diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 6f4ce9543..146160fca 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Tancar"), ("Retry", "Reintentar"), ("OK", ""), - ("remember_password_tip", ""), + ("Password Required", "Es necessita la contrasenya"), ("Please enter your password", "Si us plau, introdueixi la seva contrasenya"), ("Remember password", "Recordar contrasenya"), ("Wrong Password", "Contrasenya incorrecta"), diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 5262db44c..3f562ebd4 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "关闭"), ("Retry", "再试"), ("OK", "确认"), - ("remember_password_tip", ""), + ("Password Required", "需要密码"), ("Please enter your password", "请输入密码"), ("Remember password", "记住密码"), ("Wrong Password", "密码错误"), diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 58d10b5ee..aa40f1442 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zavřít"), ("Retry", "Zkusit znovu"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Vyžadováno heslo"), ("Please enter your password", "Zadejte své heslo"), ("Remember password", "Zapamatovat heslo"), ("Wrong Password", "Nesprávné heslo"), diff --git a/src/lang/da.rs b/src/lang/da.rs index 7e6888239..2737336c0 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Luk"), ("Retry", "Prøv igen"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Adgangskode påkrævet"), ("Please enter your password", "Indtast venligst dit kodeord"), ("Remember password", "Husk kodeord"), ("Wrong Password", "Forkert kodeord"), diff --git a/src/lang/de.rs b/src/lang/de.rs index ad9196785..6583c25e5 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Schließen"), ("Retry", "Erneut versuchen"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Passwort erforderlich"), ("Please enter your password", "Bitte geben Sie Ihr Passwort ein"), ("Remember password", "Passwort merken"), ("Wrong Password", "Falsches Passwort"), diff --git a/src/lang/el.rs b/src/lang/el.rs index 50778f4c4..fa0a3f990 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Κλείσιμο"), ("Retry", "Δοκίμασε ξανά"), ("OK", "ΟΚ"), - ("remember_password_tip", ""), + ("Password Required", "Απαιτείται κωδικός πρόσβασης"), ("Please enter your password", "Παρακαλώ εισάγετε τον κωδικό πρόσβασης"), ("Remember password", "Απομνημόνευση κωδικού πρόσβασης"), ("Wrong Password", "Λάθος κωδικός πρόσβασης"), diff --git a/src/lang/en.rs b/src/lang/en.rs index 2ea65b05f..fede80eff 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -59,7 +59,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("login_linux_tip", "You need to login to remote Linux account to enable a X desktop session"), ("verify_rustdesk_password_tip", "Veryfy RustDesk password"), ("remember_account_tip", "Remember this account"), - ("remember_password_tip", "Remember password"), ("os_account_desk_tip", "This account is used to login the remote OS and enable the desktop session in headless"), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 9fcc2b451..0d8815588 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fermi"), ("Retry", "Reprovi"), ("OK", "Konfermi"), - ("remember_password_tip", ""), + ("Password Required", "Pasvorto deviga"), ("Please enter your password", "Bonvolu tajpi vian pasvorton"), ("Remember password", "Memori pasvorton"), ("Wrong Password", "Erara pasvorto"), diff --git a/src/lang/es.rs b/src/lang/es.rs index c8120de49..a9d71dea5 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Cerrar"), ("Retry", "Reintentar"), ("OK", ""), - ("remember_password_tip", ""), + ("Password Required", "Se requiere contraseña"), ("Please enter your password", "Por favor, introduzca su contraseña"), ("Remember password", "Recordar contraseña"), ("Wrong Password", "Contraseña incorrecta"), diff --git a/src/lang/fa.rs b/src/lang/fa.rs index ccf2a670a..f73bf3fec 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "بستن"), ("Retry", "تلاش مجدد"), ("OK", "قبول"), - ("remember_password_tip", ""), + ("Password Required", "رمز عبور لازم است"), ("Please enter your password", "رمز عبور خود را وارد کنید"), ("Remember password", "رمز عبور را به خاطر بسپار"), ("Wrong Password", "رمز عبور اشتباه است"), diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 2ff02d8f9..3279b9175 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fermer"), ("Retry", "Réessayer"), ("OK", "Valider"), - ("remember_password_tip", ""), + ("Password Required", "Mot de passe requis"), ("Please enter your password", "Veuillez saisir votre mot de passe"), ("Remember password", "Mémoriser le mot de passe"), ("Wrong Password", "Mauvais mot de passe"), diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 49e767b84..cfad983a2 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Bezárás"), ("Retry", "Újra"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Jelszó megadása kötelező"), ("Please enter your password", "Kérem írja be a jelszavát"), ("Remember password", "Jelszó megjegyzése"), ("Wrong Password", "Hibás jelszó"), diff --git a/src/lang/id.rs b/src/lang/id.rs index 2c410c0ec..3c0254f8d 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Tutup"), ("Retry", "Ulangi"), ("OK", "Oke"), - ("remember_password_tip", ""), + ("Password Required", "Kata sandi dibutuhkan"), ("Please enter your password", "Silahkan masukkan kata sandi anda"), ("Remember password", "Ingat Password"), ("Wrong Password", "Kata sandi Salah"), diff --git a/src/lang/it.rs b/src/lang/it.rs index 4427743f1..a09bfa97a 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Chiudi"), ("Retry", "Riprova"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Password Richiesta"), ("Please enter your password", "Inserisci la tua password"), ("Remember password", "Ricorda password"), ("Wrong Password", "Password Errata"), diff --git a/src/lang/ja.rs b/src/lang/ja.rs index dba70c1e1..ae153feac 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "閉じる"), ("Retry", "再試行"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "パスワードが必要"), ("Please enter your password", "パスワードを入力してください"), ("Remember password", "パスワードを記憶する"), ("Wrong Password", "パスワードが間違っています"), diff --git a/src/lang/ko.rs b/src/lang/ko.rs index ab7714190..843211c49 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "닫기"), ("Retry", "재시도"), ("OK", "확인"), - ("remember_password_tip", ""), + ("Password Required", "비밀번호 입력"), ("Please enter your password", "비밀번호를 입력해주세요"), ("Remember password", "이 비밀번호 기억하기"), ("Wrong Password", "틀린 비밀번호"), diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 7fe2719cc..b8d665a60 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Жабу"), ("Retry", "Қайтадан көру"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Құпия сөз Қажет"), ("Please enter your password", "Құпия сөзіңізді еңгізуді өтінеміз"), ("Remember password", "Құпия сөзді есте сақтау"), ("Wrong Password", "Бұрыс Құпия сөз"), diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 360166e50..caaf80077 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Sluit"), ("Retry", "Probeer opnieuw"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Wachtwoord vereist"), ("Please enter your password", "Geef uw wachtwoord in"), ("Remember password", "Wachtwoord onthouden"), ("Wrong Password", "Verkeerd wachtwoord"), diff --git a/src/lang/pl.rs b/src/lang/pl.rs index f8c853026..c1f2ef3dc 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zamknij"), ("Retry", "Ponów"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Wymagane jest hasło"), ("Please enter your password", "Wpisz proszę twoje hasło"), ("Remember password", "Zapamiętaj hasło"), ("Wrong Password", "Błędne hasło"), diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index c23aa1e46..880658ff4 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fechar"), ("Retry", "Tentar novamente"), ("OK", "Confirmar"), - ("remember_password_tip", ""), + ("Password Required", "Palavra-chave Necessária"), ("Please enter your password", "Por favor introduza a sua palavra-chave"), ("Remember password", "Memorizar palavra-chave"), ("Wrong Password", "Palavra-chave inválida"), diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index c741944a1..fe7f4a36b 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Fechar"), ("Retry", "Tentar novamente"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Senha necessária"), ("Please enter your password", "Por favor informe sua senha"), ("Remember password", "Lembrar senha"), ("Wrong Password", "Senha incorreta"), diff --git a/src/lang/ro.rs b/src/lang/ro.rs index d77345356..046774f32 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Închide"), ("Retry", "Reîncearcă"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Parolă necesară"), ("Please enter your password", "Introdu parola"), ("Remember password", "Memorează parola"), ("Wrong Password", "Parolă incorectă"), diff --git a/src/lang/ru.rs b/src/lang/ru.rs index fbd1c4c62..ac87dcb48 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Закрыть"), ("Retry", "Повторить"), ("OK", "ОК"), - ("remember_password_tip", ""), + ("Password Required", "Требуется пароль"), ("Please enter your password", "Введите пароль"), ("Remember password", "Запомнить пароль"), ("Wrong Password", "Неправильный пароль"), diff --git a/src/lang/sk.rs b/src/lang/sk.rs index efa66f7ae..1a156d8a6 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zatvoriť"), ("Retry", "Zopakovať"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Vyžaduje sa heslo"), ("Please enter your password", "Zadajte vaše heslo"), ("Remember password", "Zapamätať heslo"), ("Wrong Password", "Chybné heslo"), diff --git a/src/lang/sl.rs b/src/lang/sl.rs index d897e4755..1f07b027c 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zapri"), ("Retry", "Ponovi"), ("OK", "V redu"), - ("remember_password_tip", ""), + ("Password Required", "Potrebno je geslo"), ("Please enter your password", "Vnesite vaše geslo"), ("Remember password", "Zapomni si geslo"), ("Wrong Password", "Napačno geslo"), diff --git a/src/lang/sq.rs b/src/lang/sq.rs index 88d678ed3..558984a1b 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Mbyll"), ("Retry", "Riprovo"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Fjalëkalimi i detyrueshëm"), ("Please enter your password", "Ju lutem vendosni fjalëkalimin tuaj"), ("Remember password", "Mbani mend fjalëkalimin"), ("Wrong Password", "Fjalëkalim i gabuar"), diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 078d9ba29..3ec1d32d1 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Zatvori"), ("Retry", "Ponovi"), ("OK", "Ok"), - ("remember_password_tip", ""), + ("Password Required", "Potrebna lozinka"), ("Please enter your password", "Molimo unesite svoju lozinku"), ("Remember password", "Zapamti lozinku"), ("Wrong Password", "Pogrešna lozinka"), diff --git a/src/lang/sv.rs b/src/lang/sv.rs index df5caee28..93bbaf74e 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Stäng"), ("Retry", "Försök igen"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Lösenord krävs"), ("Please enter your password", "Skriv in ditt lösenord"), ("Remember password", "Kom ihåg lösenord"), ("Wrong Password", "Fel lösenord"), diff --git a/src/lang/template.rs b/src/lang/template.rs index 1b8bf69c2..db1519e9d 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", ""), ("Retry", ""), ("OK", ""), - ("remember_password_tip", ""), + ("Password Required", ""), ("Please enter your password", ""), ("Remember password", ""), ("Wrong Password", ""), diff --git a/src/lang/th.rs b/src/lang/th.rs index a152eb7b1..1b41ff694 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "ปิด"), ("Retry", "ลองใหม่อีกครั้ง"), ("OK", "ตกลง"), - ("remember_password_tip", ""), + ("Password Required", "ต้องใช้รหัสผ่าน"), ("Please enter your password", "กรุณาใส่รหัสผ่านของคุณ"), ("Remember password", "จดจำรหัสผ่าน"), ("Wrong Password", "รหัสผ่านไม่ถูกต้อง"), diff --git a/src/lang/tr.rs b/src/lang/tr.rs index c5d21460a..0aa49a3e4 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Kapat"), ("Retry", "Tekrar Dene"), ("OK", "Tamam"), - ("remember_password_tip", ""), + ("Password Required", "Şifre Gerekli"), ("Please enter your password", "Lütfen şifrenizi giriniz"), ("Remember password", "Şifreyi hatırla"), ("Wrong Password", "Hatalı şifre"), diff --git a/src/lang/tw.rs b/src/lang/tw.rs index d2156f4b7..0077fdaad 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "關閉"), ("Retry", "重試"), ("OK", "確定"), - ("remember_password_tip", ""), + ("Password Required", "需要密碼"), ("Please enter your password", "請輸入您的密碼"), ("Remember password", "記住密碼"), ("Wrong Password", "密碼錯誤"), diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 1a91bb879..811bcd913 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Закрити"), ("Retry", "Спробувати знову"), ("OK", "ОК"), - ("remember_password_tip", ""), + ("Password Required", "Потрібен пароль"), ("Please enter your password", "Будь ласка, введіть ваш пароль"), ("Remember password", "Запам'ятати пароль"), ("Wrong Password", "Невірний пароль"), diff --git a/src/lang/vn.rs b/src/lang/vn.rs index eeafcfa54..6ad03f0f8 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -68,7 +68,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Close", "Đóng"), ("Retry", "Thử lại"), ("OK", "OK"), - ("remember_password_tip", ""), + ("Password Required", "Yêu cầu mật khẩu"), ("Please enter your password", "Mời nhập mật khẩu"), ("Remember password", "Nhớ mật khẩu"), ("Wrong Password", "Sai mật khẩu"), From b18bfa749b9747dd7067d28e3c8284b408638031 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 30 Mar 2023 23:46:06 +0800 Subject: [PATCH 32/44] remove wait_prelogin Signed-off-by: fufesou --- src/platform/linux.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 27c0fde48..b3fde7808 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -467,7 +467,7 @@ pub fn get_env_var(k: &str) -> String { } } -// Headless is enabled, no need to wait prelogin. +// Headless is enabled, always return true. pub fn is_prelogin() -> bool { let n = get_active_userid().len(); n < 4 && n > 1 From 8ea63af4b510ab9503b2d2aa6761c27fc39bc7ed Mon Sep 17 00:00:00 2001 From: fufesou Date: Fri, 31 Mar 2023 09:49:00 +0800 Subject: [PATCH 33/44] fix build android Signed-off-by: fufesou --- src/flutter.rs | 1 + src/server/connection.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/flutter.rs b/src/flutter.rs index 3d49dcf03..6c9ff7f37 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -827,6 +827,7 @@ pub mod connection_manager { start_listen_ipc(true); } + #[cfg(not(any(target_os = "android", target_os = "ios")))] fn start_listen_ipc(new_thread: bool) { use crate::ui_cm_interface::{start_ipc, ConnectionManager}; diff --git a/src/server/connection.rs b/src/server/connection.rs index 125800040..8a8714c6f 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -214,7 +214,9 @@ impl Connection { let (tx_video, mut rx_video) = mpsc::unbounded_channel::<(Instant, Arc)>(); let (tx_input, _rx_input) = std_mpsc::channel(); let mut hbbs_rx = crate::hbbs_http::sync::signal_receiver(); + #[cfg(not(any(target_os = "android", target_os = "ios")))] let (tx_cm_stream_ready, _rx_cm_stream_ready) = mpsc::channel(1); + #[cfg(not(any(target_os = "android", target_os = "ios")))] let (_tx_desktop_ready, rx_desktop_ready) = mpsc::channel(1); #[cfg(not(any(target_os = "android", target_os = "ios")))] From ee3ac310833ddc447e3e0e293d44286088550bba Mon Sep 17 00:00:00 2001 From: fufesou Date: Fri, 31 Mar 2023 10:25:58 +0800 Subject: [PATCH 34/44] add deps libpam0g-dev Signed-off-by: fufesou --- .github/workflows/flutter-nightly.yml | 2 +- libs/hbb_common/src/platform/linux.rs | 30 +++++---------------------- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index ab625e431..5aa82b847 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -11,4 +11,4 @@ jobs: uses: ./.github/workflows/flutter-build.yml with: upload-artifact: true - \ No newline at end of file + diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index ce0782a61..89c96799d 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -35,7 +35,6 @@ pub fn is_gdm_user(username: &str) -> bool { // || username == "lightgdm" } -<<<<<<< HEAD #[inline] pub fn is_desktop_wayland() -> bool { get_display_server() == DISPLAY_SERVER_WAYLAND @@ -44,26 +43,13 @@ pub fn is_desktop_wayland() -> bool { #[inline] pub fn is_x11_or_headless() -> bool { !is_desktop_wayland() -======= -pub fn is_x11_or_headless() -> bool { - let (username, display_server) = get_user_and_display_server(); - display_server == DISPLAY_SERVER_WAYLAND && is_gdm_user(&username) - || display_server != DISPLAY_SERVER_WAYLAND -} - -pub fn is_desktop_wayland() -> bool { - let (username, display_server) = get_user_and_display_server(); - display_server == DISPLAY_SERVER_WAYLAND && !is_gdm_user(&username) ->>>>>>> temp commit } // -1 const INVALID_SESSION: &str = "4294967295"; -pub fn get_user_and_display_server() -> (String, String) { - let seat0_values = get_values_of_seat0(&[0, 2]); - let mut session = seat0_values[0].clone(); - let username = seat0_values[1].clone(); +pub fn get_display_server() -> String { + let mut session = get_values_of_seat0(&[0])[0].clone(); if session.is_empty() { // loginctl has not given the expected output. try something else. if let Ok(sid) = std::env::var("XDG_SESSION_ID") { @@ -77,17 +63,11 @@ pub fn get_user_and_display_server() -> (String, String) { } } } -<<<<<<< HEAD if session.is_empty() { -======= - - let display_server = if session.is_empty() { ->>>>>>> temp commit "".to_owned() } else { get_display_server_of_session(&session) - }; - (username, display_server) + } } pub fn get_display_server_of_session(session: &str) -> String { @@ -211,7 +191,7 @@ pub fn run_cmds(cmds: &str) -> ResultType { } #[cfg(not(feature = "flatpak"))] -pub(super) fn run_loginctl(args: Option>) -> std::io::Result { +fn run_loginctl(args: Option>) -> std::io::Result { let mut cmd = std::process::Command::new("loginctl"); if let Some(a) = args { return cmd.args(a).output(); @@ -220,7 +200,7 @@ pub(super) fn run_loginctl(args: Option>) -> std::io::Result>) -> std::io::Result { +fn run_loginctl(args: Option>) -> std::io::Result { let mut l_args = String::from("loginctl"); if let Some(a) = args { l_args = format!("{} {}", l_args, a.join(" ")); From 571c1df5c446885dfc388527df30c643478d0257 Mon Sep 17 00:00:00 2001 From: fufesou Date: Fri, 31 Mar 2023 17:49:35 +0800 Subject: [PATCH 35/44] fix build Signed-off-by: fufesou --- src/platform/linux.rs | 14 ++------------ src/platform/linux_desktop_manager.rs | 2 +- src/server/connection.rs | 4 ++-- src/ui_interface.rs | 3 +-- 4 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/platform/linux.rs b/src/platform/linux.rs index b3fde7808..33ebcc82c 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -226,11 +226,11 @@ fn stop_rustdesk_servers() { } #[inline] -fn stop_xorg_subprocess() { +fn stop_subprocess() { let _ = run_cmds(&format!( r##"ps -ef | grep '/etc/rustdesk/xorg.conf' | grep -v grep | awk '{{printf("kill -9 %d\n", $2)}}' | bash"##, )); - let _ = run_cmds(format!( + let _ = run_cmds(&format!( r##"ps -ef | grep -E 'rustdesk +--cm-no-ui' | grep -v grep | awk '{{printf("kill -9 %d\n", $2)}}' | bash"##, )); } @@ -797,16 +797,6 @@ mod desktop { super::is_gdm_user(&self.username) && self.protocal == DISPLAY_SERVER_WAYLAND } - #[inline] - pub fn is_headless(&self) -> bool { - self.sid.is_empty() - } - - #[inline] - pub fn is_login_wayland(&self) -> bool { - super::is_gdm_user(&self.username) && self.protocal == DISPLAY_SERVER_WAYLAND - } - #[inline] pub fn is_headless(&self) -> bool { self.sid.is_empty() || self.is_rustdesk_subprocess diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index c70724a5e..3a72f8976 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -373,7 +373,7 @@ impl DesktopManager { fn wait_x_server_running(pid: u32, display_num: u32, max_wait_secs: u64) -> ResultType<()> { let wait_begin = Instant::now(); loop { - if run_cmds(format!("ls /proc/{}", pid))?.is_empty() { + if run_cmds(&format!("ls /proc/{}", pid))?.is_empty() { bail!("X server exit"); } diff --git a/src/server/connection.rs b/src/server/connection.rs index 8a8714c6f..65a3fd025 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -915,7 +915,7 @@ impl Connection { } #[cfg(target_os = "linux")] if !self.file_transfer.is_some() && !self.port_forward_socket.is_some() { - let (_, dtype) = crate::platform::linux::get_user_and_display_server(); + let dtype = crate::platform::linux::get_display_server(); if dtype != crate::platform::linux::DISPLAY_SERVER_X11 && dtype != crate::platform::linux::DISPLAY_SERVER_WAYLAND { @@ -2222,7 +2222,7 @@ async fn start_ipc( username = linux_desktop_manager::get_username(); } let uid = { - let output = run_cmds(format!("id -u {}", &username))?; + let output = run_cmds(&format!("id -u {}", &username))?; let output = output.trim(); if output.is_empty() || !output.parse::().is_ok() { bail!("Invalid username {}", &username); diff --git a/src/ui_interface.rs b/src/ui_interface.rs index 1181598a6..fa73490ad 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -511,9 +511,8 @@ pub fn get_error() -> String { #[cfg(not(any(feature = "cli")))] #[cfg(target_os = "linux")] { - let (username, dtype) = crate::platform::linux::get_user_and_display_server(); + let dtype = crate::platform::linux::get_display_server(); if crate::platform::linux::DISPLAY_SERVER_WAYLAND == dtype - && !crate::platform::linux::is_gdm_user(&username) { return crate::server::wayland::common_get_error(); } From 73358502e93062d3012fbcc223e322d911e1f8c4 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 1 Apr 2023 00:28:56 +0800 Subject: [PATCH 36/44] linux headless feature, tmp commit Signed-off-by: fufesou --- Cargo.toml | 5 +- libs/hbb_common/src/config.rs | 13 ++- src/client.rs | 119 +++++++++++++++++--------- src/client/io_loop.rs | 1 + src/lang/ca.rs | 16 +++- src/lang/cn.rs | 16 +++- src/lang/cs.rs | 16 +++- src/lang/da.rs | 16 +++- src/lang/de.rs | 16 +++- src/lang/el.rs | 16 +++- src/lang/en.rs | 15 ++++ src/lang/eo.rs | 16 +++- src/lang/es.rs | 16 +++- src/lang/fa.rs | 16 +++- src/lang/fr.rs | 1 - src/lang/hu.rs | 16 +++- src/lang/id.rs | 16 +++- src/lang/it.rs | 16 +++- src/lang/ja.rs | 16 +++- src/lang/ko.rs | 16 +++- src/lang/kz.rs | 16 +++- src/lang/nl.rs | 16 +++- src/lang/pl.rs | 16 +++- src/lang/pt_PT.rs | 16 +++- src/lang/ptbr.rs | 16 +++- src/lang/ro.rs | 16 +++- src/lang/ru.rs | 16 +++- src/lang/sk.rs | 16 +++- src/lang/sl.rs | 16 +++- src/lang/sq.rs | 16 +++- src/lang/sr.rs | 16 +++- src/lang/sv.rs | 16 +++- src/lang/template.rs | 16 +++- src/lang/th.rs | 16 +++- src/lang/tr.rs | 16 +++- src/lang/tw.rs | 16 +++- src/lang/ua.rs | 16 +++- src/lang/vn.rs | 16 +++- src/platform/linux_desktop_manager.rs | 81 ++++++++++++++++-- src/platform/mod.rs | 2 +- src/rendezvous_mediator.rs | 4 +- src/server/connection.rs | 105 +++++++++++------------ 42 files changed, 713 insertions(+), 145 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 10f90f387..48bd16045 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ flutter = ["flutter_rust_bridge"] default = ["use_dasp"] hwcodec = ["scrap/hwcodec"] mediacodec = ["scrap/mediacodec"] +linux_headless = ["pam", "users"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -122,8 +123,8 @@ mouce = { git="https://github.com/fufesou/mouce.git" } evdev = { git="https://github.com/fufesou/evdev" } dbus = "0.9" dbus-crossroads = "0.5" -pam = { git="https://github.com/fufesou/pam" } -users = "0.11.0" +pam = { git="https://github.com/fufesou/pam", optional = true } +users = { version = "0.11.0", optional = true } [target.'cfg(target_os = "android")'.dependencies] android_logger = "0.11" diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index 3841bf976..e6c788f9a 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -64,11 +64,15 @@ lazy_static::lazy_static! { pub static ref APP_HOME_DIR: Arc> = Default::default(); } -// #[cfg(any(target_os = "android", target_os = "ios"))] +pub const LINK_DOCS_HOME: &str = "https://rustdesk.com/docs/en/"; +pub const LINK_DOCS_X11_REQUIRED: &str = "https://rustdesk.com/docs/en/manual/linux/#x11-required"; +pub const LINK_HEADLESS_LINUX_SUPPORT: &str = + "https://github.com/rustdesk/rustdesk/wiki/Headless-Linux-Support"; lazy_static::lazy_static! { pub static ref HELPER_URL: HashMap<&'static str, &'static str> = HashMap::from([ - ("rustdesk docs home", "https://rustdesk.com/docs/en/"), - ("rustdesk docs x11-required", "https://rustdesk.com/docs/en/manual/linux/#x11-required"), + ("rustdesk docs home", LINK_DOCS_HOME), + ("rustdesk docs x11-required", LINK_DOCS_X11_REQUIRED), + ("rustdesk x11 headless", LINK_HEADLESS_LINUX_SUPPORT), ]); } @@ -917,7 +921,8 @@ impl PeerConfig { store = store || store2; for opt in ["rdp_password", "os-username", "os-password"] { if let Some(v) = config.options.get_mut(opt) { - let (encrypted, _, store2) = decrypt_str_or_original(v, PASSWORD_ENC_VERSION); + let (encrypted, _, store2) = + decrypt_str_or_original(v, PASSWORD_ENC_VERSION); *v = encrypted; store = store || store2; } diff --git a/src/client.rs b/src/client.rs index 741c45416..3f587dfe0 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1912,6 +1912,71 @@ fn _input_os_password(p: String, activate: bool, interface: impl Interface) { interface.send(Data::Message(msg_out)); } +#[derive(Copy, Clone)] +struct LoginErrorMsgBox { + msgtype: &'static str, + title: &'static str, + text: &'static str, + link: &'static str, + try_again: bool, +} + +lazy_static::lazy_static! { + static ref LOGIN_ERROR_MAP: Arc> = { + use hbb_common::config::LINK_HEADLESS_LINUX_SUPPORT; + let map = HashMap::from([(crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY, LoginErrorMsgBox{ + msgtype: "session-login", + title: "session_not_ready_title_tip", + text: "session_not_ready_text_tip", + link: "", + try_again: true, + }), (crate::server::LOGIN_MSG_DESKTOP_XSESSION_FAILED, LoginErrorMsgBox{ + msgtype: "session-re-login", + title: "xsession_failed_title_tip", + text: "xsession_failed_text_tip", + link: "", + try_again: true, + }), (crate::server::LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER, LoginErrorMsgBox{ + msgtype: "info", + title: "another_user_login_title_tip", + text: "another_user_login_text_tip", + link: "", + try_again: false, + }), (crate::server::LOGIN_MSG_DESKTOP_XORG_NOT_FOUND, LoginErrorMsgBox{ + msgtype: "session-re-login", + title: "xorg_not_found_title_tip", + text: "xorg_not_found_text_tip", + link: LINK_HEADLESS_LINUX_SUPPORT, + try_again: true, + }), (crate::server::LOGIN_MSG_DESKTOP_NO_DESKTOP, LoginErrorMsgBox{ + msgtype: "session-re-login", + title: "no_desktop_title_tip", + text: "no_desktop_text_tip", + link: LINK_HEADLESS_LINUX_SUPPORT, + try_again: true, + }), (crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY, LoginErrorMsgBox{ + msgtype: "session-login-password", + title: "session_unready_no_password_title_tip", + text: "session_unready_no_password_text_tip", + link: "", + try_again: true, + }), (crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG, LoginErrorMsgBox{ + msgtype: "session-login-re-password", + title: "session_unready_wrong_password_title_tip", + text: "session_unready_wrong_password_text_tip", + link: "", + try_again: true, + }), (crate::server::LOGIN_MSG_NO_PASSWORD_ACCESS, LoginErrorMsgBox{ + msgtype: "wait-remote-accept-nook", + title: "Prompt", + text: "no_password_access_text_tip", + link: "", + try_again: true, + })]); + Arc::new(map) + }; +} + /// Handle login error. /// Return true if the password is wrong, return false if there's an actual error. pub fn handle_login_error( @@ -1927,47 +1992,19 @@ pub fn handle_login_error( lc.write().unwrap().password = Default::default(); interface.msgbox("re-input-password", err, "Do you want to enter again?", ""); true - } else if err == crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY { - interface.msgbox( - "session-login", - "session is unready", - "Input linux user/password", - "", - ); - true - } else if err == crate::server::LOGIN_MSG_DESKTOP_XSESSION_FAILED { - interface.msgbox( - "session-re-login", - "xsession username/password is wrong", - "Do you want to enter again?", - "", - ); - true - } else if err == crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY { - interface.msgbox( - "session-login-password", - "session is unready", - "Input connection password and linux user/password", - "", - ); - true - } else if err == crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG { - interface.msgbox( - "session-login-re-password", - "session is unready and password is wrong", - "Do you want to enter again?", - "", - ); - true - } else if err == "No Password Access" { - lc.write().unwrap().password = Default::default(); - interface.msgbox( - "wait-remote-accept-nook", - "Prompt", - "Please wait for the remote side to accept your session request...", - "", - ); - true + } else if LOGIN_ERROR_MAP.contains_key(err) { + if let Some(msgbox_info) = LOGIN_ERROR_MAP.get(err) { + interface.msgbox( + msgbox_info.msgtype, + msgbox_info.title, + msgbox_info.text, + msgbox_info.link, + ); + msgbox_info.try_again + } else { + // unreachable! + false + } } else { if err.contains(SCRAP_X11_REQUIRED) { interface.msgbox("error", "Login Error", err, SCRAP_X11_REF_URL); diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index c1c38af40..ab8b76a7f 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -1256,6 +1256,7 @@ impl Remote { }, Some(message::Union::MessageBox(msgbox)) => { let mut link = msgbox.link; + // Links from remote side must be verified. if !link.starts_with("rustdesk://") { if let Some(v) = hbb_common::config::HELPER_URL.get(&link as &str) { link = v.to_string(); diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 146160fca..3dc8cdb12 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 3f562ebd4..b8df31c77 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "只允许密码访问"), ("Accept sessions via click", "只允许点击访问"), ("Accept sessions via both", "允许密码或点击访问"), - ("Please wait for the remote side to accept your session request...", "请等待对方接受你的连接..."), ("One-time Password", "一次性密码"), ("Use one-time password", "使用一次性密码"), ("One-time password length", "一次性密码长度"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", "记住此账户"), ("os_account_desk_tip", "在无显示器的环境下,此账户用于登录被控系统,并启用桌面"), ("OS Account", "系统账户"), + ("session_not_ready_title_tip", "桌面 session 未准备好"), + ("session_not_ready_text_tip", "请输入用户名密码"), + ("xsession_failed_title_tip", "用户名密码错误"), + ("xsession_failed_text_tip", "是否重试"), + ("another_user_login_title_tip", "其他用户已登录"), + ("another_user_login_text_tip", "断开"), + ("xorg_not_found_title_tip", "Xorg 未安装"), + ("xorg_not_found_text_tip", "请安装 Xorg"), + ("no_desktop_title_tip", "desktop 未安装"), + ("no_desktop_text_tip", "请安装 desktop"), + ("session_unready_no_password_title_tip", "桌面 session 未准备好"), + ("session_unready_no_password_text_tip", "请输入用户名密码和连接密码"), + ("session_unready_wrong_password_title_tip", "密码错误"), + ("session_unready_wrong_password_text_tip", "是否重试"), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index aa40f1442..020bea621 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 2737336c0..754b9671c 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Acceptér sessioner via adgangskode"), ("Accept sessions via click", "Acceptér sessioner via klik"), ("Accept sessions via both", "Acceptér sessioner via begge"), - ("Please wait for the remote side to accept your session request...", "Vent venligst på at fjernklienten accepterer din sessionsforespørgsel..."), ("One-time Password", "Engangskode"), ("Use one-time password", "Brug engangskode"), ("One-time password length", "Engangskode længde"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 6583c25e5..3d72a0242 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Sitzung mit Passwort bestätigen"), ("Accept sessions via click", "Sitzung mit einem Klick bestätigen"), ("Accept sessions via both", "Sitzung mit Klick und Passwort bestätigen"), - ("Please wait for the remote side to accept your session request...", "Bitte warten Sie, bis die Gegenseite Ihre Sitzungsanfrage akzeptiert hat …"), ("One-time Password", "Einmalpasswort"), ("Use one-time password", "Einmalpasswort verwenden"), ("One-time password length", "Länge des Einmalpassworts"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index fa0a3f990..b10d9f971 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Αποδοχή συνεδριών με κωδικό πρόσβασης"), ("Accept sessions via click", "Αποδοχή συνεδριών με κλικ"), ("Accept sessions via both", "Αποδοχή συνεδριών και με τα δύο"), - ("Please wait for the remote side to accept your session request...", "Παρακαλώ περιμένετε μέχρι η απομακρυσμένη πλευρά να αποδεχτεί το αίτημα συνεδρίας σας..."), ("One-time Password", "Κωδικός μίας χρήσης"), ("Use one-time password", "Χρήση κωδικού πρόσβασης μίας χρήσης"), ("One-time password length", "Μήκος κωδικού πρόσβασης μίας χρήσης"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index fede80eff..6035db7ba 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -60,5 +60,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("verify_rustdesk_password_tip", "Veryfy RustDesk password"), ("remember_account_tip", "Remember this account"), ("os_account_desk_tip", "This account is used to login the remote OS and enable the desktop session in headless"), + ("session_not_ready_title_tip", "Session is unready"), + ("session_not_ready_text_tip", "Input linux user/password"), + ("xsession_failed_title_tip", "Xsession username/password is wrong"), + ("xsession_failed_text_tip", "Do you want to enter again"), + ("another_user_login_title_tip", "Another user already login"), + ("another_user_login_text_tip", "Disconnect"), + ("xorg_not_found_title_tip", "Xorg not found"), + ("xorg_not_found_text_tip", "Please install Xorg"), + ("no_desktop_title_tip", "No desktop is avaliable"), + ("no_desktop_text_tip", "Please install GNOME desktop"), + ("session_unready_no_password_title_tip", "Session is unready"), + ("session_unready_no_password_text_tip", "Input connection password and linux user/password"), + ("session_unready_wrong_password_title_tip", "Password is wrong"), + ("session_unready_wrong_password_text_tip", "Do you want to enter again"), + ("no_password_access_text_tip", "Please wait for the remote side to accept your session request..."), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 0d8815588..3f2a0d573 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index a9d71dea5..9f06fff59 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Aceptar sesiones a través de contraseña"), ("Accept sessions via click", "Aceptar sesiones a través de clic"), ("Accept sessions via both", "Aceptar sesiones a través de ambos"), - ("Please wait for the remote side to accept your session request...", "Por favor, espere a que el lado remoto acepte su solicitud de sesión"), ("One-time Password", "Constaseña de un solo uso"), ("Use one-time password", "Usar contraseña de un solo uso"), ("One-time password length", "Longitud de la contraseña de un solo uso"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index f73bf3fec..1fad5bba1 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "قبول درخواست با رمز عبور"), ("Accept sessions via click", "قبول درخواست با کلیک موس"), ("Accept sessions via both", "قبول درخواست با هر دو"), - ("Please wait for the remote side to accept your session request...", "...لطفا صبر کنید تا میزبان درخواست شما را قبول کند"), ("One-time Password", "رمز عبور یکبار مصرف"), ("Use one-time password", "استفاده از رمز عبور یکبار مصرف"), ("One-time password length", "طول رمز عبور یکبار مصرف"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 3279b9175..58a65b3f4 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Accepter les sessions via mot de passe"), ("Accept sessions via click", "Accepter les sessions via clique de confirmation"), ("Accept sessions via both", "Accepter les sessions via mot de passe ou clique de confirmation"), - ("Please wait for the remote side to accept your session request...", "Veuillez attendre que votre demande de session distante soit accepter ..."), ("One-time Password", "Mot de passe unique"), ("Use one-time password", "Utiliser un mot de passe unique"), ("One-time password length", "Longueur du mot de passe unique"), diff --git a/src/lang/hu.rs b/src/lang/hu.rs index cfad983a2..5075802f1 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 3c0254f8d..4f87a926c 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Izinkan sesi dengan kata sandi"), ("Accept sessions via click", "Izinkan sesi dengan klik"), ("Accept sessions via both", "Izinkan sesi dengan keduanya"), - ("Please wait for the remote side to accept your session request...", "Harap tunggu sisi jarak jauh untuk menerima permintaan sesi Anda..."), ("One-time Password", "Kata sandi satu kali"), ("Use one-time password", "Gunakan kata sandi satu kali"), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index a09bfa97a..14a50ede9 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Accetta sessioni via password"), ("Accept sessions via click", "Accetta sessioni via click"), ("Accept sessions via both", "Accetta sessioni con entrambi"), - ("Please wait for the remote side to accept your session request...", "Attendere che il lato remoto accetti la richiesta di sessione..."), ("One-time Password", "Password monouso"), ("Use one-time password", "Usa password monouso"), ("One-time password length", "Lunghezza password monouso"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index ae153feac..e91137d8c 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 843211c49..c7c654632 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index b8d665a60..5422083bb 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index caaf80077..b043b8f7f 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Sessies accepteren via wachtwoord"), ("Accept sessions via click", "Sessies accepteren via klik"), ("Accept sessions via both", "Accepteer sessies via beide"), - ("Please wait for the remote side to accept your session request...", "Wacht tot de andere kant uw sessieverzoek accepteert..."), ("One-time Password", "Eenmalig Wachtwoord"), ("Use one-time password", "Gebruik een eenmalig Wachtwoord"), ("One-time password length", "Eenmalig Wachtwoord lengre"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index c1f2ef3dc..938a4e881 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Uwierzytelnij sesję używając hasła"), ("Accept sessions via click", "Uwierzytelnij sesję poprzez kliknięcie"), ("Accept sessions via both", "Uwierzytelnij sesję za pomocą obu sposobów"), - ("Please wait for the remote side to accept your session request...", "Oczekiwanie, na zatwierdzenie sesji przez host zdalny..."), ("One-time Password", "Hasło jednorazowe"), ("Use one-time password", "Użyj hasła jednorazowego"), ("One-time password length", "Długość hasła jednorazowego"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 880658ff4..ae4dbccba 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index fe7f4a36b..c9c0b84f7 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Aceitar sessões via senha"), ("Accept sessions via click", "Aceitar sessões via clique"), ("Accept sessions via both", "Aceitar sessões de ambos os modos"), - ("Please wait for the remote side to accept your session request...", "Por favor aguarde enquanto o cliente remoto aceita seu pedido de sessão..."), ("One-time Password", "Senha de uso único"), ("Use one-time password", "Usar senha de uso único"), ("One-time password length", "Comprimento da senha de uso único"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index 046774f32..d6632d18a 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Acceptă sesiunile folosind parola"), ("Accept sessions via click", "Acceptă sesiunile cu un clic de confirmare"), ("Accept sessions via both", "Acceptă sesiunile folosind ambele moduri"), - ("Please wait for the remote side to accept your session request...", "Așteaptă ca solicitarea ta de conectare la distanță să fie acceptată..."), ("One-time Password", "Parolă unică"), ("Use one-time password", "Folosește parola unică"), ("One-time password length", "Lungimea parolei unice"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index ac87dcb48..a99523fca 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Принимать сеансы по паролю"), ("Accept sessions via click", "Принимать сеансы по нажатию"), ("Accept sessions via both", "Принимать сеансы по паролю+нажатию"), - ("Please wait for the remote side to accept your session request...", "Подождите, пока удалённая сторона примет ваш запрос на сеанс..."), ("One-time Password", "Одноразовый пароль"), ("Use one-time password", "Использовать одноразовый пароль"), ("One-time password length", "Длина одноразового пароля"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 1a156d8a6..7a8b9a778 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 1f07b027c..581507457 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Sprejmi seje z geslom"), ("Accept sessions via click", "Sprejmi seje s potrditvijo"), ("Accept sessions via both", "Sprejmi seje z geslom ali potrditvijo"), - ("Please wait for the remote side to accept your session request...", "Počakajte, da oddaljeni računalnik sprejme povezavo..."), ("One-time Password", "Enkratno geslo"), ("Use one-time password", "Uporabi enkratno geslo"), ("One-time password length", "Dolžina enkratnega gesla"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index 558984a1b..eb1b50762 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Prano sesionin nëpërmjet fjalëkalimit"), ("Accept sessions via click", "Prano sesionet nëpërmjet klikimit"), ("Accept sessions via both", "Prano sesionet nëpërmjet të dyjave"), - ("Please wait for the remote side to accept your session request...", "Ju lutem prisni që ana në distancë të pranoj kërkësen tuaj"), ("One-time Password", "Fjalëkalim Një-herë"), ("Use one-time password", "Përdorni fjalëkalim Një-herë"), ("One-time password length", "Gjatësia e fjalëkalimit një herë"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 3ec1d32d1..260eadc24 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Prihvati sesije preko lozinke"), ("Accept sessions via click", "Prihvati sesije preko klika"), ("Accept sessions via both", "Prihvati sesije preko oboje"), - ("Please wait for the remote side to accept your session request...", "Molimo sačekajte da udaljena strana prihvati vaš zahtev za sesijom..."), ("One-time Password", "Jednokratna lozinka"), ("Use one-time password", "Koristi jednokratnu lozinku"), ("One-time password length", "Dužina jednokratne lozinke"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 93bbaf74e..9db56dcc9 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Acceptera sessioner via lösenord"), ("Accept sessions via click", "Acceptera sessioner via klick"), ("Accept sessions via both", "Acceptera sessioner via båda"), - ("Please wait for the remote side to accept your session request...", "Var god vänta på att klienten accepterar din förfrågan..."), ("One-time Password", "En-gångs lösenord"), ("Use one-time password", "Använd en-gångs lösenord"), ("One-time password length", "Längd på en-gångs lösenord"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index db1519e9d..ac4413201 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 1b41ff694..11260f440 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "ยอมรับการเชื่อมต่อด้วยรหัสผ่าน"), ("Accept sessions via click", "ยอมรับการเชื่อมต่อด้วยการคลิก"), ("Accept sessions via both", "ยอมรับการเชื่อมต่อด้วยทั้งสองวิธิ"), - ("Please wait for the remote side to accept your session request...", "กรุณารอให้อีกฝั่งยอมรับการเชื่อมต่อของคุณ..."), ("One-time Password", "รหัสผ่านครั้งเดียว"), ("Use one-time password", "ใช้รหัสผ่านครั้งเดียว"), ("One-time password length", "ความยาวรหัสผ่านครั้งเดียว"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 0aa49a3e4..b76484b33 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Oturumları parola ile kabul etme"), ("Accept sessions via click", "Tıklama yoluyla oturumları kabul edin"), ("Accept sessions via both", "Her ikisi aracılığıyla oturumları kabul edin"), - ("Please wait for the remote side to accept your session request...", "Lütfen uzak tarafın oturum isteğinizi kabul etmesini bekleyin..."), ("One-time Password", "Tek Kullanımlık Şifre"), ("Use one-time password", "Tek seferlik parola kullanın"), ("One-time password length", "Tek seferlik şifre uzunluğu"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 0077fdaad..f77014e8f 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "只允許透過輸入密碼進行連線"), ("Accept sessions via click", "只允許透過點擊接受進行連線"), ("Accept sessions via both", "允許輸入密碼或點擊接受進行連線"), - ("Please wait for the remote side to accept your session request...", "請等待對方接受您的連線請求 ..."), ("One-time Password", "一次性密碼"), ("Use one-time password", "使用一次性密碼"), ("One-time password length", "一次性密碼長度"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 811bcd913..873dad281 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Підтверджувати сеанси паролем"), ("Accept sessions via click", "Підтверджувати сеанси натисканням"), ("Accept sessions via both", "Підтверджувати сеанси обома способами"), - ("Please wait for the remote side to accept your session request...", "Буль ласка, зачекайте, поки віддалена сторона підтвердить запит на сеанс..."), ("One-time Password", "Одноразовий пароль"), ("Use one-time password", "Використати одноразовий пароль"), ("One-time password length", "Довжина одноразового пароля"), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 6ad03f0f8..7756b8894 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -402,7 +402,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), - ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -485,5 +484,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index 3a72f8976..e9dc00ef6 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -1,4 +1,9 @@ use super::{linux::*, ResultType}; +use crate::server::{ + LOGIN_MSG_DESKTOP_NO_DESKTOP, LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER, + LOGIN_MSG_DESKTOP_SESSION_NOT_READY, LOGIN_MSG_DESKTOP_XORG_NOT_FOUND, + LOGIN_MSG_DESKTOP_XSESSION_FAILED, +}; use hbb_common::{allow_err, bail, log, rand::prelude::*, tokio::time}; use pam; use std::{ @@ -59,7 +64,65 @@ pub fn stop_xdesktop() { *DESKTOP_MANAGER.lock().unwrap() = None; } -pub fn try_start_x_session(username: &str, password: &str) -> ResultType<(String, bool)> { +pub fn try_start_desktop(_username: &str, _passsword: &str) -> String { + if _username.is_empty() { + let username = get_username(); + if username.is_empty() { + LOGIN_MSG_DESKTOP_SESSION_NOT_READY + } else { + "" + } + .to_owned() + } else { + let username = get_username(); + if username == _username { + // No need to verify password here. + return "".to_owned(); + } + + match run_cmds(&format!("which {}", DesktopManager::get_xorg())) { + Ok(output) => { + if output.trim().is_empty() { + return LOGIN_MSG_DESKTOP_XORG_NOT_FOUND.to_owned(); + } + } + _ => { + return LOGIN_MSG_DESKTOP_XORG_NOT_FOUND.to_owned(); + } + } + + match run_cmds("ls /usr/share/xsessions/") { + Ok(output) => { + if output.trim().is_empty() { + return LOGIN_MSG_DESKTOP_NO_DESKTOP.to_owned(); + } + } + _ => { + return LOGIN_MSG_DESKTOP_NO_DESKTOP.to_owned(); + } + } + + match try_start_x_session(_username, _passsword) { + Ok((username, x11_ready)) => { + if x11_ready { + if _username != username { + LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER.to_owned() + } else { + "".to_owned() + } + } else { + LOGIN_MSG_DESKTOP_SESSION_NOT_READY.to_owned() + } + } + Err(e) => { + log::error!("Failed to start xsession {}", e); + LOGIN_MSG_DESKTOP_XSESSION_FAILED.to_owned() + } + } + } +} + +fn try_start_x_session(username: &str, password: &str) -> ResultType<(String, bool)> { let mut desktop_manager = DESKTOP_MANAGER.lock().unwrap(); if let Some(desktop_manager) = &mut (*desktop_manager) { if let Some(seat0_username) = desktop_manager.get_supported_display_seat0_username() { @@ -547,36 +610,36 @@ impl DesktopManager { } } - fn get_xorg() -> ResultType<&'static str> { + fn get_xorg() -> &'static str { // Fedora 26 or later let xorg = "/usr/libexec/Xorg"; if Path::new(xorg).is_file() { - return Ok(xorg); + return xorg; } // Debian 9 or later let xorg = "/usr/lib/xorg/Xorg"; if Path::new(xorg).is_file() { - return Ok(xorg); + return xorg; } // Ubuntu 16.04 or later let xorg = "/usr/lib/xorg/Xorg"; if Path::new(xorg).is_file() { - return Ok(xorg); + return xorg; } // Arch Linux let xorg = "/usr/lib/xorg-server/Xorg"; if Path::new(xorg).is_file() { - return Ok(xorg); + return xorg; } // Arch Linux let xorg = "/usr/lib/Xorg"; if Path::new(xorg).is_file() { - return Ok(xorg); + return xorg; } // CentOS 7 /usr/bin/Xorg or param=Xorg log::warn!("Failed to find xorg, use default Xorg.\n Please add \"allowed_users=anybody\" to \"/etc/X11/Xwrapper.config\"."); - Ok("Xorg") + "Xorg" } fn start_x_server( @@ -586,7 +649,7 @@ impl DesktopManager { gid: u32, envs: &HashMap<&str, String>, ) -> ResultType { - let xorg = Self::get_xorg()?; + let xorg = Self::get_xorg(); log::info!("Use xorg: {}", &xorg); match Command::new(xorg) .envs(envs) diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 7c9b2f0b0..fc27be098 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -17,7 +17,7 @@ pub mod delegate; #[cfg(target_os = "linux")] pub mod linux; -#[cfg(target_os = "linux")] +#[cfg(all(target_os = "linux", feature = "linux_headless"))] pub mod linux_desktop_manager; #[cfg(not(any(target_os = "android", target_os = "ios")))] diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 3fef9747b..cc93dbb45 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -72,7 +72,7 @@ impl RendezvousMediator { allow_err!(super::lan::start_listening()); }); } - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", feature = "linux_headless"))] crate::platform::linux_desktop_manager::start_xdesktop(); SHOULD_EXIT.store(false, Ordering::SeqCst); while !SHOULD_EXIT.load(Ordering::SeqCst) { @@ -99,7 +99,7 @@ impl RendezvousMediator { } sleep(1.).await; } - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", feature = "linux_headless"))] crate::platform::linux_desktop_manager::stop_xdesktop(); } diff --git a/src/server/connection.rs b/src/server/connection.rs index 65a3fd025..b442ff899 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -3,7 +3,7 @@ use super::{input_service::*, *}; use crate::clipboard_file::*; #[cfg(not(any(target_os = "android", target_os = "ios")))] use crate::common::update_clipboard; -#[cfg(target_os = "linux")] +#[cfg(all(target_os = "linux", feature = "linux_headless"))] use crate::platform::linux_desktop_manager; #[cfg(windows)] use crate::portable_service::client as portable_client; @@ -18,7 +18,7 @@ use crate::{ use crate::{common::DEVICE_NAME, flutter::connection_manager::start_channel}; use crate::{ipc, VERSION}; use cidr_utils::cidr::IpCidr; -#[cfg(all(target_os = "linux", feature = "flutter"))] +#[cfg(all(target_os = "linux", feature = "linux_headless"))] use hbb_common::platform::linux::run_cmds; use hbb_common::{ config::Config, @@ -65,12 +65,16 @@ pub const LOGIN_MSG_DESKTOP_NOT_INITED: &str = "Desktop env is not inited"; pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY: &str = "Desktop session unready"; pub const LOGIN_MSG_DESKTOP_XSESSION_FAILED: &str = "Desktop xsession failed"; pub const LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER: &str = "Desktop session another user login"; +pub const LOGIN_MSG_DESKTOP_XORG_NOT_FOUND: &str = "Desktop xorg not found"; +// ls /usr/share/xsessions/ +pub const LOGIN_MSG_DESKTOP_NO_DESKTOP: &str = "Desktop none"; pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY: &str = "Desktop session unready, password empty"; pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG: &str = "Desktop session unready, password wrong"; pub const LOGIN_MSG_PASSWORD_EMPTY: &str = "Empty Password"; pub const LOGIN_MSG_PASSWORD_WRONG: &str = "Wrong Password"; +pub const LOGIN_MSG_NO_PASSWORD_ACCESS: &str = "No Password Access"; pub const LOGIN_MSG_OFFLINE: &str = "Offline"; #[derive(Clone, Default)] @@ -150,9 +154,9 @@ pub struct Connection { audio_input_device_before_voice_call: Option, options_in_login: Option, pressed_modifiers: HashSet, - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", feature = "linux_headless"))] rx_cm_stream_ready: mpsc::Receiver<()>, - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", feature = "linux_headless"))] tx_desktop_ready: mpsc::Sender<()>, } @@ -270,9 +274,9 @@ impl Connection { audio_input_device_before_voice_call: None, options_in_login: None, pressed_modifiers: Default::default(), - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", feature = "linux_headless"))] rx_cm_stream_ready: _rx_cm_stream_ready, - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", feature = "linux_headless"))] tx_desktop_ready: _tx_desktop_ready, }; #[cfg(not(any(target_os = "android", target_os = "ios")))] @@ -886,6 +890,7 @@ impl Connection { if crate::platform::current_is_wayland() { platform_additions.insert("is_wayland".into(), json!(true)); } + #[cfg(feature = "linux_headless")] if linux_desktop_manager::is_headless() { platform_additions.insert("headless".into(), json!(true)); } @@ -1096,45 +1101,6 @@ impl Connection { self.tx_input.send(MessageInput::Key((msg, press))).ok(); } - fn try_start_desktop(_username: &str, _passsword: &str) -> String { - #[cfg(target_os = "linux")] - if _username.is_empty() { - let username = linux_desktop_manager::get_username(); - if username.is_empty() { - LOGIN_MSG_DESKTOP_SESSION_NOT_READY - } else { - "" - } - .to_owned() - } else { - let username = linux_desktop_manager::get_username(); - if username == _username { - // No need to verify password here. - return "".to_owned(); - } - - match linux_desktop_manager::try_start_x_session(_username, _passsword) { - Ok((username, x11_ready)) => { - if x11_ready { - if _username != username { - LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER.to_owned() - } else { - "".to_owned() - } - } else { - LOGIN_MSG_DESKTOP_SESSION_NOT_READY.to_owned() - } - } - Err(e) => { - log::error!("Failed to start xsession {}", e); - LOGIN_MSG_DESKTOP_XSESSION_FAILED.to_owned() - } - } - } - #[cfg(not(target_os = "linux"))] - "".to_owned() - } - fn validate_one_password(&self, password: String) -> bool { if password.len() == 0 { return false; @@ -1300,16 +1266,20 @@ impl Connection { _ => {} } + #[cfg(all(target_os = "linux", feature = "linux_headless"))] let desktop_err = match lr.os_login.as_ref() { - Some(os_login) => Self::try_start_desktop(&os_login.username, &os_login.password), - None => Self::try_start_desktop("", ""), + Some(os_login) => { + linux_desktop_manager::try_start_desktop(&os_login.username, &os_login.password) + } + None => linux_desktop_manager::try_start_desktop("", ""), }; - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", feature = "linux_headless"))] let is_headless = linux_desktop_manager::is_headless(); - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", feature = "linux_headless"))] let wait_ipc_timeout = 10_000; // If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password. + #[cfg(all(target_os = "linux", feature = "linux_headless"))] if !desktop_err.is_empty() && desktop_err != LOGIN_MSG_DESKTOP_SESSION_NOT_READY { self.send_login_error(desktop_err).await; return true; @@ -1324,7 +1294,7 @@ impl Connection { if hbb_common::get_version_number(&lr.version) >= hbb_common::get_version_number("1.2.0") { - self.send_login_error("No Password Access").await; + self.send_login_error(LOGIN_MSG_NO_PASSWORD_ACCESS).await; } return true; } else if password::approve_mode() == ApproveMode::Password @@ -1333,6 +1303,7 @@ impl Connection { self.send_login_error("Connection not allowed").await; return false; } else if self.is_recent_session() { + #[cfg(all(target_os = "linux", feature = "linux_headless"))] if desktop_err.is_empty() { #[cfg(target_os = "linux")] if is_headless { @@ -1347,13 +1318,24 @@ impl Connection { } else { self.send_login_error(desktop_err).await; } + #[cfg(not(all(target_os = "linux", feature = "linux_headless")))] + { + self.try_start_cm(lr.my_id, lr.my_name, true); + self.send_logon_response().await; + if self.port_forward_socket.is_some() { + return false; + } + } } else if lr.password.is_empty() { + #[cfg(all(target_os = "linux", feature = "linux_headless"))] if desktop_err.is_empty() { self.try_start_cm(lr.my_id, lr.my_name, false); } else { self.send_login_error(LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY) .await; } + #[cfg(not(all(target_os = "linux", feature = "linux_headless")))] + self.try_start_cm(lr.my_id, lr.my_name, false); } else { let mut failure = LOGIN_FAILURES .lock() @@ -1394,6 +1376,7 @@ impl Connection { .lock() .unwrap() .insert(self.ip.clone(), failure); + #[cfg(all(target_os = "linux", feature = "linux_headless"))] if desktop_err.is_empty() { self.send_login_error(LOGIN_MSG_PASSWORD_WRONG).await; self.try_start_cm(lr.my_id, lr.my_name, false); @@ -1401,10 +1384,16 @@ impl Connection { self.send_login_error(LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG) .await; } + #[cfg(not(all(target_os = "linux", feature = "linux_headless")))] + { + self.send_login_error(LOGIN_MSG_PASSWORD_WRONG).await; + self.try_start_cm(lr.my_id, lr.my_name, false); + } } else { if failure.0 != 0 { LOGIN_FAILURES.lock().unwrap().remove(&self.ip); } + #[cfg(all(target_os = "linux", feature = "linux_headless"))] if desktop_err.is_empty() { #[cfg(target_os = "linux")] if is_headless { @@ -1420,6 +1409,14 @@ impl Connection { } else { self.send_login_error(desktop_err).await; } + #[cfg(not(all(target_os = "linux", feature = "linux_headless")))] + { + self.send_logon_response().await; + self.try_start_cm(lr.my_id, lr.my_name, true); + if self.port_forward_socket.is_some() { + return false; + } + } } } } else if let Some(message::Union::TestDelay(t)) = msg.union { @@ -2207,11 +2204,13 @@ async fn start_ipc( args.push("--hide"); }; - #[cfg(all(target_os = "linux", not(feature = "flutter")))] + #[cfg(target_os = "linux")] + #[cfg(not(feature = "linux_headless"))] let user = None; - #[cfg(all(target_os = "linux", feature = "flutter"))] + #[cfg(all(target_os = "linux", feature = "linux_headless"))] let mut user = None; - #[cfg(all(target_os = "linux", feature = "flutter"))] + // Cm run as user, wait until desktop session is ready. + #[cfg(all(target_os = "linux", feature = "linux_headless"))] if linux_desktop_manager::is_headless() { let mut username = linux_desktop_manager::get_username(); loop { From 5eedbdb436b719656fcf885e4d74ecd945cc2965 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 1 Apr 2023 22:24:42 +0800 Subject: [PATCH 37/44] tmp commit Signed-off-by: fufesou --- src/lang/fr.rs | 22 +++++++++++++++++++--- src/server/connection.rs | 4 ++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 58a65b3f4..96ac0d7bd 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -479,9 +479,25 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("identical_file_tip", "Ce fichier est identique à celui du pair."), ("show_monitors_tip", "Afficher les moniteurs dans la barre d'outils."), ("View Mode", "Mode vue"), - ("enter_rustdesk_passwd_tip", "Saisissez le mot de passe RustDesk."), - ("remember_rustdesk_passwd_tip", "Se rappeler du mot de passe RustDesk."), ("login_linux_tip", "Se connecter au compte Linux distant"), - ("login_linux_tooltip_tip", "Vous devez vous connecter à un compte Linux distant pour activer une session de bureau X."), + ("verify_rustdesk_password_tip", ""), + ("remember_account_tip", ""), + ("os_account_desk_tip", ""), + ("OS Account", ""), + ("session_not_ready_title_tip", ""), + ("session_not_ready_text_tip", ""), + ("xsession_failed_title_tip", ""), + ("xsession_failed_text_tip", ""), + ("another_user_login_title_tip", ""), + ("another_user_login_text_tip", ""), + ("xorg_not_found_title_tip", ""), + ("xorg_not_found_text_tip", ""), + ("no_desktop_title_tip", ""), + ("no_desktop_text_tip", ""), + ("session_unready_no_password_title_tip", ""), + ("session_unready_no_password_text_tip", ""), + ("session_unready_wrong_password_title_tip", ""), + ("session_unready_wrong_password_text_tip", ""), + ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/server/connection.rs b/src/server/connection.rs index b442ff899..297ab18c7 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -942,7 +942,7 @@ impl Connection { } #[cfg(not(any(target_os = "android", target_os = "ios")))] if self.file_transfer.is_some() { - if !crate::platform::is_prelogin() || self.tx_to_cm.send(ipc::Data::Test).is_err() { + if crate::platform::is_prelogin() || self.tx_to_cm.send(ipc::Data::Test).is_err() { username = "".to_owned(); } } @@ -2190,7 +2190,7 @@ async fn start_ipc( tx_stream_ready: mpsc::Sender<()>, ) -> ResultType<()> { loop { - if crate::platform::is_prelogin() { + if !crate::platform::is_prelogin() { break; } sleep(1.).await; From 86313fa32855121b497478b29c8448e4e07d2f8b Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 1 Apr 2023 22:47:57 +0800 Subject: [PATCH 38/44] revert lang Signed-off-by: fufesou --- src/client.rs | 2 +- src/lang/ca.rs | 2 +- src/lang/cn.rs | 2 +- src/lang/cs.rs | 2 +- src/lang/da.rs | 2 +- src/lang/de.rs | 2 +- src/lang/el.rs | 2 +- src/lang/en.rs | 1 - src/lang/eo.rs | 2 +- src/lang/es.rs | 2 +- src/lang/fa.rs | 2 +- src/lang/fr.rs | 2 +- src/lang/hu.rs | 2 +- src/lang/id.rs | 2 +- src/lang/it.rs | 2 +- src/lang/ja.rs | 2 +- src/lang/ko.rs | 2 +- src/lang/kz.rs | 2 +- src/lang/nl.rs | 2 +- src/lang/pl.rs | 2 +- src/lang/pt_PT.rs | 2 +- src/lang/ptbr.rs | 2 +- src/lang/ro.rs | 2 +- src/lang/ru.rs | 2 +- src/lang/sk.rs | 2 +- src/lang/sl.rs | 2 +- src/lang/sq.rs | 2 +- src/lang/sr.rs | 2 +- src/lang/sv.rs | 2 +- src/lang/template.rs | 2 +- src/lang/th.rs | 2 +- src/lang/tr.rs | 2 +- src/lang/tw.rs | 2 +- src/lang/ua.rs | 2 +- src/lang/vn.rs | 2 +- 35 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/client.rs b/src/client.rs index 3f587dfe0..a541a8458 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1969,7 +1969,7 @@ lazy_static::lazy_static! { }), (crate::server::LOGIN_MSG_NO_PASSWORD_ACCESS, LoginErrorMsgBox{ msgtype: "wait-remote-accept-nook", title: "Prompt", - text: "no_password_access_text_tip", + text: "Please wait for the remote side to accept your session request...", link: "", try_again: true, })]); diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 3dc8cdb12..230a9730b 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index b8df31c77..7f0e40581 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "只允许密码访问"), ("Accept sessions via click", "只允许点击访问"), ("Accept sessions via both", "允许密码或点击访问"), + ("Please wait for the remote side to accept your session request...", "请等待对方接受你的连接..."), ("One-time Password", "一次性密码"), ("Use one-time password", "使用一次性密码"), ("One-time password length", "一次性密码长度"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", "请输入用户名密码和连接密码"), ("session_unready_wrong_password_title_tip", "密码错误"), ("session_unready_wrong_password_text_tip", "是否重试"), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 020bea621..7237b7a79 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 754b9671c..f761832da 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Acceptér sessioner via adgangskode"), ("Accept sessions via click", "Acceptér sessioner via klik"), ("Accept sessions via both", "Acceptér sessioner via begge"), + ("Please wait for the remote side to accept your session request...", "Vent venligst på at fjernklienten accepterer din sessionsforespørgsel..."), ("One-time Password", "Engangskode"), ("Use one-time password", "Brug engangskode"), ("One-time password length", "Engangskode længde"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 3d72a0242..e77ab938c 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Sitzung mit Passwort bestätigen"), ("Accept sessions via click", "Sitzung mit einem Klick bestätigen"), ("Accept sessions via both", "Sitzung mit Klick und Passwort bestätigen"), + ("Please wait for the remote side to accept your session request...", "Bitte warten Sie, bis die Gegenseite Ihre Sitzungsanfrage akzeptiert hat …"), ("One-time Password", "Einmalpasswort"), ("Use one-time password", "Einmalpasswort verwenden"), ("One-time password length", "Länge des Einmalpassworts"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index b10d9f971..3703aad27 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Αποδοχή συνεδριών με κωδικό πρόσβασης"), ("Accept sessions via click", "Αποδοχή συνεδριών με κλικ"), ("Accept sessions via both", "Αποδοχή συνεδριών και με τα δύο"), + ("Please wait for the remote side to accept your session request...", "Παρακαλώ περιμένετε μέχρι η απομακρυσμένη πλευρά να αποδεχτεί το αίτημα συνεδρίας σας..."), ("One-time Password", "Κωδικός μίας χρήσης"), ("Use one-time password", "Χρήση κωδικού πρόσβασης μίας χρήσης"), ("One-time password length", "Μήκος κωδικού πρόσβασης μίας χρήσης"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index 6035db7ba..e6499ea1c 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -74,6 +74,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", "Input connection password and linux user/password"), ("session_unready_wrong_password_title_tip", "Password is wrong"), ("session_unready_wrong_password_text_tip", "Do you want to enter again"), - ("no_password_access_text_tip", "Please wait for the remote side to accept your session request..."), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 3f2a0d573..645c8be7c 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index 9f06fff59..7a672dfec 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Aceptar sesiones a través de contraseña"), ("Accept sessions via click", "Aceptar sesiones a través de clic"), ("Accept sessions via both", "Aceptar sesiones a través de ambos"), + ("Please wait for the remote side to accept your session request...", "Por favor, espere a que el lado remoto acepte su solicitud de sesión"), ("One-time Password", "Constaseña de un solo uso"), ("Use one-time password", "Usar contraseña de un solo uso"), ("One-time password length", "Longitud de la contraseña de un solo uso"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 1fad5bba1..281478bb0 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "قبول درخواست با رمز عبور"), ("Accept sessions via click", "قبول درخواست با کلیک موس"), ("Accept sessions via both", "قبول درخواست با هر دو"), + ("Please wait for the remote side to accept your session request...", "...لطفا صبر کنید تا میزبان درخواست شما را قبول کند"), ("One-time Password", "رمز عبور یکبار مصرف"), ("Use one-time password", "استفاده از رمز عبور یکبار مصرف"), ("One-time password length", "طول رمز عبور یکبار مصرف"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 96ac0d7bd..1c4126377 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Accepter les sessions via mot de passe"), ("Accept sessions via click", "Accepter les sessions via clique de confirmation"), ("Accept sessions via both", "Accepter les sessions via mot de passe ou clique de confirmation"), + ("Please wait for the remote side to accept your session request...", "Veuillez attendre que votre demande de session distante soit accepter ..."), ("One-time Password", "Mot de passe unique"), ("Use one-time password", "Utiliser un mot de passe unique"), ("One-time password length", "Longueur du mot de passe unique"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 5075802f1..547107607 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 4f87a926c..c896db6ba 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Izinkan sesi dengan kata sandi"), ("Accept sessions via click", "Izinkan sesi dengan klik"), ("Accept sessions via both", "Izinkan sesi dengan keduanya"), + ("Please wait for the remote side to accept your session request...", "Harap tunggu sisi jarak jauh untuk menerima permintaan sesi Anda..."), ("One-time Password", "Kata sandi satu kali"), ("Use one-time password", "Gunakan kata sandi satu kali"), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 14a50ede9..0d1b6914e 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Accetta sessioni via password"), ("Accept sessions via click", "Accetta sessioni via click"), ("Accept sessions via both", "Accetta sessioni con entrambi"), + ("Please wait for the remote side to accept your session request...", "Attendere che il lato remoto accetti la richiesta di sessione..."), ("One-time Password", "Password monouso"), ("Use one-time password", "Usa password monouso"), ("One-time password length", "Lunghezza password monouso"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index e91137d8c..b7cfaf40f 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index c7c654632..849fa7ffb 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 5422083bb..b7e242eaa 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index b043b8f7f..6cd679953 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Sessies accepteren via wachtwoord"), ("Accept sessions via click", "Sessies accepteren via klik"), ("Accept sessions via both", "Accepteer sessies via beide"), + ("Please wait for the remote side to accept your session request...", "Wacht tot de andere kant uw sessieverzoek accepteert..."), ("One-time Password", "Eenmalig Wachtwoord"), ("Use one-time password", "Gebruik een eenmalig Wachtwoord"), ("One-time password length", "Eenmalig Wachtwoord lengre"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 938a4e881..529289751 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Uwierzytelnij sesję używając hasła"), ("Accept sessions via click", "Uwierzytelnij sesję poprzez kliknięcie"), ("Accept sessions via both", "Uwierzytelnij sesję za pomocą obu sposobów"), + ("Please wait for the remote side to accept your session request...", "Oczekiwanie, na zatwierdzenie sesji przez host zdalny..."), ("One-time Password", "Hasło jednorazowe"), ("Use one-time password", "Użyj hasła jednorazowego"), ("One-time password length", "Długość hasła jednorazowego"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index ae4dbccba..0fcbd360c 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index c9c0b84f7..491b48a44 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Aceitar sessões via senha"), ("Accept sessions via click", "Aceitar sessões via clique"), ("Accept sessions via both", "Aceitar sessões de ambos os modos"), + ("Please wait for the remote side to accept your session request...", "Por favor aguarde enquanto o cliente remoto aceita seu pedido de sessão..."), ("One-time Password", "Senha de uso único"), ("Use one-time password", "Usar senha de uso único"), ("One-time password length", "Comprimento da senha de uso único"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index d6632d18a..60d293e36 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Acceptă sesiunile folosind parola"), ("Accept sessions via click", "Acceptă sesiunile cu un clic de confirmare"), ("Accept sessions via both", "Acceptă sesiunile folosind ambele moduri"), + ("Please wait for the remote side to accept your session request...", "Așteaptă ca solicitarea ta de conectare la distanță să fie acceptată..."), ("One-time Password", "Parolă unică"), ("Use one-time password", "Folosește parola unică"), ("One-time password length", "Lungimea parolei unice"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index a99523fca..90be51f01 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Принимать сеансы по паролю"), ("Accept sessions via click", "Принимать сеансы по нажатию"), ("Accept sessions via both", "Принимать сеансы по паролю+нажатию"), + ("Please wait for the remote side to accept your session request...", "Подождите, пока удалённая сторона примет ваш запрос на сеанс..."), ("One-time Password", "Одноразовый пароль"), ("Use one-time password", "Использовать одноразовый пароль"), ("One-time password length", "Длина одноразового пароля"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 7a8b9a778..aec122f70 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 581507457..18bd8f44c 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Sprejmi seje z geslom"), ("Accept sessions via click", "Sprejmi seje s potrditvijo"), ("Accept sessions via both", "Sprejmi seje z geslom ali potrditvijo"), + ("Please wait for the remote side to accept your session request...", "Počakajte, da oddaljeni računalnik sprejme povezavo..."), ("One-time Password", "Enkratno geslo"), ("Use one-time password", "Uporabi enkratno geslo"), ("One-time password length", "Dolžina enkratnega gesla"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index eb1b50762..746eed96d 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Prano sesionin nëpërmjet fjalëkalimit"), ("Accept sessions via click", "Prano sesionet nëpërmjet klikimit"), ("Accept sessions via both", "Prano sesionet nëpërmjet të dyjave"), + ("Please wait for the remote side to accept your session request...", "Ju lutem prisni që ana në distancë të pranoj kërkësen tuaj"), ("One-time Password", "Fjalëkalim Një-herë"), ("Use one-time password", "Përdorni fjalëkalim Një-herë"), ("One-time password length", "Gjatësia e fjalëkalimit një herë"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 260eadc24..0a94fe103 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Prihvati sesije preko lozinke"), ("Accept sessions via click", "Prihvati sesije preko klika"), ("Accept sessions via both", "Prihvati sesije preko oboje"), + ("Please wait for the remote side to accept your session request...", "Molimo sačekajte da udaljena strana prihvati vaš zahtev za sesijom..."), ("One-time Password", "Jednokratna lozinka"), ("Use one-time password", "Koristi jednokratnu lozinku"), ("One-time password length", "Dužina jednokratne lozinke"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 9db56dcc9..25d3144d8 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Acceptera sessioner via lösenord"), ("Accept sessions via click", "Acceptera sessioner via klick"), ("Accept sessions via both", "Acceptera sessioner via båda"), + ("Please wait for the remote side to accept your session request...", "Var god vänta på att klienten accepterar din förfrågan..."), ("One-time Password", "En-gångs lösenord"), ("Use one-time password", "Använd en-gångs lösenord"), ("One-time password length", "Längd på en-gångs lösenord"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index ac4413201..1b4b6ff14 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 11260f440..2fe64b100 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "ยอมรับการเชื่อมต่อด้วยรหัสผ่าน"), ("Accept sessions via click", "ยอมรับการเชื่อมต่อด้วยการคลิก"), ("Accept sessions via both", "ยอมรับการเชื่อมต่อด้วยทั้งสองวิธิ"), + ("Please wait for the remote side to accept your session request...", "กรุณารอให้อีกฝั่งยอมรับการเชื่อมต่อของคุณ..."), ("One-time Password", "รหัสผ่านครั้งเดียว"), ("Use one-time password", "ใช้รหัสผ่านครั้งเดียว"), ("One-time password length", "ความยาวรหัสผ่านครั้งเดียว"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index b76484b33..3a925942b 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Oturumları parola ile kabul etme"), ("Accept sessions via click", "Tıklama yoluyla oturumları kabul edin"), ("Accept sessions via both", "Her ikisi aracılığıyla oturumları kabul edin"), + ("Please wait for the remote side to accept your session request...", "Lütfen uzak tarafın oturum isteğinizi kabul etmesini bekleyin..."), ("One-time Password", "Tek Kullanımlık Şifre"), ("Use one-time password", "Tek seferlik parola kullanın"), ("One-time password length", "Tek seferlik şifre uzunluğu"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index f77014e8f..86e0dfb98 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "只允許透過輸入密碼進行連線"), ("Accept sessions via click", "只允許透過點擊接受進行連線"), ("Accept sessions via both", "允許輸入密碼或點擊接受進行連線"), + ("Please wait for the remote side to accept your session request...", "請等待對方接受您的連線請求 ..."), ("One-time Password", "一次性密碼"), ("Use one-time password", "使用一次性密碼"), ("One-time password length", "一次性密碼長度"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 873dad281..36b27089c 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", "Підтверджувати сеанси паролем"), ("Accept sessions via click", "Підтверджувати сеанси натисканням"), ("Accept sessions via both", "Підтверджувати сеанси обома способами"), + ("Please wait for the remote side to accept your session request...", "Буль ласка, зачекайте, поки віддалена сторона підтвердить запит на сеанс..."), ("One-time Password", "Одноразовий пароль"), ("Use one-time password", "Використати одноразовий пароль"), ("One-time password length", "Довжина одноразового пароля"), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 7756b8894..35c40a794 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -402,6 +402,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Accept sessions via password", ""), ("Accept sessions via click", ""), ("Accept sessions via both", ""), + ("Please wait for the remote side to accept your session request...", ""), ("One-time Password", ""), ("Use one-time password", ""), ("One-time password length", ""), @@ -498,6 +499,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("session_unready_no_password_text_tip", ""), ("session_unready_wrong_password_title_tip", ""), ("session_unready_wrong_password_text_tip", ""), - ("no_password_access_text_tip", ""), ].iter().cloned().collect(); } From b207468795f2c7164e0573045519012ce5473240 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 1 Apr 2023 23:02:37 +0800 Subject: [PATCH 39/44] tmp commit Signed-off-by: fufesou --- src/rendezvous_mediator.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index cc93dbb45..6dd0a1284 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -74,8 +74,7 @@ impl RendezvousMediator { } #[cfg(all(target_os = "linux", feature = "linux_headless"))] crate::platform::linux_desktop_manager::start_xdesktop(); - SHOULD_EXIT.store(false, Ordering::SeqCst); - while !SHOULD_EXIT.load(Ordering::SeqCst) { + loop { Config::reset_online(); if Config::get_option("stop-service").is_empty() { if !nat_tested { @@ -99,8 +98,10 @@ impl RendezvousMediator { } sleep(1.).await; } - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - crate::platform::linux_desktop_manager::stop_xdesktop(); + // It should be better to call stop_xdesktop. + // But for server, it also is Ok without calling this method. + // #[cfg(all(target_os = "linux", feature = "linux_headless"))] + // crate::platform::linux_desktop_manager::stop_xdesktop(); } pub async fn start(server: ServerPtr, host: String) -> ResultType<()> { From 51b77100a7b6157c19ab2d0f8f7cad153270ae39 Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 3 Apr 2023 10:10:06 +0800 Subject: [PATCH 40/44] add libpam0g-dev Signed-off-by: fufesou --- .github/workflows/flutter-build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml index 97a4073af..198e6d03e 100644 --- a/.github/workflows/flutter-build.yml +++ b/.github/workflows/flutter-build.yml @@ -402,7 +402,7 @@ jobs: - name: Install dependencies run: | sudo apt update - sudo apt-get -qq install -y git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake libclang-dev ninja-build libappindicator3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libvdpau-dev libva-dev libclang-dev llvm-dev libclang-10-dev llvm-10-dev pkg-config tree g++ libc6-dev gcc-multilib g++-multilib openjdk-11-jdk-headless + sudo apt-get -qq install -y git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake libclang-dev ninja-build libappindicator3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libvdpau-dev libva-dev libpam0g-dev libclang-dev llvm-dev libclang-10-dev llvm-10-dev pkg-config tree g++ libc6-dev gcc-multilib g++-multilib openjdk-11-jdk-headless - name: Checkout source code uses: actions/checkout@v3 - name: Install flutter @@ -654,7 +654,7 @@ jobs: install: | apt update -y echo -e "installing deps" - apt-get -qq install -y git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake libclang-dev ninja-build libappindicator3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libvdpau-dev libva-dev libclang-dev llvm-dev libclang-10-dev llvm-10-dev pkg-config tree g++ gcc libvpx-dev tree > /dev/null + apt-get -qq install -y git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake libclang-dev ninja-build libappindicator3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libvdpau-dev libva-dev libpam0g-dev libclang-dev llvm-dev libclang-10-dev llvm-10-dev pkg-config tree g++ gcc libvpx-dev tree > /dev/null # we have libopus compiled by us. apt remove -y libopus-dev || true # output devs @@ -816,7 +816,7 @@ jobs: install: | apt update -y echo -e "installing deps" - apt-get -qq install -y git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake libclang-dev ninja-build libappindicator3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libvdpau-dev libva-dev libclang-dev llvm-dev libclang-10-dev llvm-10-dev pkg-config tree g++ gcc libvpx-dev tree > /dev/null + apt-get -qq install -y git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake libclang-dev ninja-build libappindicator3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libvdpau-dev libva-dev libpam0g-dev libclang-dev llvm-dev libclang-10-dev llvm-10-dev pkg-config tree g++ gcc libvpx-dev tree > /dev/null # we have libopus compiled by us. apt remove -y libopus-dev || true # output devs @@ -947,7 +947,7 @@ jobs: apt update -y apt-get -qq install -y git cmake g++ gcc build-essential nasm yasm curl unzip xz-utils python3 wget pkg-config ninja-build pkg-config libgtk-3-dev liblzma-dev clang libappindicator3-dev rpm libclang-dev apt-get -qq install -y libdbus-1-dev pkg-config nasm yasm libglib2.0-dev libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev - apt-get -qq install -y libpulse-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libvpx-dev libvdpau-dev libva-dev + apt-get -qq install -y libpulse-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libvpx-dev libvdpau-dev libva-dev libpam0g-dev run: | # disable git safe.directory git config --global --add safe.directory "*" From a5158d2bb75866c95375ee003a1e93883de0795b Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 3 Apr 2023 10:13:25 +0800 Subject: [PATCH 41/44] build linux headless Signed-off-by: fufesou --- .github/workflows/flutter-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml index 198e6d03e..bf73bdaa1 100644 --- a/.github/workflows/flutter-build.yml +++ b/.github/workflows/flutter-build.yml @@ -687,7 +687,7 @@ jobs: x86_64) # no need mock on x86_64 export VCPKG_ROOT=/opt/artifacts/vcpkg - cargo build --lib --features hwcodec,flutter,flutter_texture_render,${{ matrix.job.extra-build-features }} --release + cargo build --lib --features hwcodec,flutter,flutter_texture_render,linux_headless,${{ matrix.job.extra-build-features }} --release ;; esac From a0c899bd6749c2e2c5c410d5ff0c21ad10fe4b64 Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 3 Apr 2023 13:14:20 +0800 Subject: [PATCH 42/44] debug fedora Signed-off-by: fufesou --- src/client.rs | 4 +- src/platform/linux_desktop_manager.rs | 54 ++++++++++++++++----------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/client.rs b/src/client.rs index a541a8458..72bdac531 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1943,13 +1943,13 @@ lazy_static::lazy_static! { link: "", try_again: false, }), (crate::server::LOGIN_MSG_DESKTOP_XORG_NOT_FOUND, LoginErrorMsgBox{ - msgtype: "session-re-login", + msgtype: "info-nocancel-nocancel", title: "xorg_not_found_title_tip", text: "xorg_not_found_text_tip", link: LINK_HEADLESS_LINUX_SUPPORT, try_again: true, }), (crate::server::LOGIN_MSG_DESKTOP_NO_DESKTOP, LoginErrorMsgBox{ - msgtype: "session-re-login", + msgtype: "info-nocancel-nocancel", title: "no_desktop_title_tip", text: "no_desktop_text_tip", link: LINK_HEADLESS_LINUX_SUPPORT, diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index e9dc00ef6..25fada503 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -64,11 +64,41 @@ pub fn stop_xdesktop() { *DESKTOP_MANAGER.lock().unwrap() = None; } +fn detect_headless() -> Option<&'static str> { + match run_cmds(&format!("which {}", DesktopManager::get_xorg())) { + Ok(output) => { + if output.trim().is_empty() { + return Some(LOGIN_MSG_DESKTOP_XORG_NOT_FOUND); + } + } + _ => { + return Some(LOGIN_MSG_DESKTOP_XORG_NOT_FOUND); + } + } + + match run_cmds("ls /usr/share/xsessions/") { + Ok(output) => { + if output.trim().is_empty() { + return Some(LOGIN_MSG_DESKTOP_NO_DESKTOP); + } + } + _ => { + return Some(LOGIN_MSG_DESKTOP_NO_DESKTOP); + } + } + + None +} + pub fn try_start_desktop(_username: &str, _passsword: &str) -> String { if _username.is_empty() { let username = get_username(); if username.is_empty() { - LOGIN_MSG_DESKTOP_SESSION_NOT_READY + if let Some(msg) = detect_headless() { + msg + } else { + LOGIN_MSG_DESKTOP_SESSION_NOT_READY + } } else { "" } @@ -80,26 +110,8 @@ pub fn try_start_desktop(_username: &str, _passsword: &str) -> String { return "".to_owned(); } - match run_cmds(&format!("which {}", DesktopManager::get_xorg())) { - Ok(output) => { - if output.trim().is_empty() { - return LOGIN_MSG_DESKTOP_XORG_NOT_FOUND.to_owned(); - } - } - _ => { - return LOGIN_MSG_DESKTOP_XORG_NOT_FOUND.to_owned(); - } - } - - match run_cmds("ls /usr/share/xsessions/") { - Ok(output) => { - if output.trim().is_empty() { - return LOGIN_MSG_DESKTOP_NO_DESKTOP.to_owned(); - } - } - _ => { - return LOGIN_MSG_DESKTOP_NO_DESKTOP.to_owned(); - } + if let Some(msg) = detect_headless() { + return msg.to_owned(); } match try_start_x_session(_username, _passsword) { From 96a62f188dd9bb4fe1895941e6cec32988c385bd Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 3 Apr 2023 13:36:47 +0800 Subject: [PATCH 43/44] trivial changes Signed-off-by: fufesou --- .github/workflows/flutter-nightly.yml | 1 - src/client/io_loop.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index 5aa82b847..c812f43fa 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -11,4 +11,3 @@ jobs: uses: ./.github/workflows/flutter-build.yml with: upload-artifact: true - diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index ab8b76a7f..509b5bd24 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -1256,7 +1256,7 @@ impl Remote { }, Some(message::Union::MessageBox(msgbox)) => { let mut link = msgbox.link; - // Links from remote side must be verified. + // Links from the remote side must be verified. if !link.starts_with("rustdesk://") { if let Some(v) = hbb_common::config::HELPER_URL.get(&link as &str) { link = v.to_string(); From 67ddb49aab6f97feea436df528c2e678f6912819 Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 3 Apr 2023 14:24:17 +0800 Subject: [PATCH 44/44] remove unused lang Signed-off-by: fufesou --- src/client.rs | 18 +++++++++--------- src/lang/ca.rs | 8 -------- src/lang/cn.rs | 8 -------- src/lang/cs.rs | 8 -------- src/lang/da.rs | 8 -------- src/lang/de.rs | 8 -------- src/lang/el.rs | 8 -------- src/lang/en.rs | 12 ++---------- src/lang/eo.rs | 8 -------- src/lang/es.rs | 8 -------- src/lang/fa.rs | 8 -------- src/lang/fr.rs | 8 -------- src/lang/hu.rs | 8 -------- src/lang/id.rs | 8 -------- src/lang/it.rs | 8 -------- src/lang/ja.rs | 8 -------- src/lang/ko.rs | 8 -------- src/lang/kz.rs | 8 -------- src/lang/nl.rs | 8 -------- src/lang/pl.rs | 8 -------- src/lang/pt_PT.rs | 8 -------- src/lang/ptbr.rs | 8 -------- src/lang/ro.rs | 8 -------- src/lang/ru.rs | 8 -------- src/lang/sk.rs | 8 -------- src/lang/sl.rs | 8 -------- src/lang/sq.rs | 8 -------- src/lang/sr.rs | 8 -------- src/lang/sv.rs | 8 -------- src/lang/template.rs | 8 -------- src/lang/th.rs | 8 -------- src/lang/tr.rs | 8 -------- src/lang/tw.rs | 8 -------- src/lang/ua.rs | 8 -------- src/lang/vn.rs | 8 -------- src/server/connection.rs | 6 +++--- 36 files changed, 14 insertions(+), 286 deletions(-) diff --git a/src/client.rs b/src/client.rs index 72bdac531..3bd00db47 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1926,8 +1926,8 @@ lazy_static::lazy_static! { use hbb_common::config::LINK_HEADLESS_LINUX_SUPPORT; let map = HashMap::from([(crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY, LoginErrorMsgBox{ msgtype: "session-login", - title: "session_not_ready_title_tip", - text: "session_not_ready_text_tip", + title: "", + text: "", link: "", try_again: true, }), (crate::server::LOGIN_MSG_DESKTOP_XSESSION_FAILED, LoginErrorMsgBox{ @@ -1937,33 +1937,33 @@ lazy_static::lazy_static! { link: "", try_again: true, }), (crate::server::LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER, LoginErrorMsgBox{ - msgtype: "info", + msgtype: "info-nocancel", title: "another_user_login_title_tip", text: "another_user_login_text_tip", link: "", try_again: false, }), (crate::server::LOGIN_MSG_DESKTOP_XORG_NOT_FOUND, LoginErrorMsgBox{ - msgtype: "info-nocancel-nocancel", + msgtype: "info-nocancel", title: "xorg_not_found_title_tip", text: "xorg_not_found_text_tip", link: LINK_HEADLESS_LINUX_SUPPORT, try_again: true, }), (crate::server::LOGIN_MSG_DESKTOP_NO_DESKTOP, LoginErrorMsgBox{ - msgtype: "info-nocancel-nocancel", + msgtype: "info-nocancel", title: "no_desktop_title_tip", text: "no_desktop_text_tip", link: LINK_HEADLESS_LINUX_SUPPORT, try_again: true, }), (crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY, LoginErrorMsgBox{ msgtype: "session-login-password", - title: "session_unready_no_password_title_tip", - text: "session_unready_no_password_text_tip", + title: "session_not_ready_no_password_title_tip", + text: "session_not_ready_no_password_text_tip", link: "", try_again: true, }), (crate::server::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG, LoginErrorMsgBox{ msgtype: "session-login-re-password", - title: "session_unready_wrong_password_title_tip", - text: "session_unready_wrong_password_text_tip", + title: "session_not_ready_wrong_password_title_tip", + text: "session_not_ready_wrong_password_text_tip", link: "", try_again: true, }), (crate::server::LOGIN_MSG_NO_PASSWORD_ACCESS, LoginErrorMsgBox{ diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 230a9730b..f4a8a1204 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 7f0e40581..11b3144c7 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", "记住此账户"), ("os_account_desk_tip", "在无显示器的环境下,此账户用于登录被控系统,并启用桌面"), ("OS Account", "系统账户"), - ("session_not_ready_title_tip", "桌面 session 未准备好"), - ("session_not_ready_text_tip", "请输入用户名密码"), - ("xsession_failed_title_tip", "用户名密码错误"), - ("xsession_failed_text_tip", "是否重试"), ("another_user_login_title_tip", "其他用户已登录"), ("another_user_login_text_tip", "断开"), ("xorg_not_found_title_tip", "Xorg 未安装"), ("xorg_not_found_text_tip", "请安装 Xorg"), ("no_desktop_title_tip", "desktop 未安装"), ("no_desktop_text_tip", "请安装 desktop"), - ("session_unready_no_password_title_tip", "桌面 session 未准备好"), - ("session_unready_no_password_text_tip", "请输入用户名密码和连接密码"), - ("session_unready_wrong_password_title_tip", "密码错误"), - ("session_unready_wrong_password_text_tip", "是否重试"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 7237b7a79..acfbed636 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index f761832da..b165540e8 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index e77ab938c..64ac4d9d4 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index 3703aad27..e74551046 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index e6499ea1c..b20035dc9 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -57,22 +57,14 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("enter_rustdesk_passwd_tip", "Enter RustDesk password"), ("remember_rustdesk_passwd_tip", "Remember RustDesk password"), ("login_linux_tip", "You need to login to remote Linux account to enable a X desktop session"), - ("verify_rustdesk_password_tip", "Veryfy RustDesk password"), + ("verify_rustdesk_password_tip", "Verify RustDesk password"), ("remember_account_tip", "Remember this account"), ("os_account_desk_tip", "This account is used to login the remote OS and enable the desktop session in headless"), - ("session_not_ready_title_tip", "Session is unready"), - ("session_not_ready_text_tip", "Input linux user/password"), - ("xsession_failed_title_tip", "Xsession username/password is wrong"), - ("xsession_failed_text_tip", "Do you want to enter again"), - ("another_user_login_title_tip", "Another user already login"), + ("another_user_login_title_tip", "Another user already logged in"), ("another_user_login_text_tip", "Disconnect"), ("xorg_not_found_title_tip", "Xorg not found"), ("xorg_not_found_text_tip", "Please install Xorg"), ("no_desktop_title_tip", "No desktop is avaliable"), ("no_desktop_text_tip", "Please install GNOME desktop"), - ("session_unready_no_password_title_tip", "Session is unready"), - ("session_unready_no_password_text_tip", "Input connection password and linux user/password"), - ("session_unready_wrong_password_title_tip", "Password is wrong"), - ("session_unready_wrong_password_text_tip", "Do you want to enter again"), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 645c8be7c..435bc6b0a 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index 7a672dfec..6207fac3b 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 281478bb0..d78cc8b37 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 1c4126377..cd2a6c3cc 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 547107607..e8efc6aa3 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index c896db6ba..97cab077c 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 0d1b6914e..1211ceb3c 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index b7cfaf40f..cfe029cc4 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 849fa7ffb..9e1278c6e 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index b7e242eaa..a86d1c81a 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 6cd679953..329c4dd70 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 529289751..afa07046a 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 0fcbd360c..6a44584a0 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 491b48a44..51ef174f5 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index 60d293e36..5de632ec4 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 90be51f01..f813c4b2f 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index aec122f70..3b7f62b74 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 18bd8f44c..2f050333c 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index 746eed96d..453534a86 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 0a94fe103..e2728caaa 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 25d3144d8..802eff33d 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 1b4b6ff14..8941c00d4 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 2fe64b100..1bdece3b7 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 3a925942b..99977515b 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 86e0dfb98..bff471b37 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 36b27089c..755e7b041 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 35c40a794..b8086f126 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -485,19 +485,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("remember_account_tip", ""), ("os_account_desk_tip", ""), ("OS Account", ""), - ("session_not_ready_title_tip", ""), - ("session_not_ready_text_tip", ""), - ("xsession_failed_title_tip", ""), - ("xsession_failed_text_tip", ""), ("another_user_login_title_tip", ""), ("another_user_login_text_tip", ""), ("xorg_not_found_title_tip", ""), ("xorg_not_found_text_tip", ""), ("no_desktop_title_tip", ""), ("no_desktop_text_tip", ""), - ("session_unready_no_password_title_tip", ""), - ("session_unready_no_password_text_tip", ""), - ("session_unready_wrong_password_title_tip", ""), - ("session_unready_wrong_password_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/server/connection.rs b/src/server/connection.rs index 297ab18c7..5eb3bb374 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -62,16 +62,16 @@ pub static CLICK_TIME: AtomicI64 = AtomicI64::new(0); pub static MOUSE_MOVE_TIME: AtomicI64 = AtomicI64::new(0); pub const LOGIN_MSG_DESKTOP_NOT_INITED: &str = "Desktop env is not inited"; -pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY: &str = "Desktop session unready"; +pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY: &str = "Desktop session not ready"; pub const LOGIN_MSG_DESKTOP_XSESSION_FAILED: &str = "Desktop xsession failed"; pub const LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER: &str = "Desktop session another user login"; pub const LOGIN_MSG_DESKTOP_XORG_NOT_FOUND: &str = "Desktop xorg not found"; // ls /usr/share/xsessions/ pub const LOGIN_MSG_DESKTOP_NO_DESKTOP: &str = "Desktop none"; pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY: &str = - "Desktop session unready, password empty"; + "Desktop session not ready, password empty"; pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG: &str = - "Desktop session unready, password wrong"; + "Desktop session not ready, password wrong"; pub const LOGIN_MSG_PASSWORD_EMPTY: &str = "Empty Password"; pub const LOGIN_MSG_PASSWORD_WRONG: &str = "Wrong Password"; pub const LOGIN_MSG_NO_PASSWORD_ACCESS: &str = "No Password Access";