mirror of
https://github.com/openai/codex.git
synced 2026-11-12 21:20:34 +00:00
verify installed Codex app before launch
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use anyhow::Context as _;
|
||||
use codex_desktop_distribution::discover_installed_distribution;
|
||||
use codex_desktop_distribution::validate_installed_distribution_at;
|
||||
use std::ffi::CString;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
@@ -154,11 +155,11 @@ async fn install_codex_app_bundle(app_in_volume: &Path) -> anyhow::Result<PathBu
|
||||
|
||||
let dest_app = applications_dir.join("Codex.app");
|
||||
if dest_app.is_dir() {
|
||||
return Ok(dest_app);
|
||||
return validate_installed_codex_app(dest_app).await;
|
||||
}
|
||||
|
||||
match copy_app_bundle(app_in_volume, &dest_app).await {
|
||||
Ok(()) => return Ok(dest_app),
|
||||
Ok(()) => return validate_installed_codex_app(dest_app).await,
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
"warning: failed to install Codex.app to {applications_dir}: {err}",
|
||||
@@ -171,6 +172,19 @@ async fn install_codex_app_bundle(app_in_volume: &Path) -> anyhow::Result<PathBu
|
||||
anyhow::bail!("failed to install Codex.app to any applications directory");
|
||||
}
|
||||
|
||||
async fn validate_installed_codex_app(app_path: PathBuf) -> anyhow::Result<PathBuf> {
|
||||
let candidate = app_path.clone();
|
||||
let distribution =
|
||||
tokio::task::spawn_blocking(move || validate_installed_distribution_at(candidate))
|
||||
.await
|
||||
.context("Desktop validation task failed")??;
|
||||
let app_path_display = app_path.display();
|
||||
let distribution = distribution.with_context(|| {
|
||||
format!("refusing to launch unverified Codex Desktop at {app_path_display}")
|
||||
})?;
|
||||
Ok(distribution.app_root().to_path_buf())
|
||||
}
|
||||
|
||||
fn candidate_applications_dirs() -> anyhow::Result<Vec<PathBuf>> {
|
||||
let mut dirs = vec![PathBuf::from("/Applications")];
|
||||
dirs.push(user_applications_dir()?);
|
||||
|
||||
@@ -120,6 +120,16 @@ pub fn discover_installed_distribution()
|
||||
platform::discover()
|
||||
}
|
||||
|
||||
/// Validates a macOS Codex app bundle at a known path using the same identity and containment
|
||||
/// checks as installed-app discovery. Returns `Ok(None)` when the path is not a trusted Codex
|
||||
/// Desktop distribution.
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn validate_installed_distribution_at(
|
||||
app_root: impl AsRef<Path>,
|
||||
) -> Result<Option<InstalledDesktop>, DesktopDistributionError> {
|
||||
platform::validate_candidate(app_root.as_ref())
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum ResourceKind {
|
||||
Directory,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
@@ -18,12 +19,18 @@ pub(crate) fn discover() -> Result<Option<InstalledDesktop>, DesktopDistribution
|
||||
return Ok(None);
|
||||
}
|
||||
let app_root = PathBuf::from(String::from_utf8_lossy(&output.stdout).trim());
|
||||
validate_candidate(&app_root)
|
||||
}
|
||||
|
||||
pub(crate) fn validate_candidate(
|
||||
app_root: &Path,
|
||||
) -> Result<Option<InstalledDesktop>, DesktopDistributionError> {
|
||||
let resources_root = app_root.join("Contents/Resources");
|
||||
if app_root.extension().is_some_and(|value| value == "app")
|
||||
&& resources_root.is_dir()
|
||||
&& has_openai_signature(&app_root)?
|
||||
&& has_openai_signature(app_root)?
|
||||
{
|
||||
return InstalledDesktop::from_paths(app_root, resources_root).map(Some);
|
||||
return InstalledDesktop::from_paths(app_root.to_path_buf(), resources_root).map(Some);
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user