refact, option, allow linux headless

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2023-07-29 13:06:18 +08:00
parent 3c4852a254
commit c15e3c306e
5 changed files with 106 additions and 63 deletions

View File

@ -32,6 +32,10 @@ pub const COMPRESS_LEVEL: i32 = 3;
const SERIAL: i32 = 3; const SERIAL: i32 = 3;
const PASSWORD_ENC_VERSION: &str = "00"; const PASSWORD_ENC_VERSION: &str = "00";
// config2 options
#[cfg(all(target_os = "linux"))]
pub const CONFIG_OPTION_ALLOW_LINUX_HEADLESS: &str = "allow-linux-headless";
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
lazy_static::lazy_static! { lazy_static::lazy_static! {
pub static ref ORG: Arc<RwLock<String>> = Arc::new(RwLock::new("com.carriez".to_owned())); pub static ref ORG: Arc<RwLock<String>> = Arc::new(RwLock::new("com.carriez".to_owned()));

View File

@ -9,6 +9,9 @@ use hbb_common::{
message_proto::Resolution, message_proto::Resolution,
regex::{Captures, Regex}, regex::{Captures, Regex},
}; };
#[cfg(all(feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))]
use hbb_common::config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS;
use std::{ use std::{
cell::RefCell, cell::RefCell,
io::Write, io::Write,
@ -69,6 +72,13 @@ pub struct xcb_xfixes_get_cursor_image {
pub pixels: *const c_long, pub pixels: *const c_long,
} }
#[inline]
#[cfg(feature = "linux_headless")]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))]
pub fn is_headless_allowed() -> bool {
Config::get_option(CONFIG_OPTION_ALLOW_LINUX_HEADLESS) == "Y"
}
#[inline] #[inline]
fn sleep_millis(millis: u64) { fn sleep_millis(millis: u64) {
std::thread::sleep(Duration::from_millis(millis)); std::thread::sleep(Duration::from_millis(millis));

View File

@ -109,6 +109,10 @@ pub fn try_start_desktop(_username: &str, _passsword: &str) -> String {
// No need to verify password here. // No need to verify password here.
return "".to_owned(); return "".to_owned();
} }
if username.is_empty() {
// Another user is logged in. No need to start a new xsession.
return "".to_owned();
}
if let Some(msg) = detect_headless() { if let Some(msg) = detect_headless() {
return msg.to_owned(); return msg.to_owned();

View File

@ -75,7 +75,9 @@ impl RendezvousMediator {
} }
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
crate::platform::linux_desktop_manager::start_xdesktop(); if crate::platform::is_headless_allowed() {
crate::platform::linux_desktop_manager::start_xdesktop();
}
loop { loop {
Config::reset_online(); Config::reset_online();
if Config::get_option("stop-service").is_empty() { if Config::get_option("stop-service").is_empty() {

View File

@ -985,8 +985,10 @@ impl Connection {
} }
#[cfg(feature = "linux_headless")] #[cfg(feature = "linux_headless")]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
if linux_desktop_manager::is_headless() { if crate::platform::is_headless_allowed() {
platform_additions.insert("headless".into(), json!(true)); if linux_desktop_manager::is_headless() {
platform_additions.insert("headless".into(), json!(true));
}
} }
if !platform_additions.is_empty() { if !platform_additions.is_empty() {
pi.platform_additions = pi.platform_additions =
@ -1375,23 +1377,42 @@ impl Connection {
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
let desktop_err = match lr.os_login.as_ref() { let is_headless_allowed = crate::platform::is_headless_allowed();
Some(os_login) => { #[cfg(all(target_os = "linux", feature = "linux_headless"))]
linux_desktop_manager::try_start_desktop(&os_login.username, &os_login.password) #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
let desktop_err = if is_headless_allowed {
match lr.os_login.as_ref() {
Some(os_login) => linux_desktop_manager::try_start_desktop(
&os_login.username,
&os_login.password,
),
None => linux_desktop_manager::try_start_desktop("", ""),
} }
None => linux_desktop_manager::try_start_desktop("", ""), } else {
"".to_string()
}; };
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
let is_headless = linux_desktop_manager::is_headless(); let is_headless = is_headless_allowed && linux_desktop_manager::is_headless();
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
let wait_ipc_timeout = 10_000; let wait_ipc_timeout = 10_000;
#[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))]
let is_headless_proc = is_headless_allowed;
#[cfg(any(
feature = "flatpak",
feature = "appimage",
not(all(target_os = "linux", feature = "linux_headless"))
))]
let is_headless_proc = false;
// If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password. // If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password.
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
if !desktop_err.is_empty() if is_headless_proc
&& !desktop_err.is_empty()
&& desktop_err != crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY && desktop_err != crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY
{ {
self.send_login_error(desktop_err).await; self.send_login_error(desktop_err).await;
@ -1424,22 +1445,23 @@ impl Connection {
} else if self.is_recent_session() { } else if self.is_recent_session() {
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
if desktop_err.is_empty() { if is_headless_proc {
#[cfg(target_os = "linux")] if desktop_err.is_empty() {
if is_headless { if is_headless {
self.tx_desktop_ready.send(()).await.ok(); self.tx_desktop_ready.send(()).await.ok();
let _res = timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; let _res =
timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await;
}
self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), true);
self.send_logon_response().await;
if self.port_forward_socket.is_some() {
return false;
}
} else {
self.send_login_error(desktop_err).await;
} }
self.try_start_cm(lr.my_id, lr.my_name, true);
self.send_logon_response().await;
if self.port_forward_socket.is_some() {
return false;
}
} else {
self.send_login_error(desktop_err).await;
} }
#[cfg(not(all(target_os = "linux", feature = "linux_headless")))] if !is_headless_proc {
{
self.try_start_cm(lr.my_id, lr.my_name, true); self.try_start_cm(lr.my_id, lr.my_name, true);
self.send_logon_response().await; self.send_logon_response().await;
if self.port_forward_socket.is_some() { if self.port_forward_socket.is_some() {
@ -1449,16 +1471,19 @@ impl Connection {
} else if lr.password.is_empty() { } else if lr.password.is_empty() {
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
if desktop_err.is_empty() { if is_headless_proc {
self.try_start_cm(lr.my_id, lr.my_name, false); if desktop_err.is_empty() {
} else { self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), false);
self.send_login_error( } else {
crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY, self.send_login_error(
) crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY,
.await; )
.await;
}
}
if !is_headless_proc {
self.try_start_cm(lr.my_id, lr.my_name, false);
} }
#[cfg(not(all(target_os = "linux", feature = "linux_headless")))]
self.try_start_cm(lr.my_id, lr.my_name, false);
} else { } else {
let mut failure = LOGIN_FAILURES let mut failure = LOGIN_FAILURES
.lock() .lock()
@ -1499,18 +1524,19 @@ impl Connection {
.insert(self.ip.clone(), failure); .insert(self.ip.clone(), failure);
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
if desktop_err.is_empty() { if is_headless_proc {
self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG) if desktop_err.is_empty() {
self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG)
.await;
self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), false);
} else {
self.send_login_error(
crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG,
)
.await; .await;
self.try_start_cm(lr.my_id, lr.my_name, false); }
} else {
self.send_login_error(
crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG,
)
.await;
} }
#[cfg(not(all(target_os = "linux", feature = "linux_headless")))] if !is_headless_proc {
{
self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG) self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG)
.await; .await;
self.try_start_cm(lr.my_id, lr.my_name, false); self.try_start_cm(lr.my_id, lr.my_name, false);
@ -1521,23 +1547,23 @@ impl Connection {
} }
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
if desktop_err.is_empty() { if is_headless_proc {
#[cfg(target_os = "linux")] if desktop_err.is_empty() {
if is_headless { if is_headless {
self.tx_desktop_ready.send(()).await.ok(); self.tx_desktop_ready.send(()).await.ok();
let _res = let _res =
timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await;
}
self.send_logon_response().await;
self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), true);
if self.port_forward_socket.is_some() {
return false;
}
} else {
self.send_login_error(desktop_err).await;
} }
self.send_logon_response().await;
self.try_start_cm(lr.my_id, lr.my_name, true);
if self.port_forward_socket.is_some() {
return false;
}
} else {
self.send_login_error(desktop_err).await;
} }
#[cfg(not(all(target_os = "linux", feature = "linux_headless")))] if !is_headless_proc {
{
self.send_logon_response().await; self.send_logon_response().await;
self.try_start_cm(lr.my_id, lr.my_name, true); self.try_start_cm(lr.my_id, lr.my_name, true);
if self.port_forward_socket.is_some() { if self.port_forward_socket.is_some() {
@ -2361,19 +2387,16 @@ async fn start_ipc(
args.push("--hide"); args.push("--hide");
}; };
#[cfg(target_os = "linux")] #[cfg(any(feature = "flatpak", feature = "appimage", not(all(target_os = "linux", feature = "linux_headless"))))]
#[cfg(not(feature = "linux_headless"))]
let user = None;
#[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(any(feature = "flatpak", feature = "appimage"))]
let user = None; let user = None;
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
let mut user = None; let mut user = None;
// Cm run as user, wait until desktop session is ready. // Cm run as user, wait until desktop session is ready.
#[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(all(target_os = "linux", feature = "linux_headless"))]
#[cfg(not(any(feature = "flatpak", feature = "appimage")))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))]
if linux_desktop_manager::is_headless() { if crate::platform::is_headless_allowed() && linux_desktop_manager::is_headless() {
let mut username = linux_desktop_manager::get_username(); let mut username = linux_desktop_manager::get_username();
loop { loop {
if !username.is_empty() { if !username.is_empty() {