177 lines
6.0 KiB
Bash
Executable File
177 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# =============================================================================
|
|
# NetworkManager Captive Portal Auto-Detector
|
|
# =============================================================================
|
|
# Erstellt von Pascal Bouquet am 16.09.2025
|
|
# Aktualisiert am 17.09.2025
|
|
#
|
|
# Dieses Skript ist freie Software: Es kann frei verwendet, bearbeitet und
|
|
# verbreitet werden. Es wird keine Garantie für die Funktionsfähigekeit übernommen.
|
|
# =============================================================================
|
|
|
|
# =============================================================================
|
|
# KONFIGURATION
|
|
# =============================================================================
|
|
LOG_FILE="/var/log/nm-captive.log"
|
|
LOG_LEVEL="INFO" # NONE, DEBUG, INFO, WARNING, ERROR
|
|
CHECK_INTERVAL=300 # 5 Minuten in Sekunden
|
|
MAX_CHECKS=48 # Maximal 4 Stunde lang prüfen (48 * 5min)
|
|
|
|
# Test-URLs für Captive Portal Erkennung
|
|
TEST_URLS=(
|
|
"http://captive.apple.com/hotspot-detect.html"
|
|
"http://connectivitycheck.gstatic.com/generate_204"
|
|
)
|
|
|
|
# =============================================================================
|
|
# FUNKTIONEN
|
|
# =============================================================================
|
|
|
|
log() {
|
|
local level=$1
|
|
local message=$2
|
|
|
|
# Kein Logging wenn LOG_LEVEL=NONE
|
|
if [ "$LOG_LEVEL" = "NONE" ]; then
|
|
return
|
|
fi
|
|
|
|
# Log-Level Filterung
|
|
case $LOG_LEVEL in
|
|
"DEBUG") echo "$(date '+%Y-%m-%d %H:%M:%S') - $level - $message" >> "$LOG_FILE" ;;
|
|
"INFO")
|
|
if [[ "$level" != "DEBUG" ]]; then
|
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $level - $message" >> "$LOG_FILE"
|
|
fi
|
|
;;
|
|
"WARNING")
|
|
if [[ "$level" == "WARNING" || "$level" == "ERROR" ]]; then
|
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $level - $message" >> "$LOG_FILE"
|
|
fi
|
|
;;
|
|
"ERROR")
|
|
if [[ "$level" == "ERROR" ]]; then
|
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $level - $message" >> "$LOG_FILE"
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
check_captive_portal() {
|
|
local captive_detected=false
|
|
|
|
for url in "${TEST_URLS[@]}"; do
|
|
log "DEBUG" "Testing URL: $url"
|
|
|
|
if [[ "$url" == *"apple.com"* ]]; then
|
|
# Apple Check: Erwartet "Success" in der Response
|
|
local response=$(curl -s -L --connect-timeout 5 "$url")
|
|
if [ $? -ne 0 ]; then
|
|
log "DEBUG" "Network error for $url"
|
|
captive_detected=true
|
|
break
|
|
elif ! echo "$response" | grep -qi "success"; then
|
|
log "DEBUG" "Apple check failed - no 'Success' in response"
|
|
captive_detected=true
|
|
break
|
|
fi
|
|
|
|
elif [[ "$url" == *"google"* || "$url" == *"gstatic"* ]]; then
|
|
# Google Check: Erwartet HTTP 204
|
|
local http_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "$url")
|
|
if [ $? -ne 0 ]; then
|
|
log "DEBUG" "Network error for $url"
|
|
captive_detected=true
|
|
break
|
|
elif [ "$http_code" != "204" ]; then
|
|
log "DEBUG" "Google check failed - HTTP $http_code instead of 204"
|
|
captive_detected=true
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [ "$captive_detected" = true ]; then
|
|
log "INFO" "Captive portal detected"
|
|
return 1
|
|
else
|
|
log "INFO" "All connectivity checks passed - no captive portal"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
start_periodic_checks() {
|
|
local interface="$1"
|
|
local user="$2"
|
|
local check_count=0
|
|
|
|
log "INFO" "Starting periodic checks for $interface (every ${CHECK_INTERVAL}s)"
|
|
|
|
while [ $check_count -lt $MAX_CHECKS ]; do
|
|
sleep $CHECK_INTERVAL
|
|
((check_count++))
|
|
|
|
log "DEBUG" "Periodic check $check_count/$MAX_CHECKS for $interface"
|
|
|
|
if ! check_captive_portal; then
|
|
log "INFO" "Captive portal still active - re-opening browser"
|
|
|
|
export DISPLAY=:0
|
|
export XAUTHORITY=/home/$user/.Xauthority
|
|
|
|
# Starte Firefox mit Firefox's eigenem Portal Detect
|
|
sudo -u $user env DISPLAY=:0 XAUTHORITY=/home/$user/.Xauthority \
|
|
firefox --new-window "http://detectportal.firefox.com/canonical.html" &
|
|
log "INFO" "Firefox re-started for user $user"
|
|
else
|
|
log "INFO" "Captive portal resolved - stopping periodic checks"
|
|
break
|
|
fi
|
|
done
|
|
|
|
log "INFO" "Periodic checks completed for $interface"
|
|
}
|
|
|
|
# =============================================================================
|
|
# HAUPTPROGRAMM
|
|
# =============================================================================
|
|
|
|
log "INFO" "=== Dispatch triggered: $1 $2 ==="
|
|
|
|
if [[ "$1" == wl* ]] && [ "$2" = "up" ]; then
|
|
sleep 3
|
|
|
|
if ! check_captive_portal; then
|
|
log "INFO" "CAPTIVE PORTAL DETECTED! Opening browser..."
|
|
|
|
# Finde Benutzer
|
|
local_user=$(w -hs | grep ":0" | awk '{print $1}' | head -n1)
|
|
if [ -n "$local_user" ]; then
|
|
log "INFO" "Found user: $local_user"
|
|
|
|
export DISPLAY=:0
|
|
export XAUTHORITY=/home/$local_user/.Xauthority
|
|
|
|
# Starte Firefox
|
|
sudo -u $local_user env DISPLAY=:0 XAUTHORITY=/home/$local_user/.Xauthority \
|
|
firefox --new-window "http://detectportal.firefox.com/canonical.html" &
|
|
log "INFO" "Firefox started for user $local_user"
|
|
|
|
# Starte periodische Checks im Hintergrund
|
|
start_periodic_checks "$1" "$local_user" &
|
|
else
|
|
log "WARNING" "No local user found for GUI access"
|
|
fi
|
|
else
|
|
log "INFO" "No captive portal detected on connection start"
|
|
fi
|
|
|
|
elif [[ "$1" == wl* ]] && [ "$2" = "down" ]]; then
|
|
log "INFO" "WLAN interface $1 disconnected"
|
|
|
|
fi
|
|
|
|
log "INFO" "=== Completed ==="
|
|
|