mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
## Summary In https://github.com/openai/codex/pull/21584, we disabled doctests for crates that lack any doctests. We can enforce that property via `cargo shear --deny-warnings`: crates that lack doctests will be flagged if doctests are enabled, and crates with doctests will be flagged if doctests are disabled. A few additional notes: - By adding `--deny-warnings`, `cargo shear` also flagged a number of modules that were not reachable at all. Some of those have been removed. - This PR removes a usage of `windows_modules!` (since `cargo shear` and `rustfmt` couldn't see through it) in favor of simple `#[cfg(target_os = "windows")]` macros. As a consequence, many of these files exhibit churn in this PR, since they weren't being formatted by `rustfmt` at all on main. - Again, to make the code more analyzable, this PR also removes some usages of `#[path = "cwd_junction.rs"]` in favor of a more standard module structure. The bin sidecar structure is still retained, but, e.g., `windows-sandbox-rs/src/bin/command_runner.rs` was moved to `windows-sandbox-rs/src/bin/command_runner/main.rs`, and so on. --------- Co-authored-by: Codex <noreply@openai.com>
423 lines
15 KiB
Rust
423 lines
15 KiB
Rust
mod filter_specs;
|
|
|
|
use crate::to_wide;
|
|
use anyhow::Result;
|
|
use std::ffi::OsStr;
|
|
use std::mem::zeroed;
|
|
use std::ptr::null;
|
|
use std::ptr::null_mut;
|
|
use windows_sys::Win32::Foundation::FWP_E_ALREADY_EXISTS;
|
|
use windows_sys::Win32::Foundation::FWP_E_FILTER_NOT_FOUND;
|
|
use windows_sys::Win32::Foundation::FWP_E_NOT_FOUND;
|
|
use windows_sys::Win32::Foundation::HANDLE;
|
|
use windows_sys::Win32::Foundation::HLOCAL;
|
|
use windows_sys::Win32::Foundation::LocalFree;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_ACTION_BLOCK;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_ACTRL_MATCH_FILTER;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_BYTE_BLOB;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_CONDITION_VALUE0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_CONDITION_VALUE0_0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_EMPTY;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_MATCH_EQUAL;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_SECURITY_DESCRIPTOR_TYPE;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_UINT8;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_UINT16;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWP_VALUE0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_ACTION0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_ACTION0_0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_CONDITION_ALE_USER_ID;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_CONDITION_IP_PROTOCOL;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_CONDITION_IP_REMOTE_PORT;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_DISPLAY_DATA0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_FILTER_CONDITION0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_FILTER_FLAG_PERSISTENT;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_FILTER0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_FILTER0_0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_PROVIDER_FLAG_PERSISTENT;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_PROVIDER0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_SESSION0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_SUBLAYER_FLAG_PERSISTENT;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_SUBLAYER0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FwpmEngineClose0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FwpmEngineOpen0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FwpmFilterAdd0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FwpmFilterDeleteByKey0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FwpmProviderAdd0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FwpmSubLayerAdd0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FwpmTransactionAbort0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FwpmTransactionBegin0;
|
|
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FwpmTransactionCommit0;
|
|
use windows_sys::Win32::Security::Authorization::BuildExplicitAccessWithNameW;
|
|
use windows_sys::Win32::Security::Authorization::BuildSecurityDescriptorW;
|
|
use windows_sys::Win32::Security::Authorization::EXPLICIT_ACCESS_W;
|
|
use windows_sys::Win32::Security::Authorization::GRANT_ACCESS;
|
|
use windows_sys::Win32::Security::PSECURITY_DESCRIPTOR;
|
|
use windows_sys::Win32::System::Rpc::RPC_C_AUTHN_DEFAULT;
|
|
use windows_sys::Win32::System::Threading::INFINITE;
|
|
use windows_sys::core::GUID;
|
|
|
|
use filter_specs::ConditionSpec;
|
|
use filter_specs::FILTER_SPECS;
|
|
use filter_specs::FilterSpec;
|
|
|
|
const SESSION_NAME: &str = "Codex Windows Sandbox WFP";
|
|
const PROVIDER_NAME: &str = "Codex Windows Sandbox WFP";
|
|
const PROVIDER_DESCRIPTION: &str = "Persistent WFP provider for Codex Windows sandbox filters";
|
|
const SUBLAYER_NAME: &str = "Codex Windows Sandbox WFP";
|
|
const SUBLAYER_DESCRIPTION: &str = "Persistent WFP sublayer for Codex Windows sandbox filters";
|
|
|
|
// WFP identifies persistent providers, sublayers, and filters by stable GUIDs.
|
|
// These values are Codex-owned identities; do not regenerate them unless we
|
|
// intentionally want to orphan old objects and create a new WFP namespace.
|
|
const PROVIDER_KEY: GUID = GUID::from_u128(0x2e31d31c_3948_4753_9117_e5d1a6496f41);
|
|
const SUBLAYER_KEY: GUID = GUID::from_u128(0xe65054fd_4d32_4c7c_95ef_621f0cf6431a);
|
|
|
|
/// Installs the persistent Codex WFP filters for `account`.
|
|
///
|
|
/// This is intended to run from the already-elevated setup helper. Callers
|
|
/// should treat any returned error as non-fatal to the rest of setup.
|
|
pub fn install_wfp_filters_for_account(account: &str) -> Result<usize> {
|
|
let engine = Engine::open()?;
|
|
let mut transaction = engine.begin_transaction()?;
|
|
ensure_provider(engine.handle)?;
|
|
ensure_sublayer(engine.handle)?;
|
|
|
|
let user_condition = UserMatchCondition::for_account(account)?;
|
|
let mut installed_filter_count = 0;
|
|
for spec in FILTER_SPECS {
|
|
delete_filter_if_present(engine.handle, &spec.key)?;
|
|
add_filter(engine.handle, spec, &user_condition)?;
|
|
installed_filter_count += 1;
|
|
}
|
|
|
|
transaction.commit()?;
|
|
Ok(installed_filter_count)
|
|
}
|
|
|
|
/// Owns an open WFP engine handle and closes it on drop.
|
|
struct Engine {
|
|
handle: HANDLE,
|
|
}
|
|
|
|
impl Engine {
|
|
fn open() -> Result<Self> {
|
|
let session_name = to_wide(OsStr::new(SESSION_NAME));
|
|
let mut session: FWPM_SESSION0 = unsafe { zeroed() };
|
|
session.displayData = FWPM_DISPLAY_DATA0 {
|
|
name: session_name.as_ptr() as *mut _,
|
|
description: null_mut(),
|
|
};
|
|
session.txnWaitTimeoutInMSec = INFINITE;
|
|
|
|
let mut handle = HANDLE::default();
|
|
let result = unsafe {
|
|
FwpmEngineOpen0(
|
|
null(),
|
|
RPC_C_AUTHN_DEFAULT as u32,
|
|
null(),
|
|
&session,
|
|
&mut handle,
|
|
)
|
|
};
|
|
ensure_success(result, "FwpmEngineOpen0")?;
|
|
Ok(Self { handle })
|
|
}
|
|
|
|
fn begin_transaction(&self) -> Result<Transaction<'_>> {
|
|
let result = unsafe { FwpmTransactionBegin0(self.handle, 0) };
|
|
ensure_success(result, "FwpmTransactionBegin0")?;
|
|
Ok(Transaction {
|
|
engine: self,
|
|
committed: false,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl Drop for Engine {
|
|
fn drop(&mut self) {
|
|
unsafe {
|
|
FwpmEngineClose0(self.handle);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Aborts an open WFP transaction unless it was explicitly committed.
|
|
struct Transaction<'a> {
|
|
engine: &'a Engine,
|
|
committed: bool,
|
|
}
|
|
|
|
impl Transaction<'_> {
|
|
fn commit(&mut self) -> Result<()> {
|
|
let result = unsafe { FwpmTransactionCommit0(self.engine.handle) };
|
|
ensure_success(result, "FwpmTransactionCommit0")?;
|
|
self.committed = true;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Drop for Transaction<'_> {
|
|
fn drop(&mut self) {
|
|
if !self.committed {
|
|
unsafe {
|
|
FwpmTransactionAbort0(self.engine.handle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Builds the ALE_USER_ID condition blob that scopes filters to one account.
|
|
struct UserMatchCondition {
|
|
security_descriptor: PSECURITY_DESCRIPTOR,
|
|
blob: FWP_BYTE_BLOB,
|
|
}
|
|
|
|
impl UserMatchCondition {
|
|
fn for_account(account: &str) -> Result<Self> {
|
|
let account_w = to_wide(OsStr::new(account));
|
|
let mut access: EXPLICIT_ACCESS_W = unsafe { zeroed() };
|
|
unsafe {
|
|
BuildExplicitAccessWithNameW(
|
|
&mut access,
|
|
account_w.as_ptr(),
|
|
FWP_ACTRL_MATCH_FILTER,
|
|
GRANT_ACCESS,
|
|
0,
|
|
);
|
|
}
|
|
|
|
let mut security_descriptor: PSECURITY_DESCRIPTOR = null_mut();
|
|
let mut security_descriptor_len = 0;
|
|
let result = unsafe {
|
|
BuildSecurityDescriptorW(
|
|
null(),
|
|
null(),
|
|
1,
|
|
&access,
|
|
0,
|
|
null(),
|
|
null_mut(),
|
|
&mut security_descriptor_len,
|
|
&mut security_descriptor,
|
|
)
|
|
};
|
|
ensure_success(result, "BuildSecurityDescriptorW")?;
|
|
|
|
Ok(Self {
|
|
security_descriptor,
|
|
blob: FWP_BYTE_BLOB {
|
|
size: security_descriptor_len,
|
|
data: security_descriptor as *mut u8,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
impl Drop for UserMatchCondition {
|
|
fn drop(&mut self) {
|
|
if !self.security_descriptor.is_null() {
|
|
unsafe {
|
|
LocalFree(self.security_descriptor as HLOCAL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Ensures the persistent Codex WFP provider exists.
|
|
fn ensure_provider(engine: HANDLE) -> Result<()> {
|
|
let provider_name = to_wide(OsStr::new(PROVIDER_NAME));
|
|
let provider_description = to_wide(OsStr::new(PROVIDER_DESCRIPTION));
|
|
let provider = FWPM_PROVIDER0 {
|
|
providerKey: PROVIDER_KEY,
|
|
displayData: FWPM_DISPLAY_DATA0 {
|
|
name: provider_name.as_ptr() as *mut _,
|
|
description: provider_description.as_ptr() as *mut _,
|
|
},
|
|
flags: FWPM_PROVIDER_FLAG_PERSISTENT,
|
|
providerData: empty_blob(),
|
|
serviceName: null_mut(),
|
|
};
|
|
|
|
let result = unsafe { FwpmProviderAdd0(engine, &provider, null_mut()) };
|
|
ensure_success_or(result, "FwpmProviderAdd0", &[FWP_E_ALREADY_EXISTS as u32])
|
|
}
|
|
|
|
/// Ensures the persistent Codex sublayer exists under the Codex provider.
|
|
fn ensure_sublayer(engine: HANDLE) -> Result<()> {
|
|
let sublayer_name = to_wide(OsStr::new(SUBLAYER_NAME));
|
|
let sublayer_description = to_wide(OsStr::new(SUBLAYER_DESCRIPTION));
|
|
let provider_key = PROVIDER_KEY;
|
|
let sublayer = FWPM_SUBLAYER0 {
|
|
subLayerKey: SUBLAYER_KEY,
|
|
displayData: FWPM_DISPLAY_DATA0 {
|
|
name: sublayer_name.as_ptr() as *mut _,
|
|
description: sublayer_description.as_ptr() as *mut _,
|
|
},
|
|
flags: FWPM_SUBLAYER_FLAG_PERSISTENT,
|
|
providerKey: &provider_key as *const _ as *mut _,
|
|
providerData: empty_blob(),
|
|
weight: 0x8000,
|
|
};
|
|
|
|
let result = unsafe { FwpmSubLayerAdd0(engine, &sublayer, null_mut()) };
|
|
ensure_success_or(result, "FwpmSubLayerAdd0", &[FWP_E_ALREADY_EXISTS as u32])
|
|
}
|
|
|
|
/// Adds one blocking WFP filter from the static filter spec list.
|
|
fn add_filter(
|
|
engine: HANDLE,
|
|
spec: &FilterSpec,
|
|
user_condition: &UserMatchCondition,
|
|
) -> Result<()> {
|
|
let filter_name = to_wide(OsStr::new(spec.name));
|
|
let filter_description = to_wide(OsStr::new(spec.description));
|
|
let mut filter_conditions = build_conditions(spec.conditions, user_condition);
|
|
let provider_key = PROVIDER_KEY;
|
|
let filter = FWPM_FILTER0 {
|
|
filterKey: spec.key,
|
|
displayData: FWPM_DISPLAY_DATA0 {
|
|
name: filter_name.as_ptr() as *mut _,
|
|
description: filter_description.as_ptr() as *mut _,
|
|
},
|
|
flags: FWPM_FILTER_FLAG_PERSISTENT,
|
|
providerKey: &provider_key as *const _ as *mut _,
|
|
providerData: empty_blob(),
|
|
layerKey: spec.layer_key,
|
|
subLayerKey: SUBLAYER_KEY,
|
|
weight: empty_value(),
|
|
numFilterConditions: filter_conditions.len() as u32,
|
|
filterCondition: filter_conditions.as_mut_ptr(),
|
|
action: FWPM_ACTION0 {
|
|
r#type: FWP_ACTION_BLOCK,
|
|
Anonymous: FWPM_ACTION0_0 {
|
|
filterType: zero_guid(),
|
|
},
|
|
},
|
|
Anonymous: FWPM_FILTER0_0 { rawContext: 0 },
|
|
reserved: null_mut(),
|
|
filterId: 0,
|
|
effectiveWeight: empty_value(),
|
|
};
|
|
|
|
let mut filter_id = 0_u64;
|
|
let result = unsafe { FwpmFilterAdd0(engine, &filter, null_mut(), &mut filter_id) };
|
|
ensure_success(result, &format!("FwpmFilterAdd0({})", spec.name))
|
|
}
|
|
|
|
/// Converts our compact condition specs into WFP filter conditions.
|
|
fn build_conditions(
|
|
specs: &[ConditionSpec],
|
|
user_condition: &UserMatchCondition,
|
|
) -> Vec<FWPM_FILTER_CONDITION0> {
|
|
specs
|
|
.iter()
|
|
.map(|spec| match spec {
|
|
ConditionSpec::User => FWPM_FILTER_CONDITION0 {
|
|
fieldKey: FWPM_CONDITION_ALE_USER_ID,
|
|
matchType: FWP_MATCH_EQUAL,
|
|
conditionValue: FWP_CONDITION_VALUE0 {
|
|
r#type: FWP_SECURITY_DESCRIPTOR_TYPE,
|
|
Anonymous: FWP_CONDITION_VALUE0_0 {
|
|
sd: &user_condition.blob as *const _ as *mut _,
|
|
},
|
|
},
|
|
},
|
|
ConditionSpec::Protocol(protocol) => FWPM_FILTER_CONDITION0 {
|
|
fieldKey: FWPM_CONDITION_IP_PROTOCOL,
|
|
matchType: FWP_MATCH_EQUAL,
|
|
conditionValue: FWP_CONDITION_VALUE0 {
|
|
r#type: FWP_UINT8,
|
|
Anonymous: FWP_CONDITION_VALUE0_0 { uint8: *protocol },
|
|
},
|
|
},
|
|
ConditionSpec::RemotePort(port) => FWPM_FILTER_CONDITION0 {
|
|
fieldKey: FWPM_CONDITION_IP_REMOTE_PORT,
|
|
matchType: FWP_MATCH_EQUAL,
|
|
conditionValue: FWP_CONDITION_VALUE0 {
|
|
r#type: FWP_UINT16,
|
|
Anonymous: FWP_CONDITION_VALUE0_0 { uint16: *port },
|
|
},
|
|
},
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
/// Deletes an old copy of a filter before re-adding it.
|
|
fn delete_filter_if_present(engine: HANDLE, key: &GUID) -> Result<()> {
|
|
let result = unsafe { FwpmFilterDeleteByKey0(engine, key) };
|
|
ensure_success_or(
|
|
result,
|
|
"FwpmFilterDeleteByKey0",
|
|
&[FWP_E_FILTER_NOT_FOUND as u32, FWP_E_NOT_FOUND as u32],
|
|
)
|
|
}
|
|
|
|
fn ensure_success(result: u32, operation: &str) -> Result<()> {
|
|
ensure_success_or(result, operation, &[])
|
|
}
|
|
|
|
fn ensure_success_or(result: u32, operation: &str, allowed: &[u32]) -> Result<()> {
|
|
if result == 0 || allowed.contains(&result) {
|
|
Ok(())
|
|
} else {
|
|
Err(anyhow::anyhow!(
|
|
"{operation} failed: {}",
|
|
format_error_code(result)
|
|
))
|
|
}
|
|
}
|
|
|
|
fn format_error_code(result: u32) -> String {
|
|
format!("0x{result:08X}")
|
|
}
|
|
|
|
fn empty_blob() -> FWP_BYTE_BLOB {
|
|
FWP_BYTE_BLOB {
|
|
size: 0,
|
|
data: null_mut(),
|
|
}
|
|
}
|
|
|
|
fn empty_value() -> FWP_VALUE0 {
|
|
FWP_VALUE0 {
|
|
r#type: FWP_EMPTY,
|
|
Anonymous: unsafe { zeroed() },
|
|
}
|
|
}
|
|
|
|
fn zero_guid() -> GUID {
|
|
GUID::from_u128(0)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::FILTER_SPECS;
|
|
use pretty_assertions::assert_eq;
|
|
use std::collections::BTreeSet;
|
|
|
|
#[test]
|
|
fn filter_keys_are_unique() {
|
|
let keys = FILTER_SPECS
|
|
.iter()
|
|
.map(|spec| {
|
|
(
|
|
spec.key.data1,
|
|
spec.key.data2,
|
|
spec.key.data3,
|
|
spec.key.data4,
|
|
)
|
|
})
|
|
.collect::<BTreeSet<_>>();
|
|
assert_eq!(keys.len(), FILTER_SPECS.len());
|
|
}
|
|
|
|
#[test]
|
|
fn filter_names_are_unique() {
|
|
let names = FILTER_SPECS
|
|
.iter()
|
|
.map(|spec| spec.name)
|
|
.collect::<BTreeSet<_>>();
|
|
assert_eq!(names.len(), FILTER_SPECS.len());
|
|
}
|
|
}
|