travelmate: update 2.1.0
[feed/packages.git] / net / travelmate / files / tplink-omada.login
1 #!/bin/sh
2 # captive portal auto-login script for TP-Link Omada (authType=0 only)
3 # Copyright (c) 2022 Sebastian Muszynski <basti@linkt.de>
4 # This is free software, licensed under the GNU General Public License v3
5
6 # set (s)hellcheck exceptions
7 # shellcheck disable=1091,2181,3037,3043,3057
8
9 . "/lib/functions.sh"
10 . "/usr/share/libubox/jshn.sh"
11
12 urlencode()
13 {
14 local chr str="${1}" len="${#1}" pos=0
15
16 while [ "${pos}" -lt "${len}" ]; do
17 chr="${str:pos:1}"
18 case "${chr}" in
19 [a-zA-Z0-9.~_-])
20 printf "%s" "${chr}"
21 ;;
22 " ")
23 printf "%%20"
24 ;;
25 *)
26 printf "%%%02X" "'${chr}"
27 ;;
28 esac
29 pos=$((pos + 1))
30 done
31 }
32
33 urldecode()
34 {
35 echo -e "$(sed 's/+/ /g;s/%\(..\)/\\x\1/g;')"
36 }
37
38 request_parameter()
39 {
40 grep -oE "$1=[^&]+" | cut -d= -f2
41 }
42
43 export LC_ALL=C
44 export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
45
46 trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://detectportal.firefox.com")"
47 trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
48 trm_fetch="$(command -v curl) --connect-timeout $((trm_maxwait / 6)) --silent"
49
50 raw_html="$(${trm_fetch} --show-error "${trm_captiveurl}")"
51
52 if [ $? -ne 0 ];
53 then
54 echo "The captive portal didn't respond"
55 exit 1
56 fi
57
58 if [ "$raw_html" = "success" ];
59 then
60 echo "Internet access already available"
61 exit 0
62 fi
63
64 redirect_url=$(echo "$raw_html" | grep -oE 'location.href="[^\"]+"' | cut -d\" -f2)
65
66 portal_baseurl=$(echo "$redirect_url" | cut -d/ -f1-4)
67 client_mac=$(echo "$redirect_url" | request_parameter cid)
68 ap_mac=$(echo "$redirect_url" | request_parameter ap)
69 ssid=$(echo "$redirect_url" | request_parameter ssid | urldecode)
70 radio_id=$(echo "$redirect_url" | request_parameter rid)
71 url=$(echo "$redirect_url" | request_parameter u | urldecode)
72
73 ${trm_fetch} "${portal_baseurl}/pubKey" | jsonfilter -e '@.result.key' > /tmp/trm-omada-pub.key
74 if [ $? -ne 0 ];
75 then
76 exit 2
77 fi
78
79 json_init
80 json_add_string "clientMac" "$client_mac"
81 json_add_string "apMac" "$ap_mac"
82 json_add_string "ssidName" "$ssid"
83 json_add_int "radioId" "$radio_id"
84 json_add_string "originUrl" "$url"
85 json_close_object
86 incomplete_auth_request="$(json_dump)"
87
88 auth_type=$(${trm_fetch} "${portal_baseurl}/getPortalPageSetting" \
89 -H 'Accept: application/json' \
90 -H 'Content-Type: application/json' \
91 -H 'X-Requested-With: XMLHttpRequest' \
92 --data-raw "$incomplete_auth_request" | jsonfilter -e '@.result.authType')
93
94 if [ "$auth_type" -ne 0 ];
95 then
96 echo "Unsupported auth type: $auth_type"
97 exit 3
98 fi
99
100 aes_key=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c 16)
101 aes_key_hex=$(printf "%s" "$aes_key" | hexdump -e '16/1 "%02x"')
102 aes_vi=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c 16)
103 aes_vi_hex=$(printf "%s" "$aes_vi" | hexdump -e '16/1 "%02x"')
104
105 rsa_encrypted_aes_secrets=$(printf "%s" "${aes_key}${aes_vi}" | openssl rsautl -encrypt -pubin -inkey /tmp/trm-omada-pub.key | base64 -w 0)
106 rsa_encrypted_aes_secrets_urlencoded=$(urlencode "$rsa_encrypted_aes_secrets")
107
108 json_load "$incomplete_auth_request"
109 json_add_int "authType" "$auth_type"
110 json_close_object
111 auth_request="$(json_dump)"
112
113 aes_encrypted_auth_request="$(echo "$auth_request" | openssl enc -aes-128-cbc -K "$aes_key_hex" -iv "$aes_vi_hex" -a -A)"
114
115 auth_response=$(${trm_fetch} "${portal_baseurl}/auth?key=$rsa_encrypted_aes_secrets_urlencoded" \
116 -H 'Content-Type: text/plain' \
117 -H 'X-Requested-With: XMLHttpRequest' \
118 --data-raw "$aes_encrypted_auth_request" \
119 --insecure)
120
121 if echo "$auth_response" | grep -q '{"errorCode":0}';
122 then
123 exit 0
124 fi
125
126 exit 255