fix: recover DBUS_SESSION_BUS_ADDRESS when running as root for AT-SPI2 password detection
This commit is contained in:
parent
cc05e02559
commit
f77b7ea682
1 changed files with 67 additions and 0 deletions
|
|
@ -488,6 +488,8 @@ fn recover_display_env() {
|
||||||
}
|
}
|
||||||
if let Ok(d) = std::env::var("DISPLAY") {
|
if let Ok(d) = std::env::var("DISPLAY") {
|
||||||
if !d.is_empty() {
|
if !d.is_empty() {
|
||||||
|
// Already have DISPLAY, but still recover D-Bus env for AT-SPI2
|
||||||
|
recover_dbus_env();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -541,6 +543,71 @@ fn recover_display_env() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
recover_dbus_env();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Recover D-Bus session bus address and XDG_RUNTIME_DIR for AT-SPI2
|
||||||
|
/// when running as root. The accessibility bus only lives on the
|
||||||
|
/// original user's session bus, not root's.
|
||||||
|
fn recover_dbus_env() {
|
||||||
|
if unsafe { libc::getuid() } != 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let target_uid: u32 = match std::env::var("SUDO_UID") {
|
||||||
|
Ok(s) => match s.parse() {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(_) => return,
|
||||||
|
},
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
// First try: read DBUS_SESSION_BUS_ADDRESS from the original user's /proc/*/environ
|
||||||
|
if let Ok(entries) = fs::read_dir("/proc") {
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let name = entry.file_name();
|
||||||
|
let name_s = name.to_string_lossy();
|
||||||
|
if !name_s.chars().all(|c| c.is_ascii_digit()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
use std::os::linux::fs::MetadataExt;
|
||||||
|
if let Ok(meta) = entry.metadata() {
|
||||||
|
if meta.st_uid() != target_uid {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let environ_path = entry.path().join("environ");
|
||||||
|
if let Ok(content) = fs::read(&environ_path) {
|
||||||
|
if let Ok(dbus_env) = std::str::from_utf8(&content) {
|
||||||
|
for var in dbus_env.split('\0') {
|
||||||
|
if let Some(val) = var.strip_prefix("DBUS_SESSION_BUS_ADDRESS=") {
|
||||||
|
if !val.is_empty() {
|
||||||
|
std::env::set_var("DBUS_SESSION_BUS_ADDRESS", val);
|
||||||
|
log_info("[vietc] Recovered DBUS_SESSION_BUS_ADDRESS");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(val) = var.strip_prefix("XDG_RUNTIME_DIR=") {
|
||||||
|
if !val.is_empty() {
|
||||||
|
std::env::set_var("XDG_RUNTIME_DIR", val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Second try: if XDG_RUNTIME_DIR is set, check for the standard bus socket
|
||||||
|
if let Ok(xdg_dir) = std::env::var("XDG_RUNTIME_DIR") {
|
||||||
|
let bus_path = std::path::Path::new(&xdg_dir).join("bus");
|
||||||
|
if bus_path.exists() {
|
||||||
|
let addr = format!("unix:path={}", bus_path.display());
|
||||||
|
std::env::set_var("DBUS_SESSION_BUS_ADDRESS", &addr);
|
||||||
|
log_info("[vietc] Set DBUS_SESSION_BUS_ADDRESS from XDG_RUNTIME_DIR/bus");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ensure_single_instance(name: &str) {
|
fn ensure_single_instance(name: &str) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue