From 028767da8b0f06e90f156960340787aa481eda2c Mon Sep 17 00:00:00 2001 From: Awalon Date: Sun, 23 Apr 2023 03:43:47 +0200 Subject: [PATCH 1/4] Fix for #4136 connection to linux refused by using wrong Xauthority file Solution: 1. Get file from sddm-greeter and startplasma-x11 (aka KDE) processes as well 2. Get users home dir from system instead of hard coded pattern /home/ 3. Prefer XAUTHORITY environment variable over Xorg -auth if available --- Cargo.toml | 4 +- libs/hbb_common/src/config.rs | 14 ++- src/platform/linux.rs | 157 ++++++++++++++++++++++++++-------- 3 files changed, 138 insertions(+), 37 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 49e2b66fc..0200e0fee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ flutter = ["flutter_rust_bridge"] default = ["use_dasp"] hwcodec = ["scrap/hwcodec"] mediacodec = ["scrap/mediacodec"] -linux_headless = ["pam", "users"] +linux_headless = ["pam" ] virtual_display_driver = ["virtual_display"] plugin_framework = [] @@ -126,7 +126,7 @@ evdev = { git="https://github.com/fufesou/evdev" } dbus = "0.9" dbus-crossroads = "0.5" pam = { git="https://github.com/fufesou/pam", optional = true } -users = { version = "0.11.0", optional = true } +users = { version = "0.11.0" } [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 369920982..a5423c4cf 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -322,7 +322,19 @@ fn patch(path: PathBuf) -> PathBuf { .trim() .to_owned(); if user != "root" { - return format!("/home/{user}").into(); + let cmd = format!("getent passwd '{}' | awk -F':' '{{print $6}}'", user); + if let Ok(output) = std::process::Command::new(cmd).output() { + let home_dir = String::from_utf8_lossy(&output.stdout) + .to_string() + .trim() + .to_owned(); + if home_dir.is_empty() { + return format!("/home/{user}").into(); + } else { + log::info!("config::patch: got home dir from: {}", home_dir); + return home_dir.into(); + } + } } } } diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 33ebcc82c..2cab7edbf 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -9,6 +9,7 @@ use hbb_common::{ regex::{Captures, Regex}, }; use std::{ + string::String, cell::RefCell, path::{Path, PathBuf}, process::{Child, Command}, @@ -18,6 +19,7 @@ use std::{ }, time::{Duration, Instant}, }; +use users::{get_user_by_name, os::unix::UserExt}; type Xdo = *const c_void; @@ -449,12 +451,37 @@ pub fn get_active_username() -> String { get_values_of_seat0(&[2])[0].clone() } +pub fn get_user_home_by_name(username: &str) -> Option { + return match get_user_by_name(username) { + None => { + log::debug!("no uid found for user: {}", username); + None } + Some(user) => { + log::debug!("user '{:?}' (uid {:?}) with home dir: {:?}", user.uid(), user.name(), user.home_dir()); + let home = user.home_dir(); + if Path::is_dir(home) { + Some(PathBuf::from(home)) + } else { + None + } + } + } +} + pub fn get_active_user_home() -> Option { let username = get_active_username(); if !username.is_empty() { - let home = PathBuf::from(format!("/home/{}", username)); - if home.exists() { - return Some(home); + match get_user_home_by_name(&username) { + None => { + // fallback to most common default pattern + let home = PathBuf::from(format!("/home/{}", username)); + if home.exists() { + return Some(home); + } + } + Some(home) => { + return Some(home); + } } } None @@ -774,6 +801,8 @@ mod desktop { pub const XFCE4_PANEL: &str = "xfce4-panel"; pub const GNOME_SESSION_BINARY: &str = "gnome-session-binary"; + pub const SDDM_GREETER: &str = "sddm-greeter"; + pub const PLASMA_X11: &str = "startplasma-x11"; #[derive(Debug, Clone, Default)] pub struct Desktop { @@ -803,10 +832,19 @@ mod desktop { } 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); + let display_envs = vec![ + GNOME_SESSION_BINARY, + XFCE4_PANEL, + SDDM_GREETER, + PLASMA_X11, + ]; + for diplay_env in display_envs { + self.display = get_env_tries("DISPLAY", &self.uid, diplay_env, 10); + if !self.display.is_empty() { + break; + } } + if self.display.is_empty() { self.display = Self::get_display_by_user(&self.username); } @@ -824,56 +862,107 @@ mod desktop { "ps -u {} -f | grep 'Xorg' | grep -v 'grep'", &self.uid )) { + log::debug!("extracting xauth file for Xorg running with uid: {}", self.uid); for line in output.lines() { let mut auth_found = false; - for v in line.split_whitespace() { - if v == "-auth" { - auth_found = true; - } else if auth_found { - if std::path::Path::new(v).is_absolute() { - self.xauth = v.to_string(); - } else { - if let Some(pid) = line.split_whitespace().nth(1) { - let home_dir = get_env_from_pid("HOME", pid); - if home_dir.is_empty() { - self.xauth = format!("/home/{}/{}", self.username, v); - } else { - self.xauth = format!("{}/{}", home_dir, v); - } + + if let Some(pid) = line.split_whitespace().nth(1) { + for v in line.split_whitespace() { + if v == "-auth" { + log::debug!("- auth parameter detected"); + auth_found = true; + } else if auth_found { + if std::path::Path::new(v).is_absolute() + && std::path::Path::new(v).exists() { + + self.xauth = v.to_string(); + log::debug!("+ auth file with absolute path detected: {}", self.xauth); } else { - // unreachable! + log::debug!("- auth file with relative path detected: {}", v); + if let Some(pid) = line.split_whitespace().nth(1) { + let mut base_dir: String = String::from("/home"); // default pattern + let home_dir = get_env_from_pid("HOME", pid); + if home_dir.is_empty() { + if let Some(home) = get_user_home_by_name(&self.username) { + base_dir = home.as_path().to_string_lossy().to_string(); + }; + } else { + base_dir = home_dir; + } + if Path::new(&base_dir).exists() { + self.xauth = format!("{}/{}", base_dir, v); + log::debug!("+ auth file with home path added: {}", self.xauth); + }; + } else { + // unreachable! + } } + return; } - return; + } + + // get from environment variable if parameter wasn't found + let xauth = get_env_from_pid("XAUTHORITY", pid); + if !xauth.is_empty() { + if Path::new(&xauth).exists() { + log::debug!("+ auth file from environment detected: {}", xauth); + self.xauth = xauth; + }; } } } } + log::debug!("- auth file detected by Xorg: {}", self.xauth); } 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); + log::debug!("guessing xauth file..."); + // try by direct access to window manager process by name + let display_envs = vec![ + GNOME_SESSION_BINARY, + XFCE4_PANEL, + SDDM_GREETER, + PLASMA_X11, + ]; + for diplay_env in display_envs { + self.xauth = get_env_tries("XAUTHORITY", &self.uid, diplay_env, 10); + if self.xauth.is_empty() { + log::debug!("- nothing for {} {} (GNOME)", self.uid, diplay_env); + } else { + log::debug!("+ found {} for {} {} (GNOME)", self.xauth, self.uid, diplay_env); + break; + } } + + // get from Xorg process, parameter and environment if self.xauth.is_empty() { self.get_xauth_from_xorg(); } - let gdm = format!("/run/user/{}/gdm/Xauthority", self.uid); + // fallback to default file name if self.xauth.is_empty() { + let gdm = format!("/run/user/{}/gdm/Xauthority", self.uid); self.xauth = if std::path::Path::new(&gdm).exists() { + log::debug!("+ found gdm for {}: {}", self.uid, gdm); 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) + match get_user_home_by_name(username) { + None => { + log::debug!("- user home dir not detected: {}", 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) + } + } + } + Some(home) => { + format!("{}/.Xauthority", home.as_path().to_string_lossy().to_string()) } } }; From dcc9337f86db04390ef103c2f5c5a696c8ed9587 Mon Sep 17 00:00:00 2001 From: Awalon Date: Sun, 23 Apr 2023 23:58:04 +0200 Subject: [PATCH 2/4] Fix for #4136 connection to linux refused by using wrong Xauthority file. This PR handles comments of review for PR #4165. --- libs/hbb_common/src/config.rs | 5 ++- src/platform/linux.rs | 64 +++++++++++++++-------------------- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index a5423c4cf..8363e5ee6 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -328,13 +328,12 @@ fn patch(path: PathBuf) -> PathBuf { .to_string() .trim() .to_owned(); - if home_dir.is_empty() { - return format!("/home/{user}").into(); - } else { + if !home_dir.is_empty() { log::info!("config::patch: got home dir from: {}", home_dir); return home_dir.into(); } } + return format!("/home/{user}").into(); } } } diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 2cab7edbf..4b55e427b 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -455,7 +455,8 @@ pub fn get_user_home_by_name(username: &str) -> Option { return match get_user_by_name(username) { None => { log::debug!("no uid found for user: {}", username); - None } + None + } Some(user) => { log::debug!("user '{:?}' (uid {:?}) with home dir: {:?}", user.uid(), user.name(), user.home_dir()); let home = user.home_dir(); @@ -866,48 +867,37 @@ mod desktop { for line in output.lines() { let mut auth_found = false; - if let Some(pid) = line.split_whitespace().nth(1) { - for v in line.split_whitespace() { - if v == "-auth" { - log::debug!("- auth parameter detected"); - auth_found = true; - } else if auth_found { - if std::path::Path::new(v).is_absolute() - && std::path::Path::new(v).exists() { + for v in line.split_whitespace() { + if v == "-auth" { + log::debug!("- auth parameter detected"); + auth_found = true; + } else if auth_found { + if std::path::Path::new(v).is_absolute() + && std::path::Path::new(v).exists() { - self.xauth = v.to_string(); - log::debug!("+ auth file with absolute path detected: {}", self.xauth); - } else { - log::debug!("- auth file with relative path detected: {}", v); - if let Some(pid) = line.split_whitespace().nth(1) { - let mut base_dir: String = String::from("/home"); // default pattern - let home_dir = get_env_from_pid("HOME", pid); - if home_dir.is_empty() { - if let Some(home) = get_user_home_by_name(&self.username) { - base_dir = home.as_path().to_string_lossy().to_string(); - }; - } else { - base_dir = home_dir; - } - if Path::new(&base_dir).exists() { - self.xauth = format!("{}/{}", base_dir, v); - log::debug!("+ auth file with home path added: {}", self.xauth); + self.xauth = v.to_string(); + log::debug!("+ auth file with absolute path detected: {}", self.xauth); + } else { + log::debug!("- auth file with relative path detected: {}", v); + if let Some(pid) = line.split_whitespace().nth(1) { + let mut base_dir: String = String::from("/home"); // default pattern + let home_dir = get_env_from_pid("HOME", pid); + if home_dir.is_empty() { + if let Some(home) = get_user_home_by_name(&self.username) { + base_dir = home.as_path().to_string_lossy().to_string(); }; } else { - // unreachable! + base_dir = home_dir; } + if Path::new(&base_dir).exists() { + self.xauth = format!("{}/{}", base_dir, v); + log::debug!("+ auth file with home path added: {}", self.xauth); + }; + } else { + // unreachable! } - return; } - } - - // get from environment variable if parameter wasn't found - let xauth = get_env_from_pid("XAUTHORITY", pid); - if !xauth.is_empty() { - if Path::new(&xauth).exists() { - log::debug!("+ auth file from environment detected: {}", xauth); - self.xauth = xauth; - }; + return; } } } From 82c44d71f910f312744295d8b5785d14c601c7d6 Mon Sep 17 00:00:00 2001 From: Awalon Date: Mon, 24 Apr 2023 23:45:23 +0200 Subject: [PATCH 3/4] Fix for #4136 connection to linux refused by using wrong Xauthority file. This PR handles comments of 2nd review for initial PR #4165. Reduced number of info/log messages --- libs/hbb_common/src/config.rs | 1 - src/platform/linux.rs | 14 +------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index 8363e5ee6..55e80599a 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -329,7 +329,6 @@ fn patch(path: PathBuf) -> PathBuf { .trim() .to_owned(); if !home_dir.is_empty() { - log::info!("config::patch: got home dir from: {}", home_dir); return home_dir.into(); } } diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 4b55e427b..9cb0d5956 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -863,22 +863,18 @@ mod desktop { "ps -u {} -f | grep 'Xorg' | grep -v 'grep'", &self.uid )) { - log::debug!("extracting xauth file for Xorg running with uid: {}", self.uid); for line in output.lines() { let mut auth_found = false; for v in line.split_whitespace() { if v == "-auth" { - log::debug!("- auth parameter detected"); auth_found = true; } else if auth_found { if std::path::Path::new(v).is_absolute() && std::path::Path::new(v).exists() { self.xauth = v.to_string(); - log::debug!("+ auth file with absolute path detected: {}", self.xauth); } else { - log::debug!("- auth file with relative path detected: {}", v); if let Some(pid) = line.split_whitespace().nth(1) { let mut base_dir: String = String::from("/home"); // default pattern let home_dir = get_env_from_pid("HOME", pid); @@ -891,7 +887,6 @@ mod desktop { } if Path::new(&base_dir).exists() { self.xauth = format!("{}/{}", base_dir, v); - log::debug!("+ auth file with home path added: {}", self.xauth); }; } else { // unreachable! @@ -902,11 +897,9 @@ mod desktop { } } } - log::debug!("- auth file detected by Xorg: {}", self.xauth); } fn get_xauth(&mut self) { - log::debug!("guessing xauth file..."); // try by direct access to window manager process by name let display_envs = vec![ GNOME_SESSION_BINARY, @@ -916,10 +909,7 @@ mod desktop { ]; for diplay_env in display_envs { self.xauth = get_env_tries("XAUTHORITY", &self.uid, diplay_env, 10); - if self.xauth.is_empty() { - log::debug!("- nothing for {} {} (GNOME)", self.uid, diplay_env); - } else { - log::debug!("+ found {} for {} {} (GNOME)", self.xauth, self.uid, diplay_env); + if !self.xauth.is_empty() { break; } } @@ -933,13 +923,11 @@ mod desktop { if self.xauth.is_empty() { let gdm = format!("/run/user/{}/gdm/Xauthority", self.uid); self.xauth = if std::path::Path::new(&gdm).exists() { - log::debug!("+ found gdm for {}: {}", self.uid, gdm); gdm } else { let username = &self.username; match get_user_home_by_name(username) { None => { - log::debug!("- user home dir not detected: {}", username); if username == "root" { format!("/{}/.Xauthority", username) } else { From c015b66da0679b12093d98a5ccf8775fcf1b5afc Mon Sep 17 00:00:00 2001 From: RustDesk <71636191+rustdesk@users.noreply.github.com> Date: Tue, 25 Apr 2023 09:41:02 +0800 Subject: [PATCH 4/4] Update linux.rs --- src/platform/linux.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 9cb0d5956..6237ef8a1 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -454,11 +454,9 @@ pub fn get_active_username() -> String { pub fn get_user_home_by_name(username: &str) -> Option { return match get_user_by_name(username) { None => { - log::debug!("no uid found for user: {}", username); None } Some(user) => { - log::debug!("user '{:?}' (uid {:?}) with home dir: {:?}", user.uid(), user.name(), user.home_dir()); let home = user.home_dir(); if Path::is_dir(home) { Some(PathBuf::from(home))