diff --git a/config/global-defaults b/config/global-defaults index 0f4cf54..0393941 100644 --- a/config/global-defaults +++ b/config/global-defaults @@ -4,7 +4,9 @@ # Per-engagement /workspace/$TARGET/.env overrides these. # ── Default Exegol container ──────────────────────────── -export EXEGOL_CONTAINER="exegol" +# Leave unset → dotsec auto-detects the running exegol container. +# Uncomment to force a specific one: +# export EXEGOL_CONTAINER="exegol-myname" # ── Default Bug Bounty User-Agent ─────────────────────── export UA="H1-yourhandle" diff --git a/lib/core.sh b/lib/core.sh index d188fe3..0ec5271 100644 --- a/lib/core.sh +++ b/lib/core.sh @@ -17,15 +17,17 @@ __dotsec_load_global() { if [[ -f "${DOTSEC_CONFIG}/config" ]]; then source "${DOTSEC_CONFIG}/config" fi - # Auto-detect Exegol container if not set - if [[ -z "${EXEGOL_CONTAINER:-}" ]]; then + # Resolve the Exegol container: detect when unset OR when the configured one + # no longer exists (e.g. removed/recreated) — so a stale config value never + # sticks. Prefer a running container, fall back to any. + if [[ -z "${EXEGOL_CONTAINER:-}" ]] || ! docker container inspect "${EXEGOL_CONTAINER}" >/dev/null 2>&1; then local detected - detected=$(docker ps -a --filter "name=exegol" --format '{{.Names}}' 2>/dev/null | head -1) + detected=$(docker ps --filter "name=exegol" --format '{{.Names}}' 2>/dev/null | head -1) + [[ -z "$detected" ]] && detected=$(docker ps -a --filter "name=exegol" --format '{{.Names}}' 2>/dev/null | head -1) [[ -n "$detected" ]] && EXEGOL_CONTAINER="$detected" fi - # Last statement must not leak a non-zero status: under `set -e` this - # function is called top-level and a falsy [[ -n ]] above would abort dotsec - # on any host without an exegol container. + # Last statement must not leak a non-zero status under `set -e` (this + # function runs top-level; a falsy [[ -n ]] above would otherwise abort dotsec). return 0 } diff --git a/lib/engagement.sh b/lib/engagement.sh index d69edfc..898c762 100644 --- a/lib/engagement.sh +++ b/lib/engagement.sh @@ -56,7 +56,6 @@ cmd_new() { # Merge global config defaults (only if key not already set) __dotsec_load_global [[ -n "${UA:-}" ]] && sed -i "s|H1-yourhandle|${UA}|g" "${ws}/.env" - [[ -n "${EXEGOL_CONTAINER:-}" ]] && sed -i "s|exegol-default|${EXEGOL_CONTAINER}|g" "${ws}/.env" [[ -n "${PROXY_PORT:-}" ]] && sed -i "s|PROXY_PORT=\"9999\"|PROXY_PORT=\"${PROXY_PORT}\"|g" "${ws}/.env" [[ -n "${WEB_PORT:-}" ]] && sed -i "s|WEB_PORT=\"9998\"|WEB_PORT=\"${WEB_PORT}\"|g" "${ws}/.env" diff --git a/templates/.env.engagement b/templates/.env.engagement index baf73c1..c5a09ac 100644 --- a/templates/.env.engagement +++ b/templates/.env.engagement @@ -21,7 +21,7 @@ export NO_PROXY="localhost,127.0.0.1" export WORKSPACE="/workspace/acme-corp" # ── Exegol ────────────────────────────────────────────── -export EXEGOL_CONTAINER="exegol" +# EXEGOL_CONTAINER is global infra (auto-detected), not per-engagement. # ── Secrets (auto-generated, never committed) ─────────── # Generated by `dotsec new` into .env.secrets (chmod 600): diff --git a/tests/smoke.bats b/tests/smoke.bats index 20f1950..3936118 100644 --- a/tests/smoke.bats +++ b/tests/smoke.bats @@ -34,6 +34,26 @@ load test_helper [[ "$output" == *REACHED* ]] } +@test "__dotsec_load_global re-detects when the configured container is gone" { + run env DOTSEC_HOME="$DOTSEC_HOME" bash -euo pipefail -c ' + DOTSEC_CONFIG=$(mktemp -d) + docker() { + case "$1" in + container) [[ "$2" == "inspect" ]] && return 1 ;; # configured one gone + ps) echo "exegol-a" ;; # a running exegol exists + esac + return 0 + } + source "$DOTSEC_HOME/lib/ui.sh" + source "$DOTSEC_HOME/lib/core.sh" + EXEGOL_CONTAINER="exegol-dead" + __dotsec_load_global + echo "GOT=$EXEGOL_CONTAINER" + ' + [ "$status" -eq 0 ] + [[ "$output" == *"GOT=exegol-a"* ]] +} + @test "dotsec list exits 0 when engagements exist" { local ws cfg ws="$(mktemp -d)"; cfg="$(mktemp -d)"