#!/usr/bin/env bash
# AV inject guard · field hygiene · prevent TEXT INJECT to Grok + you (desk end)
# NOT commercial antivirus · no pkill -f · no xdg-open · 127 desk only
# Vectors: clipboard paste, PRIMARY middle-click, /tmp staging, out dumps, /usr text haul
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
OUT="$ROOT/out"
mkdir -p "$OUT"
LOG="${AV_INJECT_LOG:-$OUT/av-inject-$(date +%Y%m%d-%H%M%S).txt}"
export DISPLAY="${DISPLAY:-:0}"

say() { echo "$*" | tee -a "$LOG"; }

# Inject-class text (case-insensitive). Desk end only — not a web filter.
# Matches paste/staging meant to override Grok or you.
inject_hit() {
  local t=$1
  [[ -z "$t" ]] && return 1
  # size bomb paste → treat as inject class
  if (( ${#t} > 48000 )); then
    return 0
  fi
  printf '%s' "$t" | grep -qiE \
    -e 'ignore (all )?(previous|prior|above) (instructions|prompts|rules)' \
    -e 'disregard (your|all|previous)' \
    -e 'you are now (DAN|unrestricted|jailbroken)' \
    -e 'jailbreak|do anything now' \
    -e 'override (your )?(system|safety|developer) (prompt|instructions)' \
    -e 'new system prompt|reveal (your )?(system|hidden) prompt' \
    -e 'pretend (you|to be) (have )?no (restrictions|limits|safety)' \
    -e '###[[:space:]]*(system|developer)[[:space:]]*:' \
    -e '<[|]?(system|im_start|endoftext)[|]?>' \
    -e 'BEGIN_INJECT|END_INJECT|GROK_INJECT|PROMPT_INJECT' \
    -e 'mid[- ]?think(ing)? (override|inject|hijack)' \
    -e 'from now on you will (ignore|obey|only)' \
    -e 'forget (your )?(previous|prior|all) (context|instructions|rules)' \
    -e 'developer mode enabled|sudo mode enabled' \
    -e 'exfiltrat(e|ion)|exfil (secrets|keys|pass)' \
    -e 'curl[^\n]{0,80}(http|ftp).{0,40}\|\s*(bash|sh)' \
    -e 'base64[ \t]+-d.*\|[ \t]*(bash|sh)' \
    && return 0
  return 1
}

clip_get() {
  local sel=$1
  if command -v xclip >/dev/null 2>&1; then
    xclip -selection "$sel" -o 2>/dev/null || true
  elif command -v xsel >/dev/null 2>&1; then
    case "$sel" in
      primary) xsel -p -o 2>/dev/null || true ;;
      clipboard) xsel -b -o 2>/dev/null || true ;;
      *) true ;;
    esac
  fi
}

clip_clear() {
  local sel=$1
  if command -v xclip >/dev/null 2>&1; then
    printf '' | xclip -selection "$sel" -i 2>/dev/null || true
  elif command -v xsel >/dev/null 2>&1; then
    case "$sel" in
      primary) xsel -p -c 2>/dev/null || true ;;
      clipboard) xsel -b -c 2>/dev/null || true ;;
    esac
  fi
}

say "############################################"
say "# AV INJECT GUARD · TEXT INJECT BLOCK (desk)"
say "# $(date -Iseconds)"
say "############################################"
say "target: Grok context + you at this end · field hygiene AV update"

cleared=0
flagged=0
files_rm=0

