Files
omarchy/test/shell.d/fixtures/sudo-boundary-test.sh
T
Afonso Oliveira 6af052fcc3 Bind update inhibitor cleanup to owned process identity
Keep inhibitor state in validated private directories and verify the recorded owner, PID, start time and launch token before signaling. Authenticate the held command before detaching and drop it back to the invoking user.

Serialize launch and cancellation, identify the child before publishing its state, and preserve caller-owned idle choices. Cover cross-account fallback state, process identity, cancellation, retry, and update-lock handling with isolated regressions.
2026-09-21 16:09:04 +01:00

137 lines
4.7 KiB
Bash

#!/bin/bash
# Test the real orchestration with fixed privileged paths redirected to harmless
# stand-ins. No host sudo, package transaction, namespace root, or exploit runs.
boundary_tmp=$(mktemp -d)
trap 'rm -rf "$boundary_tmp"' EXIT
export SUDO_TEST_ROOT="$boundary_tmp/omarchy"
export SUDO_TEST_LOG="$boundary_tmp/events"
export SUDO_TEST_CACHE="$boundary_tmp/cache"
export OMARCHY_PATH="$SUDO_TEST_ROOT"
export SUDO_TEST_HOME="$boundary_tmp/home"
mkdir -p "$SUDO_TEST_HOME"
mkdir -p "$SUDO_TEST_ROOT/bin" "$SUDO_TEST_ROOT/mock" "$SUDO_TEST_ROOT/default/omarchy/sudo-no-update"
: >"$SUDO_TEST_LOG"
copy_boundary_file() {
python3 - "$ROOT" "$SUDO_TEST_ROOT" "$1" <<'PY'
import sys
from pathlib import Path
source, target, name = map(Path,sys.argv[1:])
p=target/name
p.parent.mkdir(parents=True,exist_ok=True)
s=(source/name).read_text().replace('$HOME', '$SUDO_TEST_HOME')
for command in ['sudo','pkexec','pacman','omarchy-pkg-missing','systemd-inhibit','setpriv','snapper']:
s=s.replace('/usr/bin/'+command, str(target/'mock'/command))
s=s.replace('PATH=/usr/bin:/usr/sbin:/bin:/sbin', 'PATH="'+str(target/'bin')+':/usr/bin:/usr/sbin:/bin:/sbin"')
p.write_text(s)
p.chmod((source/name).stat().st_mode & 0o777)
PY
}
copy_boundary_file bin/omarchy-security-functions
copy_boundary_file bin/omarchy-update-pacman
copy_boundary_file default/omarchy/sudo-no-update/sudo
cat >"$SUDO_TEST_ROOT/mock/sudo" <<'STUB'
#!/bin/bash
set -euo pipefail
printf 'sudo' >>"$SUDO_TEST_LOG"
printf ' %q' "$@" >>"$SUDO_TEST_LOG"
printf '\n' >>"$SUDO_TEST_LOG"
if [[ ${1:-} == "-h" ]]; then
if [[ ${SUDO_TEST_UNSUPPORTED:-0} == "1" ]]; then
echo 'usage: sudo [-ABbEHknPS] command'
else
echo 'usage: sudo [-ABbEHkNnPS] command'
fi
exit 0
fi
if [[ ${1:-} == "-k" || ${1:-} == "-K" ]]; then
[[ ${SUDO_TEST_REVOKE_FAIL:-0} != "1" ]] || exit 1
/usr/bin/rm -f "$SUDO_TEST_CACHE"
exit 0
fi
if [[ ${1:-} == "-N" ]]; then
shift
else
touch "$SUDO_TEST_CACHE"
fi
[[ ${SUDO_TEST_SUDO_FAIL:-0} != "1" ]] || exit 1
background=0
while (( $# )); do
case "$1" in
-N|-n) shift ;;
-b) background=1; shift ;;
-v) exit 0 ;;
-u|--user) shift 2 ;;
--) shift; break ;;
*) break ;;
esac
done
(( $# )) || exit 0
if (( background )); then
"$@" &
else
"$@"
fi
STUB
chmod +x "$SUDO_TEST_ROOT/mock/sudo"
cat >"$SUDO_TEST_ROOT/bin/test-step" <<'STUB'
#!/bin/bash
set -euo pipefail
step=${0##*/}
printf 'step:%s %s\n' "$step" "$*" >>"$SUDO_TEST_LOG"
if [[ $step == "systemd-run" ]]; then
# omarchy-update-pacman registers the transaction as a PID 1 scope on booted
# hosts. Run the wrapped command in place so the pacman step still executes.
while (( $# )) && [[ $1 == -* ]]; do shift; done
exec "$@"
fi
if [[ $step == "omarchy-hook" || $step == "omarchy-update-mise" ]]; then
[[ ! -e $SUDO_TEST_CACHE ]] || exit 91
fi
if [[ -n ${SUDO_TEST_REMOVE_WRAPPER_STEP:-} && "$step $*" == $SUDO_TEST_REMOVE_WRAPPER_STEP ]]; then
# Model a package transaction replacing the running tree with a release
# that predates the wrapper.
/usr/bin/rm -f "$OMARCHY_PATH/default/omarchy/sudo-no-update/sudo"
fi
if [[ ${SUDO_TEST_FAIL_STEP:-} == "$step" ]]; then
# Model a misbehaving child leaving state behind, then failing. Cleanup must
# still revoke it. This never invokes real sudo or exercises a privilege flaw.
touch "$SUDO_TEST_CACHE"
exit 17
fi
if [[ ${SUDO_TEST_SIGNAL_STEP:-} == "$step" ]]; then
touch "$SUDO_TEST_CACHE"
kill -TERM "$PPID"
exit 0
fi
case "$step" in
omarchy-update-system-pkgs|omarchy-update-keyring|omarchy-snapshot)
sudo /usr/bin/true
;;
pacman) exit 0 ;;
yay)
[[ $* == *"--sudo $OMARCHY_PATH/default/omarchy/sudo-no-update/sudo"* ]] || exit 92
[[ $* == *"--sudoloop=false"* ]] || exit 93
;;
esac
STUB
chmod +x "$SUDO_TEST_ROOT/bin/test-step"
for step in omarchy-update-lock omarchy-update-requires-free-space omarchy-update-confirm omarchy-update-pkg-prune omarchy-snapshot omarchy-update-stay-awake omarchy-update-dev omarchy-update-keyring omarchy-update-system-pkgs omarchy-migrate omarchy-hook omarchy-update-aur-pkgs omarchy-update-mise omarchy-update-orphan-pkgs omarchy-update-analyze-logs omarchy-update-status omarchy-update-restart omarchy-pkg-aur-accessible omarchy-notification-dismiss pacman systemd-run cp yay; do
ln -s test-step "$SUDO_TEST_ROOT/bin/$step"
done
ln -s ../bin/test-step "$SUDO_TEST_ROOT/mock/pacman"
reset_boundary() {
: >"$SUDO_TEST_LOG"
/usr/bin/rm -f "$SUDO_TEST_CACHE"
unset SUDO_TEST_FAIL_STEP SUDO_TEST_SIGNAL_STEP SUDO_TEST_SUDO_FAIL SUDO_TEST_REVOKE_FAIL SUDO_TEST_UNSUPPORTED SUDO_TEST_REMOVE_WRAPPER_STEP
}
assert_boundary_cold() {
[[ ! -e $SUDO_TEST_CACHE ]] || fail "$1 left cached authorization"
[[ $(tail -1 "$SUDO_TEST_LOG") == "sudo -k" ]] || fail "$1 did not revoke at exit" "$(<"$SUDO_TEST_LOG")"
}