MCPcopy Create free account
hub / github.com/NVIDIA/OpenShell / resolve_sandbox_source_path

Function resolve_sandbox_source_path

crates/openshell-cli/src/ssh.rs:893–912  ·  view source on GitHub ↗

Resolve every symlink in `sandbox_path` on the sandbox side and refuse the result if it lands outside `/sandbox`. The lexical guard in `validate_sandbox_source_path` cannot see symlinks; a path such as `/sandbox/etc-link/passwd` (where `etc-link -> /etc`) clears the lexical check but would still leak `/etc/passwd` once `tar -C` follows the link. Resolving symlinks on the remote side and re-valida

(
    session: &SshSessionConfig,
    sandbox_path: &str,
)

Source from the content-addressed store, hash-verified

891/// that gap. The returned fully-resolved path is what the caller should hand
892/// to probe and tar invocations.
893async fn resolve_sandbox_source_path(
894 session: &SshSessionConfig,
895 sandbox_path: &str,
896) -> Result<String> {
897 let resolve_cmd = format!("realpath -e -- {path}", path = shell_escape(sandbox_path));
898 let resolved = ssh_run_capture_stdout(session, &resolve_cmd)
899 .await
900 .wrap_err_with(|| format!("failed to resolve sandbox source path '{sandbox_path}'"))?;
901 if resolved.is_empty() {
902 return Err(miette::miette!(
903 "sandbox source path '{sandbox_path}' does not exist"
904 ));
905 }
906 if !is_under_sandbox_workspace(&resolved) {
907 return Err(miette::miette!(
908 "sandbox source path '{sandbox_path}' resolves to '{resolved}', outside the sandbox workspace ({SANDBOX_WORKSPACE_ROOT})"
909 ));
910 }
911 Ok(resolved)
912}
913
914/// Resolve the host-side target path for a downloaded *file*, following
915/// `cp`-style semantics.

Callers 1

sandbox_sync_downFunction · 0.85

Calls 3

ssh_run_capture_stdoutFunction · 0.85
is_emptyMethod · 0.45

Tested by

no test coverage detected