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/<user> 3. Prefer XAUTHORITY environment variable over Xorg -auth if available
This commit is contained in:
parent
9cc09c620f
commit
028767da8b
@ -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"
|
||||||
|
@ -322,7 +322,19 @@ 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 format!("/home/{user}").into();
|
return format!("/home/{user}").into();
|
||||||
|
} else {
|
||||||
|
log::info!("config::patch: got home dir from: {}", home_dir);
|
||||||
|
return home_dir.into();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,14 +451,39 @@ 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 => {
|
||||||
|
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<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() {
|
||||||
|
match get_user_home_by_name(&username) {
|
||||||
|
None => {
|
||||||
|
// fallback to most common default pattern
|
||||||
let home = PathBuf::from(format!("/home/{}", username));
|
let home = PathBuf::from(format!("/home/{}", username));
|
||||||
if home.exists() {
|
if home.exists() {
|
||||||
return Some(home);
|
return Some(home);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some(home) => {
|
||||||
|
return Some(home);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,6 +801,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 +832,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);
|
||||||
}
|
}
|
||||||
@ -824,22 +862,37 @@ mod desktop {
|
|||||||
"ps -u {} -f | grep 'Xorg' | grep -v 'grep'",
|
"ps -u {} -f | grep 'Xorg' | grep -v 'grep'",
|
||||||
&self.uid
|
&self.uid
|
||||||
)) {
|
)) {
|
||||||
|
log::debug!("extracting xauth file for Xorg running with uid: {}", self.uid);
|
||||||
for line in output.lines() {
|
for line in output.lines() {
|
||||||
let mut auth_found = false;
|
let mut auth_found = false;
|
||||||
|
|
||||||
|
if let Some(pid) = line.split_whitespace().nth(1) {
|
||||||
for v in line.split_whitespace() {
|
for v in line.split_whitespace() {
|
||||||
if v == "-auth" {
|
if v == "-auth" {
|
||||||
|
log::debug!("- auth parameter detected");
|
||||||
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();
|
||||||
|
log::debug!("+ auth file with absolute path detected: {}", self.xauth);
|
||||||
} else {
|
} else {
|
||||||
|
log::debug!("- auth file with relative path detected: {}", v);
|
||||||
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);
|
||||||
|
log::debug!("+ auth file with home path added: {}", self.xauth);
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
// unreachable!
|
// unreachable!
|
||||||
}
|
}
|
||||||
@ -847,25 +900,56 @@ mod desktop {
|
|||||||
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) {
|
fn get_xauth(&mut self) {
|
||||||
self.xauth = get_env_tries("XAUTHORITY", &self.uid, GNOME_SESSION_BINARY, 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() {
|
if self.xauth.is_empty() {
|
||||||
get_env_tries("XAUTHORITY", &self.uid, XFCE4_PANEL, 10);
|
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() {
|
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() {
|
||||||
|
log::debug!("+ found gdm for {}: {}", self.uid, gdm);
|
||||||
gdm
|
gdm
|
||||||
} else {
|
} else {
|
||||||
let username = &self.username;
|
let username = &self.username;
|
||||||
|
match get_user_home_by_name(username) {
|
||||||
|
None => {
|
||||||
|
log::debug!("- user home dir not detected: {}", username);
|
||||||
if username == "root" {
|
if username == "root" {
|
||||||
format!("/{}/.Xauthority", username)
|
format!("/{}/.Xauthority", username)
|
||||||
} else {
|
} else {
|
||||||
@ -876,6 +960,11 @@ mod desktop {
|
|||||||
format!("/var/lib/{}/.Xauthority", username)
|
format!("/var/lib/{}/.Xauthority", username)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Some(home) => {
|
||||||
|
format!("{}/.Xauthority", home.as_path().to_string_lossy().to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user