From: Dirk Brenken Date: Sat, 8 Aug 2026 15:50:24 +0000 (+0200) Subject: travelmate: update 2.4.7-3 X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=112a7e4e9606b1421494cc02377ba5d2951262dc;p=openwrt-packages.git travelmate: update 2.4.7-3 - fixed the shipped captive portal login scripts, corrected the curl call to 'trm_fetchcmd' - fixed the return code handling within the login scripts - added a generic portal login script recipe to the readme Signed-off-by: Dirk Brenken --- diff --git a/net/travelmate/Makefile b/net/travelmate/Makefile index f5b50dd05..6eeba80b9 100644 --- a/net/travelmate/Makefile +++ b/net/travelmate/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=travelmate PKG_VERSION:=2.4.7 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Dirk Brenken diff --git a/net/travelmate/files/README.md b/net/travelmate/files/README.md index 663ecdb88..20675dec7 100644 --- a/net/travelmate/files/README.md +++ b/net/travelmate/files/README.md @@ -226,7 +226,7 @@ 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 have to be executable and located in `/etc/travelmate` with the extension `.login`. The package ships multiple ready to run auto-login scripts: +For automated captive portal logins you can reference an external shell script per uplink. All login scripts have to be executable and located in `/etc/travelmate` with the extension `.login`. A login script signals its result via the exit code: `0` means the login succeeded, any other value means it failed. Only `0` makes travelmate re-check the connectivity right away, every other value is just logged. The package ships multiple ready to run auto-login scripts: * 'wifibahn.login' for german DB railway hotspots * 'telekom.login' for telekom hotspots (DE) @@ -242,6 +242,19 @@ user.info trm-2.4.7-1[26222]: captive portal login script for 'www.wifibahn.de' user.info trm-2.4.7-1[26222]: connected to uplink 'radio1/WIFI@DB/-' with mac 'B2:9D:F5:96:86:A4' (1/3) [...] ``` +**Building your own login script** +The fastest way to a working script is to record the login once by hand and then replay it with curl. Any browser's developer tools can do the recording: + +1. Connect a client to the hotspot - either directly, or through travelmate's own AP while the uplink is up - and open the portal page. +2. Open the developer tools (usually `F12`) and switch to the `Network` tab. Enable `Preserve log` (Chromium, Edge, Safari) resp. `Persist Logs` (Firefox, behind the gear icon) and `Disable cache`. A portal login almost always ends in a redirect, and without these options the recorded entries are dropped at that point. +3. Perform the login manually and watch which requests are sent. +4. Right-click the request that carries your credentials and choose `Copy` -> `Copy as cURL`. You now have the exact URL, method, headers, cookies and form fields as the browser sent them. `Save All As HAR` resp. `Export HAR` records the whole session if you want to study it later - note that recent Chromium versions strip cookies and authorization headers from the export unless you allow sensitive data in the devtools settings. +5. Strip the copied command down: the browser adds a lot of `Accept*`, `Sec-*` and `Priority` headers that no portal cares about. Keep the request body, the `Content-Type` and whatever the portal actually validates, then replace curl's flags with travelmate's `${trm_fetchcmd} ${trm_fetchparm}` and `--user-agent "${trm_useragent}"`. +6. Look for values that are only valid for one session - CSRF tokens, session ids, `sid` parameters. Those must not be copied into the script but fetched at runtime, see `wifibahn.login` (cookie jar plus awk) or `vodafone.login` (json response plus jsonfilter) for the two usual patterns. +7. Never hardcode credentials. Pass them via the uplink's `script_args` option and read them as `${1}` and `${2}`, like `generic-user-pass.login` does. +8. Test the script on the router while the portal is actually in the way: `sh -x /etc/travelmate/my.login user pass; echo "rc: ${?}"`. Make sure it only exits `0` when the login really succeeded - a script that reports success too eagerly is worse than one that fails, because travelmate will happily keep the uplink. + +The portal domain travelmate detected is in the system log: `logread -e "trm-"` shows it as `captive portal domain '' added to dhcp rebind allowlist`. Hopefully more scripts for different captive portals will be provided by the community! diff --git a/net/travelmate/files/generic-user-pass.login b/net/travelmate/files/generic-user-pass.login index f605539bd..455db46dd 100755 --- a/net/travelmate/files/generic-user-pass.login +++ b/net/travelmate/files/generic-user-pass.login @@ -24,6 +24,5 @@ fi # login with credentials # -raw_html="$("${trm_fetch}" ${trm_fetchparm} --user-agent "${trm_useragent}" --header "Content-Type:application/x-www-form-urlencoded" --data "username=${user}&password=${password}" "http://${trm_domain}")" -[ -z "${raw_html}" ] && exit 0 || exit 255 - +"${trm_fetchcmd}" ${trm_fetchparm} --user-agent "${trm_useragent}" --header "Content-Type:application/x-www-form-urlencoded" --data "username=${user}&password=${password}" --output /dev/null "http://${trm_domain}" +[ "${?}" = "0" ] && exit 0 || exit 255 diff --git a/net/travelmate/files/telekom.login b/net/travelmate/files/telekom.login index 124db1725..1830bbfe7 100755 --- a/net/travelmate/files/telekom.login +++ b/net/travelmate/files/telekom.login @@ -8,25 +8,24 @@ # url encoding function # -urlencode() -{ +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}" - ;; + [a-zA-Z0-9.~_-]) + printf "%s" "${chr}" + ;; + " ") + printf "%%20" + ;; + *) + printf "%%%02X" "'${chr}" + ;; esac pos=$((pos + 1)) - done + done } export LC_ALL=C @@ -47,12 +46,12 @@ fi # get redirect url # -raw_html="$("${trm_fetch}" ${trm_fetchparm} --user-agent "${trm_useragent}" "${trm_captiveurl}")" +raw_html="$("${trm_fetchcmd}" ${trm_fetchparm} --user-agent "${trm_useragent}" "${trm_captiveurl}")" redirect_url="$(printf "%s" "${raw_html}" | "${trm_awkcmd}" 'match(tolower($0),/.*<\/loginurl>/){printf "%s",substr($0,RSTART+10,RLENGTH-21)}' 2>/dev/null | "${trm_awkcmd}" '{gsub("&","\\&");printf "%s",$0}' 2>/dev/null)" [ -z "${redirect_url}" ] && exit 1 # final login request # -raw_html="$("${trm_fetch}" ${trm_fetchparm} --user-agent "${trm_useragent}" --referer "https://${trm_domain}/wlan/rest/freeLogin" --header "content-type: application/x-www-form-urlencoded" --data "UserName=${username}&Password=${password}&FNAME=0&button=Login&OriginatingServer=http%3A%2F%2F${trm_captiveurl}" "${redirect_url}")" +raw_html="$("${trm_fetchcmd}" ${trm_fetchparm} --user-agent "${trm_useragent}" --referer "https://${trm_domain}/wlan/rest/freeLogin" --header "content-type: application/x-www-form-urlencoded" --data "UserName=${username}&Password=${password}&FNAME=0&button=Login&OriginatingServer=http%3A%2F%2F${trm_captiveurl}" "${redirect_url}")" login_url="$(printf "%s" "${raw_html}" | "${trm_awkcmd}" 'match(tolower($0),/.*<\/logoffurl>/){printf "%s",substr($0,RSTART+11,RLENGTH-23)}' 2>/dev/null)" [ -n "${login_url}" ] && exit 0 || exit 255 diff --git a/net/travelmate/files/vodafone.login b/net/travelmate/files/vodafone.login index f578525f6..6979ca938 100755 --- a/net/travelmate/files/vodafone.login +++ b/net/travelmate/files/vodafone.login @@ -24,13 +24,13 @@ fi # get sid # -redirect_url="$("${trm_fetch}" ${trm_fetchparm} --user-agent "${trm_useragent}" --write-out "%{redirect_url}" --output /dev/null "${trm_captiveurl}")" +redirect_url="$("${trm_fetchcmd}" ${trm_fetchparm} --user-agent "${trm_useragent}" --write-out "%{redirect_url}" --output /dev/null "${trm_captiveurl}")" sid="$(printf "%s" "${redirect_url}" 2>/dev/null | "${trm_awkcmd}" 'BEGIN{FS="[=&]"}{printf "%s",$2}')" [ -z "${sid}" ] && exit 1 # get session # -raw_html="$("${trm_fetch}" ${trm_fetchparm} --user-agent "${trm_useragent}" --referer "http://${trm_domain}/portal/?sid=${sid}" "https://${trm_domain}/api/v4/session?sid=${sid}")" +raw_html="$("${trm_fetchcmd}" ${trm_fetchparm} --user-agent "${trm_useragent}" --referer "http://${trm_domain}/portal/?sid=${sid}" "https://${trm_domain}/api/v4/session?sid=${sid}")" session="$(printf "%s" "${raw_html}" 2>/dev/null | "${trm_jsoncmd}" -q -l1 -e '@.session')" [ -z "${session}" ] && exit 2 @@ -48,7 +48,7 @@ done # final login request # if [ "${login_id}" = "4" ] && [ -n "${username}" ] && [ -n "${password}" ]; then - raw_html="$("${trm_fetch}" ${trm_fetchparm} --user-agent "${trm_useragent}" --referer "http://${trm_domain}/portal/?sid=${sid}" --data "loginProfile=${login_id}&accessType=${access_type}&accountType=${account_type}&password=${password}&session=${session}&username=${username}" "https://${trm_domain}/api/v4/login?sid=${sid}")" + raw_html="$("${trm_fetchcmd}" ${trm_fetchparm} --user-agent "${trm_useragent}" --referer "http://${trm_domain}/portal/?sid=${sid}" --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 | "${trm_jsoncmd}" -q -l1 -e '@.success')" [ "${success}" = "true" ] && exit 0 || exit 255 diff --git a/net/travelmate/files/wifibahn.login b/net/travelmate/files/wifibahn.login index 52e8e951e..e0a3c8f6c 100755 --- a/net/travelmate/files/wifibahn.login +++ b/net/travelmate/files/wifibahn.login @@ -25,12 +25,12 @@ fi # get security token # -"${trm_fetch}" ${trm_fetchparm} --user-agent "${trm_useragent}" --cookie-jar "/tmp/${trm_domain}.cookie" --output /dev/null "https://${trm_domain}/en/" -sec_token="$("${trm_awkcmd}" '/csrf/{print $7}' "/tmp/${trm_domain}.cookie" 2>/dev/null)" +"${trm_fetchcmd}" ${trm_fetchparm} --user-agent "${trm_useragent}" --cookie-jar "/tmp/${trm_domain}.cookie" --output /dev/null "https://${trm_domain}/en/" +[ "${?}" = "0" ] && sec_token="$("${trm_awkcmd}" '/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}" ${trm_fetchparm} --user-agent "${trm_useragent}" --header "Cookie: csrf=${sec_token}" --data "login=true&CSRFToken=${sec_token}" "https://${trm_domain}/en/")" -[ -z "${raw_html}" ] && exit 0 || exit 255 +"${trm_fetchcmd}" ${trm_fetchparm} --user-agent "${trm_useragent}" --header "Cookie: csrf=${sec_token}" --data "login=true&CSRFToken=${sec_token}" --output /dev/null "https://${trm_domain}/en/" +[ "${?}" = "0" ] && exit 0 || exit 255