travelmate: bump version

This commit is contained in:
coolsnowwolf 2024-07-01 12:46:16 +08:00
parent 2a83a6112e
commit 15bad1bd56
19 changed files with 1320 additions and 1144 deletions

View File

@ -1,13 +1,13 @@
#
# Copyright (c) 2016-2021 Dirk Brenken (dev@brenken.org)
# Copyright (c) 2016-2024 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=travelmate
PKG_VERSION:=2.0.3
PKG_RELEASE:=1
PKG_VERSION:=2.1.2
PKG_RELEASE:=6
PKG_LICENSE:=GPL-3.0-or-later
PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
@ -17,7 +17,7 @@ define Package/travelmate
SECTION:=net
CATEGORY:=Network
TITLE:=A wlan connection manager for travel router
DEPENDS:=+iwinfo +jshn +jsonfilter +curl +ca-bundle
DEPENDS:=+iwinfo +jshn +jsonfilter +curl +ca-bundle +rpcd +rpcd-mod-rpcsys
PKGARCH:=all
endef

View File

@ -32,7 +32,7 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
* status & debug logging to syslog
## Prerequisites
* [OpenWrt](https://openwrt.org), only compatible with the forthcoming stable 20.x or the latest OpenWrt snapshot
* [OpenWrt](https://openwrt.org), tested/compatible with current stable 23.x and latest OpenWrt snapshot
* 'dnsmasq' as dns backend
* 'iwinfo' for wlan scanning
* 'curl' for connection checking and all kinds of captive portal magic, e.g. cp detection and auto-logins
@ -43,9 +43,8 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
## Installation & Usage
* **Please note:** before you start with travelmate ...
* you should setup at least one Access Point, ideally on a separate radio,
* if you're updating from a former 1.x release, please use the '--force-reinstall --force-maintainer' options in opkg,
* and remove any existing travelmate related uplink stations in your wireless config manually
* setup at least one AP, ideally on a separate radio
* if you're using a single radio unit set the AP channel to 'auto'
* download [travelmate](https://downloads.openwrt.org/snapshots/packages/x86_64/packages)
* download [luci-app-travelmate](https://downloads.openwrt.org/snapshots/packages/x86_64/luci)
* install both packages (_opkg install travelmate_, _opkg install luci-app-travelmate_)
@ -73,19 +72,18 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
| trm_minquality | 35 | minimum signal quality threshold as percent for conditional uplink (dis-) connections |
| trm_maxwait | 30 | how long should travelmate wait for a successful wlan uplink connection |
| trm_timeout | 60 | overall retry timeout in seconds |
| trm_scanbuffer | 1024 | buffer size in bytes to prepare nearby scan results |
| trm_captiveurl | http://captive.apple.com | four pre-configured provider URLs that will be used for connectivity- and captive portal checks |
| trm_useragent | Mozilla/5.0 (X11; Linux x86_64... | five pre-configured user agents that will be used for connectivity- and captive portal checks |
| trm_maxautoadd | 5 | limit the max. number of automatically added open uplinks. To disable this limitation set it to '0' |
| trm_captiveurl | http://detectportal.firefox.com | pre-configured provider URLs that will be used for connectivity- and captive portal checks |
| trm_useragent | Mozilla/5.0 ... | pre-configured user agents that will be used for connectivity- and captive portal checks |
| trm_nice | 0, normal priority | change the priority of the travelmate background processing |
| trm_vpn | 0, disabled | automatically handle VPN (re-) connections |
| trm_vpnservice | -, not set | reference the already configured 'wireguard' or 'openvpn' client instance as vpn provider |
| trm_vpniface | -, not set | the logical vpn interface, e.g. 'wg0' or 'tun0' |
| trm_laniface | -, not set | the logical lan network interface, e.g. 'br-lan' |
| trm_mail | 0, disabled | sends notification e-mails after every succesful uplink connect |
| trm_mailreceiver | -, not set | e-mail receiver address for travelmate notifications |
| trm_mailsender | no-reply@travelmate | e-mail sender address for travelmate notifications |
| trm_mailtopic | travelmate connection to '<sta>' | topic for travelmate notification E-Mails |
| trm_mailprofile | trm_notify | profile used by 'msmtp' for travelmate notification E-Mails |
| trm_stdvpnservice | -, not set | standard vpn service which will be automatically added to new STA profiles |
| trm_stdvpniface | -, not set | standard vpn interface which will be automatically added to new STA profiles |
* per uplink exist an additional 'uplink' section in the travelmate config, with the following options:
@ -101,15 +99,25 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
| con_end_expiry | 0, disabled | automatically (re-)enable the uplink after n minutes, e.g. after failed login attempts |
| script | -, not set | reference to an external auto login script for captive portals |
| script_args | -, not set | optional runtime args for the auto login script |
| macaddr | -, not set | use a specified MAC address for the uplink
| vpn | 0, disabled | automatically handle VPN (re-) connections |
| vpnservice | -, not set | reference the already configured 'wireguard' or 'openvpn' client instance as vpn provider |
| vpniface | -, not set | the logical vpn interface, e.g. 'wg0' or 'tun0' |
## VPN client setup
Please follow one of the following guides to get a working vpn client setup on your travel router:
Please read one of the following guides to get a working vpn client setup on your travel router:
* [Wireguard client setup guide](https://openwrt.org/docs/guide-user/services/vpn/wireguard/client)
* [OpenVPN client setup guide](https://openwrt.org/docs/guide-user/services/vpn/openvpn/client)
* [OpenVPN client setup guide](https://openwrt.org/docs/guide-user/services/vpn/openvpn/client-luci)
Once your vpn client connection is running, you can reference to that setup in travelmate to handle VPN (re-) connections automatically.
**Please note:** Make sure to uncheck the "Bring up on boot" option during vpn interface setup, so that netifd doesn't interfere with travelmate.
Also please prevent potential vpn protocol autostarts, e.g. add in newer openvpn uci configs an additional 'globals' section:
<pre><code>
config globals 'globals'
option autostart '0'
</code></pre>
Once your vpn client connection setup is correct, you can reference to that config in travelmate to handle VPN (re-) connections automatically.
## E-Mail setup
To use E-Mail notifications you have to setup the package 'msmtp'.
@ -135,11 +143,14 @@ password zzz
Finally enable E-Mail support in travelmate and add a valid E-Mail receiver address.
## Captive Portal auto-logins
For automated captive portal logins you can reference an external shell script per uplink. All login scripts should be executable and located in '/etc/travelmate' with the extension '.login'. Currently the package ships five ready to run auto-login scripts:
* 'wifionice.login' for german ICE hotspots
For automated captive portal logins you can reference an external shell script per uplink. All login scripts should be executable and located in '/etc/travelmate' with the extension '.login'. The package ships multiple ready to run auto-login scripts:
* 'wifionice.login' for ICE hotspots (DE)
* 'db-bahn.login' for german DB railway hotspots via portal login API (still WIP, only tested at Hannover central station)
* 'chs-hotel.login' for german chs hotels
* 'h-hotels.login' for Telekom hotspots in german h+hotels
* 'h-hotels.login' for Telekom hotspots in h+hotels (DE)
* 'julianahoeve.login' for Julianahoeve beach resort (NL)
* 'telekom.login' for telekom hotspots (DE)
* 'vodafone.login' for vodafone hotspots (DE)
* 'generic-user-pass.login' a template to demonstrate the optional parameter handling in login scripts
A typical and successful captive portal login looks like this:
@ -157,18 +168,18 @@ Hopefully more scripts for different captive portals will be provided by the com
**receive travelmate runtime information:**
<pre><code>
root@2go_ar750s:~# /etc/init.d/travelmate status
root@2go:~# /etc/init.d/travelmate status
::: travelmate runtime information
+ travelmate_status : connected (net ok/100)
+ travelmate_version : 2.0.0
+ station_id : radio1/WIFIonICE/-
+ station_mac : B2:9D:F5:96:86:A4
+ station_interface : trm_wwan
+ travelmate_status : connected (net ok/51)
+ travelmate_version : 2.1.1
+ station_id : radio0/403 Forbidden/00:0C:46:24:50:00
+ station_mac : 94:83:C4:24:0E:4F
+ station_interfaces : trm_wwan, wg0
+ wpa_flags : sae: ✔, owe: ✔, eap: ✔, suiteb192: ✔
+ run_flags : captive: ✔, proactive: ✔, netcheck: ✘, autoadd: ✘, randomize: ✔
+ ext_hooks : ntp: ✔, vpn: , mail: ✘
+ last_run : 2020.09.10-15:21:19
+ system : GL.iNet GL-AR750S (NOR/NAND), OpenWrt SNAPSHOT r14430-2dda301d40
+ ext_hooks : ntp: ✔, vpn: , mail: ✘
+ last_run : 2023.10.21-14:29:14
+ system : GL.iNet GL-A1300, OpenWrt SNAPSHOT r24187-bb8fd41f9a
</code></pre>
To debug travelmate runtime problems, please always enable the 'trm\_debug' flag, restart travelmate and check the system log afterwards (_logread -e "trm-"_)
@ -178,7 +189,7 @@ Please join the travelmate discussion in this [forum thread](https://forum.lede-
## Removal
* stop the travelmate daemon with _/etc/init.d/travelmate stop_
* optional: remove the travelmate package (_opkg remove luci-app-travelmate_, _opkg remove travelmate_)
* remove the travelmate package (_opkg remove luci-app-travelmate_, _opkg remove travelmate_)
Have fun!
Dirk

View File

@ -1,43 +1,31 @@
#!/bin/sh
# captive portal auto-login script for german chs hotels
# Copyright (c) 2020 Dirk Brenken (dev@brenken.org)
# captive portal auto-login script for chs hotels (DE)
# 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,2181,3040
. "/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
trm_domain="hotspot.internet-for-guests.com"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0")"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl)"
# initial get request to receive & extract valid security tokens
# get security tokens
#
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --silent --connect-timeout $((trm_maxwait/6)) --cookie-jar "/tmp/${trm_domain}.cookie" --output /dev/null "https://${trm_domain}/logon/cgi/index.cgi"
if [ -r "/tmp/${trm_domain}.cookie" ]
then
lg_id="$(awk '/LGNSID/{print $7}' "/tmp/${trm_domain}.cookie")"
ta_id="$(awk '/ta_id/{print $7}' "/tmp/${trm_domain}.cookie")"
cl_id="$(awk '/cl_id/{print $7}' "/tmp/${trm_domain}.cookie")"
rm -f "/tmp/${trm_domain}.cookie"
else
exit 2
fi
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --silent --connect-timeout $((trm_maxwait / 6)) --cookie-jar "/tmp/${trm_domain}.cookie" --output /dev/null "https://${trm_domain}/logon/cgi/index.cgi"
lg_id="$(awk '/LGNSID/{print $7}' "/tmp/${trm_domain}.cookie" 2>/dev/null)"
ta_id="$(awk '/ta_id/{print $7}' "/tmp/${trm_domain}.cookie" 2>/dev/null)"
cl_id="$(awk '/cl_id/{print $7}' "/tmp/${trm_domain}.cookie" 2>/dev/null)"
rm -f "/tmp/${trm_domain}.cookie"
{ [ -z "${lg_id}" ] || [ -z "${ta_id}" ] || [ -z "${cl_id}" ]; } && exit 1
# final post request/login with valid session cookie/security token
# final login request
#
if [ -n "${lg_id}" ] && [ -n "${ta_id}" ] && [ -n "${cl_id}" ]
then
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "https://${trm_domain}/logon/cgi/index.cgi" --silent --connect-timeout $((trm_maxwait/6)) --header "Cookie: LGNSID=${lg_id}; lang=en_US; use_mobile_interface=0; ta_id=${ta_id}; cl_id=${cl_id}" --data "accept_termsofuse=&freeperperiod=1&device_infos=1125:2048:1152:2048" --output /dev/null "https://${trm_domain}/logon/cgi/index.cgi"
else
exit 3
fi
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "https://${trm_domain}/logon/cgi/index.cgi" --silent --connect-timeout $((trm_maxwait / 6)) --header "Cookie: LGNSID=${lg_id}; lang=en_US; use_mobile_interface=0; ta_id=${ta_id}; cl_id=${cl_id}" --data "accept_termsofuse=&freeperperiod=1&device_infos=1125:2048:1152:2048" --output /dev/null "https://${trm_domain}/logon/cgi/index.cgi"
[ "${?}" = "0" ] && exit 0 || exit 255

View File

@ -1,65 +0,0 @@
#!/bin/sh
# captive portal auto-login script for german DB hotspots via portal login API
# Copyright (c) 2020 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
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
trm_domain="wifi.bahn.de"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl)"
# initial get request to receive all header information
#
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --silent --connect-timeout $((trm_maxwait/6)) --include --cookie-jar "/tmp/${trm_domain}.cookie" --output /dev/null "http://${trm_domain}"
# extract the session cookie and the hotspot location
#
if [ -s "/tmp/${trm_domain}.cookie" ]
then
sec_token="$(awk 'BEGIN{FS="[ ;]"}/^Set-Cookie:/{print $2}' "/tmp/${trm_domain}.cookie")"
location="$(awk '/^Location:/{print $2}' "/tmp/${trm_domain}.cookie")"
rm -f "/tmp/${trm_domain}.cookie"
else
exit 2
fi
# post request to subscribe to the portal API
#
if [ -n "${sec_token}" ] && [ -n "${location}" ]
then
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "${location}" --silent --connect-timeout $((trm_maxwait/6)) --include --cookie-jar "/tmp/${trm_domain}.cookie" --header "Cookie: ${sec_token}" --data "action=subscribe&type=one&connect_policy_accept=false&user_login=&user_password=&user_password_confirm=&email_address=&prefix=&phone=&policy_accept=false&gender=&interests=" --output /dev/null "https://${trm_domain}/portal_api.php"
else
exit 3
fi
# extract additional login and password information from the portal API
#
if [ -s "/tmp/${trm_domain}.cookie" ]
then
login="$(awk 'BEGIN{FS="[\"]"}/^\{\"info/{print $12}' "/tmp/${trm_domain}.cookie")"
password="$(awk 'BEGIN{FS="[\"]"}/^\{\"info/{print $16}' "/tmp/${trm_domain}.cookie")"
rm -f "/tmp/${trm_domain}.cookie"
else
exit 4
fi
# final post request to authenticate to the portal API
#
if [ -n "${login}" ] && [ -n "${password}" ]
then
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "${location}" --silent --connect-timeout $((trm_maxwait/6)) --header "Cookie: ${sec_token}" --data "action=authenticate&login=${login}&password=${password}&policy_accept=false&from_ajax=true&wispr_mode=false" "https://${trm_domain}/portal_api.php"
else
exit 5
fi

View File

@ -1,35 +1,25 @@
#!/bin/sh
# captive portal auto-login script template with credentials as parameters
# Copyright (c) 2020 Dirk Brenken (dev@brenken.org)
# 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,2039,3040
. "/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
trm_domain="example.com"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl)"
user="${1}"
password="${2}"
success="Thank you!"
trm_domain="example.com"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl)"
# login with credentials
#
response="$("${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --silent --connect-timeout $((trm_maxwait/6)) --data "username=${user}&password=${password}" --header "Content-Type:application/x-www-form-urlencoded" "http://${trm_domain}")"
if [ -n "$(printf "%s" "${response}" | grep "${success}")" ]
then
exit 0
else
exit 2
fi
raw_html="$("${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --connect-timeout $((trm_maxwait / 6)) --silent --show-error --header "Content-Type:application/x-www-form-urlencoded" --data "username=${user}&password=${password}" "http://${trm_domain}")"
[ -z "${raw_html##*${success}*}" ] && exit 0 || exit 255

View File

@ -1,43 +1,39 @@
#!/bin/sh
# captive portal auto-login script for Telekom hotspots in german h+hotels
# Copyright (c) 2020 Dirk Brenken (dev@brenken.org)
# captive portal auto-login script for hotspots in h+hotels (DE)
# Copyright (c) 2020-2024 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=all
. "/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"
trm_domain="hotspot.netcontrol365.com"
if ! nslookup "${trm_domain}" >/dev/null 2>&1; then
trm_domain="hotspot.t-mobile.net"
if ! nslookup "${trm_domain}" >/dev/null 2>&1; then
exit 1
fi
fi
trm_domain="hotspot.t-mobile.net"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0")"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl)"
# initial get request to receive & extract valid security tokens
#
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --silent --connect-timeout $((trm_maxwait/6)) --cookie-jar "/tmp/${trm_domain}.cookie" --output /dev/null "https://${trm_domain}/wlan/rest/freeLogin"
if [ -r "/tmp/${trm_domain}.cookie" ]
then
ses_id="$(awk '/JSESSIONID/{print $7}' "/tmp/${trm_domain}.cookie")"
sec_id="$(awk '/DT_H/{print $7}' "/tmp/${trm_domain}.cookie")"
dev_id="$(sha256sum /etc/config/wireless | awk '{printf "%s",substr($1,1,13)}')"
if [ "${trm_domain}" = "hotspot.netcontrol365.com" ]; then
raw_html="$("${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --connect-timeout $((trm_maxwait / 6)) --silent --show-error --header "Content-Type:application/x-www-form-urlencoded" --data "dst=&popup=false&username=hhotel&accept=on&login=" --output /dev/null "http://${trm_domain}/login")"
[ -z "${raw_html}" ] && exit 0 || exit 255
else
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --silent --connect-timeout $((trm_maxwait / 6)) --cookie-jar "/tmp/${trm_domain}.cookie" --output /dev/null "https://${trm_domain}/wlan/rest/freeLogin"
ses_id="$(awk '/JSESSIONID/{print $7}' "/tmp/${trm_domain}.cookie" 2>/dev/null)"
sec_id="$(awk '/DT_H/{print $7}' "/tmp/${trm_domain}.cookie" 2>/dev/null)"
dev_id="$(sha256sum /etc/config/wireless 2>/dev/null | awk '{printf "%s",substr($1,1,13)}' 2>/dev/null)"
rm -f "/tmp/${trm_domain}.cookie"
else
exit 2
fi
{ [ -z "${ses_id}" ] || [ -z "${sec_id}" ] || [ -z "${dev_id}" ]; } && exit 2
# final post request/login with valid session cookie/security token
#
if [ -n "${ses_id}" ] && [ -n "${sec_id}" ] && [ -n "${dev_id}" ]
then
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "https://${trm_domain}/TD/hotspot/H_Hotels/en_GB/index.html" --silent --connect-timeout $((trm_maxwait/6)) --header "Cookie: JSESSIONID=${ses_id}; DT_DEV_ID=${dev_id}; DT_H=${sec_id}" --data "rememberMe=true" --output /dev/null "https://${trm_domain}/wlan/rest/freeLogin"
else
exit 3
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "https://${trm_domain}/TD/hotspot/H_Hotels/en_GB/index.html" --silent --connect-timeout $((trm_maxwait / 6)) --header "Cookie: JSESSIONID=${ses_id}; DT_DEV_ID=${dev_id}; DT_H=${sec_id}" --data "rememberMe=true" --output /dev/null "https://${trm_domain}/wlan/rest/freeLogin"
[ "${?}" = "0" ] && exit 0 || exit 255
fi

View File

@ -0,0 +1,77 @@
#!/bin/sh
# captive portal auto-login script for H-Reward Hotelss
# This is free software, licensed under the GNU General Public License v3.
# set (s)hellcheck exceptions
# shellcheck disable=1091,2039,3040
#
#
# Username and password can be passed to the script, to get fast wifi
# If not provided, the option with the slower wifi will be selected
. "/lib/functions.sh"
export LC_ALL=C
export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
# From https://stackoverflow.com/a/17336953/819367 converted to sh
rawurlencode() {
string="$1"
strlen=${#string}
encoded=""
pos=0
c=""
o=""
while [ $pos -lt $strlen ]; do
c=$(expr substr "$string" $((pos + 1)) 1)
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) o=$(printf '%%%02x' "'$c")
esac
encoded="${encoded}${o}"
pos=$((pos + 1))
done
echo "${encoded}"
}
user=$(rawurlencode "${1}")
password=$(rawurlencode "${2}")
successUrl="https://hrewards.com/en"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
set -e
session_key="$(curl -sL --user-agent "${trm_useragent}" \
--connect-timeout $((trm_maxwait / 6)) \
"http://nossl.com/?cmd=redirect&arubalp=12345" \
| awk -F 'name="session_key" value="' 'NF>1{split($2,a,"\""); print a[1]; exit}')"
if [ -n "$user" ] && [ -n "$password" ]; then
response="$(curl -sL --user-agent "${trm_useragent}" \
--connect-timeout $((trm_maxwait / 6)) \
-w %{url_effective} \
-o /dev/null \
--header "Content-Type:application/x-www-form-urlencoded" \
--data "session_key=${session_key}&accept_terms=1&email=${user}&password=${password}&password_reset_form_email=&password_update_form_password=&password_update_form_password_repeat=&room_number=&last_name=&voucher=" \
"https://cp.deutschehospitality.com/aruba/login?lang=en")"
else
response="$(curl -sL --user-agent "${trm_useragent}" \
--connect-timeout $((trm_maxwait / 6)) \
-w %{url_effective} \
-o /dev/null \
--header "Content-Type:application/x-www-form-urlencoded" \
--data "session_key=${session_key}&email=&password=&accept_terms=1&password_reset_form_email=&password_update_form_password=&password_update_form_password_repeat=&room_number=&last_name=&voucher=" \
"https://cp.deutschehospitality.com/aruba/skip-registration?lang=en")"
fi
if [ "$response" != "$successUrl" ]; then
exit 255
fi

View File

@ -0,0 +1,35 @@
#!/bin/sh
# captive portal auto-login script for Julianahoeve beach resort (NL)
# Copyright (c) 2021-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,2039,2181,3040
. "/lib/functions.sh"
export LC_ALL=C
export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
trm_domain="n23.network-auth.com"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://detectportal.firefox.com")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl)"
# get redirect url
#
redirect_url="$(${trm_fetch} --user-agent "${trm_useragent}" --referer "http://www.example.com" --connect-timeout $((trm_maxwait / 6)) --write-out "%{redirect_url}" --silent --show-error --output /dev/null "${trm_captiveurl}")"
[ -z "${redirect_url}" ] && exit 1
# get session cookie
#
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://${trm_domain}" --silent --connect-timeout $((trm_maxwait / 6)) --cookie-jar "/tmp/${trm_domain}.cookie" --output /dev/null "${redirect_url}"
session_id="$(awk '/p_splash_session/{print $7}' "/tmp/${trm_domain}.cookie" 2>/dev/null)"
rm -f "/tmp/${trm_domain}.cookie"
[ -z "${session_id}" ] && exit 2
# final login request
#
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "${redirect_url}" --silent --connect-timeout $((trm_maxwait / 6)) --header "Cookie: p_splash_session=${session_id};" --output /dev/null "https://${trm_domain}/Camping-Julianah/hi/IHYW9cx/grant"
[ "${?}" = "0" ] && exit 0 || exit 255

View File

@ -0,0 +1,55 @@
#!/bin/sh
# captive portal auto-login script for telekom hotspots (DE)
# Copyright (c) 2021-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,3040,3043,3057
. "/lib/functions.sh"
# url encoding function
#
urlencode()
{
local chr str="${1}" len="${#1}" pos=0
while [ "${pos}" -lt "${len}" ]; do
chr="${str:pos:1}"
case "${chr}" in
[a-zA-Z0-9.~_-])
printf "%s" "${chr}"
;;
" ")
printf "%%20"
;;
*)
printf "%%%02X" "'${chr}"
;;
esac
pos=$((pos + 1))
done
}
export LC_ALL=C
export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
username="$(urlencode "${1}")"
password="$(urlencode "${2}")"
trm_domain="telekom.portal.fon.com"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://detectportal.firefox.com")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl)"
# get redirect url
#
raw_html="$(${trm_fetch} --user-agent "${trm_useragent}" --referer "http://www.example.com" --connect-timeout $((trm_maxwait / 6)) --location --silent --show-error "${trm_captiveurl}")"
redirect_url="$(printf "%s" "${raw_html}" | awk 'match(tolower($0),/<loginurl>.*<\/loginurl>/){printf "%s",substr($0,RSTART+10,RLENGTH-21)}' 2>/dev/null | awk '{gsub("&amp;","\\&");printf "%s",$0}' 2>/dev/null)"
[ -z "${redirect_url}" ] && exit 1
# final login request
#
raw_html="$("${trm_fetch}" --user-agent "${trm_useragent}" --referer "https://${trm_domain}" --connect-timeout $((trm_maxwait / 6)) --header "content-type: application/x-www-form-urlencoded" --location --silent --show-error --data "UserName=${username}&Password=${password}&FNAME=0&button=Login&OriginatingServer=http%3A%2F%2F${trm_captiveurl}" "${redirect_url}")"
login_url="$(printf "%s" "${raw_html}" | awk 'match(tolower($0),/<logoffurl>.*<\/logoffurl>/){printf "%s",substr($0,RSTART+11,RLENGTH-23)}' 2>/dev/null)"
[ -n "${login_url}" ] && exit 0 || exit 255

View File

@ -0,0 +1,126 @@
#!/bin/sh
# captive portal auto-login script for TP-Link Omada (authType=0 only)
# Copyright (c) 2022 Sebastian Muszynski <basti@linkt.de>
# This is free software, licensed under the GNU General Public License v3
# set (s)hellcheck exceptions
# shellcheck disable=1091,2181,3037,3043,3057
. "/lib/functions.sh"
. "/usr/share/libubox/jshn.sh"
urlencode()
{
local chr str="${1}" len="${#1}" pos=0
while [ "${pos}" -lt "${len}" ]; do
chr="${str:pos:1}"
case "${chr}" in
[a-zA-Z0-9.~_-])
printf "%s" "${chr}"
;;
" ")
printf "%%20"
;;
*)
printf "%%%02X" "'${chr}"
;;
esac
pos=$((pos + 1))
done
}
urldecode()
{
echo -e "$(sed 's/+/ /g;s/%\(..\)/\\x\1/g;')"
}
request_parameter()
{
grep -oE "$1=[^&]+" | cut -d= -f2
}
export LC_ALL=C
export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://detectportal.firefox.com")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl) --connect-timeout $((trm_maxwait / 6)) --silent"
raw_html="$(${trm_fetch} --show-error "${trm_captiveurl}")"
if [ $? -ne 0 ];
then
echo "The captive portal didn't respond"
exit 1
fi
if [ "$raw_html" = "success" ];
then
echo "Internet access already available"
exit 0
fi
redirect_url=$(echo "$raw_html" | grep -oE 'location.href="[^\"]+"' | cut -d\" -f2)
portal_baseurl=$(echo "$redirect_url" | cut -d/ -f1-4)
client_mac=$(echo "$redirect_url" | request_parameter cid)
ap_mac=$(echo "$redirect_url" | request_parameter ap)
ssid=$(echo "$redirect_url" | request_parameter ssid | urldecode)
radio_id=$(echo "$redirect_url" | request_parameter rid)
url=$(echo "$redirect_url" | request_parameter u | urldecode)
${trm_fetch} "${portal_baseurl}/pubKey" | jsonfilter -e '@.result.key' > /tmp/trm-omada-pub.key
if [ $? -ne 0 ];
then
exit 2
fi
json_init
json_add_string "clientMac" "$client_mac"
json_add_string "apMac" "$ap_mac"
json_add_string "ssidName" "$ssid"
json_add_int "radioId" "$radio_id"
json_add_string "originUrl" "$url"
json_close_object
incomplete_auth_request="$(json_dump)"
auth_type=$(${trm_fetch} "${portal_baseurl}/getPortalPageSetting" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'X-Requested-With: XMLHttpRequest' \
--data-raw "$incomplete_auth_request" | jsonfilter -e '@.result.authType')
if [ "$auth_type" -ne 0 ];
then
echo "Unsupported auth type: $auth_type"
exit 3
fi
aes_key=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c 16)
aes_key_hex=$(printf "%s" "$aes_key" | hexdump -e '16/1 "%02x"')
aes_vi=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c 16)
aes_vi_hex=$(printf "%s" "$aes_vi" | hexdump -e '16/1 "%02x"')
rsa_encrypted_aes_secrets=$(printf "%s" "${aes_key}${aes_vi}" | openssl rsautl -encrypt -pubin -inkey /tmp/trm-omada-pub.key | base64 -w 0)
rsa_encrypted_aes_secrets_urlencoded=$(urlencode "$rsa_encrypted_aes_secrets")
json_load "$incomplete_auth_request"
json_add_int "authType" "$auth_type"
json_close_object
auth_request="$(json_dump)"
aes_encrypted_auth_request="$(echo "$auth_request" | openssl enc -aes-128-cbc -K "$aes_key_hex" -iv "$aes_vi_hex" -a -A)"
auth_response=$(${trm_fetch} "${portal_baseurl}/auth?key=$rsa_encrypted_aes_secrets_urlencoded" \
-H 'Content-Type: text/plain' \
-H 'X-Requested-With: XMLHttpRequest' \
--data-raw "$aes_encrypted_auth_request" \
--insecure)
if echo "$auth_response" | grep -q '{"errorCode":0}';
then
exit 0
fi
exit 255

