#!/usr/bin/env bash # `boot --server` is deliberately public and must be safe before it reaches the # cloned repository. Exercise its root branch through a PTY, against only a # temporary filesystem and PATH adapters. set -uo pipefail repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" boot="$repo_dir/boot" [[ -x "$boot" ]] || { printf 'root server bootstrap: %s is not executable\n' "$boot" >&2 exit 1 } python3 - "$boot" <<'PY' import atexit import errno import fcntl import os import pty import re import signal import shutil import subprocess import sys import tempfile import termios import time from pathlib import Path boot = sys.argv[1] work = Path(tempfile.mkdtemp()) atexit.register(shutil.rmtree, work, ignore_errors=True) findings: list[str] = [] def note(message: str) -> None: findings.append(message) def write_executable(path: Path, contents: str) -> None: path.write_text(contents) path.chmod(0o755) def make_stubs(stub_dir: Path, fixture_root: Path, calls: Path) -> None: common = f'''#!/usr/bin/env bash set -u calls={str(calls)!r} log() {{ local argument {{ for argument in "$@"; do printf '%q ' "$argument"; done; printf '\\n'; }} >>"$calls" }} consume_result() {{ local name="$1" results result results="$PANAMA_BOOT_FIXTURE_ROOT/state/$name" if ! IFS= read -r result <"$results"; then return 0 fi /usr/bin/tail -n +2 "$results" >"$results.next" /usr/bin/mv -f -- "$results.next" "$results" [[ "$result" =~ ^[0-9]+$ ]] || exit 97 return "$result" }} ''' write_executable(stub_dir / "id", common + r''' log id "$@" case "${1:-}" in -u) case "${2:-}" in '') printf '0\n' ;; root) printf '0\n' ;; gib) cat "$PANAMA_BOOT_FIXTURE_ROOT/state/target-uid" ;; *) exit 97 ;; esac ;; -nG) [[ "${2:-}" == gib ]] || exit 97; printf 'gib wheel\n' ;; *) exit 97 ;; esac ''') write_executable(stub_dir / "passwd", common + r''' log passwd "$@" [[ "${1:-}" == -S && "${2:-}" == gib ]] || exit 97 printf 'gib PS\n' ''') write_executable(stub_dir / "getent", common + r''' log getent "$@" [[ "${1:-}" == passwd && "${2:-}" == gib ]] || exit 97 home="$(<"$PANAMA_BOOT_FIXTURE_ROOT/state/home")" printf 'gib:x:1000:1000::%s:/bin/bash\n' "$home" ''') write_executable(stub_dir / "stat", common + r''' log stat "$@" [[ "${1:-}" == -Lc && "${2:-}" == '%u:%a' ]] || exit 97 case "${3:-}" in "$PANAMA_BOOT_FIXTURE_ROOT/home/gib/.ssh") cat "$PANAMA_BOOT_FIXTURE_ROOT/state/target-dir-meta" ;; "$PANAMA_BOOT_FIXTURE_ROOT/home/gib/.ssh/authorized_keys") cat "$PANAMA_BOOT_FIXTURE_ROOT/state/target-key-meta" ;; "$PANAMA_BOOT_FIXTURE_ROOT/root/.ssh/authorized_keys") cat "$PANAMA_BOOT_FIXTURE_ROOT/state/root-key-meta" ;; *) exit 97 ;; esac ''') write_executable(stub_dir / "runuser", common + r''' log runuser "$@" [[ "${1:-}" == -u && "${2:-}" == gib && "${3:-}" == -- ]] || exit 97 shift 3 "$@" ''') write_executable(stub_dir / "git", common + r''' log git "$@" case "${1:-}" in clone) mkdir -p "$3/.git" cp "$PANAMA_BOOT_FIXTURE_ROOT/stub-install" "$3/install" chmod +x "$3/install" ;; -C) [[ "${3:-}" == pull && "${4:-}" == --ff-only ]] || exit 97 ;; *) exit 97 ;; esac ''') write_executable(stub_dir / "dnf", common + r''' log dnf "$@" [[ "${1:-}" == install && "${2:-}" == -y && "${3:-}" == git ]] || exit 97 ''') write_executable(stub_dir / "sshd", common + r''' log sshd "$@" [[ "$#" -eq 1 && "$1" == -t ]] || exit 97 for artifact in "$PANAMA_BOOT_FIXTURE_ROOT/etc/ssh/sshd_config.d"/.90-panama.*; do [[ -e "$artifact" ]] || continue log ssh-artifact "$artifact" "$(/usr/bin/stat -c %a -- "$artifact")" done consume_result SSHD_RESULTS ''') write_executable(stub_dir / "systemctl", common + r''' log systemctl "$@" case "${1:-}:${2:-}" in cat:sshd.service) [[ "$(<"$PANAMA_BOOT_FIXTURE_ROOT/state/SSHD_UNIT")" == present ]] ;; cat:ssh.service) [[ "$(<"$PANAMA_BOOT_FIXTURE_ROOT/state/SSH_UNIT")" == present ]] ;; reload:sshd.service|reload:ssh.service) consume_result RELOAD_RESULTS ;; *) exit 97 ;; esac ''') write_executable(stub_dir / "mv", common + r''' log mv "$@" "source-mode=$(/usr/bin/stat -c %a -- "${3:-}")" if [[ "${3:-}" == *.tmp ]]; then consume_result MV_ACTIVATION_RESULTS result=$? (( result == 0 )) || exit "$result" fi /usr/bin/mv "$@" if [[ "${3:-}" == *.tmp && -e "$PANAMA_BOOT_FIXTURE_ROOT/state/HOLD_ACTIVATION" ]]; then : >"$PANAMA_BOOT_FIXTURE_ROOT/state/ACTIVATED" while [[ ! -e "$PANAMA_BOOT_FIXTURE_ROOT/state/RELEASE_ACTIVATION" ]]; do /usr/bin/sleep 0.01 done fi ''') write_executable(stub_dir / "rm", common + r''' log rm "$@" if [[ "${1:-}" == -f && "${2:-}" == -- && "${3:-}" == *.backup ]]; then consume_result RM_BACKUP_RESULTS result=$? (( result == 0 )) || exit "$result" fi if [[ "${1:-}" == -f && "${2:-}" == -- && "${3:-}" == *.tmp ]]; then consume_result RM_CANDIDATE_RESULTS result=$? (( result == 0 )) || exit "$result" fi exec /usr/bin/rm "$@" ''') for command in ("useradd", "usermod"): write_executable(stub_dir / command, common + f'''\nlog {command} "$@"\nexit 97\n''') def configure_case( name: str, *, sshd_results: tuple[int, ...] = (), reload_results: tuple[int, ...] = (), mv_activation_results: tuple[int, ...] = (), rm_backup_results: tuple[int, ...] = (), rm_candidate_results: tuple[int, ...] = (), prior_dropin: bytes | None = None, sshd_unit: bool = True, ssh_unit: bool = True, hold_activation: bool = False, ) -> tuple[Path, Path]: fixture_root = work / name / "root" stub_dir = work / name / "bin" calls = fixture_root / "calls" state = fixture_root / "state" ssh_dir = fixture_root / "home/gib/.ssh" root_ssh_dir = fixture_root / "root/.ssh" (fixture_root / "etc/ssh/sshd_config.d").mkdir(parents=True) ssh_dir.mkdir(parents=True) root_ssh_dir.mkdir(parents=True) stub_dir.mkdir(parents=True) state.mkdir() calls.touch() (state / "target-uid").write_text("1000\n") (state / "home").write_text("/home/gib\n") (state / "target-dir-meta").write_text("1000:700\n") (state / "target-key-meta").write_text("1000:600\n") (state / "root-key-meta").write_text("0:600\n") (state / "SSHD_RESULTS").write_text("".join(f"{result}\n" for result in sshd_results)) (state / "RELOAD_RESULTS").write_text("".join(f"{result}\n" for result in reload_results)) (state / "MV_ACTIVATION_RESULTS").write_text( "".join(f"{result}\n" for result in mv_activation_results) ) (state / "RM_BACKUP_RESULTS").write_text( "".join(f"{result}\n" for result in rm_backup_results) ) (state / "RM_CANDIDATE_RESULTS").write_text( "".join(f"{result}\n" for result in rm_candidate_results) ) (state / "SSHD_UNIT").write_text("present\n" if sshd_unit else "absent\n") (state / "SSH_UNIT").write_text("present\n" if ssh_unit else "absent\n") if hold_activation: (state / "HOLD_ACTIVATION").touch() (fixture_root / "stub-install").write_text( "#!/usr/bin/env bash\nprintf 'install-handoff %s\\n' \"${PANAMA_PATH:-unset}\" >> \"$PANAMA_BOOT_FIXTURE_ROOT/calls\"\n" ) (fixture_root / "stub-install").chmod(0o755) make_stubs(stub_dir, fixture_root, calls) if prior_dropin is not None: dropin = fixture_root / "etc/ssh/sshd_config.d/90-panama.conf" dropin.write_bytes(prior_dropin) dropin.chmod(0o600) target_keys = ssh_dir / "authorized_keys" root_keys = root_ssh_dir / "authorized_keys" if name == "missing": pass elif name == "empty": target_keys.touch() elif name == "comment-only": target_keys.write_text("# no usable key\n\n") elif name == "ssh-directory-symlink": shutil.rmtree(ssh_dir) alternate = fixture_root / "unsafe-ssh" alternate.mkdir() (fixture_root / "home/gib/.ssh").symlink_to(alternate) elif name == "authorized-keys-symlink": alternate = fixture_root / "unsafe-authorized-keys" alternate.write_text("ssh-ed25519 unsafe\n") target_keys.symlink_to(alternate) elif name == "directory-wrong-mode": target_keys.write_text("ssh-ed25519 target\n") (state / "target-dir-meta").write_text("1000:755\n") elif name == "root-copy-directory-wrong-mode": root_keys.write_text("ssh-ed25519 root\n") (state / "target-dir-meta").write_text("1000:755\n") elif name == "file-wrong-mode": target_keys.write_text("ssh-ed25519 target\n") (state / "target-key-meta").write_text("1000:644\n") elif name == "directory-wrong-owner": target_keys.write_text("ssh-ed25519 target\n") (state / "target-dir-meta").write_text("0:700\n") elif name == "file-wrong-owner": target_keys.write_text("ssh-ed25519 target\n") (state / "target-key-meta").write_text("0:600\n") elif name == "root-target-account": target_keys.write_text("ssh-ed25519 target\n") (state / "target-uid").write_text("0\n") elif name == "relative-home": target_keys.write_text("ssh-ed25519 target\n") (state / "home").write_text("home/gib\n") elif name in ( "safe-existing-key", "success-without-prior-dropin", "success-replaces-prior-dropin", "candidate-invalid", "candidate-invalid-without-prior", "candidate-reload-fails", "candidate-reload-fails-without-prior", "rollback-validation-fails", "rollback-reload-fails", "success-backup-cleanup-fails", "rollback-backup-cleanup-fails", "signal-int-restores-prior", "signal-term-removes-new-dropin", "candidate-cleanup-fails", ): target_keys.write_text("ssh-ed25519 target\n") elif name == "safe-root-key-copy": root_keys.write_text("ssh-ed25519 root\n") else: raise ValueError(name) return fixture_root, stub_dir def run_case( name: str, *, signal_after_activation: int | None = None, prior_traps: bool = False, **configuration: object, ) -> tuple[int, str, str, Path, int]: fixture_root, stub_dir = configure_case( name, hold_activation=signal_after_activation is not None, **configuration, ) master, slave = pty.openpty() def attach_terminal() -> None: # The test runner launches contracts as background jobs, which inherit # SIGINT ignored. A real interactive bootstrap starts with SIGINT at # its default disposition, so restore that state before exec. signal.signal(signal.SIGINT, signal.SIG_DFL) fcntl.ioctl(0, termios.TIOCSCTTY, 0) env = { **os.environ, "PATH": f"{stub_dir}:/usr/bin:/bin", "PANAMA_BOOT_FIXTURE_ROOT": str(fixture_root), "PANAMA_PATH": f"{fixture_root}/home/gib/.local/share/Panama", "HOME": f"{fixture_root}/root", } if prior_traps: bash_env = fixture_root / "prior-traps" bash_env.write_text( '''if [[ "$0" == "$PANAMA_BOOT_SCRIPT" ]]; then trap 'printf "prior-exit %s\\n" "$BASHPID" >>"$PANAMA_BOOT_FIXTURE_ROOT/calls"' EXIT trap 'printf "prior-int %s\\n" "$BASHPID" >>"$PANAMA_BOOT_FIXTURE_ROOT/calls"' INT trap 'printf "prior-term %s\\n" "$BASHPID" >>"$PANAMA_BOOT_FIXTURE_ROOT/calls"' TERM fi ''' ) env["BASH_ENV"] = str(bash_env) env["PANAMA_BOOT_SCRIPT"] = boot process = subprocess.Popen( ["bash", boot, "--server"], stdin=slave, stdout=slave, stderr=slave, env=env, start_new_session=True, preexec_fn=attach_terminal, ) os.close(slave) os.write(master, b"gib\nY\n") if signal_after_activation is not None: activation = fixture_root / "state/ACTIVATED" deadline = time.monotonic() + 5 while not activation.exists() and process.poll() is None and time.monotonic() < deadline: time.sleep(0.01) if not activation.exists(): note(f"{name}: fixture did not observe atomic activation before signaling") else: os.kill(process.pid, signal_after_activation) (fixture_root / "state/RELEASE_ACTIVATION").touch() chunks: list[bytes] = [] while True: try: chunk = os.read(master, 4096) except OSError as error: if error.errno == errno.EIO: break raise if not chunk: break chunks.append(chunk) os.close(master) status = process.wait() calls = (fixture_root / "calls").read_text() output = b"".join(chunks).decode(errors="replace") return status, output, calls, fixture_root, process.pid unsafe_cases = ( "missing", "empty", "comment-only", "ssh-directory-symlink", "authorized-keys-symlink", "directory-wrong-mode", "root-copy-directory-wrong-mode", "file-wrong-mode", "directory-wrong-owner", "file-wrong-owner", "root-target-account", "relative-home", ) for case in unsafe_cases: status, output, calls, fixture_root, _ = run_case(case) if status != 0: note(f"{case}: bootstrap stopped with status {status}: {output.strip()}") if "SSH hardening unavailable" not in output: note(f"{case}: unsafe login path did not explain why hardening was unavailable") if "sshd -t" in calls: note(f"{case}: unsafe login path validated sshd") if "systemctl reload" in calls: note(f"{case}: unsafe login path reloaded SSH") if (fixture_root / "etc/ssh/sshd_config.d/90-panama.conf").exists(): note(f"{case}: unsafe login path changed the SSH drop-in") if case == "root-copy-directory-wrong-mode" and ( fixture_root / "home/gib/.ssh/authorized_keys" ).exists(): note("root-copy-directory-wrong-mode: copied a root key into an unsafe SSH directory") if "install-handoff " not in calls: note(f"{case}: unsafe login path did not hand off to install") for case in ("safe-existing-key", "safe-root-key-copy"): status, output, calls, fixture_root, _ = run_case(case) if status != 0: note(f"{case}: safe login path stopped with status {status}: {output.strip()}") if "SSH hardening unavailable" in output: note(f"{case}: safe login path was rejected") if "systemctl reload" not in calls: note(f"{case}: safe login path did not reach SSH hardening") if "install-handoff " not in calls: note(f"{case}: safe login path did not hand off to install") dropin = fixture_root / "etc/ssh/sshd_config.d/90-panama.conf" if (dropin.read_text() if dropin.exists() else "") != "PermitRootLogin no\nPasswordAuthentication no\n": note(f"{case}: safe login path did not write the expected SSH drop-in") if case == "safe-root-key-copy": keys = fixture_root / "home/gib/.ssh/authorized_keys" if not keys.exists() or keys.read_text() != "ssh-ed25519 root\n": note("safe-root-key-copy: root key was not copied to the target account") desired_dropin = b"PermitRootLogin no\nPasswordAuthentication no\n" prior_dropin = b"# prior Panama settings\nPasswordAuthentication yes\n" transaction_cases = { "success-without-prior-dropin": { "sshd_results": (0,), "reload_results": (0,), "prior_dropin": None, "sshd_unit": True, "ssh_unit": True, "succeeds": True, }, "success-replaces-prior-dropin": { "sshd_results": (0,), "reload_results": (0,), "prior_dropin": prior_dropin, "sshd_unit": False, "ssh_unit": True, "succeeds": True, }, "candidate-invalid": { "sshd_results": (1, 0), "reload_results": (), "prior_dropin": prior_dropin, "sshd_unit": True, "ssh_unit": True, "succeeds": False, }, "candidate-invalid-without-prior": { "sshd_results": (1, 0), "reload_results": (), "prior_dropin": None, "sshd_unit": True, "ssh_unit": True, "succeeds": False, }, "candidate-reload-fails": { "sshd_results": (0, 0), "reload_results": (1, 0), "prior_dropin": prior_dropin, "sshd_unit": True, "ssh_unit": True, "succeeds": False, }, "candidate-reload-fails-without-prior": { "sshd_results": (0, 0), "reload_results": (1, 0), "prior_dropin": None, "sshd_unit": True, "ssh_unit": True, "succeeds": False, }, "rollback-validation-fails": { "sshd_results": (0, 1), "reload_results": (1,), "prior_dropin": prior_dropin, "sshd_unit": True, "ssh_unit": True, "succeeds": False, "rollback_fails": True, }, "rollback-reload-fails": { "sshd_results": (0, 0), "reload_results": (1, 1), "prior_dropin": prior_dropin, "sshd_unit": True, "ssh_unit": True, "succeeds": False, "rollback_fails": True, }, } for case, expected in transaction_cases.items(): configuration = { key: value for key, value in expected.items() if key not in {"succeeds", "rollback_fails"} } status, output, calls, fixture_root, _ = run_case(case, **configuration) call_lines = calls.splitlines() dropin = fixture_root / "etc/ssh/sshd_config.d/90-panama.conf" sshd_dir = dropin.parent validations = [index for index, line in enumerate(call_lines) if line.startswith("sshd -t ")] reloads = [ index for index, line in enumerate(call_lines) if line.startswith("systemctl reload ") ] activation_lines = [ (index, line) for index, line in enumerate(call_lines) if re.fullmatch( rf"mv -f -- {re.escape(str(sshd_dir))}/\.90-panama\.[A-Za-z0-9]+\.tmp " rf"{re.escape(str(dropin))} source-mode=600 ", line, ) ] restore_lines = [ index for index, line in enumerate(call_lines) if re.fullmatch( rf"mv -f -- {re.escape(str(sshd_dir))}/\.90-panama\.[A-Za-z0-9]+\.restore " rf"{re.escape(str(dropin))} source-mode=600 ", line, ) ] removal_lines = [ index for index, line in enumerate(call_lines) if line == f"rm -f -- {dropin} " ] rollback_lines = restore_lines if expected["prior_dropin"] is not None else removal_lines succeeds = bool(expected["succeeds"]) if succeeds and status != 0: note(f"{case}: transaction stopped with status {status}: {output.strip()}") if not succeeds and status == 0: note(f"{case}: failed transaction returned success") if succeeds and "install-handoff " not in calls: note(f"{case}: successful transaction did not hand off to install") if not succeeds and "install-handoff " in calls: note(f"{case}: failed transaction handed off to install") wanted_contents = desired_dropin if succeeds else expected["prior_dropin"] actual_contents = dropin.read_bytes() if dropin.exists() else None if actual_contents != wanted_contents: note(f"{case}: SSH drop-in contents were not {'activated' if succeeds else 'restored'}") if len(activation_lines) != 1: note(f"{case}: candidate was not activated once through a restrictive same-directory rename") if succeeds: if len(validations) != 1 or len(reloads) != 1: note(f"{case}: success did not validate once and reload once") elif activation_lines and not activation_lines[0][0] < validations[0] < reloads[0]: note(f"{case}: success did not activate, validate, then reload") elif case in {"candidate-invalid", "candidate-invalid-without-prior"}: if len(validations) != 2 or reloads: note(f"{case}: invalid candidate did not validate candidate and restoration without reload") elif activation_lines and rollback_lines and not ( activation_lines[0][0] < validations[0] < rollback_lines[0] < validations[1] ): note(f"{case}: rollback command order was wrong") else: if len(validations) != 2 or len(reloads) != 2: note(f"{case}: reload failure did not validate and reload the restored configuration") elif activation_lines and rollback_lines and not ( activation_lines[0][0] < validations[0] < reloads[0] < rollback_lines[0] < validations[1] < reloads[1] ): note(f"{case}: rollback command order was wrong") if succeeds and restore_lines: note(f"{case}: successful transaction performed a rollback") if not succeeds: if len(rollback_lines) != 1: note(f"{case}: pre-transaction SSH state was not restored exactly once") detected_unit = "ssh.service" if case == "success-replaces-prior-dropin" else "sshd.service" other_unit = "sshd.service" if detected_unit == "ssh.service" else "ssh.service" reload_lines = [call_lines[index] for index in reloads] if reload_lines and any(line != f"systemctl reload {detected_unit} " for line in reload_lines): note(f"{case}: reloaded a unit other than detected {detected_unit}") if any(line == f"systemctl reload {other_unit} " for line in call_lines): note(f"{case}: guessed {other_unit} after reload failure") if detected_unit == "sshd.service": if "systemctl cat sshd.service " not in call_lines: note(f"{case}: did not detect sshd.service") if "systemctl cat ssh.service " in call_lines: note(f"{case}: probed ssh.service after finding sshd.service") elif not ( "systemctl cat sshd.service " in call_lines and "systemctl cat ssh.service " in call_lines and call_lines.index("systemctl cat sshd.service ") < call_lines.index("systemctl cat ssh.service ") ): note(f"{case}: did not fall back from absent sshd.service to ssh.service") artifacts = list(sshd_dir.glob(".90-panama.*")) rollback_fails = bool(expected.get("rollback_fails", False)) if not rollback_fails and artifacts: note(f"{case}: successful or cleanly rolled-back transaction left temporary artifacts") if rollback_fails: backups = [artifact for artifact in artifacts if artifact.name.endswith(".backup")] if len(backups) != 1: note(f"{case}: rollback failure did not retain exactly one backup") else: backup = backups[0] if backup.parent != sshd_dir or backup.read_bytes() != prior_dropin: note(f"{case}: retained backup was not a same-directory byte copy") if backup.stat().st_mode & 0o777 != 0o600: note(f"{case}: retained backup permissions were not restrictive") if str(backup.resolve()) not in output: note(f"{case}: recovery output omitted the absolute backup path") if "sshd -t" not in output or f"systemctl reload {detected_unit}" not in output: note(f"{case}: recovery output omitted validation or reload commands") artifact_logs = [line for line in call_lines if line.startswith("ssh-artifact ")] if expected["prior_dropin"] is not None and not any( re.fullmatch( rf"ssh-artifact {re.escape(str(sshd_dir))}/\.90-panama\.[A-Za-z0-9]+\.backup 600 ", line, ) for line in artifact_logs ): note(f"{case}: backup was not collision-safe, same-directory, non-.conf, and restrictive") cleanup_failure_cases = { "success-backup-cleanup-fails": { "sshd_results": (0,), "reload_results": (0,), "rm_backup_results": (1,), "expected_dropin": desired_dropin, "expected_validations": 1, "expected_reloads": 1, }, "rollback-backup-cleanup-fails": { "sshd_results": (1, 0), "reload_results": (), "rm_backup_results": (1,), "expected_dropin": prior_dropin, "expected_validations": 2, "expected_reloads": 0, }, } for case, expected in cleanup_failure_cases.items(): status, output, calls, fixture_root, _ = run_case( case, sshd_results=expected["sshd_results"], reload_results=expected["reload_results"], rm_backup_results=expected["rm_backup_results"], prior_dropin=prior_dropin, ) dropin = fixture_root / "etc/ssh/sshd_config.d/90-panama.conf" backups = list(dropin.parent.glob(".90-panama.*.backup")) if status == 0: note(f"{case}: cleanup failure returned success") if "install-handoff " in calls: note(f"{case}: cleanup failure handed off to install") if dropin.read_bytes() != expected["expected_dropin"]: note(f"{case}: cleanup failure changed the settled SSH drop-in") if calls.count("sshd -t \n") != expected["expected_validations"]: note(f"{case}: cleanup failure validation count was wrong") if calls.count("systemctl reload sshd.service \n") != expected["expected_reloads"]: note(f"{case}: cleanup failure reload count was wrong") if len(backups) != 1: note(f"{case}: failed cleanup did not retain exactly one backup") else: backup = backups[0] if str(backup.resolve()) not in output or "rm -f --" not in output: note(f"{case}: retained backup was not reported with an actionable cleanup command") status, output, calls, fixture_root, _ = run_case( "candidate-cleanup-fails", mv_activation_results=(1,), rm_candidate_results=(1,), ) dropin = fixture_root / "etc/ssh/sshd_config.d/90-panama.conf" candidates = list(dropin.parent.glob(".90-panama.*.tmp")) if status == 0: note("candidate-cleanup-fails: activation cleanup failure returned success") if dropin.exists(): note("candidate-cleanup-fails: failed activation changed the final drop-in") if "install-handoff " in calls: note("candidate-cleanup-fails: failed activation reached install handoff") if len(candidates) != 1: note("candidate-cleanup-fails: failed cleanup did not retain exactly one candidate") else: candidate = candidates[0] if str(candidate.resolve()) not in output or "rm -f --" not in output: note("candidate-cleanup-fails: retained candidate lacked an actionable cleanup command") signal_cases = { "signal-int-restores-prior": { "signal": signal.SIGINT, "status": 130, "prior_dropin": prior_dropin, }, "signal-term-removes-new-dropin": { "signal": signal.SIGTERM, "status": 143, "prior_dropin": None, }, } for case, expected in signal_cases.items(): status, output, calls, fixture_root, boot_pid = run_case( case, signal_after_activation=expected["signal"], prior_traps=True, sshd_results=(0,), reload_results=(0,), prior_dropin=expected["prior_dropin"], ) dropin = fixture_root / "etc/ssh/sshd_config.d/90-panama.conf" actual_dropin = dropin.read_bytes() if dropin.exists() else None if status != expected["status"]: note(f"{case}: signal returned status {status}, expected {expected['status']}") if actual_dropin != expected["prior_dropin"]: note(f"{case}: signal did not restore the pre-transaction SSH state") if list(dropin.parent.glob(".90-panama.*")): note(f"{case}: signal left transaction residue") if "install-handoff " in calls: note(f"{case}: signal reached install handoff") if f"prior-exit {boot_pid}\n" not in calls: note(f"{case}: signal suppressed the saved EXIT trap") if calls.count("sshd -t \n") != 1: note(f"{case}: signal did not validate restored configuration once") if calls.count("systemctl reload sshd.service \n") != 1: note(f"{case}: signal did not reload restored configuration once") call_lines = calls.splitlines() rollback_indices = [ index for index, line in enumerate(call_lines) if ( expected["prior_dropin"] is not None and re.fullmatch( rf"mv -f -- {re.escape(str(dropin.parent))}/\.90-panama\.[A-Za-z0-9]+\.restore " rf"{re.escape(str(dropin))} source-mode=600 ", line, ) ) or (expected["prior_dropin"] is None and line == f"rm -f -- {dropin} ") ] validation_indices = [ index for index, line in enumerate(call_lines) if line == "sshd -t " ] reload_indices = [ index for index, line in enumerate(call_lines) if line == "systemctl reload sshd.service " ] if not ( len(rollback_indices) == len(validation_indices) == len(reload_indices) == 1 and rollback_indices[0] < validation_indices[0] < reload_indices[0] ): note(f"{case}: signal did not restore, validate, then reload in order") if findings: print(f"root server bootstrap: {len(findings)} finding(s)", file=sys.stderr) for finding in findings: print(f" - {finding}", file=sys.stderr) raise SystemExit(1) print("root server bootstrap: PASS") PY