#!/usr/bin/env bash
# verify-day-zero.sh — as cinco condições que definem o fim do Dia Zero.
#
# O onboarding SO pode ser declarado concluído quando as cinco passam. Não e
# julgamento do agente: e comando, com resposta objetiva.
#
#   1. acesso por chave como usuário de operação funciona
#   2. login de root pela rede está desligado
#   3. login por senha está desligado
#   4. firewall ativo com politica de negar entrada
#   5. atualizações automáticas de segurança ligadas
#
# Uso: verify-day-zero.sh --host <ip> --user <deploy> [--port 22] [--key <chave>]
# Código 0 apenas quando as cinco passam.

set -uo pipefail

HOST=""; USER_NAME=""; PORT=22; KEY_PATH=""

while [ $# -gt 0 ]; do
  case "$1" in
    --host) HOST="$2"; shift 2 ;;
    --user) USER_NAME="$2"; shift 2 ;;
    --port) PORT="$2"; shift 2 ;;
    --key)  KEY_PATH="$2"; shift 2 ;;
    *) echo "argumento desconhecido: $1" >&2; exit 2 ;;
  esac
done

[ -n "$HOST" ] && [ -n "$USER_NAME" ] || { echo "ERRO: --host e --user são obrigatórios" >&2; exit 2; }

SSH_OPTS=(-o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ForwardAgent=no -o ConnectTimeout=10 -o ControlMaster=no -o ControlPath=none -p "$PORT")
[ -n "$KEY_PATH" ] && SSH_OPTS+=(-i "${KEY_PATH/#\~/$HOME}" -o IdentitiesOnly=yes)

echo ""
echo "============================================"
echo " VERIFICACAO FINAL DO DIA ZERO — ${HOST}"
echo "============================================"

PASS=0
FAIL=0
mark() { if [ "$1" -eq 1 ]; then echo "  [OK]    $2"; PASS=$((PASS+1)); else echo "  [FALHA] $2"; echo "          -> $3"; FAIL=$((FAIL+1)); fi; }

