#!/bin/sh
# 10-capabilities-audit.sh - Inspects the container bounding set for required privileges.
#
# This script runs early to detect missing capabilities that would cause later
# scripts (like Python-based checks) to fail with "Operation not permitted".

RED=$(printf '\033[1;31m')
YELLOW=$(printf '\033[1;33m')
GREY=$(printf '\033[90m')
RESET=$(printf '\033[0m')

# Parse Bounding Set from /proc/self/status
cap_bnd_hex=$(awk '/CapBnd/ {print $2}' /proc/self/status 2>/dev/null || echo "0")
# Convert hex to dec (POSIX compliant)
cap_bnd_dec=$(awk -v hex="$cap_bnd_hex" 'BEGIN { h = "0x" hex; if (h ~ /^0x[0-9A-Fa-f]+$/) { printf "%d", h } else { print 0 } }')

has_cap() {
    bit=$1
    # Check if bit is set in cap_bnd_dec
    [ $(( (cap_bnd_dec >> bit) & 1 )) -eq 1 ]
}

# 1. ALERT: Python Requirements (NET_RAW=13, NET_ADMIN=12)
if ! has_cap 13 || ! has_cap 12; then
    printf "%s" "${RED}"
    cat <<'EOF'
══════════════════════════════════════════════════════════════════════════════
🚨 ALERT: Python execution capabilities (NET_RAW/NET_ADMIN) are missing.

    The Python binary in this image has file capabilities (+eip) that
    require these bits in the container's bounding set. Without them,
    the binary will fail to execute (Operation not permitted).

    Restart with: --cap-add=NET_RAW --cap-add=NET_ADMIN
══════════════════════════════════════════════════════════════════════════════
EOF
    printf "%s" "${RESET}"
fi

# 2. WARNING: NET_BIND_SERVICE (10)
if ! has_cap 10; then
    printf "%s" "${YELLOW}"
    cat <<'EOF'
══════════════════════════════════════════════════════════════════════════════
⚠️  WARNING: Reduced functionality (NET_BIND_SERVICE missing).

    Tools like nbtscan cannot bind to privileged ports (UDP 137).
    This will reduce discovery accuracy for legacy devices.

    Consider adding: --cap-add=NET_BIND_SERVICE
══════════════════════════════════════════════════════════════════════════════
EOF
    printf "%s" "${RESET}"
fi

# 3. NOTE: Security Context (CHOWN=0, SETGID=6, SETUID=7)
missing_admin=""
has_cap 0 || missing_admin="${missing_admin} CHOWN"
has_cap 6 || missing_admin="${missing_admin} SETGID"
has_cap 7 || missing_admin="${missing_admin} SETUID"

if [ -n "${missing_admin}" ]; then
    printf "%sSecurity context: Operational capabilities (%s) not granted.%s\n" "${GREY}" "${missing_admin# }" "${RESET}"
    if echo "${missing_admin}" | grep -q "CHOWN"; then
        printf "%sSee https://github.com/jokob-sk/NetAlertX/blob/main/docs/docker-troubleshooting/missing-capabilities.md%s\n" "${GREY}" "${RESET}"
    fi
fi

exit 0
