diff --git a/src/platform/windows.cc b/src/platform/windows.cc index 74c20c80d..9027d9d89 100644 --- a/src/platform/windows.cc +++ b/src/platform/windows.cc @@ -580,9 +580,8 @@ extern "C" return rdp_or_console; } - BOOL is_session_locked(BOOL include_rdp) + BOOL is_session_locked(DWORD session_id) { - DWORD session_id = get_current_session(include_rdp); if (session_id == 0xFFFFFFFF) { return FALSE; } diff --git a/src/platform/windows.rs b/src/platform/windows.rs index b579891f1..7e4e390aa 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -523,7 +523,7 @@ const SERVICE_TYPE: ServiceType = ServiceType::OWN_PROCESS; extern "C" { fn get_current_session(rdp: BOOL) -> DWORD; - fn is_session_locked(include_rdp: BOOL) -> BOOL; + fn is_session_locked(session_id: DWORD) -> BOOL; fn LaunchProcessWin( cmd: *const u16, session_id: DWORD, @@ -1149,20 +1149,21 @@ pub fn is_prelogin() -> bool { } pub fn is_locked() -> bool { - unsafe { is_session_locked(share_rdp()) == TRUE } + let Some(session_id) = get_current_process_session_id() else { + return false; + }; + unsafe { is_session_locked(session_id) == TRUE } } -// `is_logon_ui()` is regardless of multiple sessions now. -// It only check if "LogonUI.exe" exists. -// -// If there're mulitple sessions (logged in users), -// some are in the login screen, while the others are not. -// Then this function may not work fine if the session we want to handle(connect) is not in the login screen. -// But it's a rare case and cannot be simply handled, so it will not be dealt with for the time being. #[inline] pub fn is_logon_ui() -> ResultType { + let Some(current_sid) = get_current_process_session_id() else { + return Ok(false); + }; let pids = get_pids("LogonUI.exe")?; - Ok(!pids.is_empty()) + Ok(pids + .into_iter() + .any(|pid| get_session_id_of_process(pid) == Some(current_sid))) } pub fn is_root() -> bool { diff --git a/src/server/connection.rs b/src/server/connection.rs index afa40a25b..0e7f26263 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2025,7 +2025,7 @@ impl Connection { self.validate_password_plain(storage) } - fn validate_password(&mut self) -> bool { + fn validate_password(&mut self, allow_permanent_password: bool) -> bool { if password::temporary_enabled() { let password = password::temporary_password(); if self.validate_one_password(&password) { @@ -2037,13 +2037,19 @@ impl Connection { return true; } } - if password::permanent_enabled() { + if password::permanent_enabled() || allow_permanent_password { + let print_fallback = || { + if allow_permanent_password && !password::permanent_enabled() { + log::info!("Permanent password accepted via logon-screen fallback"); + } + }; // Since hashed storage uses a prefix-based encoding, a hard plaintext that // happens to look like hashed storage could be mis-detected. Validate local storage // and hard/preset plaintext via separate paths to avoid that ambiguity. let (local_storage, _) = Config::get_local_permanent_password_storage_and_salt(); if !local_storage.is_empty() { if self.validate_password_storage(&local_storage) { + print_fallback(); return true; } } else { @@ -2054,6 +2060,7 @@ impl Connection { .cloned() .unwrap_or_default(); if !hard.is_empty() && self.validate_password_plain(&hard) { + print_fallback(); return true; } } @@ -2349,6 +2356,10 @@ impl Connection { #[cfg(any(target_os = "android", target_os = "ios"))] let is_logon = || crate::platform::is_prelogin(); + let allow_logon_screen_password = + crate::get_builtin_option(keys::OPTION_ALLOW_LOGON_SCREEN_PASSWORD) == "Y" + && is_logon(); + if !hbb_common::is_ip_str(&lr.username) && !hbb_common::is_domain_port_str(&lr.username) && lr.username != Config::get_id() @@ -2357,8 +2368,7 @@ impl Connection { .await; return false; } else if (password::approve_mode() == ApproveMode::Click - && !(crate::get_builtin_option(keys::OPTION_ALLOW_LOGON_SCREEN_PASSWORD) == "Y" - && is_logon())) + && !allow_logon_screen_password) || password::approve_mode() == ApproveMode::Both && !password::has_valid_password() { self.try_start_cm(lr.my_id, lr.my_name, false); @@ -2394,7 +2404,7 @@ impl Connection { if !res { return true; } - if !self.validate_password() { + if !self.validate_password(allow_logon_screen_password) { self.update_failure(failure, false, 0); if err_msg.is_empty() { self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG)