#!/usr/bin/env bash
# gobrr STAGE-0 — the GENERIC public bootstrap. Streamed to ANYONE:
#   ssh gobrr.lol | bash          (anonymous responder on :22)
#   curl -fsSL https://gobrr.lol | bash
#
# What it does, and ONLY this (no owner-specific config — no lock-in):
#   1. install Nix (Determinate, sha-pinned)
#   2. provision a FIDO2-capable ssh (nixpkgs openssh) — stock macOS /usr/bin/ssh
#      has NO libfido2, so it CANNOT use the YubiKey's sk-ssh-ed25519 credential.
#      This is the missing tool a fresh Mac needs before any YubiKey SSH works.
#   3. materialize the caller's YubiKey resident credential (ssh-keygen -K)
#   4. hand off to STAGE-1 over the KEYED channel (install@gobrr.lol:2222),
#      reachable only by an AUTHORIZED YubiKey. That keyed endpoint is where any
#      owner-specific files come from. A stranger/keyless caller stops here with
#      Nix + FIDO2 ssh + their own key, nothing owner-specific. (DESIGN §3b.)
#
# PUBLIC — keep free of names, emails, secrets, owner config. Guard-enforced.
# Truncation safety: whole body inside main(), run only by the last line.

set -euo pipefail

DET_NIX_URL="https://install.determinate.systems/nix/tag/v3.18.1"
DET_NIX_SHA256="fbf69e92ae8c70c49b07dbb507c566653d095acf31f9500170deed2cbcbfea16"

PUBLIC_HOST="gobrr.lol"      # hop-1: where stage-0 came from (responder, :22)
ADMIN_HOST="gobrr.lol"       # hop-2: the keyed OpenSSH endpoint (same name, :2222)
ADMIN_PORT="2222"

main() {
    say() { printf '== %s ==\n' "$*"; }

    say "gobrr stage-0 (generic: Nix + FIDO2 ssh + YubiKey, then keyed handoff)"

    # 1. Nix (Determinate installer, version + sha pinned). Generic.
    if ! command -v nix >/dev/null 2>&1; then
        say "installing Nix (Determinate ${DET_NIX_URL##*/})"
        local tmp
        tmp="$(mktemp -t gobrr-det-nix.XXXXXX)"
        trap 'rm -f "$tmp"' RETURN
        curl --proto '=https' --tlsv1.2 -sSf -L "$DET_NIX_URL" -o "$tmp"
        printf '%s  %s\n' "$DET_NIX_SHA256" "$tmp" \
            | shasum -a 256 -c - >/dev/null \
            || { say "Determinate installer sha256 mismatch — refusing to run"; exit 1; }
        sh "$tmp" install --no-confirm
    fi
    if ! command -v nix >/dev/null 2>&1; then
        # shellcheck disable=SC1091
        . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh 2>/dev/null || true
    fi
    command -v nix >/dev/null 2>&1 || {
        say "nix not on PATH after install — open a fresh shell and re-run"; exit 1; }

    # 2. FIDO2-capable ssh. Stock macOS /usr/bin/ssh ships WITHOUT libfido2
    #    ("No FIDO SecurityKeyProvider specified"), so it can't use the YubiKey's
    #    FIDO2 resident key. nixpkgs' openssh is built with libfido2 → use it for
    #    every SK operation below. (Transient via `nix shell`; the box's ongoing
    #    SK setup is handled later by the owner config in stage-1.)
    say "provisioning a FIDO2-capable ssh (nixpkgs openssh; stock macOS lacks libfido2)"
    local -a SKSSH=(nix shell nixpkgs#openssh -c)
    "${SKSSH[@]}" ssh -V >/dev/null 2>&1 || { say "could not provision FIDO2 ssh via nix"; exit 1; }

    # 3. Materialize the YubiKey resident credential (FIDO2 ssh + touch/PIN).
    #    No YubiKey? Stop: Nix + FIDO2 ssh are in place, no owner config (no lock-in).
    local skkey
    skkey="$(ls "$HOME"/.ssh/id_*_sk_rk_* 2>/dev/null | head -1 || true)"
    if [ -z "$skkey" ]; then
        say "materializing YubiKey credential — touch it (PIN may be required)"
        ( umask 077; mkdir -p "$HOME/.ssh"; cd "$HOME/.ssh" && "${SKSSH[@]}" ssh-keygen -K ) \
            || { say "no YubiKey materialized — stopping (Nix + FIDO2 ssh present, no owner config)"; return 0; }
        skkey="$(ls "$HOME"/.ssh/id_*_sk_rk_* 2>/dev/null | head -1 || true)"
    fi
    [ -z "$skkey" ] && { say "still no SK key present — stopping (no owner config)"; return 0; }

    # 4. CHECK #2 — verify the keyed endpoint (:${ADMIN_PORT}) is the SAME server
    #    verified against the dog tag at genesis. Machine-exact AND human eyeball.
    verify_hop2 || { say "hop-2 host-key check FAILED — aborting before fetching stage-1"; return 1; }

    # 5. Auto-handoff to KEYED stage-1 via the FIDO2 ssh. The materialized YubiKey
    #    authenticates to install@; its ForceCommand streams the differentiated
    #    payload. An unauthorized key is rejected here → no owner config.
    say "fetching your config (stage-1) over the YubiKey-gated channel..."
    # IdentityAgent=none: sign with the SK stub DIRECTLY via this ssh's libfido2.
    # Do NOT delegate to a running ssh-agent — the macOS system agent has no
    # libfido2 and refuses SK signing ("agent refused operation").
    "${SKSSH[@]}" ssh -o StrictHostKeyChecking=yes -o IdentitiesOnly=yes \
        -o IdentityAgent=none -i "$skkey" \
        -p "$ADMIN_PORT" "install@${ADMIN_HOST}" | bash
}

# verify_hop2: confirm gobrr.lol:2222 presents the SAME host key the human
# approved at genesis (hop-1), then pin it so the stage-1 ssh can't be MITM'd.
# Uses stock ssh-keyscan/ssh-keygen — no SK/FIDO2 needed just to read host keys.
verify_hop2() {
    local scanned pinned fp
    scanned="$(ssh-keyscan -p "$ADMIN_PORT" -t ed25519 "$ADMIN_HOST" 2>/dev/null \
                 | grep -v '^#' | awk '{print $2" "$3}' | head -1)"
    [ -z "$scanned" ] && { echo "cannot reach ${ADMIN_HOST}:${ADMIN_PORT}"; return 1; }

    pinned="$(ssh-keygen -F "$PUBLIC_HOST" 2>/dev/null | grep -v '^#' | awk '{print $2" "$3}' | head -1)"
    if [ -n "$pinned" ]; then
        if [ "$pinned" != "$scanned" ]; then
            echo "MISMATCH: ${ADMIN_HOST}:${ADMIN_PORT} key != the genesis key you verified."
            echo "  This is exactly a hop-2 injection attempt. Refusing."
            return 1
        fi
        echo "machine check: :${ADMIN_PORT} host key == your verified genesis key ✓"
    else
        echo "no SSH genesis key to anchor (curl path?) — verify the next line by hand."
    fi

    fp="$(printf '%s %s\n' "$ADMIN_HOST" "$scanned" | ssh-keygen -lf - 2>/dev/null | awk '{print $2}')"
    {
        printf '\n  hop-2 %s:%s host key:\n    %s\n' "$ADMIN_HOST" "$ADMIN_PORT" "$fp"
        printf '  Compare to your dog tag. Enter = proceed, Ctrl-C = abort: '
    } >/dev/tty
    read -r _ </dev/tty

    printf '[%s]:%s %s\n' "$ADMIN_HOST" "$ADMIN_PORT" "$scanned" >> "$HOME/.ssh/known_hosts"
    return 0
}

main "$@"
