Codex Handbook
windows-sandbox-rs/src/desktop.rs 196 lines
use crate::logging;use crate::token::get_current_token_for_restriction;use crate::token::get_logon_sid_bytes;use crate::winutil::format_last_error;use crate::winutil::to_wide;use anyhow::Result;use rand::Rng;use rand::SeedableRng;use rand::rngs::SmallRng;use std::ffi::c_void;use std::path::Path;use std::ptr;use windows_sys::Win32::Foundation::CloseHandle;use windows_sys::Win32::Foundation::ERROR_SUCCESS;use windows_sys::Win32::Foundation::GetLastError;use windows_sys::Win32::Foundation::HLOCAL;use windows_sys::Win32::Foundation::LocalFree;use windows_sys::Win32::Security::Authorization::EXPLICIT_ACCESS_W;use windows_sys::Win32::Security::Authorization::GRANT_ACCESS;use windows_sys::Win32::Security::Authorization::SE_WINDOW_OBJECT;use windows_sys::Win32::Security::Authorization::SetEntriesInAclW;use windows_sys::Win32::Security::Authorization::SetSecurityInfo;use windows_sys::Win32::Security::Authorization::TRUSTEE_IS_SID;use windows_sys::Win32::Security::Authorization::TRUSTEE_IS_UNKNOWN;use windows_sys::Win32::Security::Authorization::TRUSTEE_W;use windows_sys::Win32::Security::DACL_SECURITY_INFORMATION;use windows_sys::Win32::System::StationsAndDesktops::CloseDesktop;use windows_sys::Win32::System::StationsAndDesktops::CreateDesktopW;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_CREATEMENU;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_CREATEWINDOW;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_DELETE;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_ENUMERATE;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_HOOKCONTROL;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_JOURNALPLAYBACK;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_JOURNALRECORD;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_READ_CONTROL;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_READOBJECTS;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_SWITCHDESKTOP;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_WRITE_DAC;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_WRITE_OWNER;use windows_sys::Win32::System::StationsAndDesktops::DESKTOP_WRITEOBJECTS;const DESKTOP_ALL_ACCESS: u32 = DESKTOP_READOBJECTS    | DESKTOP_CREATEWINDOW    | DESKTOP_CREATEMENU    | DESKTOP_HOOKCONTROL    | DESKTOP_JOURNALRECORD    | DESKTOP_JOURNALPLAYBACK    | DESKTOP_ENUMERATE    | DESKTOP_WRITEOBJECTS    | DESKTOP_SWITCHDESKTOP    | DESKTOP_DELETE    | DESKTOP_READ_CONTROL    | DESKTOP_WRITE_DAC    | DESKTOP_WRITE_OWNER;pub struct LaunchDesktop {    _private_desktop: Option<PrivateDesktop>,    startup_name: Vec<u16>,}impl LaunchDesktop {    pub fn prepare(use_private_desktop: bool, logs_base_dir: Option<&Path>) -> Result<Self> {        if use_private_desktop {            let private_desktop = PrivateDesktop::create(logs_base_dir)?;            let startup_name = to_wide(format!("Winsta0\\{}", private_desktop.name));            Ok(Self {                _private_desktop: Some(private_desktop),                startup_name,            })        } else {            Ok(Self {                _private_desktop: None,                startup_name: to_wide("Winsta0\\Default"),            })        }    }    pub fn startup_info_desktop(&self) -> *mut u16 {        self.startup_name.as_ptr() as *mut u16    }}struct PrivateDesktop {    handle: isize,    name: String,}impl PrivateDesktop {    fn create(logs_base_dir: Option<&Path>) -> Result<Self> {        let mut rng = SmallRng::from_entropy();        let name = format!("CodexSandboxDesktop-{:x}", rng.r#gen::<u128>());        let name_wide = to_wide(&name);        let handle = unsafe {            CreateDesktopW(                name_wide.as_ptr(),                ptr::null(),                ptr::null_mut(),                0,                DESKTOP_ALL_ACCESS,                ptr::null_mut(),            )        };        if handle == 0 {            let err = unsafe { GetLastError() } as i32;            logging::debug_log(                &format!(                    "CreateDesktopW failed for {name}: {} ({})",                    err,                    format_last_error(err),                ),                logs_base_dir,            );            return Err(anyhow::anyhow!("CreateDesktopW failed: {err}"));        }        unsafe {            if let Err(err) = grant_desktop_access(handle, logs_base_dir) {                let _ = CloseDesktop(handle);                return Err(err);            }        }        Ok(Self { handle, name })    }}unsafe fn grant_desktop_access(handle: isize, logs_base_dir: Option<&Path>) -> Result<()> {    let token = get_current_token_for_restriction()?;    let mut logon_sid = get_logon_sid_bytes(token)?;    CloseHandle(token);    let entries = [EXPLICIT_ACCESS_W {        grfAccessPermissions: DESKTOP_ALL_ACCESS,        grfAccessMode: GRANT_ACCESS,        grfInheritance: 0,        Trustee: TRUSTEE_W {            pMultipleTrustee: ptr::null_mut(),            MultipleTrusteeOperation: 0,            TrusteeForm: TRUSTEE_IS_SID,            TrusteeType: TRUSTEE_IS_UNKNOWN,            ptstrName: logon_sid.as_mut_ptr() as *mut c_void as *mut u16,        },    }];    let mut updated_dacl = ptr::null_mut();    let set_entries_code = SetEntriesInAclW(        entries.len() as u32,        entries.as_ptr(),        ptr::null_mut(),        &mut updated_dacl,    );    if set_entries_code != ERROR_SUCCESS {        logging::debug_log(            &format!("SetEntriesInAclW failed for private desktop: {set_entries_code}"),            logs_base_dir,        );        return Err(anyhow::anyhow!(            "SetEntriesInAclW failed for private desktop: {set_entries_code}"        ));    }    let set_security_code = SetSecurityInfo(        handle,        SE_WINDOW_OBJECT,        DACL_SECURITY_INFORMATION,        ptr::null_mut(),        ptr::null_mut(),        updated_dacl,        ptr::null_mut(),    );    if !updated_dacl.is_null() {        LocalFree(updated_dacl as HLOCAL);    }    if set_security_code != ERROR_SUCCESS {        logging::debug_log(            &format!("SetSecurityInfo failed for private desktop: {set_security_code}"),            logs_base_dir,        );        return Err(anyhow::anyhow!(            "SetSecurityInfo failed for private desktop: {set_security_code}"        ));    }    Ok(())}impl Drop for PrivateDesktop {    fn drop(&mut self) {        unsafe {            if self.handle != 0 {                let _ = CloseDesktop(self.handle);            }        }    }}