fix, wayland --server, envs
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
		
							parent
							
								
									3907cc679a
								
							
						
					
					
						commit
						da7bcf89d4
					
				@ -14,6 +14,7 @@ use hbb_common::{
 | 
			
		||||
};
 | 
			
		||||
use std::{
 | 
			
		||||
    cell::RefCell,
 | 
			
		||||
    ffi::OsStr,
 | 
			
		||||
    io::Write,
 | 
			
		||||
    path::{Path, PathBuf},
 | 
			
		||||
    process::{Child, Command},
 | 
			
		||||
@ -195,17 +196,29 @@ fn start_uinput_service() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[inline]
 | 
			
		||||
fn try_start_server_(user: Option<(String, String)>) -> ResultType<Option<Child>> {
 | 
			
		||||
    if user.is_some() {
 | 
			
		||||
        run_as_user(vec!["--server"], user)
 | 
			
		||||
    } else {
 | 
			
		||||
        Ok(Some(crate::run_me(vec!["--server"])?))
 | 
			
		||||
fn try_start_server_(desktop: Option<&Desktop>) -> ResultType<Option<Child>> {
 | 
			
		||||
    match desktop {
 | 
			
		||||
        Some(desktop) => {
 | 
			
		||||
            let mut envs = vec![];
 | 
			
		||||
            if !desktop.display.is_empty() {
 | 
			
		||||
                envs.push(("DISPLAY", desktop.display.clone()));
 | 
			
		||||
            }
 | 
			
		||||
            if !desktop.xauth.is_empty() {
 | 
			
		||||
                envs.push(("XAUTHORITY", desktop.xauth.clone()));
 | 
			
		||||
            }
 | 
			
		||||
            run_as_user(
 | 
			
		||||
                vec!["--server"],
 | 
			
		||||
                Some((desktop.uid.clone(), desktop.username.clone())),
 | 
			
		||||
                envs,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        None => Ok(Some(crate::run_me(vec!["--server"])?)),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[inline]
 | 
			
		||||
fn start_server(user: Option<(String, String)>, server: &mut Option<Child>) {
 | 
			
		||||
    match try_start_server_(user) {
 | 
			
		||||
fn start_server(desktop: Option<&Desktop>, server: &mut Option<Child>) {
 | 
			
		||||
    match try_start_server_(desktop) {
 | 
			
		||||
        Ok(ps) => *server = ps,
 | 
			
		||||
        Err(err) => {
 | 
			
		||||
            log::error!("Failed to start server: {}", err);
 | 
			
		||||
@ -257,6 +270,7 @@ fn stop_subprocess() {
 | 
			
		||||
 | 
			
		||||
fn should_start_server(
 | 
			
		||||
    try_x11: bool,
 | 
			
		||||
    is_display_changed: bool,
 | 
			
		||||
    uid: &mut String,
 | 
			
		||||
    desktop: &Desktop,
 | 
			
		||||
    cm0: &mut bool,
 | 
			
		||||
@ -273,7 +287,7 @@ fn should_start_server(
 | 
			
		||||
            *uid = "".to_owned();
 | 
			
		||||
            should_kill = true;
 | 
			
		||||
        }
 | 
			
		||||
    } else if desktop.uid != *uid && !desktop.uid.is_empty() {
 | 
			
		||||
    } else if is_display_changed || desktop.uid != *uid && !desktop.uid.is_empty() {
 | 
			
		||||
        *uid = desktop.uid.clone();
 | 
			
		||||
        if try_x11 {
 | 
			
		||||
            set_x11_env(&desktop);
 | 
			
		||||
@ -335,6 +349,7 @@ pub fn start_os_service() {
 | 
			
		||||
 | 
			
		||||
    let running = Arc::new(AtomicBool::new(true));
 | 
			
		||||
    let r = running.clone();
 | 
			
		||||
    let (mut display, mut xauth): (String, String) = ("".to_owned(), "".to_owned());
 | 
			
		||||
    let mut desktop = Desktop::default();
 | 
			
		||||
    let mut sid = "".to_owned();
 | 
			
		||||
    let mut uid = "".to_owned();
 | 
			
		||||
@ -357,8 +372,10 @@ pub fn start_os_service() {
 | 
			
		||||
            // try kill subprocess "--server"
 | 
			
		||||
            stop_server(&mut user_server);
 | 
			
		||||
            // try start subprocess "--server"
 | 
			
		||||
            // No need to check is_display_changed here.
 | 
			
		||||
            if should_start_server(
 | 
			
		||||
                true,
 | 
			
		||||
                false,
 | 
			
		||||
                &mut uid,
 | 
			
		||||
                &desktop,
 | 
			
		||||
                &mut cm0,
 | 
			
		||||
@ -373,9 +390,14 @@ pub fn start_os_service() {
 | 
			
		||||
            // try kill subprocess "--server"
 | 
			
		||||
            stop_server(&mut server);
 | 
			
		||||
 | 
			
		||||
            let is_display_changed = desktop.display != display || desktop.xauth != xauth;
 | 
			
		||||
            display = desktop.display.clone();
 | 
			
		||||
            xauth = desktop.xauth.clone();
 | 
			
		||||
 | 
			
		||||
            // try start subprocess "--server"
 | 
			
		||||
            if should_start_server(
 | 
			
		||||
                false,
 | 
			
		||||
                is_display_changed,
 | 
			
		||||
                &mut uid,
 | 
			
		||||
                &desktop,
 | 
			
		||||
                &mut cm0,
 | 
			
		||||
@ -384,10 +406,7 @@ pub fn start_os_service() {
 | 
			
		||||
            ) {
 | 
			
		||||
                stop_subprocess();
 | 
			
		||||
                force_stop_server();
 | 
			
		||||
                start_server(
 | 
			
		||||
                    Some((desktop.uid.clone(), desktop.username.clone())),
 | 
			
		||||
                    &mut user_server,
 | 
			
		||||
                );
 | 
			
		||||
                start_server(Some(&desktop), &mut user_server);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            force_stop_server();
 | 
			
		||||
@ -541,7 +560,16 @@ fn is_opensuse() -> bool {
 | 
			
		||||
    false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn run_as_user(arg: Vec<&str>, user: Option<(String, String)>) -> ResultType<Option<Child>> {
 | 
			
		||||
pub fn run_as_user<I, K, V>(
 | 
			
		||||
    arg: Vec<&str>,
 | 
			
		||||
    user: Option<(String, String)>,
 | 
			
		||||
    envs: I,
 | 
			
		||||
) -> ResultType<Option<Child>>
 | 
			
		||||
where
 | 
			
		||||
    I: IntoIterator<Item = (K, V)>,
 | 
			
		||||
    K: AsRef<OsStr>,
 | 
			
		||||
    V: AsRef<OsStr>,
 | 
			
		||||
{
 | 
			
		||||
    let (uid, username) = match user {
 | 
			
		||||
        Some(id_name) => id_name,
 | 
			
		||||
        None => get_active_user_id_name(),
 | 
			
		||||
@ -558,7 +586,7 @@ pub fn run_as_user(arg: Vec<&str>, user: Option<(String, String)>) -> ResultType
 | 
			
		||||
        args.insert(0, "-E");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let task = Command::new("sudo").args(args).spawn()?;
 | 
			
		||||
    let task = Command::new("sudo").envs(envs).args(args).spawn()?;
 | 
			
		||||
    Ok(Some(task))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -652,7 +680,7 @@ pub(super) fn get_env_tries(name: &str, uid: &str, process: &str, n: usize) -> S
 | 
			
		||||
 | 
			
		||||
#[inline]
 | 
			
		||||
fn get_env(name: &str, uid: &str, process: &str) -> String {
 | 
			
		||||
    let cmd = format!("ps -u {} -f | grep '{}' | grep -v 'grep' | tail -1 | awk '{{print $2}}' | xargs -I__ cat /proc/__/environ 2>/dev/null | tr '\\0' '\\n' | grep '^{}=' | tail -1 | sed 's/{}=//g'", uid, process, name, name);
 | 
			
		||||
    let cmd = format!("ps -u {} -f | grep -E '{}' | grep -v 'grep' | tail -1 | awk '{{print $2}}' | xargs -I__ cat /proc/__/environ 2>/dev/null | tr '\\0' '\\n' | grep '^{}=' | tail -1 | sed 's/{}=//g'", uid, process, name, name);
 | 
			
		||||
    if let Ok(x) = run_cmds(&cmd) {
 | 
			
		||||
        x.trim_end().to_string()
 | 
			
		||||
    } else {
 | 
			
		||||
@ -887,9 +915,11 @@ mod desktop {
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    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";
 | 
			
		||||
 | 
			
		||||
    const PLASMA_KDED5: &str = "kded5";
 | 
			
		||||
    const GNOME_GOA_DAEMON: &str = "goa-daemon";
 | 
			
		||||
    const RUSTDESK_TRAY: &str = "rustdesk +--tray";
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug, Clone, Default)]
 | 
			
		||||
    pub struct Desktop {
 | 
			
		||||
@ -918,10 +948,30 @@ mod desktop {
 | 
			
		||||
            self.sid.is_empty() || self.is_rustdesk_subprocess
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn get_display(&mut self) {
 | 
			
		||||
            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);
 | 
			
		||||
        fn get_display_wayland(&mut self) {
 | 
			
		||||
            let display_proc = vec![PLASMA_KDED5, GNOME_GOA_DAEMON, RUSTDESK_TRAY];
 | 
			
		||||
            for proc in display_proc {
 | 
			
		||||
                self.display = get_env("DISPLAY", &self.uid, proc);
 | 
			
		||||
                if !self.display.is_empty() {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn get_xauth_wayland(&mut self) {
 | 
			
		||||
            let display_proc = vec![PLASMA_KDED5, GNOME_GOA_DAEMON, RUSTDESK_TRAY];
 | 
			
		||||
            for proc in display_proc {
 | 
			
		||||
                self.xauth = get_env("XAUTHORITY", &self.uid, proc);
 | 
			
		||||
                if !self.xauth.is_empty() {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn get_display_x11(&mut self) {
 | 
			
		||||
            let display_envs = vec![PLASMA_KDED5, GNOME_GOA_DAEMON, XFCE4_PANEL, SDDM_GREETER];
 | 
			
		||||
            for display_env in display_envs {
 | 
			
		||||
                self.display = get_env_tries("DISPLAY", &self.uid, display_env, 10);
 | 
			
		||||
                if !self.display.is_empty() {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
@ -980,9 +1030,9 @@ mod desktop {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn get_xauth(&mut self) {
 | 
			
		||||
        fn get_xauth_x11(&mut self) {
 | 
			
		||||
            // try by direct access to window manager process by name
 | 
			
		||||
            let display_envs = vec![GNOME_SESSION_BINARY, XFCE4_PANEL, SDDM_GREETER, PLASMA_X11];
 | 
			
		||||
            let display_envs = vec![PLASMA_KDED5, GNOME_GOA_DAEMON, XFCE4_PANEL, SDDM_GREETER];
 | 
			
		||||
            for diplay_env in display_envs {
 | 
			
		||||
                self.xauth = get_env_tries("XAUTHORITY", &self.uid, diplay_env, 10);
 | 
			
		||||
                if !self.xauth.is_empty() {
 | 
			
		||||
@ -1088,16 +1138,22 @@ mod desktop {
 | 
			
		||||
            self.uid = seat0_values[1].clone();
 | 
			
		||||
            self.username = seat0_values[2].clone();
 | 
			
		||||
            self.protocal = get_display_server_of_session(&self.sid).into();
 | 
			
		||||
            if self.is_wayland() {
 | 
			
		||||
            if self.is_login_wayland() {
 | 
			
		||||
                self.display = "".to_owned();
 | 
			
		||||
                self.xauth = "".to_owned();
 | 
			
		||||
                self.is_rustdesk_subprocess = false;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            self.get_display();
 | 
			
		||||
            self.get_xauth();
 | 
			
		||||
            self.set_is_subprocess();
 | 
			
		||||
            if self.is_wayland() {
 | 
			
		||||
                self.get_display_wayland();
 | 
			
		||||
                self.get_xauth_wayland();
 | 
			
		||||
                self.is_rustdesk_subprocess = false;
 | 
			
		||||
            } else {
 | 
			
		||||
                self.get_display_x11();
 | 
			
		||||
                self.get_xauth_x11();
 | 
			
		||||
                self.set_is_subprocess();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2522,7 +2522,11 @@ async fn start_ipc(
 | 
			
		||||
                #[cfg(target_os = "linux")]
 | 
			
		||||
                {
 | 
			
		||||
                    log::debug!("Start cm");
 | 
			
		||||
                    res = crate::platform::run_as_user(args.clone(), user.clone());
 | 
			
		||||
                    res = crate::platform::run_as_user(
 | 
			
		||||
                        args.clone(),
 | 
			
		||||
                        user.clone(),
 | 
			
		||||
                        None::<(&str, &str)>,
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                if res.is_ok() {
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user