#!/bin/bash
# =============================================================================
# security-auth.sh -- Authentication & User Management
# =============================================================================
# Category: security | Bird: falcon | Tier: 1 | Node-aware: yes
# Absorbs: auth.sh, users.sh
# Actions: --users, --sessions, --rotate-ssh, --status, --send, --digest, --flush
# =============================================================================

TOOL_NAME="security-auth"
TOOL_VERSION="3.0.0"
TOOL_TIER=1
TOOL_BIRD="falcon"
TOOL_LOG="/opt/binary/logs/tools/${TOOL_NAME}.log"

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [[ -f "${SCRIPT_DIR}/common.sh" ]]; then source "${SCRIPT_DIR}/common.sh"
elif [[ -f "${SCRIPT_DIR}/../common.sh" ]]; then source "${SCRIPT_DIR}/../common.sh"
else echo "FATAL: common.sh not found" >&2; exit 1; fi
export BIRD_ID="${TOOL_BIRD}"

_do_send_impl() {
    echo "=== Auth Status: $(ts_local) ==="
    echo "  Node: ${NODE_ID}"
    echo "  Users with shell:"
    grep -vE '(nologin|false)$' /etc/passwd 2>/dev/null | awk -F: '{printf "    %-15s uid=%s\n",$1,$3}'
    echo "  Active sessions:"
    who 2>/dev/null | sed 's/^/    /'
    echo "  SSH keys:"
    for u in root snowdaddy automation phoenix; do
        local kc=0
        [ -f "/home/${u}/.ssh/authorized_keys" ] && kc=$(wc -l < "/home/${u}/.ssh/authorized_keys" 2>/dev/null || echo 0)
        [ -f "/root/.ssh/authorized_keys" ] && [ "$u" = "root" ] && kc=$(wc -l < "/root/.ssh/authorized_keys" 2>/dev/null || echo 0)
        echo "    ${u}: ${kc} key(s)"
    done
    tool_audit "send" "node=${NODE_ID}"
}

_do_status_impl() {
    local sessions; sessions=$(who 2>/dev/null | wc -l)
    local s="healthy"; [ "$sessions" -gt 5 ] && s="degraded"
    echo "{\"tool\":\"${TOOL_NAME}\",\"node\":\"${NODE_ID}\",\"status\":\"${s}\",\"sessions\":${sessions},\"checked_at\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}"
}

_do_digest_impl() {
    echo "=== Auth Report: ${NODE_ID} ==="
    _do_send_impl; echo ""
    _do_ssh_harden_impl; echo ""
    _do_sudo_audit_impl; echo ""
    _do_login_history_impl
}
_do_flush_impl() { [ -f "$TOOL_LOG" ] && truncate -s 0 "$TOOL_LOG"; echo "Flush complete"; }

# --ssh-harden (SSH hardening audit)
_do_ssh_harden_impl() {
    echo "=== SSH Hardening: ${NODE_ID} ==="
    local issues=0
    local cfg="/etc/ssh/sshd_config"
    [ -f "$cfg" ] || { echo "  [FAIL] sshd_config not found"; return 1; }

    # Check critical settings
    local port; port=$(grep -E '^Port ' "$cfg" 2>/dev/null | awk '{print $2}')
    echo "  Port: ${port:-22}"
    [ "${port:-22}" = "22" ] && { echo "  [WARN] Using default port 22"; issues=$((issues+1)); }

    local root_login; root_login=$(grep -E '^PermitRootLogin' "$cfg" 2>/dev/null | awk '{print $2}')
    echo "  PermitRootLogin: ${root_login:-default}"
    [ "$root_login" != "no" ] && [ "$root_login" != "prohibit-password" ] && { echo "  [WARN] Root login should be 'no' or 'prohibit-password'"; issues=$((issues+1)); }

    local pw_auth; pw_auth=$(grep -E '^PasswordAuthentication' "$cfg" 2>/dev/null | awk '{print $2}')
    echo "  PasswordAuth: ${pw_auth:-default}"
    [ "$pw_auth" != "no" ] && { echo "  [WARN] Password auth should be disabled"; issues=$((issues+1)); }

    local max_auth; max_auth=$(grep -E '^MaxAuthTries' "$cfg" 2>/dev/null | awk '{print $2}')
    echo "  MaxAuthTries: ${max_auth:-6}"
    [ "${max_auth:-6}" -gt 5 ] 2>/dev/null && { echo "  [WARN] MaxAuthTries should be <= 5"; issues=$((issues+1)); }

    local alive; alive=$(grep -E '^ClientAliveInterval' "$cfg" 2>/dev/null | awk '{print $2}')
    echo "  ClientAliveInterval: ${alive:-0}"

    echo ""
    [ "$issues" -eq 0 ] && echo "  [OK] SSH hardening: PASS" || echo "  [WARN] SSH hardening: ${issues} issue(s)"
    tool_audit "ssh_harden" "issues=${issues} node=${NODE_ID}"
}

# --login-history (SSH login alerts)
_do_login_history_impl() {
    echo "=== Login History: ${NODE_ID} ==="
    echo "--- Last 10 logins ---"
    last -10 2>/dev/null | sed 's/^/  /'
    echo ""
    echo "--- Failed logins (24h) ---"
    local fails; fails=$(journalctl -u sshd --since "24 hours ago" --no-pager 2>/dev/null | grep -c "Failed password" || echo 0)
    echo "  Failed SSH attempts: ${fails}"
    [ "${fails:-0}" -gt 100 ] && echo "  [WARN] High brute-force activity detected"
    echo ""
    echo "--- Currently logged in ---"
    who 2>/dev/null | sed 's/^/  /'
}