View File

@ -6,5 +6,4 @@ config travelmate 'global'
option trm_netcheck '0'
option trm_autoadd '0'
option trm_mail '0'
option trm_vpn '0'
option trm_debug '0'

View File

@ -1,32 +1,34 @@
#!/bin/sh /etc/rc.common
# Copyright (c) 2016-2024 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,2034,2039,2059,2086,2143,2181,2188
# shellcheck disable=all
START=25
USE_PROCD=1
EXTRA_COMMANDS="scan setup"
EXTRA_HELP=" scan <radio> Scan for available nearby uplinks
setup [<iface>] [<zone>] [<metric>] Setup the travelmate uplink interface, by default 'trm_wwan' with firewall zone 'wan' and metric '100'"
extra_command "scan" "[<radio>|<ifname>] Scan for available nearby uplinks"
extra_command "assoc" "[<radio>|<ifname>] Get MAC adresses of associated wlan stations"
extra_command "setup" "[<iface>] [<zone>] [<metric>] Setup the travelmate uplink interface, by default 'trm_wwan' with firewall zone 'wan' and metric '100'"
trm_init="/etc/init.d/travelmate"
trm_script="/usr/bin/travelmate.sh"
trm_pidfile="/var/run/travelmate.pid"
trm_scanfile="/var/run/travelmate.scan"
boot()
{
if [ -s "${trm_pidfile}" ]
then
> "${trm_pidfile}"
boot() {
if [ -s "${trm_pidfile}" ]; then
: >"${trm_pidfile}"
fi
rc_procd start_service
}
start_service()
{
if [ "$("${trm_init}" enabled; printf "%u" ${?})" = "0" ]
then
start_service() {
if "${trm_init}" enabled; then
if [ "${action}" = "boot" ]; then
return 0
fi
procd_open_instance "travelmate"
procd_set_param command "${trm_script}" "${@}"
procd_set_param pidfile "${trm_pidfile}"
@ -37,44 +39,35 @@ start_service()
fi
}
reload_service()
{
reload_service() {
local ppid pid timeout
timeout="$(uci_get travelmate global trm_timeout)"
if [ -s "${trm_pidfile}" ]
then
if [ -s "${trm_pidfile}" ]; then
ppid="$(cat "${trm_pidfile}" 2>/dev/null)"
if [ -n "${ppid}" ]
then
if [ -n "${ppid}" ]; then
pid="$(pgrep -xnf "sleep ${timeout:-60} 0" -P ${ppid} 2>/dev/null)"
if [ -n "${pid}" ]
then
if [ -n "${pid}" ]; then
kill -INT ${pid} 2>/dev/null
fi
fi
fi
}
stop_service()
{
stop_service() {
rc_procd "${trm_script}" stop
}
status_service()
{
status_service() {
local key keylist value rtfile
rtfile="$(uci_get travelmate global trm_rtfile "/tmp/trm_runtime.json")"
json_load_file "${rtfile}" >/dev/null 2>&1
json_select data >/dev/null 2>&1
if [ "${?}" = "0" ]
then
if json_select data >/dev/null 2>&1; then
printf "%s\n" "::: travelmate runtime information"
json_get_keys keylist
for key in ${keylist}
do
for key in ${keylist}; do
json_get_var value "${key}"
printf " + %-18s : %s\n" "${key}" "${value}"
done
@ -83,30 +76,30 @@ status_service()
fi
}
scan()
{
local result scan_dev radio="${1:-"radio0"}"
scan() {
local result radio="${1}"
scan_dev="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -l1 -e "@.${radio}.interfaces[0].ifname")"
result="$(iwinfo "${scan_dev:-${radio}}" scan 2>/dev/null | \
: > "${trm_scanfile}"
if [ -z "${radio}" ]; then
radio="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -q -l1 -e '@[@.up=true].interfaces[0].ifname')"
fi
result="$(iwinfo "${radio}" scan 2>/dev/null |
awk 'BEGIN{FS="[[:space:]]"}/Address:/{var1=$NF}/ESSID:/{var2="";
for(i=12;i<=NF;i++)if(var2==""){var2=$i}else{var2=var2" "$i}}/Channel:/{var3=$NF}/Quality:/{split($NF,var0,"/")}/Encryption:/{var4="";
for(j=12;j<=NF;j++)if(var4==""){var4=$j}else{var4=var4" "$j};printf " %-11i%-10s%-35s%-20s%s\n",(var0[1]*100/var0[2]),var3,var2,var1,var4}' | \
for(j=12;j<=NF;j++)if(var4==""){var4=$j}else{var4=var4" "$j};printf " %-11i%-10s%-35s%-20s%s\n",(var0[1]*100/var0[2]),var3,var2,var1,var4}' |
sort -rn)"
printf "%s\\n" "::: Available nearby uplinks on '${scan_dev:-${radio}}'"
printf "%s\\n" ":::"
if [ -n "${result}" ]
then
printf "%-15s%-10s%-35s%-20s%s\\n" " Strength" "Channel" "ESSID" "BSSID" "Encryption"
printf "%s\\n" " --------------------------------------------------------------------------------------"
printf "%s\\n" "${result}"
printf "::: %s\n:::\n" "Available nearby uplinks on '${radio}'"
if [ -n "${result}" ]; then
printf "%s\n" "${result}" > "${trm_scanfile}"
printf "%-15s%-10s%-35s%-20s%s\n" " Strength" "Channel" "ESSID" "BSSID" "Encryption"
printf "%s\n" " --------------------------------------------------------------------------------------"
printf "%s\n" "${result}"
else
printf "%s\\n" "::: No scan results"
printf "%s\n" "::: Empty resultset"
fi
}
setup()
{
setup() {
local iface cnt=0 input="${1:-"trm_wwan"}" zone="${2:-"wan"}" metric="${3:-"100"}"
iface="$(uci_get travelmate global trm_iface)"
@ -114,13 +107,10 @@ setup()
zone="${zone//[+*~%&\$@\"\' ]/}"
metric="${metric//[^0-9]/}"
if [ -n "${iface}" ] && [ "${iface}" = "${input}" ]
then
if [ -n "${iface}" ] && [ "${iface}" = "${input}" ]; then
printf "%s\n" "The uplink interface '${input}' has been already configured"
elif [ -n "${input}" ]
then
if [ -n "${iface}" ]
then
elif [ -n "${input}" ]; then
if [ -n "${iface}" ]; then
uci -q batch <<-EOC
del network."${iface}"
del network."${iface}6"
@ -133,18 +123,15 @@ setup()
set network."${input}".proto="dhcp"
set network."${input}".metric="${metric}"
set network."${input}6"=interface
set network."${input}6".ifname="@${input}"
set network."${input}6".device="@${input}"
set network."${input}6".proto="dhcpv6"
commit travelmate
commit network
EOC
while [ -n "$(uci -q get firewall.@zone["${cnt}"].name)" ]
do
if [ "$(uci -q get firewall.@zone["${cnt}"].name)" = "${zone}" ]
then
if [ -n "${iface}" ]
then
while [ -n "$(uci -q get firewall.@zone["${cnt}"].name)" ]; do
if [ "$(uci -q get firewall.@zone["${cnt}"].name)" = "${zone}" ]; then
if [ -n "${iface}" ]; then
uci -q batch <<-EOC
del_list firewall.@zone["${cnt}"].network="${iface}"
del_list firewall.@zone["${cnt}"].network="${iface}6"
@ -157,19 +144,16 @@ setup()
EOC
break
fi
cnt=$((cnt+1))
cnt=$((cnt + 1))
done
if [ -n "${iface}" ]
then
if [ -n "${iface}" ]; then
cnt=0
while [ -n "$(uci -q get wireless.@wifi-iface["${cnt}"].network)" ]
do
if [ "$(uci -q get wireless.@wifi-iface["${cnt}"].network)" = "${iface}" ]
then
while [ -n "$(uci -q get wireless.@wifi-iface["${cnt}"].network)" ]; do
if [ "$(uci -q get wireless.@wifi-iface["${cnt}"].network)" = "${iface}" ]; then
uci -q set wireless.@wifi-iface["${cnt}"].network="${input}"
fi
cnt=$((cnt+1))
cnt=$((cnt + 1))
done
uci -q commit wireless
fi
@ -179,17 +163,34 @@ setup()
fi
}
service_triggers()
{
assoc() {
local result radio="${1}"
if [ -z "${radio}" ]; then
radio="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -q -l1 -e '@[@.*.*.config.mode="ap"].interfaces[0].ifname')"
fi
result="$(iwinfo "${radio}" assoc 2>/dev/null | awk '/^[A-Z0-9:]+/{printf " %s\n",$1}')"
printf "%s\n" "::: Associated wlan stations on '${radio}'"
printf "%s\n" ":::"
if [ -n "${result}" ]; then
printf "%s\n" " MAC addresses"
printf "%s\n" " -----------------"
printf "%s\n" "${result}"
else
printf "%s\n" "::: Empty resultset"
fi
}
service_triggers() {
local iface delay
iface="$(uci_get travelmate global trm_iface)"
delay="$(uci_get travelmate global trm_triggerdelay "2")"
PROCD_RELOAD_DELAY=$((delay * 1000))
if [ -n "${iface}" ]
then
if [ -n "${iface}" ]; then
procd_add_interface_trigger "interface.*.down" "${iface}" "${trm_init}" reload
fi
procd_add_raw_trigger "interface.*.up" "${PROCD_RELOAD_DELAY}" "${trm_init}" start
procd_add_config_trigger "config.change" "travelmate" "${trm_init}" restart
}

View File

@ -1,21 +1,17 @@
#!/bin/sh
# send mail script for travelmate notifications
# Copyright (c) 2020 Dirk Brenken (dev@brenken.org)
# Copyright (c) 2020-2024 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=all
# Please note: you have to setup the package 'msmtp' 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
trm_debug="$(uci_get travelmate global trm_debug "0")"
trm_mailreceiver="$(uci_get travelmate global trm_mailreceiver)"
@ -25,47 +21,34 @@ trm_rtfile="$(uci_get travelmate global trm_rtfile "/tmp/trm_runtime.json")"
trm_mailpgm="$(command -v msmtp)"
trm_logger="$(command -v logger)"
f_log()
{
local class="${1}" log_msg="${2}"
if [ -x "${trm_logger}" ]
then
"${trm_logger}" -p "${class}" -t "trm-mail [${$}]" "${log_msg}"
else
printf "%s %s %s\\n" "${class}" "trm-mail [${$}]" "${log_msg}"
fi
}
if [ -z "${trm_mailreceiver}" ]
then
f_log "err" "please set the mail receiver with the 'trm_mailreceiver' option"
if [ -z "${trm_mailreceiver}" ]; then
"${trm_logger}" -p "err" -t "trm-mail [${$}]" "please set the mail receiver with the 'trm_mailreceiver' option" 2>/dev/null
exit 1
fi
if [ "${trm_debug}" = "1" ]
then
if [ "${trm_debug}" = "1" ]; then
debug="--debug"
fi
# info preparation
#
sys_info="$(strings /etc/banner 2>/dev/null; ubus call system board | sed -e 's/\"release\": {//' | sed -e 's/^[ \t]*//' | sed -e 's/[{}\",]//g' | sed -e 's/[ ]/ \t/' | sed '/^$/d' 2>/dev/null)"
sys_info="$(
strings /etc/banner 2>/dev/null
ubus call system board | awk 'BEGIN{FS="[{}\"]"}{if($2=="kernel"||$2=="hostname"||$2=="system"||$2=="model"||$2=="description")printf " + %-12s: %s\n",$2,$4}'
)"
trm_info="$(/etc/init.d/travelmate status 2>/dev/null)"
sta_info="$(jsonfilter -i "${trm_rtfile}" -l1 -e '@.data.station_id')"
sta_info="$(jsonfilter -i "${trm_rtfile}" -q -l1 -e '@.data.station_id')"
trm_mailtopic="$(uci_get travelmate global trm_mailtopic "travelmate connection to '${sta_info}'")"
trm_mailhead="From: ${trm_mailsender}\\nTo: ${trm_mailreceiver}\\nSubject: ${trm_mailtopic}\\nReply-to: ${trm_mailsender}\\nMime-Version: 1.0\\nContent-Type: text/html; charset=UTF-8\\nContent-Disposition: inline\\n\\n"
trm_mailhead="From: ${trm_mailsender}\nTo: ${trm_mailreceiver}\nSubject: ${trm_mailtopic}\nReply-to: ${trm_mailsender}\nMime-Version: 1.0\nContent-Type: text/html;charset=utf-8\nContent-Disposition: inline\n\n"
# mail body
#
trm_mailtext="<html><body><pre style='display:block;font-family:monospace;font-size:1rem;padding:20;background-color:#f3eee5;white-space:pre'>"
trm_mailtext="${trm_mailtext}\\n<strong>++\\n++ System Information ++\\n++</strong>\\n${sys_info}"
trm_mailtext="${trm_mailtext}\\n\\n<strong>++\\n++ Travelmate Information ++\\n++</strong>\\n${trm_info}"
trm_mailtext="<html><body><pre style='font-family:monospace;padding:20;background-color:#f3eee5;white-space:pre-wrap;overflow-x:auto;' >"
trm_mailtext="${trm_mailtext}\n<strong>++\n++ System Information ++\n++</strong>\n${sys_info}"
trm_mailtext="${trm_mailtext}\n\n<strong>++\n++ Travelmate Information ++\n++</strong>\n${trm_info}"
trm_mailtext="${trm_mailtext}</pre></body></html>"
# send mail
#
printf "%b" "${trm_mailhead}${trm_mailtext}" 2>/dev/null | "${trm_mailpgm}" ${debug} -a "${trm_mailprofile}" "${trm_mailreceiver}" >/dev/null 2>&1
mail_rc="${?}"
f_log "info" "mail sent to '${trm_mailreceiver}' with rc '${mail_rc}'"
exit ${mail_rc}
"${trm_logger}" -p "info" -t "trm-mail [${$}]" "mail sent to '${trm_mailreceiver}' with rc '${?}'" 2>/dev/null

File diff suppressed because it is too large Load Diff

View File

@ -1,153 +1,90 @@
#!/bin/sh
# vpn switch for travelmate
# Copyright (c) 2020 Dirk Brenken (dev@brenken.org)
# vpn handler called by travelmate
# Copyright (c) 2020-2023 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=all
# 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}"
vpn_instance="${5}"
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 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0")"
trm_ubuscmd="$(command -v ubus)"
trm_jsoncmd="$(command -v jsonfilter)"
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
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}"
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
json_rc="net ok"
fi
printf "%s" "${json_rc}"
}
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
if [ "${vpn}" = "1" ] && [ "${vpn_action%_*}" = "enable" ]; then
if [ "${vpn_action}" = "enable_keep" ]; then
vpn_status="$("${trm_ubuscmd}" -S call network.interface."${vpn_iface}" status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.up')"
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}'"
if [ "${vpn_action}" = "enable" ] || [ "${vpn_status}" != "true" ]; then
if [ "${vpn_status}" != "true" ]; then
/sbin/ifdown "${vpn_iface}"
"${trm_ubuscmd}" -S call network.interface."${vpn_iface}" remove >/dev/null 2>&1
fi
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}'"
if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ] && /etc/init.d/openvpn running "${vpn_instance}"; then
/etc/init.d/openvpn stop "${vpn_instance}"
sleep 1
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"
fi
;;
esac
if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]
then
if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ] && ! /etc/init.d/openvpn running "${vpn_instance}"; then
/etc/init.d/openvpn start "${vpn_instance}"
fi
/sbin/ifup "${vpn_iface}"
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
while true; do
vpn_status="$("${trm_ubuscmd}" -S call network.interface."${vpn_iface}" status 2>/dev/null | "${trm_jsoncmd}" -ql1 -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
if [ "${net_status}" = "net ok" ]; then
: >"${trm_vpnfile}"
"${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${vpn_service} client connection enabled '${vpn_iface}/${vpn_instance:-"-"}'" 2>/dev/null
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
if [ "${cnt}" -ge "$((trm_maxwait / 3))" ]; then
/sbin/ifdown "${vpn_iface}"
"${trm_ubuscmd}" -S call network.interface."${vpn_iface}" remove >/dev/null 2>&1
if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ] && /etc/init.d/openvpn running "${vpn_instance}"; then
/etc/init.d/openvpn stop "${vpn_instance}"
fi
rm -f "${trm_vpnfile}"
"${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${vpn_service} client connection can't be established '${vpn_iface}/${vpn_instance:-"-", rc: ${net_status:-"-"}}'" 2>/dev/null
return 1
fi
sleep 1
cnt="$((cnt+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
fi
elif { [ "${vpn}" != "1" ] && [ "${vpn_action%_*}" = "enable" ]; } || [ "${vpn_action}" = "disable" ]; then
/sbin/ifdown "${vpn_iface}"
"${trm_ubuscmd}" -S call network.interface."${vpn_iface}" remove >/dev/null 2>&1
if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ] && /etc/init.d/openvpn running "${vpn_instance}"; then
/etc/init.d/openvpn stop "${vpn_instance}"
fi
exit 0
rm -f "${trm_vpnfile}"
"${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${vpn_service} client connection disabled '${vpn_iface}/${vpn_instance:-"-"}'" 2>/dev/null
fi
exit 1

View File

@ -1,35 +1,16 @@
#!/bin/sh
# ntp hotplug script for travelmate
# Copyright (c) 2020 Dirk Brenken (dev@brenken.org)
# Copyright (c) 2020-2023 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=all
trm_init="/etc/init.d/travelmate"
trm_ntpfile="/var/state/travelmate.ntp"
trm_logger="$(command -v logger)"
f_log()
{
local class="${1}" log_msg="${2}"
if [ -x "${trm_logger}" ]
then
"${trm_logger}" -p "${class}" -t "trm-ntp [${$}]" "${log_msg}"
else
printf "%s %s %s\\n" "${class}" "trm-ntp [${$}]" "${log_msg}"
fi
}
if [ "${ACTION}" = "stratum" ] && [ ! -f "${trm_ntpfile}" ] && [ "$("${trm_init}" enabled; printf "%u" ${?})" = "0" ]
then
{
flock -xn 1001
if [ "$?" = "0" ]
then
f_log "info" "get ntp time sync"
"${trm_init}" restart
fi
} 1001>"${trm_ntpfile}"
if [ "${ACTION}" = "stratum" ] && [ ! -s "${trm_ntpfile}" ] && "${trm_init}" enabled; then
printf "%s" "$(date "+%Y.%m.%d-%H:%M:%S")" > "${trm_ntpfile}"
"${trm_logger}" -p "info" -t "trm-ntp [${$}]" "get ntp time sync"
fi

