You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
3.4 KiB

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