|
|
|
|
@@ -189,6 +189,10 @@ EOF
|
|
|
|
|
cat >"$STUB_BIN/jq" <<'EOF'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
if [[ ${1-} == "-n" ]]; then
|
|
|
|
|
shift
|
|
|
|
|
exec /usr/bin/jq -n "$@"
|
|
|
|
|
fi
|
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
|
|
case "$1" in
|
|
|
|
|
-r)
|
|
|
|
|
@@ -380,21 +384,6 @@ run_secret_mask() {
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_git_ignore_mask() {
|
|
|
|
|
local scenario_dir="$ROOT_DIR"
|
|
|
|
|
printf '==> git_ignore_mask\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" --trust-capabilities "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "git_ignore_mask: sloptrap exited non-zero"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "--mount type=tmpfs,target=/workspace/.git" "$STUB_LOG"; then
|
|
|
|
|
record_failure "git_ignore_mask: .git was not masked with tmpfs"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_resume_target() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/resume_target"
|
|
|
|
|
@@ -418,7 +407,7 @@ run_runtime_context_prompt() {
|
|
|
|
|
printf '==> runtime_context_prompt\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" --trust-capabilities "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "runtime_context_prompt: sloptrap exited non-zero"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
@@ -429,10 +418,12 @@ run_runtime_context_prompt() {
|
|
|
|
|
if [[ -z $run_line || $run_line != *"You are running inside sloptrap"* ]]; then
|
|
|
|
|
record_failure "runtime_context_prompt: startup prompt missing from fresh run"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "tools_bin=/sloptrap-tools/bin" "$STUB_LOG"; then
|
|
|
|
|
record_failure "runtime_context_prompt: tools path missing from startup prompt"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "name=host-network-repo" "$STUB_LOG" \
|
|
|
|
|
|| ! grep -q -- "enabled_capabilities=apt-install" "$STUB_LOG" \
|
|
|
|
|
|| ! grep -q -- "network_mode=host" "$STUB_LOG"; then
|
|
|
|
|
record_failure "runtime_context_prompt: runtime summary missing manifest or capability state"
|
|
|
|
|
record_failure "runtime_context_prompt: runtime summary missing manifest state"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -n $login_line && $login_line == *"You are running inside sloptrap"* ]]; then
|
|
|
|
|
record_failure "runtime_context_prompt: login flow should not receive startup prompt"
|
|
|
|
|
@@ -445,7 +436,7 @@ run_sh_reexec() {
|
|
|
|
|
printf '==> sh_reexec\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
sh "$SLOPTRAP_BIN" --trust-capabilities "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
sh "$SLOPTRAP_BIN" "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "sh_reexec: sloptrap exited non-zero when launched via sh"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
@@ -462,7 +453,7 @@ run_resume_omits_runtime_context() {
|
|
|
|
|
printf '==> resume_omits_runtime_context\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" --trust-capabilities "$scenario_dir" resume "$session_id" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" resume "$session_id" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "resume_omits_runtime_context: sloptrap exited non-zero"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
@@ -470,12 +461,37 @@ run_resume_omits_runtime_context() {
|
|
|
|
|
if grep -q -- "You are running inside sloptrap" "$STUB_LOG"; then
|
|
|
|
|
record_failure "resume_omits_runtime_context: resume should not receive startup prompt"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "codex --sandbox danger-full-access --ask-for-approval never resume $session_id" "$STUB_LOG"; then
|
|
|
|
|
if ! grep -q -- "--sandbox danger-full-access --ask-for-approval never resume $session_id" "$STUB_LOG"; then
|
|
|
|
|
record_failure "resume_omits_runtime_context: resume invocation missing"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_shell_target_uses_entrypoint() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/opencode_localhost"
|
|
|
|
|
printf '==> shell_target_uses_entrypoint\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" shell </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "shell_target_uses_entrypoint: shell target failed"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "--entrypoint /bin/bash" "$STUB_LOG"; then
|
|
|
|
|
record_failure "shell_target_uses_entrypoint: missing entrypoint override"
|
|
|
|
|
fi
|
|
|
|
|
if grep -q -- "/codex/auth.json" "$STUB_LOG"; then
|
|
|
|
|
record_failure "shell_target_uses_entrypoint: codex auth mount should not be present for opencode shell"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "-e PATH=/sloptrap-tools/bin:" "$STUB_LOG"; then
|
|
|
|
|
record_failure "shell_target_uses_entrypoint: tools PATH export missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "-e SLOPTRAP_TOOLS_HOME=/sloptrap-tools" "$STUB_LOG"; then
|
|
|
|
|
record_failure "shell_target_uses_entrypoint: tools home export missing"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_auth_file_mount() {
|
|
|
|
|
local scenario_dir
|
|
|
|
|
scenario_dir=$(cd "$TEST_ROOT/resume_target" && pwd -P)
|
|
|
|
|
@@ -495,6 +511,31 @@ run_auth_file_mount() {
|
|
|
|
|
if ! grep -q -- "-v ${STUB_HOME}/.codex/sloptrap/state/" "$STUB_LOG"; then
|
|
|
|
|
record_failure "auth_file_mount: missing project state bind mount"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "--mount type=volume,source=resume_target-sloptrap-tools-" "$STUB_LOG"; then
|
|
|
|
|
record_failure "auth_file_mount: missing project tools volume mount"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_runtime_hardening_flags() {
|
|
|
|
|
local scenario_dir
|
|
|
|
|
scenario_dir=$(cd "$TEST_ROOT/resume_target" && pwd -P)
|
|
|
|
|
printf '==> runtime_hardening_flags\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
mkdir -p "$STUB_HOME/.codex"
|
|
|
|
|
printf '{"access_token":"test"}\n' >"$STUB_HOME/.codex/auth.json"
|
|
|
|
|
if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "runtime_hardening_flags: sloptrap exited non-zero"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "--cap-drop ALL" "$STUB_LOG"; then
|
|
|
|
|
record_failure "runtime_hardening_flags: cap-drop flag missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "--read-only" "$STUB_LOG"; then
|
|
|
|
|
record_failure "runtime_hardening_flags: read-only rootfs flag missing"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -530,26 +571,6 @@ run_codex_home_override() {
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_removed_nested_podman_manifest() {
|
|
|
|
|
local scenario_dir output_log
|
|
|
|
|
scenario_dir=$(mktemp -d)
|
|
|
|
|
output_log=$(mktemp)
|
|
|
|
|
printf '==> removed_nested_podman_manifest\n'
|
|
|
|
|
cat >"$scenario_dir/.sloptrap" <<'EOF'
|
|
|
|
|
name=removed-nested-podman
|
|
|
|
|
capabilities=nested-podman
|
|
|
|
|
EOF
|
|
|
|
|
if "$SLOPTRAP_BIN" --dry-run "$scenario_dir" >/dev/null 2>&1; then
|
|
|
|
|
record_failure "removed_nested_podman_manifest: expected nested-podman manifest rejection"
|
|
|
|
|
fi
|
|
|
|
|
if ! "$SLOPTRAP_BIN" --dry-run "$scenario_dir" >"$output_log" 2>&1; then
|
|
|
|
|
if ! grep -q -- "capability 'nested-podman' was removed" "$output_log"; then
|
|
|
|
|
record_failure "removed_nested_podman_manifest: missing explicit removal error"
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
rm -f "$output_log"
|
|
|
|
|
rm -rf "$scenario_dir"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_project_state_isolation() {
|
|
|
|
|
local scenario_a scenario_b
|
|
|
|
|
@@ -643,59 +664,6 @@ run_root_directory_project() {
|
|
|
|
|
rm -rf "$tmp_home"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_shared_dir_override() {
|
|
|
|
|
local scenario_dir
|
|
|
|
|
scenario_dir=$(cd "$TEST_ROOT/resume_target" && pwd -P)
|
|
|
|
|
printf '==> shared_dir_override\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
local bogus_shared
|
|
|
|
|
bogus_shared=$(mktemp -d)
|
|
|
|
|
if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" \
|
|
|
|
|
SLOPTRAP_SHARED_DIR="$bogus_shared" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "shared_dir_override: sloptrap exited non-zero"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
rm -rf "$bogus_shared"
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
if grep -q "$bogus_shared" "$STUB_LOG"; then
|
|
|
|
|
record_failure "shared_dir_override: respected SLOPTRAP_SHARED_DIR override"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "-v ${scenario_dir}:/workspace" "$STUB_LOG"; then
|
|
|
|
|
record_failure "shared_dir_override: missing expected project bind mount"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
rm -rf "$bogus_shared"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_packages_env_validation() {
|
|
|
|
|
local scenario_dir
|
|
|
|
|
scenario_dir=$(cd "$TEST_ROOT/resume_target" && pwd -P)
|
|
|
|
|
printf '==> packages_env_validation\n'
|
|
|
|
|
local tmp_home
|
|
|
|
|
tmp_home=$(mktemp -d)
|
|
|
|
|
if HOME="$tmp_home" SLOPTRAP_PACKAGES='curl";touch /tmp/pwn #' \
|
|
|
|
|
"$SLOPTRAP_BIN" --dry-run "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "packages_env_validation: expected rejection of invalid SLOPTRAP_PACKAGES"
|
|
|
|
|
fi
|
|
|
|
|
rm -rf "$tmp_home"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_abs_path_ignore() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/abs_path_ignore"
|
|
|
|
|
printf '==> abs_path_ignore\n'
|
|
|
|
|
if "$SLOPTRAP_BIN" --dry-run "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "abs_path_ignore: expected rejection for anchored parent traversal entry"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_dotdot_ignore() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/dotdot_ignore"
|
|
|
|
|
printf '==> dotdot_ignore\n'
|
|
|
|
|
if "$SLOPTRAP_BIN" --dry-run "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "dotdot_ignore: expected rejection for parent traversal entry"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_invalid_manifest_name() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/invalid_manifest_name"
|
|
|
|
|
@@ -721,67 +689,57 @@ run_invalid_manifest_packages() {
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_invalid_manifest_capabilities() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/invalid_manifest_capabilities"
|
|
|
|
|
printf '==> invalid_manifest_capabilities\n'
|
|
|
|
|
run_invalid_manifest_agent() {
|
|
|
|
|
printf '==> invalid_manifest_agent\n'
|
|
|
|
|
local scenario_dir
|
|
|
|
|
scenario_dir=$(mktemp -d)
|
|
|
|
|
cat >"$scenario_dir/.sloptrap" <<'EOF'
|
|
|
|
|
name=invalid-agent
|
|
|
|
|
agent=bogus
|
|
|
|
|
EOF
|
|
|
|
|
if "$SLOPTRAP_BIN" --dry-run "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "invalid_manifest_capabilities: expected rejection for bad capabilities"
|
|
|
|
|
record_failure "invalid_manifest_agent: expected rejection for invalid agent"
|
|
|
|
|
fi
|
|
|
|
|
rm -rf "$scenario_dir"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_invalid_agent_env_override() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/opencode_print_config"
|
|
|
|
|
printf '==> invalid_agent_env_override\n'
|
|
|
|
|
if SLOPTRAP_AGENT=bogus "$SLOPTRAP_BIN" --dry-run "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "invalid_agent_env_override: expected rejection for invalid SLOPTRAP_AGENT"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_invalid_allow_host_network() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/invalid_allow_host_network"
|
|
|
|
|
printf '==> invalid_allow_host_network\n'
|
|
|
|
|
if "$SLOPTRAP_BIN" --dry-run "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "invalid_allow_host_network: expected rejection for invalid value"
|
|
|
|
|
run_removed_runtime_override_envs() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/resume_target"
|
|
|
|
|
printf '==> removed_runtime_override_envs\n'
|
|
|
|
|
if SLOPTRAP_SECURITY_OPTS_EXTRA='--privileged' "$SLOPTRAP_BIN" --dry-run "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "removed_runtime_override_envs: expected rejection for SLOPTRAP_SECURITY_OPTS_EXTRA"
|
|
|
|
|
fi
|
|
|
|
|
if SLOPTRAP_ROOTFS_READONLY=0 "$SLOPTRAP_BIN" --dry-run "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "removed_runtime_override_envs: expected rejection for SLOPTRAP_ROOTFS_READONLY"
|
|
|
|
|
fi
|
|
|
|
|
if SLOPTRAP_NETWORK_NAME=host "$SLOPTRAP_BIN" --dry-run "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "removed_runtime_override_envs: expected rejection for SLOPTRAP_NETWORK_NAME"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_host_network_packet_capture_ack_required() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/host_network_packet_capture"
|
|
|
|
|
printf '==> host_network_packet_capture_ack_required\n'
|
|
|
|
|
local output_log
|
|
|
|
|
output_log=$(mktemp)
|
|
|
|
|
setup_stub_env
|
|
|
|
|
if PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" --trust-capabilities "$scenario_dir" </dev/null >"$output_log" 2>&1; then
|
|
|
|
|
record_failure "host_network_packet_capture_ack_required: expected failure without interactive acknowledgement"
|
|
|
|
|
run_removed_build_override_envs() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/resume_target"
|
|
|
|
|
printf '==> removed_build_override_envs\n'
|
|
|
|
|
if SLOPTRAP_DOCKERFILE_PATH=/etc/passwd "$SLOPTRAP_BIN" --dry-run "$scenario_dir" build </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "removed_build_override_envs: expected rejection for SLOPTRAP_DOCKERFILE_PATH"
|
|
|
|
|
fi
|
|
|
|
|
if grep -q -- "FAKE PODMAN: run " "$STUB_LOG"; then
|
|
|
|
|
record_failure "host_network_packet_capture_ack_required: runtime container should not start without acknowledgement"
|
|
|
|
|
if SLOPTRAP_CODEX_URL=https://example.invalid/codex.tgz "$SLOPTRAP_BIN" --dry-run "$scenario_dir" build </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "removed_build_override_envs: expected rejection for SLOPTRAP_CODEX_URL"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
rm -f "$output_log"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_host_network_packet_capture_ack_prompt() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/host_network_packet_capture"
|
|
|
|
|
printf '==> host_network_packet_capture_ack_prompt\n'
|
|
|
|
|
if ! can_run_script_pty; then
|
|
|
|
|
printf 'skipping host_network_packet_capture_ack_prompt: script PTY support not available\n'
|
|
|
|
|
return
|
|
|
|
|
if SLOPTRAP_CODEX_ARCHIVE=codex-custom "$SLOPTRAP_BIN" --dry-run "$scenario_dir" build </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "removed_build_override_envs: expected rejection for SLOPTRAP_CODEX_ARCHIVE"
|
|
|
|
|
fi
|
|
|
|
|
local output_log
|
|
|
|
|
output_log=$(mktemp)
|
|
|
|
|
setup_stub_env
|
|
|
|
|
if ! printf 'y\n' | script -q -c "env PATH=\"$STUB_BIN:$PATH\" HOME=\"$STUB_HOME\" FAKE_PODMAN_LOG=\"$STUB_LOG\" FAKE_PODMAN_INSPECT_FAIL=1 \"$SLOPTRAP_BIN\" --trust-capabilities \"$scenario_dir\"" "$output_log" >/dev/null 2>&1; then
|
|
|
|
|
record_failure "host_network_packet_capture_ack_prompt: interactive acknowledgement should allow the run"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
rm -f "$output_log"
|
|
|
|
|
return
|
|
|
|
|
if SLOPTRAP_CODEX_BIN=custom-codex "$SLOPTRAP_BIN" --dry-run "$scenario_dir" build </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "removed_build_override_envs: expected rejection for SLOPTRAP_CODEX_BIN"
|
|
|
|
|
fi
|
|
|
|
|
if [[ $(grep -c -- 'Continue with host-network packet capture for this run' "$output_log" || true) -ne 1 ]]; then
|
|
|
|
|
record_failure "host_network_packet_capture_ack_prompt: expected a single runtime acknowledgement prompt"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- 'capture host-network traffic' "$output_log" \
|
|
|
|
|
|| ! grep -q -- 'transmit spoofed packets' "$output_log"; then
|
|
|
|
|
record_failure "host_network_packet_capture_ack_prompt: warning should describe concrete consequences"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "--network host" "$STUB_LOG"; then
|
|
|
|
|
record_failure "host_network_packet_capture_ack_prompt: host networking run did not reach the container engine"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
rm -f "$output_log"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_wizard_create_manifest() {
|
|
|
|
|
@@ -792,8 +750,9 @@ run_wizard_create_manifest() {
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
rm -f "$scenario_dir/.sloptrap"
|
|
|
|
|
local input=$'\n\n\n\n'
|
|
|
|
|
if ! printf '%s' "$input" | script -q -c "$SLOPTRAP_BIN \"$scenario_dir\" wizard" /dev/null >/dev/null 2>&1; then
|
|
|
|
|
# Wizard now has: name, packages_extra, agent (codex), allow_host_network
|
|
|
|
|
# Use empty for name (default), empty for packages_extra, empty for agent (uses default), false for allow_host_network
|
|
|
|
|
if ! printf '\n\n\nfalse\n\n' | "$SLOPTRAP_BIN" "$scenario_dir" wizard >/dev/null 2>&1; then
|
|
|
|
|
record_failure "wizard_create_manifest: wizard failed"
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
@@ -807,8 +766,8 @@ run_wizard_create_manifest() {
|
|
|
|
|
if ! grep -qx "packages_extra=" "$scenario_dir/.sloptrap"; then
|
|
|
|
|
record_failure "wizard_create_manifest: packages_extra mismatch"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -qx "capabilities=" "$scenario_dir/.sloptrap"; then
|
|
|
|
|
record_failure "wizard_create_manifest: capabilities mismatch"
|
|
|
|
|
if ! grep -qx "agent=codex" "$scenario_dir/.sloptrap"; then
|
|
|
|
|
record_failure "wizard_create_manifest: agent mismatch"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -qx "allow_host_network=false" "$scenario_dir/.sloptrap"; then
|
|
|
|
|
record_failure "wizard_create_manifest: allow_host_network mismatch"
|
|
|
|
|
@@ -822,8 +781,16 @@ run_wizard_existing_defaults() {
|
|
|
|
|
printf 'skipping wizard_existing_defaults: script PTY support not available\n'
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
local input=$'\n\n\n\n'
|
|
|
|
|
if ! printf '%s' "$input" | script -q -c "$SLOPTRAP_BIN \"$scenario_dir\" wizard" /dev/null >/dev/null 2>&1; then
|
|
|
|
|
# Create initial manifest with custom-wizard name
|
|
|
|
|
cat > "$scenario_dir/.sloptrap" <<EOF
|
|
|
|
|
name=custom-wizard
|
|
|
|
|
packages_extra=make git
|
|
|
|
|
agent=codex
|
|
|
|
|
allow_host_network=true
|
|
|
|
|
EOF
|
|
|
|
|
# Wizard now has: name, packages_extra, agent (codex), allow_host_network
|
|
|
|
|
# Use empty for name (default), make git for packages_extra, empty for agent (uses default), false for allow_host_network
|
|
|
|
|
if ! printf '\nmake git\n\n\nfalse\n\n' | "$SLOPTRAP_BIN" "$scenario_dir" wizard >/dev/null 2>&1; then
|
|
|
|
|
record_failure "wizard_existing_defaults: wizard failed"
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
@@ -833,8 +800,8 @@ run_wizard_existing_defaults() {
|
|
|
|
|
if ! grep -qx "packages_extra=make git" "$scenario_dir/.sloptrap"; then
|
|
|
|
|
record_failure "wizard_existing_defaults: packages_extra not preserved"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -qx "capabilities=apt-install" "$scenario_dir/.sloptrap"; then
|
|
|
|
|
record_failure "wizard_existing_defaults: capabilities not preserved"
|
|
|
|
|
if ! grep -qx "agent=codex" "$scenario_dir/.sloptrap"; then
|
|
|
|
|
record_failure "wizard_existing_defaults: agent not preserved"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -qx "allow_host_network=true" "$scenario_dir/.sloptrap"; then
|
|
|
|
|
record_failure "wizard_existing_defaults: allow_host_network not preserved"
|
|
|
|
|
@@ -850,389 +817,292 @@ run_wizard_build_trigger() {
|
|
|
|
|
fi
|
|
|
|
|
setup_stub_env
|
|
|
|
|
rm -f "$scenario_dir/.sloptrap"
|
|
|
|
|
local input=$'\n\n\n\n'
|
|
|
|
|
if ! printf '%s' "$input" | script -q -c "env PATH=\"$STUB_BIN:$PATH\" HOME=\"$STUB_HOME\" FAKE_PODMAN_LOG=\"$STUB_LOG\" FAKE_PODMAN_INSPECT_FAIL=1 \"$SLOPTRAP_BIN\" \"$scenario_dir\"" /dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "wizard_build_trigger: sloptrap failed"
|
|
|
|
|
# Wizard now has: name, packages_extra, agent (codex), allow_host_network
|
|
|
|
|
# Use empty for name (default), empty for packages_extra, empty for agent (uses default), false for allow_host_network
|
|
|
|
|
if ! env PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
printf '\n\n\nfalse\n\n' | "$SLOPTRAP_BIN" "$scenario_dir" wizard >/dev/null 2>&1; then
|
|
|
|
|
record_failure "wizard_build_trigger: wizard failed"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
if [[ ! -f $scenario_dir/.sloptrap ]]; then
|
|
|
|
|
record_failure "wizard_build_trigger: manifest not created"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
# Run build to trigger image build
|
|
|
|
|
if ! env PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" build >/dev/null 2>&1; then
|
|
|
|
|
record_failure "wizard_build_trigger: build failed"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "FAKE PODMAN: build " "$STUB_LOG"; then
|
|
|
|
|
record_failure "wizard_build_trigger: build not invoked after wizard"
|
|
|
|
|
record_failure "wizard_build_trigger: build not invoked"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_opencode_build_downloads_release_cli() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/opencode_build"
|
|
|
|
|
printf '==> opencode_build_downloads_release_cli\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
mkdir -p "$scenario_dir"
|
|
|
|
|
cat > "$scenario_dir/.sloptrap" <<'EOF'
|
|
|
|
|
name=opencode-build
|
|
|
|
|
packages_extra=htop
|
|
|
|
|
agent=opencode
|
|
|
|
|
allow_host_network=false
|
|
|
|
|
EOF
|
|
|
|
|
if ! env PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" build >/dev/null 2>&1; then
|
|
|
|
|
record_failure "opencode_build_downloads_release_cli: build failed"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "FAKE PODMAN: build " "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_build_downloads_release_cli: build not invoked"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "--build-arg OPENCODE_BIN=opencode" "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_build_downloads_release_cli: default OPENCODE_BIN build arg missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "--build-arg EXTRA_PACKAGES=htop" "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_build_downloads_release_cli: EXTRA_PACKAGES build arg missing"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_capability_trust_required() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/capability_repo"
|
|
|
|
|
printf '==> capability_trust_required\n'
|
|
|
|
|
run_opencode_localhost_rewrite() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/opencode_localhost"
|
|
|
|
|
printf '==> opencode_localhost_rewrite\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
if PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
mkdir -p "$scenario_dir"
|
|
|
|
|
cat > "$scenario_dir/.sloptrap" <<'EOF'
|
|
|
|
|
name=opencode-localhost
|
|
|
|
|
packages_extra=
|
|
|
|
|
agent=opencode
|
|
|
|
|
opencode_server=http://localhost:8080
|
|
|
|
|
allow_host_network=false
|
|
|
|
|
EOF
|
|
|
|
|
cat > "$STUB_BIN/slirp4netns" <<'EOF'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
exit 0
|
|
|
|
|
EOF
|
|
|
|
|
chmod +x "$STUB_BIN/slirp4netns"
|
|
|
|
|
if ! env PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "capability_trust_required: expected failure without trusted capabilities"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_capabilities_require_podman() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/capability_repo"
|
|
|
|
|
printf '==> capabilities_require_podman\n'
|
|
|
|
|
local output_log
|
|
|
|
|
output_log=$(mktemp)
|
|
|
|
|
setup_stub_env
|
|
|
|
|
if PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" SLOPTRAP_CONTAINER_ENGINE=docker \
|
|
|
|
|
"$SLOPTRAP_BIN" --dry-run "$scenario_dir" >"$output_log" 2>&1; then
|
|
|
|
|
record_failure "capabilities_require_podman: expected docker capability run to be rejected"
|
|
|
|
|
elif ! grep -q -- 'capability-enabled runs require podman' "$output_log"; then
|
|
|
|
|
record_failure "capabilities_require_podman: missing explicit podman requirement"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
rm -f "$output_log"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_capability_profiles() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/capability_repo"
|
|
|
|
|
printf '==> capability_profiles\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
local main_lines capture_lines pod_lines
|
|
|
|
|
local expected_build_network="bridge"
|
|
|
|
|
if command -v slirp4netns >/dev/null 2>&1; then
|
|
|
|
|
expected_build_network="slirp4netns"
|
|
|
|
|
fi
|
|
|
|
|
if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" --trust-capabilities "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "capability_profiles: sloptrap exited non-zero"
|
|
|
|
|
record_failure "opencode_localhost_rewrite: run failed"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "CAPABILITY_PACKAGES=tcpdump" "$STUB_LOG"; then
|
|
|
|
|
record_failure "capability_profiles: build arg for capability packages missing"
|
|
|
|
|
local config_path
|
|
|
|
|
config_path=$(find "$STUB_HOME" -path '*/config/opencode/opencode.json' | head -n 1 || true)
|
|
|
|
|
if [[ -z $config_path || ! -f $config_path ]]; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: opencode config not written"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "FAKE PODMAN: build --quiet -t capability-repo-sloptrap-image -f .* --network $expected_build_network " "$STUB_LOG"; then
|
|
|
|
|
record_failure "capability_profiles: build should stay on isolated networking"
|
|
|
|
|
if ! grep -q -- "--network slirp4netns:allow_host_loopback=true" "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: slirp host loopback not enabled"
|
|
|
|
|
fi
|
|
|
|
|
main_lines=$(grep "FAKE PODMAN: run " "$STUB_LOG" | grep -- "--name capability-repo-sloptrap-container" || true)
|
|
|
|
|
capture_lines=$(grep "FAKE PODMAN: run " "$STUB_LOG" | grep -- "--name capability-repo-sloptrap-capture" || true)
|
|
|
|
|
pod_lines=$(grep "FAKE PODMAN: pod create " "$STUB_LOG" | grep -- "--name capability-repo-sloptrap-pod" || true)
|
|
|
|
|
if [[ -z $main_lines ]]; then
|
|
|
|
|
record_failure "capability_profiles: main runtime container did not reach the container engine"
|
|
|
|
|
if ! grep -q -- "--add-host sloptrap.host:host-gateway" "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: host alias not injected"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -z $pod_lines ]]; then
|
|
|
|
|
record_failure "capability_profiles: packet capture should create a dedicated pod"
|
|
|
|
|
if ! grep -q -- "OPENCODE_CONFIG=/codex/config/opencode/opencode.json" "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: opencode config path not exported"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -z $capture_lines || $capture_lines != *"--cap-add NET_RAW"* ]]; then
|
|
|
|
|
record_failure "capability_profiles: capture sidecar should receive NET_RAW"
|
|
|
|
|
if ! grep -q -- "--prompt You are running inside sloptrap" "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: startup prompt not passed to opencode"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -n $main_lines && $main_lines == *"--cap-add NET_RAW"* ]]; then
|
|
|
|
|
record_failure "capability_profiles: main container should not receive NET_RAW"
|
|
|
|
|
if ! grep -q -- "tools_home=/sloptrap-tools" "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: tools path missing from opencode prompt"
|
|
|
|
|
fi
|
|
|
|
|
if grep -q -- "--cap-add NET_ADMIN" <<<"$capture_lines"; then
|
|
|
|
|
record_failure "capability_profiles: NET_ADMIN should not be granted"
|
|
|
|
|
if grep -q -- "/codex/auth.json" "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: codex auth mount should not be present for opencode"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -z $capture_lines || $capture_lines != *"--cap-add SETUID"* ]]; then
|
|
|
|
|
record_failure "capability_profiles: SETUID capability missing"
|
|
|
|
|
if ! grep -q -- '"baseURL": "http://sloptrap.host:8080/v1"' "$config_path"; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: localhost server not rewritten in config"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -z $capture_lines || $capture_lines != *"--cap-add SETGID"* ]]; then
|
|
|
|
|
record_failure "capability_profiles: SETGID capability missing"
|
|
|
|
|
if [[ $(jq -r '.provider["llama.cpp"].name' "$config_path") != "llama-server (local)" ]]; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: provider name not merged into config"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -z $capture_lines || $capture_lines != *"--cap-add CHOWN"* ]]; then
|
|
|
|
|
record_failure "capability_profiles: CHOWN capability missing"
|
|
|
|
|
if [[ $(jq -r '.model' "$config_path") != "llama.cpp/bartowski/Qwen_Qwen3.5-9B-GGUF:Q8_0 - 262144" ]]; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: opencode model not written to config"
|
|
|
|
|
fi
|
|
|
|
|
if grep -q -- "--cap-add DAC_OVERRIDE" <<<"$capture_lines$main_lines"; then
|
|
|
|
|
record_failure "capability_profiles: DAC_OVERRIDE should not be granted"
|
|
|
|
|
if [[ $(jq -r '.enabled_providers[0]' "$config_path") != "llama.cpp" ]]; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: enabled_providers not merged into config"
|
|
|
|
|
fi
|
|
|
|
|
if grep -q -- "--cap-add FOWNER" <<<"$capture_lines$main_lines"; then
|
|
|
|
|
record_failure "capability_profiles: FOWNER should not be granted"
|
|
|
|
|
if [[ $(jq -r '.provider["llama.cpp"].models["bartowski/Qwen_Qwen3.5-9B-GGUF:Q8_0 - 262144"].limit.context' "$config_path") != "262144" ]]; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: opencode context not written to config"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "--security-opt no-new-privileges" <<<"$capture_lines$main_lines"; then
|
|
|
|
|
record_failure "capability_profiles: no-new-privileges missing"
|
|
|
|
|
if grep -q -- "--server " "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: deprecated --server flag should not be passed"
|
|
|
|
|
fi
|
|
|
|
|
if grep -q -- "--read-only" <<<"$main_lines"; then
|
|
|
|
|
record_failure "capability_profiles: apt profile should disable read-only rootfs"
|
|
|
|
|
if grep -q -- "--sandbox workspace-write" "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: codex sandbox args leaked into opencode run"
|
|
|
|
|
fi
|
|
|
|
|
if grep -q -- "--user " <<<"$main_lines"; then
|
|
|
|
|
record_failure "capability_profiles: capability-enabled run should not force --user"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "--userns=keep-id:uid=$(id -u),gid=$(id -g)" <<<"$capture_lines$main_lines"; then
|
|
|
|
|
record_failure "capability_profiles: podman keep-id user namespace missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "SLOPTRAP_ACTIVE_CAPABILITIES=apt-install" <<<"$main_lines"; then
|
|
|
|
|
record_failure "capability_profiles: main helper capability environment missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "SLOPTRAP_PACKET_CAPTURE_ENABLED=1" <<<"$main_lines"; then
|
|
|
|
|
record_failure "capability_profiles: main container should advertise packet capture availability"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "SLOPTRAP_HELPER_DIR=/codex/state/capture-helper" <<<"$capture_lines"; then
|
|
|
|
|
record_failure "capability_profiles: capture sidecar helper dir missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "SLOPTRAP_ACTIVE_CAPABILITIES=packet-capture" <<<"$capture_lines"; then
|
|
|
|
|
record_failure "capability_profiles: capture sidecar capability environment missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "SLOPTRAP_HOST_UID=$(id -u)" "$STUB_LOG"; then
|
|
|
|
|
record_failure "capability_profiles: host uid environment missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "SLOPTRAP_HOST_GID=$(id -g)" "$STUB_LOG"; then
|
|
|
|
|
record_failure "capability_profiles: host gid environment missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "SLOPTRAP_HOST_USER=$(id -un)" "$STUB_LOG"; then
|
|
|
|
|
record_failure "capability_profiles: host user environment missing"
|
|
|
|
|
fi
|
|
|
|
|
local state_root capability_dir
|
|
|
|
|
state_root="$STUB_HOME/.codex/sloptrap/state"
|
|
|
|
|
capability_dir=$(find "$state_root" -mindepth 2 -maxdepth 2 -type d -name capabilities | head -n 1 || true)
|
|
|
|
|
if [[ -z $capability_dir ]]; then
|
|
|
|
|
record_failure "capability_profiles: project capability state directory missing"
|
|
|
|
|
if ! grep -q -- "-e PATH=/sloptrap-tools/bin:" "$STUB_LOG"; then
|
|
|
|
|
record_failure "opencode_localhost_rewrite: tools PATH export missing"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_embedded_capability_helpers() {
|
|
|
|
|
printf '==> embedded_capability_helpers\n'
|
|
|
|
|
local temp_root helper_bin helper_dir workspace_dir capture_dir tool_log helper_pid
|
|
|
|
|
temp_root=$(mktemp -d)
|
|
|
|
|
helper_bin="$temp_root/bin"
|
|
|
|
|
helper_dir="$temp_root/helper"
|
|
|
|
|
workspace_dir="$temp_root/workspace"
|
|
|
|
|
capture_dir="$temp_root/captures"
|
|
|
|
|
tool_log="$temp_root/tool.log"
|
|
|
|
|
helper_pid=""
|
|
|
|
|
mkdir -p "$helper_bin" "$helper_dir/queue" "$workspace_dir/data" "$capture_dir"
|
|
|
|
|
: >"$tool_log"
|
|
|
|
|
|
|
|
|
|
if ! extract_embedded_helper "sloptrap-entrypoint" "$helper_bin/sloptrap-entrypoint" \
|
|
|
|
|
|| ! extract_embedded_helper "sloptrap-helperd" "$helper_bin/sloptrap-helperd" \
|
|
|
|
|
|| ! extract_embedded_helper "slop-apt" "$helper_bin/slop-apt" \
|
|
|
|
|
|| ! extract_embedded_helper "slopcap" "$helper_bin/slopcap"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: failed to extract embedded helper scripts"
|
|
|
|
|
rm -rf "$temp_root"
|
|
|
|
|
run_opencode_print_config_runtime_flags() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/opencode_print_config"
|
|
|
|
|
printf '==> opencode_print_config_runtime_flags\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
mkdir -p "$scenario_dir"
|
|
|
|
|
cat > "$scenario_dir/.sloptrap" <<'EOF'
|
|
|
|
|
name=opencode-print-config
|
|
|
|
|
packages_extra=
|
|
|
|
|
agent=opencode
|
|
|
|
|
allow_host_network=false
|
|
|
|
|
EOF
|
|
|
|
|
local output
|
|
|
|
|
local plain_output
|
|
|
|
|
if ! output=$(env PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" --print-config "$scenario_dir" 2>/dev/null); then
|
|
|
|
|
record_failure "opencode_print_config_runtime_flags: print-config failed"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
cat >"$helper_bin/apt-get" <<'EOF'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
printf 'apt-get %s\n' "$*" >>"$TEST_TOOL_LOG"
|
|
|
|
|
exit 0
|
|
|
|
|
EOF
|
|
|
|
|
cat >"$helper_bin/tcpdump" <<'EOF'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
printf 'tcpdump %s\n' "$*" >>"$TEST_TOOL_LOG"
|
|
|
|
|
output=""
|
|
|
|
|
prev=""
|
|
|
|
|
for arg in "$@"; do
|
|
|
|
|
if [[ $prev == "-w" ]]; then
|
|
|
|
|
output=$arg
|
|
|
|
|
break
|
|
|
|
|
plain_output=$(printf '%s' "$output" | sed -E $'s/\x1B\\[[0-9;]*m//g')
|
|
|
|
|
if ! grep -q 'runtime_flags=' <<<"$plain_output"; then
|
|
|
|
|
record_failure "opencode_print_config_runtime_flags: runtime_flags line missing for opencode"
|
|
|
|
|
fi
|
|
|
|
|
prev=$arg
|
|
|
|
|
done
|
|
|
|
|
if [[ -n $output ]]; then
|
|
|
|
|
mkdir -p "$(dirname "$output")"
|
|
|
|
|
: >"$output"
|
|
|
|
|
fi
|
|
|
|
|
exit 0
|
|
|
|
|
EOF
|
|
|
|
|
cat >"$helper_bin/setpriv" <<'EOF'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
printf 'setpriv %s\n' "$*" >>"$TEST_TOOL_LOG"
|
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
|
|
case "$1" in
|
|
|
|
|
--reuid|--regid)
|
|
|
|
|
shift 2
|
|
|
|
|
;;
|
|
|
|
|
--clear-groups)
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
--)
|
|
|
|
|
shift
|
|
|
|
|
break
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
break
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
done
|
|
|
|
|
exec "$@"
|
|
|
|
|
EOF
|
|
|
|
|
chmod +x "$helper_bin/apt-get" "$helper_bin/tcpdump" "$helper_bin/setpriv"
|
|
|
|
|
|
|
|
|
|
if ! grep -q "chmod 711 \"\\\$helper_dir\"" "$helper_bin/sloptrap-entrypoint" \
|
|
|
|
|
|| ! grep -q "chmod 1733 \"\\\$queue_dir\"" "$helper_bin/sloptrap-entrypoint"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: entrypoint did not expose helper queue to the dropped user"
|
|
|
|
|
if ! grep -q 'opencode_config=' <<<"$plain_output"; then
|
|
|
|
|
record_failure "opencode_print_config_runtime_flags: opencode config path missing"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if grep -q -- "setpriv --reuid 0 --regid 0" "$helper_bin/slop-apt" \
|
|
|
|
|
|| grep -q -- "setpriv --reuid 0 --regid 0" "$helper_bin/slopcap"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: helper clients should not attempt to regain root"
|
|
|
|
|
if ! grep -q 'tools_volume=' <<<"$plain_output"; then
|
|
|
|
|
record_failure "opencode_print_config_runtime_flags: tools volume missing"
|
|
|
|
|
fi
|
|
|
|
|
if TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_HELPER_DIR="$temp_root/helper-missing" \
|
|
|
|
|
SLOPTRAP_ACTIVE_CAPABILITIES="apt-install packet-capture" \
|
|
|
|
|
SLOPTRAP_CAPTURE_DIR="$capture_dir" SLOPTRAP_WORKDIR="$workspace_dir" \
|
|
|
|
|
"$helper_bin/slop-apt" install jq >"$temp_root/missing-helper.out" 2>"$temp_root/missing-helper.err"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: slop-apt should fail when the root helper is unavailable"
|
|
|
|
|
elif ! grep -q -- 'capability helper is unavailable' "$temp_root/missing-helper.err"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: missing helper failure should explain the boundary"
|
|
|
|
|
if ! grep -q 'tools_home=/sloptrap-tools' <<<"$plain_output"; then
|
|
|
|
|
record_failure "opencode_print_config_runtime_flags: tools home missing"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_HELPER_DIR="$helper_dir" \
|
|
|
|
|
SLOPTRAP_ACTIVE_CAPABILITIES="apt-install packet-capture" \
|
|
|
|
|
SLOPTRAP_APT_GET_BIN="$helper_bin/apt-get" \
|
|
|
|
|
SLOPTRAP_TCPDUMP_BIN="$helper_bin/tcpdump" \
|
|
|
|
|
SLOPTRAP_CAPTURE_DIR="$capture_dir" SLOPTRAP_WORKDIR="$workspace_dir" \
|
|
|
|
|
SLOPTRAP_AUDIT_LOG="$temp_root/audit.log" "$helper_bin/sloptrap-helperd" >/dev/null 2>&1 &
|
|
|
|
|
helper_pid=$!
|
|
|
|
|
if ! wait_for_path "$helper_dir/helperd.pid"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: helper daemon did not publish its pid file"
|
|
|
|
|
if ! grep -q 'tools_bin=/sloptrap-tools/bin' <<<"$plain_output"; then
|
|
|
|
|
record_failure "opencode_print_config_runtime_flags: tools bin missing"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_HELPER_DIR="$helper_dir" \
|
|
|
|
|
"$helper_bin/slop-apt" install jq >/dev/null 2>&1; then
|
|
|
|
|
record_failure "embedded_capability_helpers: slop-apt failed against the embedded helper daemon"
|
|
|
|
|
if grep -q -- '--sandbox danger-full-access --ask-for-approval never' <<<"$plain_output"; then
|
|
|
|
|
record_failure "opencode_print_config_runtime_flags: codex runtime flags leaked into opencode config"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- 'apt-get install -y --no-install-recommends jq' "$tool_log"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: slop-apt did not reach apt-get install"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
local bad_apt_request
|
|
|
|
|
bad_apt_request=$(mktemp -d "$helper_dir/queue/request.XXXXXX.req")
|
|
|
|
|
printf 'apt-install\n' >"$bad_apt_request/op"
|
|
|
|
|
printf '%s\n' '--allow-unauthenticated' >"$bad_apt_request/packages"
|
|
|
|
|
if ! wait_for_path "$bad_apt_request/status"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: helper daemon did not answer the invalid apt request"
|
|
|
|
|
elif [[ $(<"$bad_apt_request/status") != "2" ]]; then
|
|
|
|
|
record_failure "embedded_capability_helpers: invalid apt request returned the wrong status"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -s "$bad_apt_request/stderr" ]] && ! grep -q -- 'invalid package name' "$bad_apt_request/stderr"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: invalid apt request did not explain the rejection"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_HELPER_DIR="$helper_dir" \
|
|
|
|
|
SLOPTRAP_CAPTURE_DIR="$capture_dir" SLOPTRAP_WORKDIR="$workspace_dir" \
|
|
|
|
|
SLOPTRAP_CAPTURE_HELPER_DIR="$helper_dir" SLOPTRAP_PACKET_CAPTURE_ENABLED=1 \
|
|
|
|
|
"$helper_bin/slopcap" capture --interface eth0 --output /tmp/escape.pcap >/dev/null 2>&1; then
|
|
|
|
|
record_failure "embedded_capability_helpers: slopcap accepted an out-of-bounds output path"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_HELPER_DIR="$helper_dir" \
|
|
|
|
|
SLOPTRAP_CAPTURE_DIR="$capture_dir" SLOPTRAP_WORKDIR="$workspace_dir" \
|
|
|
|
|
SLOPTRAP_CAPTURE_HELPER_DIR="$helper_dir" SLOPTRAP_PACKET_CAPTURE_ENABLED=1 \
|
|
|
|
|
"$helper_bin/slopcap" capture --interface eth0 --filter 'tcp port 80' \
|
|
|
|
|
--output "$workspace_dir/capture.pcap" >/dev/null 2>&1; then
|
|
|
|
|
record_failure "embedded_capability_helpers: slopcap failed for a workspace-local capture file"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "tcpdump -p -i eth0 -w $workspace_dir/capture.pcap -- tcp port 80" "$tool_log"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: slopcap did not invoke tcpdump with the expected guarded arguments"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
local bad_capture_request
|
|
|
|
|
bad_capture_request=$(mktemp -d "$helper_dir/queue/request.XXXXXX.req")
|
|
|
|
|
printf 'packet-capture\n' >"$bad_capture_request/op"
|
|
|
|
|
printf 'eth0\n' >"$bad_capture_request/interface"
|
|
|
|
|
printf '\n' >"$bad_capture_request/filter"
|
|
|
|
|
printf '/tmp/escape.pcap\n' >"$bad_capture_request/output"
|
|
|
|
|
printf '0\n' >"$bad_capture_request/stdout_mode"
|
|
|
|
|
if ! wait_for_path "$bad_capture_request/status"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: helper daemon did not answer the invalid capture request"
|
|
|
|
|
elif [[ $(<"$bad_capture_request/status") != "2" ]]; then
|
|
|
|
|
record_failure "embedded_capability_helpers: invalid capture request returned the wrong status"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -s "$bad_capture_request/stderr" ]] && ! grep -q -- 'output path must stay within' "$bad_capture_request/stderr"; then
|
|
|
|
|
record_failure "embedded_capability_helpers: invalid capture request did not explain the rejection"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [[ -n $helper_pid ]]; then
|
|
|
|
|
kill "$helper_pid" >/dev/null 2>&1 || true
|
|
|
|
|
wait "$helper_pid" >/dev/null 2>&1 || true
|
|
|
|
|
fi
|
|
|
|
|
rm -rf "$temp_root"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_make_install_single_file() {
|
|
|
|
|
run_clean_removes_tools_volume() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/resume_target"
|
|
|
|
|
printf '==> make_install_single_file\n'
|
|
|
|
|
if ! command -v make >/dev/null 2>&1; then
|
|
|
|
|
record_failure "make_install_single_file: make binary not found in PATH"
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
printf '==> clean_removes_tools_volume\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
local install_root install_dir installed_bin
|
|
|
|
|
install_root=$(mktemp -d)
|
|
|
|
|
install_dir="$install_root/bin"
|
|
|
|
|
installed_bin="$install_dir/sloptrap"
|
|
|
|
|
if ! make -C "$ROOT_DIR" install INSTALL_DIR="$install_dir" >/dev/null 2>&1; then
|
|
|
|
|
record_failure "make_install_single_file: make install failed"
|
|
|
|
|
if ! env PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" \
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" clean </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "clean_removes_tools_volume: clean failed"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
rm -rf "$install_root"
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
if [[ ! -x $installed_bin ]]; then
|
|
|
|
|
record_failure "make_install_single_file: installed launcher missing"
|
|
|
|
|
fi
|
|
|
|
|
local helper
|
|
|
|
|
for helper in sloptrap-entrypoint sloptrap-helperd slop-apt slopcap; do
|
|
|
|
|
if [[ -e $install_dir/$helper ]]; then
|
|
|
|
|
record_failure "make_install_single_file: unexpected helper installed ($helper)"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$installed_bin" "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "make_install_single_file: installed launcher failed"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q -- "FAKE PODMAN: build " "$STUB_LOG"; then
|
|
|
|
|
record_failure "make_install_single_file: installed launcher did not reach build path"
|
|
|
|
|
fi
|
|
|
|
|
if ! make -C "$ROOT_DIR" uninstall INSTALL_DIR="$install_dir" >/dev/null 2>&1; then
|
|
|
|
|
record_failure "make_install_single_file: make uninstall failed"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -e $installed_bin ]]; then
|
|
|
|
|
record_failure "make_install_single_file: installed launcher not removed by uninstall"
|
|
|
|
|
if ! grep -q -- "FAKE PODMAN: volume rm -f resume_target-sloptrap-tools-" "$STUB_LOG"; then
|
|
|
|
|
record_failure "clean_removes_tools_volume: tools volume not removed"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_opencode_env_overrides() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/opencode_print_config"
|
|
|
|
|
printf '==> opencode_env_overrides\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
mkdir -p "$scenario_dir"
|
|
|
|
|
cat > "$scenario_dir/.sloptrap" <<'EOF'
|
|
|
|
|
name=opencode-print-config
|
|
|
|
|
packages_extra=
|
|
|
|
|
agent=opencode
|
|
|
|
|
opencode_server=http://manifest:8080
|
|
|
|
|
opencode_model=manifest-model
|
|
|
|
|
opencode_context=128K
|
|
|
|
|
allow_host_network=false
|
|
|
|
|
EOF
|
|
|
|
|
local output
|
|
|
|
|
local plain_output
|
|
|
|
|
if ! output=$(env PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
SLOPTRAP_OPENCODE_SERVER=http://env:8080 SLOPTRAP_OPENCODE_MODEL=env-model SLOPTRAP_OPENCODE_CONTEXT=64K \
|
|
|
|
|
"$SLOPTRAP_BIN" --print-config "$scenario_dir" 2>/dev/null); then
|
|
|
|
|
record_failure "opencode_env_overrides: print-config failed"
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
plain_output=$(printf '%s' "$output" | sed -E $'s/\x1B\\[[0-9;]*m//g')
|
|
|
|
|
if ! grep -q 'opencode_server=http://env:8080' <<<"$plain_output"; then
|
|
|
|
|
record_failure "opencode_env_overrides: server env override missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q 'opencode_model=env-model' <<<"$plain_output"; then
|
|
|
|
|
record_failure "opencode_env_overrides: model env override missing"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -q 'opencode_context=64K' <<<"$plain_output"; then
|
|
|
|
|
record_failure "opencode_env_overrides: context env override missing"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_opencode_config_symlink_rejected() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/opencode_localhost"
|
|
|
|
|
printf '==> opencode_config_symlink_rejected\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
mkdir -p "$scenario_dir"
|
|
|
|
|
cat > "$scenario_dir/.sloptrap" <<'EOF'
|
|
|
|
|
name=opencode-localhost
|
|
|
|
|
packages_extra=
|
|
|
|
|
agent=opencode
|
|
|
|
|
allow_host_network=false
|
|
|
|
|
EOF
|
|
|
|
|
local state_key
|
|
|
|
|
state_key=$(printf '%s' "$scenario_dir" | sha256sum | awk '{print $1}')
|
|
|
|
|
local config_dir="$STUB_HOME/.codex/sloptrap/state/$state_key/config/opencode"
|
|
|
|
|
mkdir -p "$config_dir"
|
|
|
|
|
ln -s "$STUB_HOME/target.json" "$config_dir/opencode.json"
|
|
|
|
|
if env PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "opencode_config_symlink_rejected: expected rejection for symlinked config"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_opencode_login_rejected() {
|
|
|
|
|
local scenario_dir="$TEST_ROOT/opencode_localhost"
|
|
|
|
|
printf '==> opencode_login_rejected\n'
|
|
|
|
|
setup_stub_env
|
|
|
|
|
if env PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
|
|
|
|
"$SLOPTRAP_BIN" "$scenario_dir" login </dev/null >/dev/null 2>&1; then
|
|
|
|
|
record_failure "opencode_login_rejected: expected login rejection for opencode"
|
|
|
|
|
fi
|
|
|
|
|
teardown_stub_env
|
|
|
|
|
rm -rf "$install_root"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_shellcheck
|
|
|
|
|
run_mount_injection
|
|
|
|
|
run_root_target
|
|
|
|
|
run_symlink_escape
|
|
|
|
|
run_manifest_injection
|
|
|
|
|
run_helper_symlink
|
|
|
|
|
run_secret_mask
|
|
|
|
|
run_git_ignore_mask
|
|
|
|
|
run_resume_target
|
|
|
|
|
run_runtime_context_prompt
|
|
|
|
|
run_sh_reexec
|
|
|
|
|
run_resume_omits_runtime_context
|
|
|
|
|
run_shell_target_uses_entrypoint
|
|
|
|
|
run_auth_file_mount
|
|
|
|
|
run_runtime_hardening_flags
|
|
|
|
|
run_codex_home_override
|
|
|
|
|
run_project_state_isolation
|
|
|
|
|
run_auto_login_empty_auth
|
|
|
|
|
run_codex_symlink_home
|
|
|
|
|
run_root_directory_project
|
|
|
|
|
run_shared_dir_override
|
|
|
|
|
run_packages_env_validation
|
|
|
|
|
run_abs_path_ignore
|
|
|
|
|
run_dotdot_ignore
|
|
|
|
|
run_invalid_manifest_name
|
|
|
|
|
run_invalid_manifest_sandbox
|
|
|
|
|
run_invalid_manifest_packages
|
|
|
|
|
run_invalid_manifest_capabilities
|
|
|
|
|
run_invalid_allow_host_network
|
|
|
|
|
run_host_network_packet_capture_ack_required
|
|
|
|
|
run_host_network_packet_capture_ack_prompt
|
|
|
|
|
run_removed_nested_podman_manifest
|
|
|
|
|
run_wizard_create_manifest
|
|
|
|
|
run_wizard_existing_defaults
|
|
|
|
|
run_wizard_build_trigger
|
|
|
|
|
run_capability_trust_required
|
|
|
|
|
run_capabilities_require_podman
|
|
|
|
|
run_capability_profiles
|
|
|
|
|
run_embedded_capability_helpers
|
|
|
|
|
run_make_install_single_file
|
|
|
|
|
run_invalid_manifest_agent
|
|
|
|
|
run_invalid_agent_env_override
|
|
|
|
|
run_removed_runtime_override_envs
|
|
|
|
|
run_removed_build_override_envs
|
|
|
|
|
run_opencode_build_downloads_release_cli
|
|
|
|
|
run_opencode_localhost_rewrite
|
|
|
|
|
run_opencode_print_config_runtime_flags
|
|
|
|
|
run_opencode_env_overrides
|
|
|
|
|
run_opencode_config_symlink_rejected
|
|
|
|
|
run_opencode_login_rejected
|
|
|
|
|
run_clean_removes_tools_volume
|
|
|
|
|
|
|
|
|
|
if [[ ${#failures[@]} -gt 0 ]]; then
|
|
|
|
|
printf '\nTest failures:\n'
|
|
|
|
|
|