2024-11-10 22:12:38 +13:00
#!/usr/bin/env sh
2023-10-18 20:32:39 -07:00
2024-11-10 22:12:38 +13:00
# Here is a script to deploy cert to Ruckus ZoneDirector / Unleashed.
2024-11-14 07:16:38 +13:00
#
2024-11-10 22:12:38 +13:00
# Public domain, 2024, Tony Rielly <https://github.com/ms264556>
2023-10-18 20:32:39 -07:00
#
# ```sh
# acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus
# ```
#
# Then you need to set the environment variables for the
# deploy script to work.
#
# ```sh
2024-11-10 22:12:38 +13:00
# export RUCKUS_HOST=myruckus.example.com
2023-10-18 20:32:39 -07:00
# export RUCKUS_USER=myruckususername
# export RUCKUS_PASS=myruckuspassword
#
2024-11-10 22:12:38 +13:00
# acme.sh --deploy -d myruckus.example.com --deploy-hook ruckus
2023-10-18 20:32:39 -07:00
# ```
#
# returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
ruckus_deploy( ) {
_cdomain = " $1 "
_ckey = " $2 "
_ccert = " $3 "
_cca = " $4 "
_cfullchain = " $5 "
_err_code = 0
_debug _cdomain " $_cdomain "
_debug _ckey " $_ckey "
_debug _ccert " $_ccert "
_debug _cca " $_cca "
_debug _cfullchain " $_cfullchain "
_getdeployconf RUCKUS_HOST
_getdeployconf RUCKUS_USER
_getdeployconf RUCKUS_PASS
if [ -z " $RUCKUS_HOST " ] ; then
_debug "Using _cdomain as RUCKUS_HOST, please set if not correct."
RUCKUS_HOST = " $_cdomain "
fi
if [ -z " $RUCKUS_USER " ] ; then
_err "Need to set the env variable RUCKUS_USER"
return 1
fi
if [ -z " $RUCKUS_PASS " ] ; then
_err "Need to set the env variable RUCKUS_PASS"
return 1
fi
_savedeployconf RUCKUS_HOST " $RUCKUS_HOST "
_savedeployconf RUCKUS_USER " $RUCKUS_USER "
_savedeployconf RUCKUS_PASS " $RUCKUS_PASS "
_debug RUCKUS_HOST " $RUCKUS_HOST "
_debug RUCKUS_USER " $RUCKUS_USER "
2024-11-13 12:50:51 +13:00
_secure_debug RUCKUS_PASS " $RUCKUS_PASS "
2023-10-18 20:32:39 -07:00
2024-11-10 22:12:38 +13:00
export ACME_HTTP_NO_REDIRECTS = 1
2024-11-13 17:27:36 +13:00
_info "Discovering the login URL"
2024-11-10 22:12:38 +13:00
_get " https:// $RUCKUS_HOST " >/dev/null
_login_url = " $( _response_header 'Location' ) "
if [ -n " $_login_url " ] ; then
_login_path = $( echo " $_login_url " | sed 's|https\?://[^/]\+||' )
if [ -z " $_login_path " ] ; then
# redirect was to a different host
2024-11-15 12:39:41 +13:00
_err "Connection failed: redirected to a different host. Configure Unleashed with a Preferred Master or Management Interface."
return 1
2024-11-10 22:12:38 +13:00
fi
fi
2023-10-18 20:32:39 -07:00
2024-11-10 22:12:38 +13:00
if [ -z " ${ _login_url } " ] ; then
_err "Connection failed: couldn't find login page."
2023-10-18 20:32:39 -07:00
return 1
fi
2024-11-14 07:16:38 +13:00
2024-11-10 22:12:38 +13:00
_base_url = $( dirname " $_login_url " )
_login_page = $( basename " $_login_url " )
2023-10-18 20:32:39 -07:00
2024-11-14 07:16:38 +13:00
if [ " $_login_page " = "index.html" ] ; then
2024-11-10 22:12:38 +13:00
_err "Connection temporarily unavailable: Unleashed Rebuilding."
return 1
fi
2023-10-18 20:32:39 -07:00
2024-11-14 07:16:38 +13:00
if [ " $_login_page " = "wizard.jsp" ] ; then
2024-11-10 22:12:38 +13:00
_err "Connection failed: Setup Wizard not complete."
return 1
fi
2024-11-14 07:16:38 +13:00
2024-11-13 17:27:36 +13:00
_info "Login"
2024-11-10 22:12:38 +13:00
_username_encoded = " $( printf "%s" " $RUCKUS_USER " | _url_encode) "
_password_encoded = " $( printf "%s" " $RUCKUS_PASS " | _url_encode) "
_login_query = " $( printf "%s" " username= ${ _username_encoded } &password= ${ _password_encoded } &ok=Log+In " ) "
_post " $_login_query " " $_login_url " >/dev/null
_login_code = " $( _response_code) "
if [ " $_login_code " = "200" ] ; then
_err "Login failed: incorrect credentials."
return 1
fi
2024-11-14 07:16:38 +13:00
2024-11-13 17:27:36 +13:00
_info "Collect Session Cookie"
2024-11-10 22:12:38 +13:00
_H1 = " Cookie: $( _response_cookie) "
export _H1
2024-11-13 17:27:36 +13:00
_info "Collect CSRF Token"
2024-11-10 22:12:38 +13:00
_H2 = " X-CSRF-Token: $( _response_header 'HTTP_X_CSRF_TOKEN' ) "
export _H2
2023-10-18 20:32:39 -07:00
2025-03-27 14:03:08 +13:00
if _isRSA " $_ckey " >/dev/null 2>& 1; then
_debug "Using RSA certificate."
else
_info "Verifying ECC certificate support."
_ul_version = " $( _get_unleashed_version) "
if [ -z " $_ul_version " ] ; then
_err "Your controller doesn't support ECC certificates. Please deploy an RSA certificate."
return 1
fi
_ul_version_major = " $( echo " $_ul_version " | cut -d . -f 1) "
_ul_version_minor = " $( echo " $_ul_version " | cut -d . -f 2) "
if [ " $_ul_version_major " -lt "200" ] ; then
_err "ZoneDirector doesn't support ECC certificates. Please deploy an RSA certificate."
return 1
elif [ " $_ul_version_minor " -lt "13" ] ; then
_err " Unleashed $_ul_version_major . $_ul_version_minor doesn't support ECC certificates. Please deploy an RSA certificate or upgrade to Unleashed 200.13+. "
return 1
fi
_debug " ECC certificates OK for Unleashed $_ul_version_major . $_ul_version_minor . "
fi
2023-10-18 20:32:39 -07:00
_info "Uploading certificate"
2024-11-10 22:12:38 +13:00
_post_upload "uploadcert" " $_cfullchain "
2024-11-14 07:16:38 +13:00
2023-10-18 20:32:39 -07:00
_info "Uploading private key"
2024-11-10 22:12:38 +13:00
_post_upload "uploadprivatekey" " $_ckey "
2023-10-18 20:32:39 -07:00
_info "Replacing certificate"
2024-11-10 22:12:38 +13:00
_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>'
_post " $_replace_cert_ajax " " $_base_url /_cmdstat.jsp " >/dev/null
2024-11-14 07:16:38 +13:00
2024-11-13 12:50:51 +13:00
_info "Rebooting"
2024-11-10 22:12:38 +13:00
_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>'
_post " $_cert_reboot_ajax " " $_base_url /_cmdstat.jsp " >/dev/null
2024-11-14 07:16:38 +13:00
2024-11-10 22:12:38 +13:00
return 0
}
_response_code( ) {
2024-11-14 07:16:38 +13:00
_egrep_o <" $HTTP_HEADER " " ^HTTP[^ ]* .* $" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*"
2024-11-10 22:12:38 +13:00
}
2023-10-18 20:32:39 -07:00
2024-11-10 22:12:38 +13:00
_response_header( ) {
2024-11-14 07:16:38 +13:00
grep <" $HTTP_HEADER " -i " ^ $1 : " | cut -d ':' -f 2- | tr -d "\r\n\t "
2024-11-10 22:12:38 +13:00
}
2023-10-18 20:32:39 -07:00
2024-11-10 22:12:38 +13:00
_response_cookie( ) {
2024-11-15 12:39:41 +13:00
_response_header 'Set-Cookie' | sed 's/;.*//'
2023-10-18 20:32:39 -07:00
}
2025-03-27 14:03:08 +13:00
_get_unleashed_version( ) {
_post '<ajax-request action="getstat" comp="system"><sysinfo/></ajax-request>' " $_base_url /_cmdstat.jsp " | _egrep_o "version-num=\"[^\"]*\"" | cut -d '"' -f 2
}
2024-11-10 22:12:38 +13:00
_post_upload( ) {
_post_action = " $1 "
_post_file = " $2 "
2024-11-14 07:16:38 +13:00
2024-11-10 22:12:38 +13:00
_post_boundary = " ----FormBoundary $( date "+%s%N" ) "
2024-11-14 07:16:38 +13:00
2024-11-10 22:12:38 +13:00
_post_data = " $( {
printf -- "--%s\r\n" " $_post_boundary "
printf -- "Content-Disposition: form-data; name=\"u\"; filename=\"%s\"\r\n" " $_post_action "
printf -- "Content-Type: application/octet-stream\r\n\r\n"
printf -- "%s\r\n" " $( cat " $_post_file " ) "
printf -- "--%s\r\n" " $_post_boundary "
printf -- "Content-Disposition: form-data; name=\"action\"\r\n\r\n"
printf -- "%s\r\n" " $_post_action "
printf -- "--%s\r\n" " $_post_boundary "
printf -- "Content-Disposition: form-data; name=\"callback\"\r\n\r\n"
printf -- "%s\r\n" " uploader_ $_post_action "
printf -- "--%s--\r\n\r\n" " $_post_boundary "
} ) "
_post " $_post_data " " $_base_url /_upload.jsp?request_type=xhr " "" "" " multipart/form-data; boundary= $_post_boundary " >/dev/null
}