elevation request

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages
2023-01-12 21:03:05 +08:00
parent 741e5eeb0e
commit d3b490ac48
46 changed files with 900 additions and 59 deletions

View File

@@ -101,6 +101,7 @@ pub struct Connection {
last_recv_time: Arc<Mutex<Instant>>,
chat_unanswered: bool,
close_manually: bool,
elevation_requested: bool,
}
impl Subscriber for ConnInner {
@@ -196,6 +197,7 @@ impl Connection {
last_recv_time: Arc::new(Mutex::new(Instant::now())),
chat_unanswered: false,
close_manually: false,
elevation_requested: false,
};
#[cfg(not(any(target_os = "android", target_os = "ios")))]
tokio::spawn(async move {
@@ -247,6 +249,8 @@ impl Connection {
#[cfg(windows)]
let mut last_foreground_window_elevated = false;
#[cfg(windows)]
let mut last_portable_service_running = false;
#[cfg(windows)]
let is_installed = crate::platform::is_installed();
loop {
@@ -353,7 +357,8 @@ impl Connection {
}
#[cfg(windows)]
ipc::Data::DataPortableService(ipc::DataPortableService::RequestStart) => {
if let Err(e) = crate::portable_service::client::start_portable_service() {
use crate::portable_service::client;
if let Err(e) = client::start_portable_service(client::StartPara::Direct) {
log::error!("Failed to start portable service from cm:{:?}", e);
}
}
@@ -440,8 +445,18 @@ impl Connection {
_ = second_timer.tick() => {
#[cfg(windows)]
{
if !is_installed {
let portable_service_running = crate::portable_service::client::PORTABLE_SERVICE_RUNNING.lock().unwrap().clone();
if !is_installed && conn.file_transfer.is_none() && conn.port_forward_socket.is_none(){
let portable_service_running = crate::portable_service::client::running();
if portable_service_running != last_portable_service_running {
last_portable_service_running = portable_service_running;
if portable_service_running && conn.elevation_requested {
let mut misc = Misc::new();
misc.set_portable_service_running(portable_service_running);
let mut msg = Message::new();
msg.set_misc(misc);
conn.inner.send(msg.into());
}
}
let uac = crate::video_service::IS_UAC_RUNNING.lock().unwrap().clone();
if last_uac != uac {
last_uac = uac;
@@ -1476,6 +1491,51 @@ impl Connection {
}
}
}
Some(misc::Union::ElevationRequest(r)) => match r.union {
Some(elevation_request::Union::Direct(_)) => {
#[cfg(windows)]
{
let mut err = "No need to elevate".to_string();
if !crate::platform::is_installed()
&& !crate::portable_service::client::running()
{
use crate::portable_service::client;
err = client::start_portable_service(client::StartPara::Direct)
.err()
.map_or("".to_string(), |e| e.to_string());
}
self.elevation_requested = err.is_empty();
let mut misc = Misc::new();
misc.set_elevation_response(err);
let mut msg = Message::new();
msg.set_misc(misc);
self.send(msg).await;
}
}
Some(elevation_request::Union::Logon(r)) => {
#[cfg(windows)]
{
let mut err = "No need to elevate".to_string();
if !crate::platform::is_installed()
&& !crate::portable_service::client::running()
{
use crate::portable_service::client;
err = client::start_portable_service(client::StartPara::Logon(
r.username, r.password,
))
.err()
.map_or("".to_string(), |e| e.to_string());
}
self.elevation_requested = err.is_empty();
let mut misc = Misc::new();
misc.set_elevation_response(err);
let mut msg = Message::new();
msg.set_misc(misc);
self.send(msg).await;
}
}
_ => {}
},
_ => {}
},
_ => {}

View File

@@ -451,18 +451,24 @@ pub mod server {
// functions called in main process.
pub mod client {
use hbb_common::anyhow::Context;
use std::path::PathBuf;
use super::*;
lazy_static::lazy_static! {
pub static ref PORTABLE_SERVICE_RUNNING: Arc<Mutex<bool>> = Default::default();
static ref RUNNING: Arc<Mutex<bool>> = Default::default();
static ref SHMEM: Arc<Mutex<Option<SharedMemory>>> = Default::default();
static ref SENDER : Mutex<mpsc::UnboundedSender<ipc::Data>> = Mutex::new(client::start_ipc_server());
}
pub(crate) fn start_portable_service() -> ResultType<()> {
pub enum StartPara {
Direct,
Logon(String, String),
}
pub(crate) fn start_portable_service(para: StartPara) -> ResultType<()> {
log::info!("start portable service");
if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
if RUNNING.lock().unwrap().clone() {
bail!("already running");
}
if SHMEM.lock().unwrap().is_none() {
@@ -491,14 +497,60 @@ pub mod client {
unsafe {
libc::memset(shmem.as_ptr() as _, 0, shmem.len() as _);
}
if crate::platform::run_background(
&std::env::current_exe()?.to_string_lossy().to_string(),
"--portable-service",
)
.is_err()
{
*SHMEM.lock().unwrap() = None;
bail!("Failed to run portable service process");
drop(option);
match para {
StartPara::Direct => {
if let Err(e) = crate::platform::run_background(
&std::env::current_exe()?.to_string_lossy().to_string(),
"--portable-service",
) {
*SHMEM.lock().unwrap() = None;
bail!("Failed to run portable service process:{}", e);
}
}
StartPara::Logon(username, password) => {
#[allow(unused_mut)]
let mut exe = std::env::current_exe()?.to_string_lossy().to_string();
#[cfg(feature = "flutter")]
{
if let Some(dir) = PathBuf::from(&exe).parent() {
if !set_dir_permission(&PathBuf::from(dir)) {
*SHMEM.lock().unwrap() = None;
bail!("Failed to set permission of {:?}", dir);
}
}
}
#[cfg(not(feature = "flutter"))]
match hbb_common::directories_next::UserDirs::new() {
Some(user_dir) => {
let dir = user_dir
.home_dir()
.join("AppData")
.join("Local")
.join("rustdesk-sciter");
if std::fs::create_dir_all(&dir).is_ok() {
let dst = dir.join("rustdesk.exe");
if std::fs::copy(&exe, &dst).is_ok() {
if dst.exists() {
if set_dir_permission(&dir) {
exe = dst.to_string_lossy().to_string();
}
}
}
}
}
None => {}
}
if let Err(e) = crate::platform::windows::create_process_with_logon(
username.as_str(),
password.as_str(),
&exe,
"--portable-service",
) {
*SHMEM.lock().unwrap() = None;
bail!("Failed to run portable service process:{}", e);
}
}
}
let _sender = SENDER.lock().unwrap();
Ok(())
@@ -509,6 +561,16 @@ pub mod client {
*SHMEM.lock().unwrap() = None;
}
fn set_dir_permission(dir: &PathBuf) -> bool {
// // give Everyone RX permission
std::process::Command::new("icacls")
.arg(dir.as_os_str())
.arg("/grant")
.arg("Everyone:(OI)(CI)RX")
.arg("/T")
.spawn()
.is_ok()
}
pub struct CapturerPortable;
impl CapturerPortable {
@@ -668,7 +730,7 @@ pub mod client {
}
Pong => {
nack = 0;
*PORTABLE_SERVICE_RUNNING.lock().unwrap() = true;
*RUNNING.lock().unwrap() = true;
},
ConnCount(None) => {
if !quick_support {
@@ -699,7 +761,7 @@ pub mod client {
}
}
}
*PORTABLE_SERVICE_RUNNING.lock().unwrap() = false;
*RUNNING.lock().unwrap() = false;
});
}
Err(err) => {
@@ -752,7 +814,7 @@ pub mod client {
use_yuv: bool,
portable_service_running: bool,
) -> ResultType<Box<dyn TraitCapturer>> {
if portable_service_running != PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
if portable_service_running != RUNNING.lock().unwrap().clone() {
log::info!("portable service status mismatch");
}
if portable_service_running {
@@ -767,7 +829,7 @@ pub mod client {
}
pub fn get_cursor_info(pci: PCURSORINFO) -> BOOL {
if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
if RUNNING.lock().unwrap().clone() {
get_cursor_info_(&mut SHMEM.lock().unwrap().as_mut().unwrap(), pci)
} else {
unsafe { winuser::GetCursorInfo(pci) }
@@ -775,7 +837,7 @@ pub mod client {
}
pub fn handle_mouse(evt: &MouseEvent) {
if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
if RUNNING.lock().unwrap().clone() {
handle_mouse_(evt).ok();
} else {
crate::input_service::handle_mouse_(evt);
@@ -783,12 +845,16 @@ pub mod client {
}
pub fn handle_key(evt: &KeyEvent) {
if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
if RUNNING.lock().unwrap().clone() {
handle_key_(evt).ok();
} else {
crate::input_service::handle_key_(evt);
}
}
pub fn running() -> bool {
RUNNING.lock().unwrap().clone()
}
}
#[repr(C)]

View File

@@ -20,14 +20,10 @@
use super::{video_qos::VideoQoS, *};
#[cfg(windows)]
use crate::portable_service::client::PORTABLE_SERVICE_RUNNING;
#[cfg(windows)]
use hbb_common::get_version_number;
use hbb_common::{
tokio::sync::{
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
Mutex as TokioMutex,
},
use hbb_common::tokio::sync::{
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
Mutex as TokioMutex,
};
#[cfg(not(windows))]
use scrap::Capturer;
@@ -419,7 +415,7 @@ fn run(sp: GenericService) -> ResultType<()> {
#[cfg(target_os = "linux")]
super::wayland::ensure_inited()?;
#[cfg(windows)]
let last_portable_service_running = PORTABLE_SERVICE_RUNNING.lock().unwrap().clone();
let last_portable_service_running = crate::portable_service::client::running();
#[cfg(not(windows))]
let last_portable_service_running = false;
@@ -518,14 +514,14 @@ fn run(sp: GenericService) -> ResultType<()> {
bail!("SWITCH");
}
#[cfg(windows)]
if last_portable_service_running != PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
if last_portable_service_running != crate::portable_service::client::running() {
bail!("SWITCH");
}
check_privacy_mode_changed(&sp, c.privacy_mode_id)?;
#[cfg(windows)]
{
if crate::platform::windows::desktop_changed()
&& !PORTABLE_SERVICE_RUNNING.lock().unwrap().clone()
&& !crate::portable_service::client::running()
{
bail!("Desktop changed");
}