|
|
@@ -14,6 +14,82 @@ fail() {
|
|
|
|
exit 1
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pane_command_clears_environment() {
|
|
|
|
|
|
|
|
local calls_file="$1"
|
|
|
|
|
|
|
|
local -a argv=()
|
|
|
|
|
|
|
|
local index
|
|
|
|
|
|
|
|
mapfile -d '' -t argv < "$calls_file"
|
|
|
|
|
|
|
|
for ((index = 0; index + 1 < ${#argv[@]}; index++)); do
|
|
|
|
|
|
|
|
if [ "${argv[$index]}" = /usr/bin/env ] && [ "${argv[$((index + 1))]}" = -i ]; then
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print_pane_argv() {
|
|
|
|
|
|
|
|
local calls_file="$1"
|
|
|
|
|
|
|
|
local -a argv=()
|
|
|
|
|
|
|
|
local bytes index
|
|
|
|
|
|
|
|
mapfile -d '' -t argv < "$calls_file"
|
|
|
|
|
|
|
|
bytes=$(wc -c < "$calls_file")
|
|
|
|
|
|
|
|
printf 'observed pane argv: records=%s bytes=%s\n' "${#argv[@]}" "$bytes" >&2
|
|
|
|
|
|
|
|
for ((index = 0; index < ${#argv[@]}; index++)); do
|
|
|
|
|
|
|
|
printf ' [%03d] %q\n' "$index" "${argv[$index]}" >&2
|
|
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
check_pane_environment_boundary() {
|
|
|
|
|
|
|
|
local calls_file="$1"
|
|
|
|
|
|
|
|
if pane_command_clears_environment "$calls_file"; then
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
print_pane_argv "$calls_file"
|
|
|
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
contains_literal() {
|
|
|
|
|
|
|
|
grep -F -- "$2" <<< "$1" >/dev/null
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
contains_line() {
|
|
|
|
|
|
|
|
grep -xF -- "$2" <<< "$1" >/dev/null
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Portability regression: inspect the authoritative NUL-delimited argv instead
|
|
|
|
|
|
|
|
# of piping a newline reconstruction through `grep -q` under pipefail. The old
|
|
|
|
|
|
|
|
# pipeline could report failure after a successful match when an upstream
|
|
|
|
|
|
|
|
# producer received SIGPIPE. A large trailing argument keeps that failure class
|
|
|
|
|
|
|
|
# covered without making stream size part of the semantic contract.
|
|
|
|
|
|
|
|
PORTABILITY_CALLS="$ROOT/portability-calls"
|
|
|
|
|
|
|
|
printf -v PORTABILITY_PADDING '%*s' 32768 ''
|
|
|
|
|
|
|
|
PORTABILITY_PADDING=${PORTABILITY_PADDING// /x}
|
|
|
|
|
|
|
|
printf '%s\0' /usr/bin/env -i "$PORTABILITY_PADDING" > "$PORTABILITY_CALLS"
|
|
|
|
|
|
|
|
pane_command_clears_environment "$PORTABILITY_CALLS" || \
|
|
|
|
|
|
|
|
fail "valid large pane argv was rejected by the environment-boundary assertion"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert_pane_boundary_rejected() {
|
|
|
|
|
|
|
|
local case_name="$1"
|
|
|
|
|
|
|
|
local expected_records="$2"
|
|
|
|
|
|
|
|
local diagnostic
|
|
|
|
|
|
|
|
if diagnostic=$(check_pane_environment_boundary "$PORTABILITY_CALLS" 2>&1); then
|
|
|
|
|
|
|
|
fail "pane boundary accepted invalid $case_name fixture"
|
|
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
contains_literal "$diagnostic" "records=$expected_records bytes=" || \
|
|
|
|
|
|
|
|
fail "pane argv diagnostic omitted counts for $case_name fixture"
|
|
|
|
|
|
|
|
contains_literal "$diagnostic" '[000]' || \
|
|
|
|
|
|
|
|
fail "pane argv diagnostic omitted indexed arguments for $case_name fixture"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf '%s\0' tmux -i > "$PORTABILITY_CALLS"
|
|
|
|
|
|
|
|
assert_pane_boundary_rejected missing-env 2
|
|
|
|
|
|
|
|
printf '%s\0' /usr/bin/env HOME=/untrusted > "$PORTABILITY_CALLS"
|
|
|
|
|
|
|
|
assert_pane_boundary_rejected missing-i 2
|
|
|
|
|
|
|
|
printf '%s\0' /usr/bin/env HOME=/untrusted -i > "$PORTABILITY_CALLS"
|
|
|
|
|
|
|
|
assert_pane_boundary_rejected non-adjacent-i 3
|
|
|
|
|
|
|
|
printf '%s\0' -i /usr/bin/env > "$PORTABILITY_CALLS"
|
|
|
|
|
|
|
|
assert_pane_boundary_rejected reversed-boundary 2
|
|
|
|
|
|
|
|
|
|
|
|
cat > "$FAKE_BIN/tmux" <<'SHIM'
|
|
|
|
cat > "$FAKE_BIN/tmux" <<'SHIM'
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
set -euo pipefail
|
|
|
@@ -115,19 +191,19 @@ AGENT_VALID="coder0"
|
|
|
|
write_generated "$HOME_VALID" "$AGENT_VALID"
|
|
|
|
write_generated "$HOME_VALID" "$AGENT_VALID"
|
|
|
|
run_start "$HOME_VALID" "$AGENT_VALID"
|
|
|
|
run_start "$HOME_VALID" "$AGENT_VALID"
|
|
|
|
valid_args=$(tr '\0' '\n' < "$TMUX_CALLS")
|
|
|
|
valid_args=$(tr '\0' '\n' < "$TMUX_CALLS")
|
|
|
|
echo "$valid_args" | grep -qF new-session || fail "valid generated projection did not reach tmux"
|
|
|
|
contains_literal "$valid_args" new-session || fail "valid generated projection did not reach tmux"
|
|
|
|
echo "$valid_args" | grep -qF 'mosaic' || fail "fixed mosaic launcher command missing"
|
|
|
|
contains_literal "$valid_args" mosaic || fail "fixed mosaic launcher command missing"
|
|
|
|
echo "$valid_args" | grep -qF 'yolo' || fail "fixed yolo launcher command missing"
|
|
|
|
contains_literal "$valid_args" yolo || fail "fixed yolo launcher command missing"
|
|
|
|
echo "$valid_args" | grep -qF 'pi' || fail "roster runtime missing"
|
|
|
|
contains_literal "$valid_args" pi || fail "roster runtime missing"
|
|
|
|
if echo "$valid_args" | grep -qF 'bash -c'; then
|
|
|
|
if contains_literal "$valid_args" 'bash -c'; then
|
|
|
|
fail "launcher constructed a shell command payload"
|
|
|
|
fail "launcher constructed a shell command payload"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# The pane must start through an absolute clean-environment boundary. Its
|
|
|
|
# The pane must start through an absolute clean-environment boundary. Its
|
|
|
|
# runtime command remains an argv vector, but no holder/session environment
|
|
|
|
# runtime command remains an argv vector, but no holder/session environment
|
|
|
|
# control variable can pass through the pane command.
|
|
|
|
# control variable can pass through the pane command.
|
|
|
|
echo "$valid_args" | grep -qxF '/usr/bin/env' || fail "pane does not use absolute env"
|
|
|
|
check_pane_environment_boundary "$TMUX_CALLS" || \
|
|
|
|
echo "$valid_args" | grep -qxF -- '-i' || fail "pane environment is not cleared"
|
|
|
|
fail "pane command did not use an adjacent /usr/bin/env -i boundary"
|
|
|
|
|
|
|
|
|
|
|
|
# Git identity is generated authority, not an optional or independently mutable
|
|
|
|
# Git identity is generated authority, not an optional or independently mutable
|
|
|
|
# local value. Each invalid form must fail before fake tmux receives a call.
|
|
|
|
# local value. Each invalid form must fail before fake tmux receives a call.
|
|
|
@@ -156,7 +232,7 @@ assert_git_identity_rejected() {
|
|
|
|
fail "Git identity case $case_name was accepted"
|
|
|
|
fail "Git identity case $case_name was accepted"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before Git identity $case_name rejection"
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before Git identity $case_name rejection"
|
|
|
|
echo "$output" | grep -qF "code=$expected_code" || \
|
|
|
|
contains_literal "$output" "code=$expected_code" || \
|
|
|
|
fail "Git identity $case_name diagnostic omitted code $expected_code"
|
|
|
|
fail "Git identity $case_name diagnostic omitted code $expected_code"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -176,7 +252,7 @@ if output=$(run_start "$HOME_UNSAFE_PARENT" coder-parent 2>&1); then
|
|
|
|
fail "generated file under a world-writable parent was accepted"
|
|
|
|
fail "generated file under a world-writable parent was accepted"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before unsafe parent rejection"
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before unsafe parent rejection"
|
|
|
|
echo "$output" | grep -qF 'code=unsafe-permissions' || fail "unsafe parent diagnostic missing"
|
|
|
|
contains_literal "$output" 'code=unsafe-permissions' || fail "unsafe parent diagnostic missing"
|
|
|
|
|
|
|
|
|
|
|
|
: > "$TMUX_CALLS"
|
|
|
|
: > "$TMUX_CALLS"
|
|
|
|
HOME_SYMLINK_PARENT="$ROOT/symlink-parent"
|
|
|
|
HOME_SYMLINK_PARENT="$ROOT/symlink-parent"
|
|
|
@@ -187,7 +263,7 @@ if output=$(run_start "$HOME_SYMLINK_PARENT" coder-symlink-parent 2>&1); then
|
|
|
|
fail "generated file under a symlinked parent was accepted"
|
|
|
|
fail "generated file under a symlinked parent was accepted"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before symlinked parent rejection"
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before symlinked parent rejection"
|
|
|
|
echo "$output" | grep -qF 'code=unsafe-directory' || fail "symlinked parent diagnostic missing"
|
|
|
|
contains_literal "$output" 'code=unsafe-directory' || fail "symlinked parent diagnostic missing"
|
|
|
|
|
|
|
|
|
|
|
|
# Every managed ancestor is a boundary: MOSAIC_HOME, fleet, and agents. A
|
|
|
|
# Every managed ancestor is a boundary: MOSAIC_HOME, fleet, and agents. A
|
|
|
|
# symlink or group/world-writable ancestor must fail before environment parsing,
|
|
|
|
# symlink or group/world-writable ancestor must fail before environment parsing,
|
|
|
@@ -225,8 +301,8 @@ assert_managed_ancestor_rejected() {
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before $hazard $ancestor rejection"
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before $hazard $ancestor rejection"
|
|
|
|
[ ! -e "$home/work" ] || fail "workdir was created before $hazard $ancestor rejection"
|
|
|
|
[ ! -e "$home/work" ] || fail "workdir was created before $hazard $ancestor rejection"
|
|
|
|
echo "$output" | grep -qF "code=unsafe-" || fail "managed ancestor diagnostic missing"
|
|
|
|
contains_literal "$output" 'code=unsafe-' || fail "managed ancestor diagnostic missing"
|
|
|
|
if echo "$output" | grep -qF 'key=MOSAIC_AGENT_COMMAND'; then
|
|
|
|
if contains_literal "$output" 'key=MOSAIC_AGENT_COMMAND'; then
|
|
|
|
fail "environment parsing ran before $hazard $ancestor rejection"
|
|
|
|
fail "environment parsing ran before $hazard $ancestor rejection"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -247,9 +323,9 @@ if output=$(run_start "$HOME_SHADOW" coder1 2>&1); then
|
|
|
|
fail "generated-key shadow was accepted"
|
|
|
|
fail "generated-key shadow was accepted"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before generated-key shadow rejection"
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before generated-key shadow rejection"
|
|
|
|
echo "$output" | grep -qF 'key=MOSAIC_AGENT_RUNTIME' || fail "shadow diagnostic omitted key"
|
|
|
|
contains_literal "$output" 'key=MOSAIC_AGENT_RUNTIME' || fail "shadow diagnostic omitted key"
|
|
|
|
echo "$output" | grep -qF 'sha256=' || fail "shadow diagnostic omitted hash"
|
|
|
|
contains_literal "$output" 'sha256=' || fail "shadow diagnostic omitted hash"
|
|
|
|
if echo "$output" | grep -qF 'codex'; then
|
|
|
|
if contains_literal "$output" codex; then
|
|
|
|
fail "shadow diagnostic leaked value"
|
|
|
|
fail "shadow diagnostic leaked value"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
@@ -265,9 +341,9 @@ if output=$(run_start "$HOME_COMMAND" coder2 2>&1); then
|
|
|
|
fail "arbitrary command override was accepted"
|
|
|
|
fail "arbitrary command override was accepted"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before command rejection"
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before command rejection"
|
|
|
|
echo "$output" | grep -qF 'key=MOSAIC_AGENT_COMMAND' || fail "command diagnostic omitted key"
|
|
|
|
contains_literal "$output" 'key=MOSAIC_AGENT_COMMAND' || fail "command diagnostic omitted key"
|
|
|
|
echo "$output" | grep -qF 'sha256=' || fail "command diagnostic omitted hash"
|
|
|
|
contains_literal "$output" 'sha256=' || fail "command diagnostic omitted hash"
|
|
|
|
if echo "$output" | grep -qF "$COMMAND_VALUE"; then
|
|
|
|
if contains_literal "$output" "$COMMAND_VALUE"; then
|
|
|
|
fail "command diagnostic leaked command value"
|
|
|
|
fail "command diagnostic leaked command value"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
@@ -281,7 +357,7 @@ if output=$(run_start "$HOME_PERMS" coder3 2>&1); then
|
|
|
|
fail "world-readable local input was accepted"
|
|
|
|
fail "world-readable local input was accepted"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before permissions rejection"
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before permissions rejection"
|
|
|
|
echo "$output" | grep -qF 'code=unsafe-permissions' || fail "permission diagnostic missing"
|
|
|
|
contains_literal "$output" 'code=unsafe-permissions' || fail "permission diagnostic missing"
|
|
|
|
|
|
|
|
|
|
|
|
# A unit/holder-like clean bootstrap must yield a pane with trusted HOME and
|
|
|
|
# A unit/holder-like clean bootstrap must yield a pane with trusted HOME and
|
|
|
|
# computed PATH only. The pane command itself must not carry loader, shell
|
|
|
|
# computed PATH only. The pane command itself must not carry loader, shell
|
|
|
@@ -311,19 +387,17 @@ PATH="$PANE_STALE_PATH" \
|
|
|
|
MOSAIC_TEST_EXECUTE_PANE=1 \
|
|
|
|
MOSAIC_TEST_EXECUTE_PANE=1 \
|
|
|
|
"$START" coder-pane-boundary
|
|
|
|
"$START" coder-pane-boundary
|
|
|
|
pane_args=$(tr '\0' '\n' < "$TMUX_CALLS")
|
|
|
|
pane_args=$(tr '\0' '\n' < "$TMUX_CALLS")
|
|
|
|
echo "$pane_args" | grep -qxF "HOME=$PANE_TRUSTED_HOME" || \
|
|
|
|
contains_line "$pane_args" "HOME=$PANE_TRUSTED_HOME" || \
|
|
|
|
fail "pane did not restore trusted HOME"
|
|
|
|
fail "pane did not restore trusted HOME"
|
|
|
|
echo "$pane_args" | grep -qF "HOME=$PANE_STALE_HOME" && \
|
|
|
|
contains_literal "$pane_args" "HOME=$PANE_STALE_HOME" && \
|
|
|
|
fail "pane inherited stale HOME"
|
|
|
|
fail "pane inherited stale HOME"
|
|
|
|
echo "$pane_args" | grep -qF "$PANE_STALE_PATH" && fail "pane inherited stale PATH"
|
|
|
|
contains_literal "$pane_args" "$PANE_STALE_PATH" && fail "pane inherited stale PATH"
|
|
|
|
for blocked in LD_PRELOAD= BASH_ENV= MOSAIC_UNTRUSTED_SENTINEL=; do
|
|
|
|
for blocked in LD_PRELOAD= BASH_ENV= MOSAIC_UNTRUSTED_SENTINEL=; do
|
|
|
|
echo "$pane_args" | grep -qF "$blocked" && fail "pane inherited $blocked"
|
|
|
|
contains_literal "$pane_args" "$blocked" && fail "pane inherited $blocked"
|
|
|
|
done
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
after_pane_env=$(printf '%s\n' "$pane_args" | grep -n -m1 -F '/usr/bin/env' | cut -d: -f1)
|
|
|
|
check_pane_environment_boundary "$TMUX_CALLS" || \
|
|
|
|
[ -n "$after_pane_env" ] || fail "pane command did not use absolute env"
|
|
|
|
fail "pane command did not use an adjacent /usr/bin/env -i boundary"
|
|
|
|
printf '%s\n' "$pane_args" | tail -n +"$after_pane_env" | grep -qxF -- '-i' || \
|
|
|
|
|
|
|
|
fail "pane command did not clear its environment"
|
|
|
|
|
|
|
|
pane_environment=$(tr '\0' '\n' < "$HOME_PANE_BOUNDARY/fleet/pane-environment")
|
|
|
|
pane_environment=$(tr '\0' '\n' < "$HOME_PANE_BOUNDARY/fleet/pane-environment")
|
|
|
|
# Exercise the repository launcher at $START, not the independently installed
|
|
|
|
# Exercise the repository launcher at $START, not the independently installed
|
|
|
|
# host copy. Set-compare every declared generated projection entry with the
|
|
|
|
# host copy. Set-compare every declared generated projection entry with the
|
|
|
@@ -337,11 +411,11 @@ if [ -n "$missing_or_changed_generated_environment" ]; then
|
|
|
|
missing_or_changed_keys=$(printf '%s\n' "$missing_or_changed_generated_environment" | cut -d= -f1 | paste -sd, -)
|
|
|
|
missing_or_changed_keys=$(printf '%s\n' "$missing_or_changed_generated_environment" | cut -d= -f1 | paste -sd, -)
|
|
|
|
fail "runtime pane omitted or changed generated environment keys: $missing_or_changed_keys"
|
|
|
|
fail "runtime pane omitted or changed generated environment keys: $missing_or_changed_keys"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
echo "$pane_environment" | grep -qxF "HOME=$PANE_TRUSTED_HOME" || \
|
|
|
|
contains_line "$pane_environment" "HOME=$PANE_TRUSTED_HOME" || \
|
|
|
|
fail "runtime pane did not receive trusted HOME"
|
|
|
|
fail "runtime pane did not receive trusted HOME"
|
|
|
|
echo "$pane_environment" | grep -qF "$PANE_STALE_PATH" && fail "runtime pane received stale PATH"
|
|
|
|
contains_literal "$pane_environment" "$PANE_STALE_PATH" && fail "runtime pane received stale PATH"
|
|
|
|
for blocked in LD_PRELOAD= BASH_ENV= MOSAIC_UNTRUSTED_SENTINEL=; do
|
|
|
|
for blocked in LD_PRELOAD= BASH_ENV= MOSAIC_UNTRUSTED_SENTINEL=; do
|
|
|
|
echo "$pane_environment" | grep -qF "$blocked" && fail "runtime pane received $blocked"
|
|
|
|
contains_literal "$pane_environment" "$blocked" && fail "runtime pane received $blocked"
|
|
|
|
done
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
write_interaction_generated() {
|
|
|
|
write_interaction_generated() {
|
|
|
@@ -442,7 +516,7 @@ if output=$(run_interaction "$HOME_INTERACTION_MALFORMED" interaction-malformed
|
|
|
|
fail "interaction wrapper accepted malformed generated data"
|
|
|
|
fail "interaction wrapper accepted malformed generated data"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before interaction strict-parser rejection"
|
|
|
|
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before interaction strict-parser rejection"
|
|
|
|
echo "$output" | grep -qF 'code=unknown-key' || fail "interaction did not use shared strict parser first"
|
|
|
|
contains_literal "$output" 'code=unknown-key' || fail "interaction did not use shared strict parser first"
|
|
|
|
|
|
|
|
|
|
|
|
# A syntactically valid but policy-incompatible projection reaches the pinned
|
|
|
|
# A syntactically valid but policy-incompatible projection reaches the pinned
|
|
|
|
# interaction policy check only after strict parsing and never starts tmux.
|
|
|
|
# interaction policy check only after strict parsing and never starts tmux.
|
|
|
@@ -455,9 +529,9 @@ if output=$(run_interaction "$HOME_INTERACTION_POLICY" interaction-policy 2>&1);
|
|
|
|
fail "interaction wrapper accepted a policy-incompatible projection"
|
|
|
|
fail "interaction wrapper accepted a policy-incompatible projection"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
interaction_policy_args=$(tr '\0' '\n' < "$TMUX_CALLS")
|
|
|
|
interaction_policy_args=$(tr '\0' '\n' < "$TMUX_CALLS")
|
|
|
|
echo "$interaction_policy_args" | grep -qF 'new-session' && \
|
|
|
|
contains_literal "$interaction_policy_args" new-session && \
|
|
|
|
fail "interaction pinned-policy rejection created a tmux session"
|
|
|
|
fail "interaction pinned-policy rejection created a tmux session"
|
|
|
|
echo "$output" | grep -qF 'operator interaction service requires runtime pi' || \
|
|
|
|
contains_literal "$output" 'operator interaction service requires runtime pi' || \
|
|
|
|
fail "interaction pinned-policy check did not follow strict parsing"
|
|
|
|
fail "interaction pinned-policy check did not follow strict parsing"
|
|
|
|
|
|
|
|
|
|
|
|
# Exact stop derives the socket exclusively from the validated generated
|
|
|
|
# Exact stop derives the socket exclusively from the validated generated
|
|
|
@@ -470,10 +544,10 @@ HOME="$HOME_STOP" PATH="$FAKE_BIN:$PATH" MOSAIC_TEST_TMUX_CALLS="$TMUX_CALLS" \
|
|
|
|
MOSAIC_TEST_FLEET_OWNER=123e4567-e89b-12d3-a456-426614174000 \
|
|
|
|
MOSAIC_TEST_FLEET_OWNER=123e4567-e89b-12d3-a456-426614174000 \
|
|
|
|
MOSAIC_HOME="$HOME_STOP" MOSAIC_TMUX_SOCKET=ambient-socket "$START" --stop coder-stop
|
|
|
|
MOSAIC_HOME="$HOME_STOP" MOSAIC_TMUX_SOCKET=ambient-socket "$START" --stop coder-stop
|
|
|
|
stop_args=$(tr '\0' '\n' < "$TMUX_CALLS")
|
|
|
|
stop_args=$(tr '\0' '\n' < "$TMUX_CALLS")
|
|
|
|
echo "$stop_args" | grep -qxF 'mosaic-test' || fail "exact stop did not use the validated generated socket"
|
|
|
|
contains_line "$stop_args" mosaic-test || fail "exact stop did not use the validated generated socket"
|
|
|
|
echo "$stop_args" | grep -qxF 'kill-session' || fail "exact stop did not request session termination"
|
|
|
|
contains_line "$stop_args" kill-session || fail "exact stop did not request session termination"
|
|
|
|
echo "$stop_args" | grep -qxF '=coder-stop' || fail "exact stop did not exact-match the generated agent name"
|
|
|
|
contains_line "$stop_args" '=coder-stop' || fail "exact stop did not exact-match the generated agent name"
|
|
|
|
if echo "$stop_args" | grep -qF 'ambient-socket'; then
|
|
|
|
if contains_literal "$stop_args" ambient-socket; then
|
|
|
|
fail "exact stop trusted an ambient socket"
|
|
|
|
fail "exact stop trusted an ambient socket"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|