travelmate: update 2.0.9-2
[feed/packages.git] / net / travelmate / files / travelmate.vpn
index 94da997a13fb92adedc8c11f19e47698b35d9427..230f5899e66e4ac6a7b4f2668c1965b9e0e7cd07 100755 (executable)
 #!/bin/sh
-# vpn switch for travelmate
-# Copyright (c) 2020 Dirk Brenken (dev@brenken.org)
+# vpn handler called by travelmate
+# Copyright (c) 2020-2022 Dirk Brenken (dev@brenken.org)
 # This is free software, licensed under the GNU General Public License v3.
 
 # set (s)hellcheck exceptions
-# shellcheck disable=1091,2016,2039,2059,2086,2143,2181,2188
+# shellcheck disable=1091,3040,3043
 
 # Please note: you have to setup the package 'wireguard' or 'openvpn' before using this script
 
+. "/lib/functions.sh"
+
 export LC_ALL=C
 export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
 set -o pipefail
 
-if [ "$(uci_get 2>/dev/null; printf "%u" "${?}")" = "127" ]
-then
-       . "/lib/functions.sh"
-fi
-
-vpn_action="${1}"
-trm_vpnservice="$(uci_get travelmate global trm_vpnservice)"
-trm_vpniface="$(uci_get travelmate global trm_vpniface)"
-trm_landevice="$(uci_get travelmate global trm_landevice)"
+vpn="${1}"
+vpn_action="${2}"
+vpn_service="${3}"
+vpn_iface="${4}"
 trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
-trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://captive.apple.com")"
-trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0")"
-trm_iptrule_accept="FORWARD -i ${trm_landevice} -p tcp  --match multiport --dports 80,443 -j ACCEPT"
-trm_iptrule_drop="FORWARD -i ${trm_landevice} -j DROP"
-trm_iptables="$(command -v iptables)"
+trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://detectportal.firefox.com")"
+trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
 trm_logger="$(command -v logger)"
 trm_fetch="$(command -v curl)"
+trm_vpnfile="/var/state/travelmate.vpn"
 
-f_log()
-{
-       local class="${1}" log_msg="${2}"
+f_net() {
+       local json_rc result="net nok"
 
-       if [ -x "${trm_logger}" ]
-       then
-               "${trm_logger}" -p "${class}" -t "trm-vpn  [${$}]" "${log_msg}"
-       else
-               printf "%s %s %s\\n" "${class}" "trm-vpn  [${$}]" "${log_msg}"
-       fi
-}
-
-f_net()
-{
-       local IFS json_raw json_rc result="net nok"
-
-       json_raw="$(${trm_fetch} --user-agent "${trm_useragent}" --referer "http://www.example.com" --write-out "%{json}" --silent --show-error --connect-timeout $((trm_maxwait/10)) "${trm_captiveurl}" 2>/dev/null)"
-       json_raw="${json_raw#*\{}"
-       if [ -n "${json_raw}" ]
-       then
-               json_rc="$(printf "%s" "{${json_raw}" | jsonfilter -l1 -e '@.response_code' 2>/dev/null)"
-               if [ "${json_rc}" = "200" ] || [ "${json_rc}" = "204" ]
-               then
-                       result="net ok"
-               fi
+       json_rc="$(${trm_fetch} --user-agent "${trm_useragent}" --referer "http://www.example.com" --header "Cache-Control: no-cache, no-store, must-revalidate, max-age=0" --write-out "%{response_code}" --silent --output /dev/null --max-time $((trm_maxwait / 6)) "${trm_captiveurl}")"
+       if [ "${json_rc}" = "200" ] || [ "${json_rc}" = "204" ]; then
+               result="net ok"
        fi
        printf "%s" "${result}"
 }
 
-if [ -n "${trm_vpnservice}" ] && [ -n "${trm_vpniface}" ] && [ -n "${trm_landevice}" ] && [ -f "/tmp/trm_runtime.json" ]
-then
-       status="$(jsonfilter -i "/tmp/trm_runtime.json" -l1 -e '@.data.travelmate_status' 2>/dev/null)"
-       vpn_status="$(ubus -S call network.interface."${trm_vpniface}" status 2>/dev/null | jsonfilter -l1 -e '@.up')"
-       if [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]
-       then
-               if [ -n "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_drop} 2>&1)" ] && \
-                       [ -n "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_accept} 2>&1)" ]
-               then
-                       "${trm_iptables}" "-w $((trm_maxwait/6))" -I ${trm_iptrule_drop} 2>&1
-                       f_log "info" "lan forward blocked for device '${trm_landevice}'"
-               fi
+vpn_status="$(ubus -S call network.interface."${vpn_iface}" status 2>/dev/null | jsonfilter -q -l1 -e '@.up')"
+if [ "${vpn}" = "1" ] && [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]; then
+       if [ "${vpn_service}" = "openvpn" ] && [ -x "/etc/init.d/openvpn" ]; then
+               /etc/init.d/openvpn start
        fi
-       if [ "${vpn_action}" = "disable" ] && [ "${status%% (net cp *}" = "connected" ]
-       then
-               if [ -n "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_accept} 2>&1)" ] && \
-                       [ -z "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_drop} 2>&1)" ]
-               then
-                       "${trm_iptables}" "-w $((trm_maxwait/6))" -I ${trm_iptrule_accept} 2>&1
-                       f_log "info" "lan forward on ports 80/443 freed for device '${trm_landevice}'"
-               fi
-       fi
-
-       case "${trm_vpnservice}" in
-               "wireguard")
-                       if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]
-                       then
-                               ubus call network.interface."${trm_vpniface}" up
-                       elif [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]
-                       then
-                               ubus call network.interface."${trm_vpniface}" down
-                               f_log "info" "${trm_vpnservice} client connection disabled"
-                       fi
-               ;;
-               "openvpn")
-                       if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]
-                       then
-                               ubus call network.interface."${trm_vpniface}" up
-                               /etc/init.d/openvpn restart >/dev/null 2>&1
-                       elif [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]
-                       then
-                               ubus call network.interface."${trm_vpniface}" down
-                               /etc/init.d/openvpn stop >/dev/null 2>&1
-                               f_log "info" "${trm_vpnservice} client connection disabled"
+       ifup "${vpn_iface}"
+       cnt=0
+       while true; do
+               vpn_status="$(ubus -S call network.interface."${vpn_iface}" status 2>/dev/null | jsonfilter -q -l1 -e '@.up')"
+               if [ "${vpn_status}" = "true" ]; then
+                       net_status="$(f_net)"
+                       if [ "${net_status}" = "net ok" ]; then
+                               : >"${trm_vpnfile}"
+                               "${trm_logger}" -p "info" -t "trm-vpn  [${$}]" "${vpn_service} client connection enabled" 2>/dev/null
+                               break
                        fi