# 1. acesso
read -r -d '' REMOTE <<'REMOTE_SCRIPT' || true
  # O valor efetivo vem de `sshd -T`, que exige root. O usuário de operação não
  # tem sudo para ele, então a falta de resposta não pode virar FALHA: os
  # arquivos são lidos na ordem do sshd (primeira ocorrência vence, Include
  # expandido no lugar). O que a leitura não resolve com certeza (bloco Match,
  # arquivo ilegível, Include aninhado, diretiva ausente) vira "?", e "?" falha.
  ler_cfg() {
    local arq="$1" chave="$2" nivel="$3" linha k pat g
    local -a campos
    if [ "$nivel" -gt 1 ] || [ ! -r "$arq" ]; then RES="?"; return; fi
    while IFS= read -r linha || [ -n "$linha" ]; do
      linha="${linha/=/ }"
      read -ra campos <<< "$linha"
      [ "${#campos[@]}" -gt 0 ] || continue
      k="${campos[0],,}"
      case "$k" in
        \#*) continue ;;
        match) RES="?"; return ;;
        include)
          for pat in "${campos[@]:1}"; do
            case "$pat" in /*) ;; *) pat="/etc/ssh/$pat" ;; esac
            for g in $pat; do
              [ -e "$g" ] || continue
              ler_cfg "$g" "$chave" $((nivel + 1))
              [ -n "$RES" ] && return
            done
          done ;;
        "$chave") RES="${campos[1],,}"; [ -n "$RES" ] || RES="?"; return ;;
      esac
    done < "$arq"
  }
  EFF=$(sudo -n sshd -T 2>/dev/null || sshd -T 2>/dev/null)
  echo "WHO=$(id -un)"
  if [ -n "$EFF" ]; then
    echo "FONTE=sshd -T"
    echo "ROOT=$(printf "%s" "$EFF" | grep -i "^permitrootlogin" | awk "{print \$2}" | head -n1)"
    echo "PASS=$(printf "%s" "$EFF" | grep -i "^passwordauthentication" | awk "{print \$2}" | head -n1)"
  else
    echo "FONTE=arquivos"
    RES=""; ler_cfg /etc/ssh/sshd_config permitrootlogin 0; echo "ROOT=${RES:-?}"
    RES=""; ler_cfg /etc/ssh/sshd_config passwordauthentication 0; echo "PASS=${RES:-?}"
  fi
  if command -v ufw >/dev/null 2>&1; then
    S=$(sudo -n ufw status verbose 2>/dev/null || ufw status verbose 2>/dev/null)
    printf "%s" "$S" | grep -qi "Status: active" && printf "%s" "$S" | grep -qi "deny (incoming)" && echo "FW=ok" || echo "FW=não"
  else echo "FW=ausente"; fi
  if [ -f /etc/apt/apt.conf.d/20auto-upgrades ] && grep -q "Unattended-Upgrade \"1\"" /etc/apt/apt.conf.d/20auto-upgrades 2>/dev/null; then echo "UPD=ok"; else echo "UPD=não"; fi
REMOTE_SCRIPT

OUT=$(ssh "${SSH_OPTS[@]}" "${USER_NAME}@${HOST}" "$REMOTE" 2>&1)
CODE=$?

if [ $CODE -ne 0 ]; then
  mark 0 "acesso por chave como '${USER_NAME}'" "não consegui entrar; o Dia Zero NAO esta concluído"
  printf '%s\n' "$OUT" | sed 's/^/          /'
  echo ""
  echo "RESULTADO: 0 de 5. Dia Zero incompleto."
  echo "DAY_ZERO=incompleto"
  exit 1
fi

WHO=$(printf '%s' "$OUT" | grep '^WHO=' | cut -d= -f2)
ROOT=$(printf '%s' "$OUT" | grep '^ROOT=' | cut -d= -f2)
PASSA=$(printf '%s' "$OUT" | grep '^PASS=' | cut -d= -f2)
FONTE=$(printf '%s' "$OUT" | grep '^FONTE=' | cut -d= -f2)
FW=$(printf '%s' "$OUT" | grep '^FW=' | cut -d= -f2)
UPD=$(printf '%s' "$OUT" | grep '^UPD=' | cut -d= -f2)

mark "$([ "$WHO" = "$USER_NAME" ] && echo 1 || echo 0)" \
  "acesso por chave como '${USER_NAME}' (respondeu: ${WHO})" \
  "o servidor respondeu como outro usuário; confira o perfil"

mark "$([ "$ROOT" = "no" ] && echo 1 || echo 0)" \
  "login de root pela rede desligado (valor: ${ROOT:-?}, via ${FONTE:-?})" \
  "rode harden.sh; root exposto é o alvo número um de varredura"

mark "$([ "$PASSA" = "no" ] && echo 1 || echo 0)" \
  "login por senha desligado (valor: ${PASSA:-?}, via ${FONTE:-?})" \
  "rode harden.sh; senha pode ser quebrada por tentativa e erro"

mark "$([ "$FW" = "ok" ] && echo 1 || echo 0)" \
  "firewall ativo negando entrada (valor: ${FW:-?})" \
  "rode harden.sh; sem firewall toda porta aberta por engano fica exposta"

mark "$([ "$UPD" = "ok" ] && echo 1 || echo 0)" \
  "atualizações automáticas de segurança (valor: ${UPD:-?})" \
  "rode harden.sh; falha conhecida sem correção é o caminho mais fácil de invasão"

echo ""
echo "============================================"
echo " RESULTADO: ${PASS} de 5"
if [ "$FAIL" -eq 0 ]; then
  echo " Dia Zero CONCLUIDO. Próximo passo: /sshp-provision"
  echo "============================================"
  echo "DAY_ZERO=concluído"
  exit 0
fi
echo " Dia Zero INCOMPLETO. Não declare concluído."
echo "============================================"
echo "DAY_ZERO=incompleto"
exit 1