View File

@ -0,0 +1,51 @@
#!/bin/sh
# captive portal auto-login script for vodafone hotspots (DE)
# Copyright (c) 2021-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,3040
. "/lib/functions.sh"
export LC_ALL=C
export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
username="${1}"
password="${2}"
trm_domain="hotspot.vodafone.de"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://detectportal.firefox.com")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl)"
# get sid
#
redirect_url="$(${trm_fetch} --user-agent "${trm_useragent}" --referer "http://www.example.com" --connect-timeout $((trm_maxwait / 6)) --write-out "%{redirect_url}" --silent --show-error --output /dev/null "${trm_captiveurl}")"
sid="$(printf "%s" "${redirect_url}" 2>/dev/null | awk 'BEGIN{FS="[=&]"}{printf "%s",$2}')"
[ -z "${sid}" ] && exit 1
# get session
#
raw_html="$("${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://${trm_domain}/portal/?sid=${sid}" --silent --connect-timeout $((trm_maxwait / 6)) "https://${trm_domain}/api/v4/session?sid=${sid}")"
session="$(printf "%s" "${raw_html}" 2>/dev/null | jsonfilter -q -l1 -e '@.session')"
[ -z "${session}" ] && exit 2
ids="$(printf "%s" "${raw_html}" 2>/dev/null | jsonfilter -q -e '@.loginProfiles[*].id' | sort -n | awk '{ORS=" ";print $0}')"
for id in ${ids}; do
if [ "${id}" = "4" ]; then
login_id="4"
access_type="csc-community"
account_type="csc"
break
fi
done
[ -z "${login_id}" ] && exit 3
# final login request
#
if [ "${login_id}" = "4" ] && [ -n "${username}" ] && [ -n "${password}" ]; then
raw_html="$("${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://${trm_domain}/portal/?sid=${sid}" --silent --connect-timeout $((trm_maxwait / 6)) --data "loginProfile=${login_id}&accessType=${access_type}&accountType=${account_type}&password=${password}&session=${session}&username=${username}" "https://${trm_domain}/api/v4/login?sid=${sid}")"
fi
success="$(printf "%s" "${raw_html}" 2>/dev/null | jsonfilter -q -l1 -e '@.success')"
[ "${success}" = "true" ] && exit 0 || exit 255

View File

@ -0,0 +1,36 @@
#!/bin/sh
# captive portal auto-login script for bahn/ICE hotspots (DE)
# Copyright (c) 2020-2024 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.
# set (s)hellcheck exceptions
# shellcheck disable=all
. "/lib/functions.sh"
export LC_ALL=C
export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
trm_domain="wifi.bahn.de"
if ! nslookup "${trm_domain}" >/dev/null 2>&1; then
trm_domain="login.wifionice.de"
if ! nslookup "${trm_domain}" >/dev/null 2>&1; then
exit 1
fi
fi
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl)"
# get security token
#
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --connect-timeout $((trm_maxwait / 6)) --cookie-jar "/tmp/${trm_domain}.cookie" --silent --show-error --output /dev/null "https://${trm_domain}/en/"
sec_token="$(awk '/csrf/{print $7}' "/tmp/${trm_domain}.cookie" 2>/dev/null)"
rm -f "/tmp/${trm_domain}.cookie"
[ -z "${sec_token}" ] && exit 2
# final post request
#
raw_html="$("${trm_fetch}" --user-agent "${trm_useragent}" --connect-timeout $((trm_maxwait / 6)) --header "Cookie: csrf=${sec_token}" --data "login=true&CSRFToken=${sec_token}" --silent --show-error "https://${trm_domain}/en/")"
[ -z "${raw_html}" ] && exit 0 || exit 255

View File

@ -1,41 +0,0 @@
#!/bin/sh
# captive portal auto-login script for german ICE hotspots
# Copyright (c) 2020 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
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
trm_domain="www.wifionice.de"
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0")"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_fetch="$(command -v curl)"
# initial get request to receive & extract a valid security token
#
"${trm_fetch}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --silent --connect-timeout $((trm_maxwait/6)) --cookie-jar "/tmp/${trm_domain}.cookie" --output /dev/null "http://${trm_domain}/en/"
if [ -f "/tmp/${trm_domain}.cookie" ]
then
sec_token="$(awk '/csrf/{print $7}' "/tmp/${trm_domain}.cookie")"
rm -f "/tmp/${trm_domain}.cookie"
else
exit 2
fi
# final post request/login with valid session cookie/security token
#
if [ -n "${sec_token}" ]
then
"${trm_fetch}" --user-agent "${trm_useragent}" --silent --connect-timeout $((trm_maxwait/6)) --header "Cookie: csrf=${sec_token}" --data "login=true&CSRFToken=${sec_token}&connect=" --output /dev/null "http://${trm_domain}/en/"
else
exit 3
fi