-               ;;
-       esac
-
-       if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]
-       then
-               cnt=0
-               while true
-               do
-                       vpn_status="$(ubus -S call network.interface."${trm_vpniface}" status 2>/dev/null | jsonfilter -l1 -e '@.up')"
-                       if [ "${vpn_status}" = "true" ]
-                       then
-                               net_status="$(f_net)"
-                               if [ "${net_status}" = "net ok" ]
-                               then
-                                       f_log "info" "${trm_vpnservice} client connection enabled"
-                                       if [ -z "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_drop} 2>&1)" ]
-                                       then
-                                               "${trm_iptables}" "-w $((trm_maxwait/6))" -D ${trm_iptrule_drop} 2>&1
-                                               if [ -z "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_accept} 2>&1)" ]
-                                               then
-                                                       "${trm_iptables}" "-w $((trm_maxwait/6))" -D ${trm_iptrule_accept} 2>&1
-                                               fi
-                                               f_log "info" "lan forward freed for device '${trm_landevice}'"
-                                       fi
-                                       break
-                               fi
-                       fi
-                       if [ "${cnt}" -ge "$((trm_maxwait/6))" ]
-                       then
-                               f_log "info" "${trm_vpnservice} restart failed, lan forward for device '${trm_landevice}' still blocked"
-                               ubus call network.interface."${trm_vpniface}" down
-                               exit 2
+               fi
+               if [ "${cnt}" -ge "$((trm_maxwait / 3))" ]; then
+                       ifdown "${vpn_iface}"
+                       if [ "${vpn_service}" = "openvpn" ] && [ -x "/etc/init.d/openvpn" ]; then
+                               /etc/init.d/openvpn stop
                        fi
-                       sleep 1
-                       cnt="$((cnt+1))"
-               done
-       fi
-       if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" = "true" ]
-       then
-               if [ -f "/etc/init.d/sysntpd" ]
-               then
-                       /etc/init.d/sysntpd restart >/dev/null 2>&1
+                       rm -f "${trm_vpnfile}"
+                       "${trm_logger}" -p "info" -t "trm-vpn  [${$}]" "${vpn_service} client connection can't be established" 2>/dev/null
+                       exit 1
                fi
+               sleep 1
+               cnt="$((cnt + 1))"
+       done
+elif { [ "${vpn}" != "1" ] && [ "${vpn_action}" = "enable" ]; } || [ "${vpn_action}" = "disable" ]; then
+       ifdown "${vpn_iface}"
+       if [ "${vpn_service}" = "openvpn" ] && [ -x "/etc/init.d/openvpn" ]; then
+               /etc/init.d/openvpn stop
        fi
-       exit 0
+       rm -f "${trm_vpnfile}"
+       "${trm_logger}" -p "info" -t "trm-vpn  [${$}]" "${vpn_service} client connection disabled" 2>/dev/null
 fi
-exit 1