[codex] Preserve proxy state for filesystem sandbox helpers (#29671)

## Why

Filesystem helpers intentionally run with a minimal environment that
excludes proxy variables. After filesystem operations started using the
Windows sandbox wrapper, the wrapper derived an empty proxy
configuration from that helper environment and compared it with the
persistent sandbox setup marker. When the marker contained proxy ports,
every filesystem operation appeared to require a firewall update, which
could launch elevated setup, show a UAC or loader dialog, and fail
operations such as `apply_patch` with error 1223.

Filesystem helpers do not use network access, so they should preserve
the proxy/firewall state established by normal sandboxed process
launches.

## What changed

- Add an explicit Windows sandbox proxy-settings mode for reconciling or
preserving persistent proxy state.
- Use preserve mode for filesystem helpers while normal process launches
continue to reconcile proxy settings from their environment.
- Carry the selected proxy state consistently through setup validation,
elevated setup, and non-elevated ACL refreshes.
- Cover wrapper argument propagation and marker-derived proxy
preservation.

## Validation

- `cargo build -p codex-cli --bin codex`
- `just test -p codex-windows-sandbox
preserving_proxy_settings_uses_the_existing_marker`
- `just test -p codex-windows-sandbox windows_wrapper_args_round_trip`
- `just test -p codex-windows-sandbox
setup_request_prefers_explicit_proxy_settings`
- `just test -p codex-sandboxing transform_for_direct_spawn_windows`
- `just test -p codex-exec-server fs_sandbox::tests`
- Ran the same sandboxed `fs/writeFile` reproduction against published
`0.142.0-alpha.6` and the new CLI. The published CLI launched elevated
setup and failed with `ShellExecuteExW ... 1223`; the new CLI completed
without elevation.

Related to #28359.
This commit is contained in:
iceweasel-oai
2026-06-23 12:29:46 -07:00
committed by GitHub
Unverified
parent ff50b47dce
commit 18fe1d9fe3
15 changed files with 211 additions and 15 deletions
+2
View File
@@ -473,6 +473,7 @@ async fn run_command_under_windows_session(
) -> ! {
use codex_core::windows_sandbox::WindowsSandboxLevelExt;
use codex_protocol::config_types::WindowsSandboxLevel;
use codex_windows_sandbox::WindowsSandboxProxySettingsMode;
use codex_windows_sandbox::WindowsSandboxSessionRequest;
use codex_windows_sandbox::spawn_windows_sandbox_session_for_level;
@@ -485,6 +486,7 @@ async fn run_command_under_windows_session(
cwd: cwd.as_path(),
env_map: env,
windows_sandbox_level: WindowsSandboxLevel::from_config(config),
proxy_settings_mode: WindowsSandboxProxySettingsMode::Reconcile,
proxy_enforced: false,
timeout_ms: None,
read_roots_override: None,
+2
View File
@@ -131,6 +131,8 @@ impl FileSystemSandboxRunner {
sandbox_manager
.transform_for_direct_spawn(SandboxDirectSpawnTransformRequest {
workspace_roots,
windows_sandbox_proxy_settings_mode:
codex_sandboxing::WindowsSandboxProxySettingsMode::Preserve,
transform: SandboxTransformRequest {
command,
permissions: permission_profile,
@@ -107,6 +107,8 @@ pub(crate) fn prepare_exec_request(
let request = sandbox_manager
.transform_for_direct_spawn(SandboxDirectSpawnTransformRequest {
workspace_roots,
windows_sandbox_proxy_settings_mode:
codex_sandboxing::WindowsSandboxProxySettingsMode::Reconcile,
transform: SandboxTransformRequest {
// TODO(jif): Preserve params.arg0 for the inner command across the sandbox
// wrapper, or reject sandboxed requests with a custom arg0.
+1
View File
@@ -12,6 +12,7 @@ mod windows;
pub use bwrap::find_system_bwrap_in_path;
#[cfg(target_os = "linux")]
pub use bwrap::system_bwrap_warning;
pub use codex_windows_sandbox::WindowsSandboxProxySettingsMode;
pub use denial::is_likely_sandbox_denied;
pub use manager::SandboxCommand;
pub use manager::SandboxDirectSpawnTransformRequest;
+5
View File
@@ -152,6 +152,7 @@ pub struct SandboxTransformRequest<'a> {
pub struct SandboxDirectSpawnTransformRequest<'a> {
pub transform: SandboxTransformRequest<'a>,
pub workspace_roots: &'a [AbsolutePathBuf],
pub windows_sandbox_proxy_settings_mode: codex_windows_sandbox::WindowsSandboxProxySettingsMode,
}
// TODO(anp): Revisit this preparation type once this module's PathUri migration is complete.
@@ -484,12 +485,14 @@ impl SandboxManager {
codex_home: &Path,
) -> Result<SandboxExecRequest, SandboxTransformError> {
let workspace_roots = request.workspace_roots;
let proxy_settings_mode = request.windows_sandbox_proxy_settings_mode;
let mut request = self.transform(request.transform)?;
if request.sandbox == SandboxType::WindowsRestrictedToken {
wrap_windows_sandbox_exec_request_for_direct_spawn(
&mut request,
workspace_roots,
codex_home,
proxy_settings_mode,
)?;
}
Ok(request)
@@ -501,6 +504,7 @@ fn wrap_windows_sandbox_exec_request_for_direct_spawn(
request: &mut SandboxExecRequest,
workspace_roots: &[AbsolutePathBuf],
codex_home: &Path,
proxy_settings_mode: codex_windows_sandbox::WindowsSandboxProxySettingsMode,
) -> Result<(), SandboxTransformError> {
// TODO(anp): Keep PathUri through the Windows sandbox wrapper boundary.
let native_cwd =
@@ -572,6 +576,7 @@ fn wrap_windows_sandbox_exec_request_for_direct_spawn(
request.windows_sandbox_level,
request.windows_sandbox_private_desktop,
proxy_enforced,
proxy_settings_mode,
read_roots_override,
read_roots_include_platform_defaults,
write_roots_override,
+8
View File
@@ -499,6 +499,8 @@ fn transform_for_direct_spawn_windows_materializes_inner_helper() {
.transform_for_direct_spawn_with_codex_home(
SandboxDirectSpawnTransformRequest {
workspace_roots: workspace_roots.as_slice(),
windows_sandbox_proxy_settings_mode:
codex_windows_sandbox::WindowsSandboxProxySettingsMode::Preserve,
transform: SandboxTransformRequest {
command: SandboxCommand {
program: configured_helper.as_os_str().to_owned(),
@@ -544,6 +546,12 @@ fn transform_for_direct_spawn_windows_materializes_inner_helper() {
.iter()
.any(|arg| arg == "--run-as-windows-sandbox")
);
assert!(
exec_request
.command
.iter()
.any(|arg| arg == "--preserve-proxy-settings")
);
assert!(
exec_request
.command
@@ -150,6 +150,7 @@ mod windows_impl {
&deny_read_paths_override,
&deny_write_paths_override,
proxy_enforced,
crate::WindowsSandboxProxySettingsMode::Reconcile,
)?;
// Build capability SID for ACL grants.
let caps = load_or_create_cap_sids(codex_home)?;
@@ -214,6 +215,7 @@ mod windows_impl {
&deny_read_paths_override,
&deny_write_paths_override,
proxy_enforced,
crate::WindowsSandboxProxySettingsMode::Reconcile,
)?;
spawn_runner_transport(
codex_home,
+75 -6
View File
@@ -8,8 +8,8 @@ use crate::setup::SetupMarker;
use crate::setup::gather_read_roots;
use crate::setup::gather_write_roots_for_permissions;
use crate::setup::offline_proxy_settings_from_env;
use crate::setup::run_elevated_setup;
use crate::setup::run_setup_refresh_with_overrides;
use crate::setup::run_elevated_setup_with_proxy_settings;
use crate::setup::run_setup_refresh_with_overrides_and_proxy_settings;
use crate::setup::sandbox_users_path;
use crate::setup::setup_marker_path;
use anyhow::Context;
@@ -154,6 +154,7 @@ pub fn require_logon_sandbox_creds(
deny_read_paths_override: &[PathBuf],
deny_write_paths_override: &[PathBuf],
proxy_enforced: bool,
proxy_settings_mode: crate::WindowsSandboxProxySettingsMode,
) -> Result<SandboxCreds> {
let sandbox_dir = crate::setup::sandbox_dir(codex_home);
let needed_read = read_roots_override
@@ -163,13 +164,19 @@ pub fn require_logon_sandbox_creds(
.map(<[PathBuf]>::to_vec)
.unwrap_or_else(|| gather_write_roots_for_permissions(permissions, command_cwd, env_map));
let network_identity = SandboxNetworkIdentity::from_permissions(permissions, proxy_enforced);
let desired_offline_proxy_settings = offline_proxy_settings_from_env(env_map, network_identity);
let marker = load_marker(codex_home)?;
let desired_offline_proxy_settings = desired_offline_proxy_settings(
marker.as_ref(),
proxy_settings_mode,
env_map,
network_identity,
);
// NOTE: Do not add CODEX_HOME/.sandbox to `needed_write`; it must remain non-writable by the
// restricted capability token. The setup helper's `lock_sandbox_dir` is responsible for
// granting the sandbox group access to this directory without granting the capability SID.
let mut setup_reason: Option<String> = None;
let mut identity = match load_marker(codex_home)? {
let mut identity = match marker {
Some(marker) if marker.version_matches() => {
if let Some(reason) =
marker.request_mismatch_reason(network_identity, &desired_offline_proxy_settings)
@@ -201,7 +208,7 @@ pub fn require_logon_sandbox_creds(
} else {
crate::logging::log_note("sandbox setup required", Some(&sandbox_dir));
}
run_elevated_setup(
run_elevated_setup_with_proxy_settings(
crate::setup::SandboxSetupRequest {
permissions,
command_cwd,
@@ -216,11 +223,12 @@ pub fn require_logon_sandbox_creds(
deny_read_paths: Some(deny_read_paths_override.to_vec()),
deny_write_paths: Some(deny_write_paths_override.to_vec()),
},
&desired_offline_proxy_settings,
)?;
identity = select_identity(network_identity, codex_home)?;
}
// Always refresh ACLs (non-elevated) for current roots via the setup binary.
run_setup_refresh_with_overrides(
run_setup_refresh_with_overrides_and_proxy_settings(
crate::setup::SandboxSetupRequest {
permissions,
command_cwd,
@@ -235,6 +243,7 @@ pub fn require_logon_sandbox_creds(
deny_read_paths: Some(deny_read_paths_override.to_vec()),
deny_write_paths: Some(deny_write_paths_override.to_vec()),
},
&desired_offline_proxy_settings,
)?;
let identity = identity.ok_or_else(|| {
anyhow!(
@@ -247,6 +256,22 @@ pub fn require_logon_sandbox_creds(
})
}
fn desired_offline_proxy_settings(
marker: Option<&SetupMarker>,
proxy_settings_mode: crate::WindowsSandboxProxySettingsMode,
env_map: &HashMap<String, String>,
network_identity: SandboxNetworkIdentity,
) -> crate::setup::OfflineProxySettings {
match (marker, proxy_settings_mode) {
(Some(marker), crate::WindowsSandboxProxySettingsMode::Preserve)
if marker.version_matches() =>
{
marker.offline_proxy_settings()
}
_ => offline_proxy_settings_from_env(env_map, network_identity),
}
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn refresh_logon_sandbox_creds(
permissions: &ResolvedWindowsSandboxPermissions,
@@ -259,6 +284,7 @@ pub(crate) fn refresh_logon_sandbox_creds(
deny_read_paths_override: &[PathBuf],
deny_write_paths_override: &[PathBuf],
proxy_enforced: bool,
proxy_settings_mode: crate::WindowsSandboxProxySettingsMode,
) -> Result<SandboxCreds> {
remove_sandbox_users_file(codex_home, "sandbox user login failed")?;
require_logon_sandbox_creds(
@@ -272,13 +298,20 @@ pub(crate) fn refresh_logon_sandbox_creds(
deny_read_paths_override,
deny_write_paths_override,
proxy_enforced,
proxy_settings_mode,
)
}
#[cfg(test)]
mod tests {
use super::desired_offline_proxy_settings;
use super::remove_sandbox_users_file;
use crate::WindowsSandboxProxySettingsMode;
use crate::setup::SandboxNetworkIdentity;
use crate::setup::SetupMarker;
use crate::setup::sandbox_users_path;
use pretty_assertions::assert_eq;
use std::collections::HashMap;
use std::fs;
use tempfile::TempDir;
@@ -302,4 +335,40 @@ mod tests {
remove_sandbox_users_file(codex_home.path(), "stale creds").expect("remove users");
assert!(!users_path.exists());
}
#[test]
fn preserving_proxy_settings_uses_the_existing_marker() {
let marker = SetupMarker {
version: crate::setup::SETUP_VERSION,
offline_username: "offline".to_string(),
online_username: "online".to_string(),
created_at: None,
proxy_ports: vec![7890],
allow_local_binding: true,
};
let env_map = HashMap::from([(
"HTTP_PROXY".to_string(),
"http://127.0.0.1:8080".to_string(),
)]);
assert_eq!(
desired_offline_proxy_settings(
Some(&marker),
WindowsSandboxProxySettingsMode::Preserve,
&env_map,
SandboxNetworkIdentity::Offline,
),
marker.offline_proxy_settings()
);
assert_eq!(
desired_offline_proxy_settings(
Some(&marker),
WindowsSandboxProxySettingsMode::Reconcile,
&env_map,
SandboxNetworkIdentity::Offline,
)
.proxy_ports,
vec![8080]
);
}
}
+9
View File
@@ -35,6 +35,15 @@ impl fmt::Debug for WindowsSandboxCancellationToken {
}
}
/// Controls whether a Windows sandbox launch reconciles persistent proxy
/// firewall settings or preserves the settings established by another launch.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum WindowsSandboxProxySettingsMode {
#[default]
Reconcile,
Preserve,
}
#[cfg(target_os = "windows")]
mod acl;
#[cfg(target_os = "windows")]
+77 -8
View File
@@ -130,14 +130,16 @@ pub fn run_setup_refresh(
proxy_enforced,
},
SetupRootOverrides::default(),
/*offline_proxy_settings_override*/ None,
)
}
pub fn run_setup_refresh_with_overrides(
pub(crate) fn run_setup_refresh_with_overrides_and_proxy_settings(
request: SandboxSetupRequest<'_>,
overrides: SetupRootOverrides,
offline_proxy_settings: &OfflineProxySettings,
) -> Result<()> {
run_setup_refresh_inner(request, overrides)
run_setup_refresh_inner(request, overrides, Some(offline_proxy_settings))
}
pub fn run_setup_refresh_with_extra_read_roots(
@@ -174,12 +176,14 @@ pub fn run_setup_refresh_with_extra_read_roots(
deny_read_paths: None,
deny_write_paths: None,
},
/*offline_proxy_settings_override*/ None,
)
}
fn run_setup_refresh_inner(
request: SandboxSetupRequest<'_>,
overrides: SetupRootOverrides,
offline_proxy_settings_override: Option<&OfflineProxySettings>,
) -> Result<()> {
if !request.permissions.is_enforceable_by_windows_sandbox() {
anyhow::bail!("unsupported filesystem permissions for Windows sandbox setup");
@@ -187,9 +191,8 @@ fn run_setup_refresh_inner(
let (read_roots, write_roots) = build_payload_roots(&request, &overrides);
let deny_read_paths = build_payload_deny_read_paths(overrides.deny_read_paths);
let deny_write_paths = build_payload_deny_write_paths(&request, overrides.deny_write_paths);
let network_identity =
SandboxNetworkIdentity::from_permissions(request.permissions, request.proxy_enforced);
let offline_proxy_settings = offline_proxy_settings_from_env(request.env_map, network_identity);
let offline_proxy_settings =
offline_proxy_settings_for_request(&request, offline_proxy_settings_override);
let payload = ElevationPayload {
version: SETUP_VERSION,
offline_username: OFFLINE_USERNAME.to_string(),
@@ -283,6 +286,13 @@ impl SetupMarker {
self.version == SETUP_VERSION
}
pub(crate) fn offline_proxy_settings(&self) -> OfflineProxySettings {
OfflineProxySettings {
proxy_ports: self.proxy_ports.clone(),
allow_local_binding: self.allow_local_binding,
}
}
pub(crate) fn request_mismatch_reason(
&self,
network_identity: SandboxNetworkIdentity,
@@ -593,6 +603,17 @@ pub(crate) fn offline_proxy_settings_from_env(
}
}
fn offline_proxy_settings_for_request(
request: &SandboxSetupRequest<'_>,
offline_proxy_settings_override: Option<&OfflineProxySettings>,
) -> OfflineProxySettings {
offline_proxy_settings_override.cloned().unwrap_or_else(|| {
let network_identity =
SandboxNetworkIdentity::from_permissions(request.permissions, request.proxy_enforced);
offline_proxy_settings_from_env(request.env_map, network_identity)
})
}
pub(crate) fn proxy_ports_from_env(env_map: &HashMap<String, String>) -> Vec<u16> {
let mut ports = BTreeSet::new();
for key in PROXY_ENV_KEYS {
@@ -821,6 +842,24 @@ fn run_setup_exe(
pub fn run_elevated_setup(
request: SandboxSetupRequest<'_>,
overrides: SetupRootOverrides,
) -> Result<()> {
run_elevated_setup_inner(
request, overrides, /*offline_proxy_settings_override*/ None,
)
}
pub(crate) fn run_elevated_setup_with_proxy_settings(
request: SandboxSetupRequest<'_>,
overrides: SetupRootOverrides,
offline_proxy_settings: &OfflineProxySettings,
) -> Result<()> {
run_elevated_setup_inner(request, overrides, Some(offline_proxy_settings))
}
fn run_elevated_setup_inner(
request: SandboxSetupRequest<'_>,
overrides: SetupRootOverrides,
offline_proxy_settings_override: Option<&OfflineProxySettings>,
) -> Result<()> {
if !request.permissions.is_enforceable_by_windows_sandbox() {
anyhow::bail!("unsupported filesystem permissions for Windows sandbox setup");
@@ -836,9 +875,8 @@ pub fn run_elevated_setup(
let (read_roots, write_roots) = build_payload_roots(&request, &overrides);
let deny_read_paths = build_payload_deny_read_paths(overrides.deny_read_paths);
let deny_write_paths = build_payload_deny_write_paths(&request, overrides.deny_write_paths);
let network_identity =
SandboxNetworkIdentity::from_permissions(request.permissions, request.proxy_enforced);
let offline_proxy_settings = offline_proxy_settings_from_env(request.env_map, network_identity);
let offline_proxy_settings =
offline_proxy_settings_for_request(&request, offline_proxy_settings_override);
let payload = ElevationPayload {
version: SETUP_VERSION,
offline_username: OFFLINE_USERNAME.to_string(),
@@ -1170,6 +1208,37 @@ mod tests {
)
}
#[test]
fn setup_request_prefers_explicit_proxy_settings() {
let tmp = TempDir::new().expect("tempdir");
let command_cwd = tmp.path().join("workspace");
fs::create_dir_all(&command_cwd).expect("create workspace");
let permissions = permissions_for(
&PermissionProfile::read_only(),
workspace_roots_for(&command_cwd).as_slice(),
);
let env_map = HashMap::from([(
"HTTP_PROXY".to_string(),
"http://127.0.0.1:8080".to_string(),
)]);
let explicit = super::OfflineProxySettings {
proxy_ports: vec![7890],
allow_local_binding: true,
};
let request = super::SandboxSetupRequest {
permissions: &permissions,
command_cwd: &command_cwd,
env_map: &env_map,
codex_home: tmp.path(),
proxy_enforced: false,
};
assert_eq!(
super::offline_proxy_settings_for_request(&request, Some(&explicit)),
explicit
);
}
#[test]
fn report_helper_failure_uses_setup_error_report_when_clear_succeeded() {
let tmp = TempDir::new().expect("tempdir");
@@ -357,6 +357,7 @@ pub(crate) fn prepare_elevated_spawn_context_for_permissions(
deny_read_paths_override: &[PathBuf],
deny_write_paths_override: &[PathBuf],
proxy_enforced: bool,
proxy_settings_mode: crate::WindowsSandboxProxySettingsMode,
) -> Result<ElevatedSpawnContext> {
normalize_null_device_env(env_map);
ensure_non_interactive_pager(env_map);
@@ -412,6 +413,7 @@ pub(crate) fn prepare_elevated_spawn_context_for_permissions(
deny_write_paths_override
},
proxy_enforced,
proxy_settings_mode,
)?;
let caps = load_or_create_cap_sids(codex_home)?;
let (psid_to_use, cap_sids) = if uses_write_capabilities {
@@ -56,6 +56,7 @@ pub(crate) async fn spawn_windows_sandbox_session_elevated_for_permission_profil
cwd: &Path,
mut env_map: HashMap<String, String>,
proxy_enforced: bool,
proxy_settings_mode: crate::WindowsSandboxProxySettingsMode,
timeout_ms: Option<u64>,
read_roots_override: Option<&[PathBuf]>,
read_roots_include_platform_defaults: bool,
@@ -91,6 +92,7 @@ pub(crate) async fn spawn_windows_sandbox_session_elevated_for_permission_profil
&deny_read_paths_override,
&deny_write_paths_override,
proxy_enforced,
proxy_settings_mode,
)?;
let spawn_request = SpawnRequest {
@@ -133,6 +135,7 @@ pub(crate) async fn spawn_windows_sandbox_session_elevated_for_permission_profil
&deny_read_paths_override,
&deny_write_paths_override,
/*proxy_enforced*/ false,
proxy_settings_mode,
)?;
spawn_runner_transport_task(
codex_home,
@@ -31,6 +31,7 @@ pub struct WindowsSandboxSessionRequest<'a> {
pub env_map: HashMap<String, String>,
pub windows_sandbox_level: WindowsSandboxLevel,
pub proxy_enforced: bool,
pub proxy_settings_mode: crate::WindowsSandboxProxySettingsMode,
pub timeout_ms: Option<u64>,
pub read_roots_override: Option<&'a [PathBuf]>,
pub read_roots_include_platform_defaults: bool,
@@ -48,7 +49,7 @@ pub async fn spawn_windows_sandbox_session_for_level(
if request.proxy_enforced
|| matches!(request.windows_sandbox_level, WindowsSandboxLevel::Elevated)
{
spawn_windows_sandbox_session_elevated_for_permission_profile(
backends::elevated::spawn_windows_sandbox_session_elevated_for_permission_profile(
request.permission_profile,
request.workspace_roots,
request.codex_home,
@@ -56,6 +57,7 @@ pub async fn spawn_windows_sandbox_session_for_level(
request.cwd,
request.env_map,
request.proxy_enforced,
request.proxy_settings_mode,
request.timeout_ms,
request.read_roots_override,
request.read_roots_include_platform_defaults,
@@ -145,6 +147,7 @@ pub async fn spawn_windows_sandbox_session_elevated_for_permission_profile(
cwd,
env_map,
proxy_enforced,
crate::WindowsSandboxProxySettingsMode::Reconcile,
timeout_ms,
read_roots_override,
read_roots_include_platform_defaults,
@@ -26,6 +26,7 @@ const DENY_WRITE_PATHS_JSON_FLAG: &str = "--deny-write-paths-json";
const ENV_JSON_FLAG: &str = "--env-json";
const PERMISSION_PROFILE_FLAG: &str = "--permission-profile";
const PRIVATE_DESKTOP_FLAG: &str = "--windows-sandbox-private-desktop";
const PRESERVE_PROXY_SETTINGS_FLAG: &str = "--preserve-proxy-settings";
const PROXY_ENFORCED_FLAG: &str = "--proxy-enforced";
const READ_ROOTS_INCLUDE_PLATFORM_DEFAULTS_FLAG: &str = "--read-roots-include-platform-defaults";
const READ_ROOTS_JSON_FLAG: &str = "--read-roots-json";
@@ -43,6 +44,7 @@ pub fn create_windows_sandbox_command_args_for_permission_profile(
windows_sandbox_level: WindowsSandboxLevel,
windows_sandbox_private_desktop: bool,
proxy_enforced: bool,
proxy_settings_mode: crate::WindowsSandboxProxySettingsMode,
read_roots_override: Option<&[PathBuf]>,
read_roots_include_platform_defaults: bool,
write_roots_override: Option<&[PathBuf]>,
@@ -82,6 +84,9 @@ pub fn create_windows_sandbox_command_args_for_permission_profile(
if proxy_enforced {
args.push(PROXY_ENFORCED_FLAG.to_string());
}
if proxy_settings_mode == crate::WindowsSandboxProxySettingsMode::Preserve {
args.push(PRESERVE_PROXY_SETTINGS_FLAG.to_string());
}
if let Some(read_roots_override) = read_roots_override {
push_json_arg(&mut args, READ_ROOTS_JSON_FLAG, &read_roots_override);
}
@@ -154,6 +159,7 @@ struct WindowsSandboxWrapperRequest {
windows_sandbox_level: WindowsSandboxLevel,
windows_sandbox_private_desktop: bool,
proxy_enforced: bool,
proxy_settings_mode: crate::WindowsSandboxProxySettingsMode,
read_roots_override: Option<Vec<PathBuf>>,
read_roots_include_platform_defaults: bool,
write_roots_override: Option<Vec<PathBuf>>,
@@ -176,6 +182,7 @@ async fn run_windows_sandbox_wrapper_request(request: WindowsSandboxWrapperReque
env_map: request.env_map,
windows_sandbox_level: request.windows_sandbox_level,
proxy_enforced: request.proxy_enforced,
proxy_settings_mode: request.proxy_settings_mode,
timeout_ms: None,
read_roots_override: request.read_roots_override.as_deref(),
read_roots_include_platform_defaults: request.read_roots_include_platform_defaults,
@@ -201,6 +208,7 @@ fn parse_windows_sandbox_wrapper_args(args: Vec<String>) -> Result<WindowsSandbo
let mut windows_sandbox_level = None;
let mut windows_sandbox_private_desktop = false;
let mut proxy_enforced = false;
let mut proxy_settings_mode = crate::WindowsSandboxProxySettingsMode::Reconcile;
let mut read_roots_override = None;
let mut read_roots_include_platform_defaults = false;
let mut write_roots_override = None;
@@ -240,6 +248,9 @@ fn parse_windows_sandbox_wrapper_args(args: Vec<String>) -> Result<WindowsSandbo
windows_sandbox_level = Some(parse_windows_sandbox_level(&value)?);
}
PRIVATE_DESKTOP_FLAG => windows_sandbox_private_desktop = true,
PRESERVE_PROXY_SETTINGS_FLAG => {
proxy_settings_mode = crate::WindowsSandboxProxySettingsMode::Preserve;
}
PROXY_ENFORCED_FLAG => proxy_enforced = true,
READ_ROOTS_INCLUDE_PLATFORM_DEFAULTS_FLAG => {
read_roots_include_platform_defaults = true;
@@ -282,6 +293,7 @@ fn parse_windows_sandbox_wrapper_args(args: Vec<String>) -> Result<WindowsSandbo
.ok_or_else(|| anyhow!("missing required {SANDBOX_LEVEL_FLAG}"))?,
windows_sandbox_private_desktop,
proxy_enforced,
proxy_settings_mode,
read_roots_override,
read_roots_include_platform_defaults,
write_roots_override,
@@ -15,6 +15,7 @@ use super::DENY_READ_PATHS_JSON_FLAG;
use super::DENY_WRITE_PATHS_JSON_FLAG;
use super::ENV_JSON_FLAG;
use super::PERMISSION_PROFILE_FLAG;
use super::PRESERVE_PROXY_SETTINGS_FLAG;
use super::PRIVATE_DESKTOP_FLAG;
use super::PROXY_ENFORCED_FLAG;
use super::READ_ROOTS_INCLUDE_PLATFORM_DEFAULTS_FLAG;
@@ -61,6 +62,7 @@ fn windows_wrapper_args_round_trip() {
WindowsSandboxLevel::Elevated,
/*windows_sandbox_private_desktop*/ true,
/*proxy_enforced*/ true,
crate::WindowsSandboxProxySettingsMode::Preserve,
Some(read_roots_override.as_slice()),
/*read_roots_include_platform_defaults*/ true,
Some(write_roots_override.as_slice()),
@@ -78,6 +80,7 @@ fn windows_wrapper_args_round_trip() {
assert!(args.contains(&SANDBOX_LEVEL_FLAG.to_string()));
assert!(args.contains(&PRIVATE_DESKTOP_FLAG.to_string()));
assert!(args.contains(&PROXY_ENFORCED_FLAG.to_string()));
assert!(args.contains(&PRESERVE_PROXY_SETTINGS_FLAG.to_string()));
assert!(args.contains(&READ_ROOTS_JSON_FLAG.to_string()));
assert!(args.contains(&READ_ROOTS_INCLUDE_PLATFORM_DEFAULTS_FLAG.to_string()));
assert!(args.contains(&WRITE_ROOTS_JSON_FLAG.to_string()));
@@ -98,6 +101,10 @@ fn windows_wrapper_args_round_trip() {
assert_eq!(parsed.windows_sandbox_level, WindowsSandboxLevel::Elevated);
assert_eq!(parsed.windows_sandbox_private_desktop, true);
assert_eq!(parsed.proxy_enforced, true);
assert_eq!(
parsed.proxy_settings_mode,
crate::WindowsSandboxProxySettingsMode::Preserve
);
assert_eq!(parsed.read_roots_override, Some(read_roots_override));
assert_eq!(parsed.read_roots_include_platform_defaults, true);
assert_eq!(parsed.write_roots_override, Some(write_roots_override));