Merge pull request #4165 from awalon/master

Fix for #4136 connection to linux refused by using wrong Xauthority file
This commit is contained in:
RustDesk 2023-04-25 09:42:08 +08:00 committed by GitHub
commit ce1ce19567
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 98 additions and 23 deletions

View File

@ -29,7 +29,7 @@ flutter = ["flutter_rust_bridge"]
default = ["use_dasp"] default = ["use_dasp"]
hwcodec = ["scrap/hwcodec"] hwcodec = ["scrap/hwcodec"]
mediacodec = ["scrap/mediacodec"] mediacodec = ["scrap/mediacodec"]
linux_headless = ["pam", "users"] linux_headless = ["pam" ]
virtual_display_driver = ["virtual_display"] virtual_display_driver = ["virtual_display"]
plugin_framework = [] plugin_framework = []
@ -126,7 +126,7 @@ evdev = { git="https://github.com/fufesou/evdev" }
dbus = "0.9" dbus = "0.9"
dbus-crossroads = "0.5" dbus-crossroads = "0.5"
pam = { git="https://github.com/fufesou/pam", optional = true } 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] [target.'cfg(target_os = "android")'.dependencies]
android_logger = "0.11" android_logger = "0.11"

View File

@ -322,6 +322,16 @@ fn patch(path: PathBuf) -> PathBuf {
.trim() .trim()
.to_owned(); .to_owned();
if user != "root" { if user != "root" {
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 home_dir.into();
}
}
return format!("/home/{user}").into(); return format!("/home/{user}").into();
} }
} }

View File

@ -9,6 +9,7 @@ use hbb_common::{
regex::{Captures, Regex}, regex::{Captures, Regex},
}; };
use std::{ use std::{
string::String,
cell::RefCell, cell::RefCell,
path::{Path, PathBuf}, path::{Path, PathBuf},
process::{Child, Command}, process::{Child, Command},
@ -18,6 +19,7 @@ use std::{
}, },
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use users::{get_user_by_name, os::unix::UserExt};
type Xdo = *const c_void; type Xdo = *const c_void;
@ -449,12 +451,36 @@ pub fn get_active_username() -> String {
get_values_of_seat0(&[2])[0].clone() get_values_of_seat0(&[2])[0].clone()
} }
pub fn get_user_home_by_name(username: &str) -> Option<PathBuf> {
return match get_user_by_name(username) {
None => {
None
}
Some(user) => {
let home = user.home_dir();
if Path::is_dir(home) {
Some(PathBuf::from(home))
} else {
None
}
}
}
}
pub fn get_active_user_home() -> Option<PathBuf> { pub fn get_active_user_home() -> Option<PathBuf> {
let username = get_active_username(); let username = get_active_username();
if !username.is_empty() { if !username.is_empty() {
let home = PathBuf::from(format!("/home/{}", username)); match get_user_home_by_name(&username) {
if home.exists() { None => {
return Some(home); // 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 None
@ -774,6 +800,8 @@ mod desktop {
pub const XFCE4_PANEL: &str = "xfce4-panel"; pub const XFCE4_PANEL: &str = "xfce4-panel";
pub const GNOME_SESSION_BINARY: &str = "gnome-session-binary"; 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)] #[derive(Debug, Clone, Default)]
pub struct Desktop { pub struct Desktop {
@ -803,10 +831,19 @@ mod desktop {
} }
fn get_display(&mut self) { fn get_display(&mut self) {
self.display = get_env_tries("DISPLAY", &self.uid, GNOME_SESSION_BINARY, 10); let display_envs = vec![
if self.display.is_empty() { GNOME_SESSION_BINARY,
self.display = get_env_tries("DISPLAY", &self.uid, XFCE4_PANEL, 10); 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() { if self.display.is_empty() {
self.display = Self::get_display_by_user(&self.username); self.display = Self::get_display_by_user(&self.username);
} }
@ -826,20 +863,29 @@ mod desktop {
)) { )) {
for line in output.lines() { for line in output.lines() {
let mut auth_found = false; let mut auth_found = false;
for v in line.split_whitespace() { for v in line.split_whitespace() {
if v == "-auth" { if v == "-auth" {
auth_found = true; auth_found = true;
} else if auth_found { } else if auth_found {
if std::path::Path::new(v).is_absolute() { if std::path::Path::new(v).is_absolute()
&& std::path::Path::new(v).exists() {
self.xauth = v.to_string(); self.xauth = v.to_string();
} else { } else {
if let Some(pid) = line.split_whitespace().nth(1) { 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); let home_dir = get_env_from_pid("HOME", pid);
if home_dir.is_empty() { if home_dir.is_empty() {
self.xauth = format!("/home/{}/{}", self.username, v); if let Some(home) = get_user_home_by_name(&self.username) {
base_dir = home.as_path().to_string_lossy().to_string();
};
} else { } else {
self.xauth = format!("{}/{}", home_dir, v); base_dir = home_dir;
} }
if Path::new(&base_dir).exists() {
self.xauth = format!("{}/{}", base_dir, v);
};
} else { } else {
// unreachable! // unreachable!
} }
@ -852,28 +898,47 @@ mod desktop {
} }
fn get_xauth(&mut self) { fn get_xauth(&mut self) {
self.xauth = get_env_tries("XAUTHORITY", &self.uid, GNOME_SESSION_BINARY, 10); // try by direct access to window manager process by name
if self.xauth.is_empty() { let display_envs = vec![
get_env_tries("XAUTHORITY", &self.uid, XFCE4_PANEL, 10); 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() {
break;
}
} }
// get from Xorg process, parameter and environment
if self.xauth.is_empty() { if self.xauth.is_empty() {
self.get_xauth_from_xorg(); self.get_xauth_from_xorg();
} }
let gdm = format!("/run/user/{}/gdm/Xauthority", self.uid); // fallback to default file name
if self.xauth.is_empty() { if self.xauth.is_empty() {
let gdm = format!("/run/user/{}/gdm/Xauthority", self.uid);
self.xauth = if std::path::Path::new(&gdm).exists() { self.xauth = if std::path::Path::new(&gdm).exists() {
gdm gdm
} else { } else {
let username = &self.username; let username = &self.username;
if username == "root" { match get_user_home_by_name(username) {
format!("/{}/.Xauthority", username) None => {
} else { if username == "root" {
let tmp = format!("/home/{}/.Xauthority", username); format!("/{}/.Xauthority", username)
if std::path::Path::new(&tmp).exists() { } else {
tmp let tmp = format!("/home/{}/.Xauthority", username);
} else { if std::path::Path::new(&tmp).exists() {
format!("/var/lib/{}/.Xauthority", username) tmp
} else {
format!("/var/lib/{}/.Xauthority", username)
}
}
}
Some(home) => {
format!("{}/.Xauthority", home.as_path().to_string_lossy().to_string())
} }
} }
}; };