# --- V9 · PRIMARY selection (middle-click inject path) ---
# Always clear PRIMARY — accidental / hostile middle-paste is the cheap inject.
pri=$(clip_get primary || true)
pri_len=${#pri}
if (( pri_len > 0 )); then
  if inject_hit "$pri"; then
    say "PRIMARY · inject-class · CLEARED len=$pri_len"
    flagged=$((flagged + 1))
  else
    say "PRIMARY · residual paste · CLEARED len=$pri_len (middle-click inject path)"
  fi
  clip_clear primary
  cleared=$((cleared + 1))
else
  say "PRIMARY · empty · OK"
fi

# --- V10 · CLIPBOARD · clear only on inject-class hit ---
cb=$(clip_get clipboard || true)
cb_len=${#cb}
if (( cb_len > 0 )); then
  if inject_hit "$cb"; then
    say "CLIPBOARD · inject-class · CLEARED len=$cb_len"
    clip_clear clipboard
    cleared=$((cleared + 1))
    flagged=$((flagged + 1))
  else
    say "CLIPBOARD · keep (no inject pattern) len=$cb_len"
  fi
else
  say "CLIPBOARD · empty · OK"
fi

# --- V11 · /tmp inject staging (names + small text dumps only) ---
say "=== /tmp inject staging ==="
for f in /tmp/grok-inject* /tmp/prompt-dump* /tmp/system-prompt* \
         /tmp/jailbreak* /tmp/*PROMPT_INJECT* /tmp/grok-orphan-* \
         /tmp/rtx_inject* /tmp/bgl_inject* /tmp/hostile-inject*; do
  [[ -e "$f" ]] || continue
  # never touch dirs owned by systemd private · never our own av-inject logs
  [[ -d "$f" && "$f" == *systemd-private* ]] && continue
  bn=$(basename "$f")
  case "$bn" in av-inject*|av_inject*) continue ;; esac
  rm -rf "$f" 2>/dev/null && { say "rm $f"; files_rm=$((files_rm + 1)); } || true
done
# small loose text that looks like inject haul ( ≤ 256k )
while IFS= read -r -d '' f; do
  [[ -f "$f" && -r "$f" ]] || continue
  bn=$(basename "$f")
  case "$bn" in
    *.o|*.so|*.ppm|*.png|*.jpg|*.log) continue ;;
  esac
  # only scan tiny files
  sz=$(wc -c <"$f" 2>/dev/null | tr -d ' ' || echo 0)
  (( sz > 0 && sz < 262144 )) || continue
  # skip binary-ish
  if file -b --mime-encoding "$f" 2>/dev/null | grep -qi binary; then
    continue
  fi
  headc=$(head -c 8000 "$f" 2>/dev/null || true)
  if inject_hit "$headc"; then
    rm -f "$f" 2>/dev/null && { say "rm inject-text $f sz=$sz"; files_rm=$((files_rm + 1)); flagged=$((flagged + 1)); } || true
  fi
done < <(find /tmp -maxdepth 1 -type f -user "$(id -un)" -print0 2>/dev/null || true)

# --- V12 · out/ inject dumps + /usr text haul residues ---
say "=== out/ inject + /usr haul residue ==="
for f in "$OUT"/inject* "$OUT"/prompt-dump* "$OUT"/system-prompt* \
         "$OUT"/usr-haul* "$OUT"/usr_share* "$OUT"/dict-raw* "$OUT"/*JAILBREAK* \
         "$OUT"/hostile-inject* "$OUT"/grok-inject*; do
  [[ -e "$f" ]] || continue
  bn=$(basename "$f")
  case "$bn" in av-inject*|av_inject*|av_inject.json|av_inject_latest.json) continue ;; esac
  rm -f "$f" 2>/dev/null && { say "rm $f"; files_rm=$((files_rm + 1)); } || true
done
# flag (do not auto-delete) large out dumps that are pure /usr path lists — report only
while IFS= read -r f; do
  [[ -f "$f" ]] || continue
  sz=$(wc -c <"$f" 2>/dev/null | tr -d ' ' || echo 0)
  (( sz > 200000 )) || continue
  headc=$(head -c 4000 "$f" 2>/dev/null || true)
  if printf '%s' "$headc" | grep -qE '^(/usr/|/bin/|/lib/)'; then
    say "WARN large /usr-path dump (not auto-fed to Grok): $f sz=$sz"
    flagged=$((flagged + 1))
  fi
done < <(find "$OUT" -maxdepth 1 -type f -size +200k 2>/dev/null || true)

# --- V13 · desk law pin: no /usr mass text → Grok · no xdg paste chain ---
LAW="$OUT/NO_INJECT"
cat >"$LAW" <<'PIN'
NO_INJECT · field hygiene · desk end
====================================
1. Do NOT paste clipboard/PRIMARY into Grok unless YOU typed it.
2. PRIMARY (middle-click) is always cleared by av-inject-guard.
3. CLIPBOARD is cleared only when inject-class patterns hit.
4. Do NOT cat /usr/share /usr/bin man pages into Grok as bulk context.
5. Tree-first: Desktop/x + magazine · never force /usr text inject.
6. xdg-open = virus class · never auto-launch browser with payload URL.
7. Agent: exact PID/comm kill only · never pkill -f (self-match death).
8. If a paste says ignore previous / jailbreak / new system prompt → discard.
PIN
say "wrote $LAW"

# machine-readable mark
cat >"$OUT/av_inject.json" <<JSON
{
  "av": "field hygiene inject guard · not commercial antivirus",
  "ts": "$(date -Iseconds)",
  "protects": ["grok_context", "user_desk_end"],
  "primary_cleared": $cleared,
  "inject_flagged": $flagged,
  "files_removed": $files_rm,
  "law": "$LAW",
  "log": "$LOG"
}
JSON
cp -f "$OUT/av_inject.json" "$OUT/av_inject_latest.json"

say "=== RESULT ==="
say "cleared_ops=$cleared  inject_flagged=$flagged  files_rm=$files_rm"
say "AV inject guard DONE · Grok + you · desk end sealed"
echo "$LOG"