# --sudo-audit (sudo usage audit)
_do_sudo_audit_impl() {
    echo "=== Sudo Audit: ${NODE_ID} ==="
    echo "--- Sudoers files ---"
    ls -la /etc/sudoers.d/ 2>/dev/null | sed 's/^/  /'
    echo ""
    echo "--- Recent sudo usage ---"
    journalctl -t sudo --since "24 hours ago" --no-pager -n 15 2>/dev/null | sed 's/^/  /'
}

# --hop-guard (verify hop authentication chain)
_do_hop_guard_impl() {
    echo "=== Hop Guard: ${NODE_ID} ==="
    echo "  Verifying authentication hop chain..."
    # Check WireGuard is up (required for hop auth)
    if command -v wg &>/dev/null && wg show interfaces &>/dev/null; then
        echo "  [OK] WireGuard: active"
    else
        echo "  [FAIL] WireGuard: not active (hop chain broken)"
        return 1
    fi
    # Check SSH key-only from WireGuard peers
    local wg_port; wg_port=$(grep -E '^Port ' /etc/ssh/sshd_config 2>/dev/null | awk '{print $2}')
    echo "  SSH management port: ${wg_port:-22}"
    # Check s3rv1c3agent is running (required for authenticated dispatch)
    if pgrep -f s3rv1c3agent &>/dev/null || ss -tlnp 2>/dev/null | grep -q ':8366 '; then
        echo "  [OK] s3rv1c3agent: listening"
    else
        echo "  [WARN] s3rv1c3agent: not running"
    fi
    # Check veil approval queue
    local pending; pending=$(find /opt/binary/data/pending-approvals -name '*.json' 2>/dev/null | wc -l)
    echo "  Veil pending: ${pending}"
    tool_audit "hop_guard" "node=${NODE_ID}"
}

# --verify (full auth verification)
_do_verify_impl() {
    echo "=== Auth Verification: ${NODE_ID} ==="
    local pass=0 fail=0
    # Check passwd integrity
    if pwck -r 2>/dev/null; then echo "  [OK] passwd integrity"; pass=$((pass+1))
    else echo "  [FAIL] passwd integrity"; fail=$((fail+1)); fi
    # Check shadow integrity
    if grpck -r 2>/dev/null; then echo "  [OK] group integrity"; pass=$((pass+1))
    else echo "  [FAIL] group integrity"; fail=$((fail+1)); fi
    # Check for UID 0 accounts other than root
    local uid0; uid0=$(awk -F: '$3==0 && $1!="root"{print $1}' /etc/passwd 2>/dev/null)
    if [ -z "$uid0" ]; then echo "  [OK] No extra UID 0 accounts"; pass=$((pass+1))
    else echo "  [FAIL] Extra UID 0: ${uid0}"; fail=$((fail+1)); fi
    # Check for empty passwords
    local empty; empty=$(awk -F: '$2=="" {print $1}' /etc/shadow 2>/dev/null | head -5)
    if [ -z "$empty" ]; then echo "  [OK] No empty passwords"; pass=$((pass+1))
    else echo "  [FAIL] Empty passwords: ${empty}"; fail=$((fail+1)); fi
    echo ""
    echo "  Passed: ${pass}  Failed: ${fail}"
    tool_audit "verify" "pass=${pass} fail=${fail} node=${NODE_ID}"
    return $fail
}

tool_help() {
    echo "${TOOL_NAME} v${TOOL_VERSION} -- Auth & User Management"
    echo ""
    echo "Status:"
    echo "  --users           List users with shell access"
    echo "  --sessions        Active sessions"
    echo "  --status          JSON pill"
    echo ""
    echo "Audit:"
    echo "  --ssh-harden      SSH hardening audit"
    echo "  --login-history   Login history + failed attempts"
    echo "  --sudo-audit      Sudo usage audit"
    echo "  --hop-guard       Verify hop authentication chain"
    echo "  --verify          Full auth verification"
    echo ""
    echo "Standard: --send|--digest|--flush"
}

do_send()   { tool_wrap "send"   _do_send_impl "$@"; }
do_status() { tool_wrap "status" _do_status_impl "$@"; }
do_digest() { tool_wrap "digest" _do_digest_impl "$@"; }
do_flush()  { tool_wrap "flush"  _do_flush_impl "$@"; }

tool_init; trap 'tool_complete' EXIT
case "${1:---help}" in
    --send) shift; do_send "$@" ;; --status) shift; do_status "$@" ;;
    --digest) shift; do_digest "$@" ;; --flush) shift; do_flush "$@" ;;
    --users) tool_wrap "users" _do_send_impl ;;
    --sessions) tool_wrap "sessions" who ;;
    --ssh-harden) tool_wrap "ssh_harden" _do_ssh_harden_impl ;;
    --login-history) tool_wrap "login_history" _do_login_history_impl ;;
    --sudo-audit) tool_wrap "sudo_audit" _do_sudo_audit_impl ;;
    --hop-guard) tool_wrap "hop_guard" _do_hop_guard_impl ;;
    --verify) tool_wrap "verify" _do_verify_impl ;;
    --help) tool_help ;; *) handle_standard_command "$@" ;;
esac

