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.

174 lines
5.0 KiB

  1. #!/usr/bin/env sh
  2. # Here is a script to deploy cert to Ruckus ZoneDirector / Unleashed.
  3. #
  4. # Public domain, 2024, Tony Rielly <https://github.com/ms264556>
  5. #
  6. # ```sh
  7. # acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus
  8. # ```
  9. #
  10. # Then you need to set the environment variables for the
  11. # deploy script to work.
  12. #
  13. # ```sh
  14. # export RUCKUS_HOST=myruckus.example.com
  15. # export RUCKUS_USER=myruckususername
  16. # export RUCKUS_PASS=myruckuspassword
  17. #
  18. # acme.sh --deploy -d myruckus.example.com --deploy-hook ruckus
  19. # ```
  20. #
  21. # returns 0 means success, otherwise error.
  22. ######## Public functions #####################
  23. #domain keyfile certfile cafile fullchain
  24. ruckus_deploy() {
  25. _cdomain="$1"
  26. _ckey="$2"
  27. _ccert="$3"
  28. _cca="$4"
  29. _cfullchain="$5"
  30. _err_code=0
  31. _debug _cdomain "$_cdomain"
  32. _debug _ckey "$_ckey"
  33. _debug _ccert "$_ccert"
  34. _debug _cca "$_cca"
  35. _debug _cfullchain "$_cfullchain"
  36. _getdeployconf RUCKUS_HOST
  37. _getdeployconf RUCKUS_USER
  38. _getdeployconf RUCKUS_PASS
  39. if [ -z "$RUCKUS_HOST" ]; then
  40. _debug "Using _cdomain as RUCKUS_HOST, please set if not correct."
  41. RUCKUS_HOST="$_cdomain"
  42. fi
  43. if [ -z "$RUCKUS_USER" ]; then
  44. _err "Need to set the env variable RUCKUS_USER"
  45. return 1
  46. fi
  47. if [ -z "$RUCKUS_PASS" ]; then
  48. _err "Need to set the env variable RUCKUS_PASS"
  49. return 1
  50. fi
  51. _savedeployconf RUCKUS_HOST "$RUCKUS_HOST"
  52. _savedeployconf RUCKUS_USER "$RUCKUS_USER"
  53. _savedeployconf RUCKUS_PASS "$RUCKUS_PASS"
  54. _debug RUCKUS_HOST "$RUCKUS_HOST"
  55. _debug RUCKUS_USER "$RUCKUS_USER"
  56. _debug RUCKUS_PASS "$RUCKUS_PASS"
  57. export HTTPS_INSECURE=1
  58. export ACME_HTTP_NO_REDIRECTS=1
  59. _info Discovering the login URL
  60. _get "https://$RUCKUS_HOST" >/dev/null
  61. _login_url="$(_response_header 'Location')"
  62. if [ -n "$_login_url" ]; then
  63. _login_path=$(echo "$_login_url" | sed 's|https\?://[^/]\+||')
  64. if [ -z "$_login_path" ]; then
  65. # redirect was to a different host
  66. _get "$_login_url" >/dev/null
  67. _login_url="$(_response_header 'Location')"
  68. fi
  69. fi
  70. if [ -z "${_login_url}" ]; then
  71. _err "Connection failed: couldn't find login page."
  72. return 1
  73. fi
  74. _base_url=$(dirname "$_login_url")
  75. _login_page=$(basename "$_login_url")
  76. if [ "$_login_page" = "index.html" ]; then
  77. _err "Connection temporarily unavailable: Unleashed Rebuilding."
  78. return 1
  79. fi
  80. if [ "$_login_page" = "wizard.jsp" ]; then
  81. _err "Connection failed: Setup Wizard not complete."
  82. return 1
  83. fi
  84. _info Login
  85. _username_encoded="$(printf "%s" "$RUCKUS_USER" | _url_encode)"
  86. _password_encoded="$(printf "%s" "$RUCKUS_PASS" | _url_encode)"
  87. _login_query="$(printf "%s" "username=${_username_encoded}&password=${_password_encoded}&ok=Log+In")"
  88. _post "$_login_query" "$_login_url" >/dev/null
  89. _login_code="$(_response_code)"
  90. if [ "$_login_code" = "200" ]; then
  91. _err "Login failed: incorrect credentials."
  92. return 1
  93. fi
  94. _info Collect Session Cookie
  95. _H1="Cookie: $(_response_cookie)"
  96. export _H1
  97. _info Collect CSRF Token
  98. _H2="X-CSRF-Token: $(_response_header 'HTTP_X_CSRF_TOKEN')"
  99. export _H2
  100. _info "Uploading certificate"
  101. _post_upload "uploadcert" "$_cfullchain"
  102. _info "Uploading private key"
  103. _post_upload "uploadprivatekey" "$_ckey"
  104. _info "Replacing certificate"
  105. _replace_cert_ajax='<ajax-request action="docmd" comp="system" updater="rid.0.5" xcmd="replace-cert" checkAbility="6" timeout="-1"><xcmd cmd="replace-cert" cn="'$RUCKUS_HOST'"/></ajax-request>'
  106. _post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null
  107. info "Rebooting"
  108. _cert_reboot_ajax='<ajax-request action="docmd" comp="worker" updater="rid.0.5" xcmd="cert-reboot" checkAbility="6"><xcmd cmd="cert-reboot" action="undefined"/></ajax-request>'
  109. _post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null
  110. return 0
  111. }
  112. _response_code() {
  113. < "$HTTP_HEADER" _egrep_o "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*"
  114. }
  115. _response_header() {
  116. < "$HTTP_HEADER" grep -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t "
  117. }
  118. _response_cookie() {
  119. _response_header 'Set-Cookie' | awk -F';' '{for(i=1;i<=NF;i++) if (tolower($i) !~ /(path|domain|expires|max-age|secure|httponly|samesite)/) printf "%s; ", $i}' | sed 's/; $//'
  120. }
  121. _post_upload() {
  122. _post_action="$1"
  123. _post_file="$2"
  124. _post_url="$3"
  125. _post_boundary="----FormBoundary$(date "+%s%N")"
  126. _post_data="$({
  127. printf -- "--%s\r\n" "$_post_boundary"
  128. printf -- "Content-Disposition: form-data; name=\"u\"; filename=\"%s\"\r\n" "$_post_action"
  129. printf -- "Content-Type: application/octet-stream\r\n\r\n"
  130. printf -- "%s\r\n" "$(cat "$_post_file")"
  131. printf -- "--%s\r\n" "$_post_boundary"
  132. printf -- "Content-Disposition: form-data; name=\"action\"\r\n\r\n"
  133. printf -- "%s\r\n" "$_post_action"
  134. printf -- "--%s\r\n" "$_post_boundary"
  135. printf -- "Content-Disposition: form-data; name=\"callback\"\r\n\r\n"
  136. printf -- "%s\r\n" "uploader_$_post_action"
  137. printf -- "--%s--\r\n\r\n" "$_post_boundary"
  138. })"
  139. _post "$_post_data" "$_base_url/_upload.jsp?request_type=xhr" "" "" "multipart/form-data; boundary=$_post_boundary" >/dev/null
  140. }