|
@@ -66,6 +66,9 @@ END_CERT="-----END CERTIFICATE-----"
|
|
|
CONTENT_TYPE_JSON="application/jose+json"
|
|
|
RENEW_SKIP=2
|
|
|
|
|
|
+B64CONF_START="__ACME_BASE64__START_"
|
|
|
+B64CONF_END="__ACME_BASE64__END_"
|
|
|
+
|
|
|
ECC_SEP="_"
|
|
|
ECC_SUFFIX="${ECC_SEP}ecc"
|
|
|
|
|
@@ -1827,23 +1830,29 @@ _send_signed_request() {
|
|
|
nonceurl="$ACME_NEW_NONCE"
|
|
|
if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type"; then
|
|
|
_headers="$(cat "$HTTP_HEADER")"
|
|
|
+ _debug2 _headers "$_headers"
|
|
|
+ _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)"
|
|
|
fi
|
|
|
fi
|
|
|
- if [ -z "$_headers" ]; then
|
|
|
+ if [ -z "$_CACHED_NONCE" ]; then
|
|
|
_debug2 "Get nonce with GET. ACME_DIRECTORY" "$ACME_DIRECTORY"
|
|
|
nonceurl="$ACME_DIRECTORY"
|
|
|
_headers="$(_get "$nonceurl" "onlyheader")"
|
|
|
+ _debug2 _headers "$_headers"
|
|
|
+ _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)"
|
|
|
fi
|
|
|
-
|
|
|
+ if [ -z "$_CACHED_NONCE" ] && [ "$ACME_NEW_NONCE" ]; then
|
|
|
+ _debug2 "Get nonce with GET. ACME_NEW_NONCE" "$ACME_NEW_NONCE"
|
|
|
+ nonceurl="$ACME_NEW_NONCE"
|
|
|
+ _headers="$(_get "$nonceurl" "onlyheader")"
|
|
|
+ _debug2 _headers "$_headers"
|
|
|
+ _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)"
|
|
|
+ fi
|
|
|
+ _debug2 _CACHED_NONCE "$_CACHED_NONCE"
|
|
|
if [ "$?" != "0" ]; then
|
|
|
_err "Can not connect to $nonceurl to get nonce."
|
|
|
return 1
|
|
|
fi
|
|
|
-
|
|
|
- _debug2 _headers "$_headers"
|
|
|
-
|
|
|
- _CACHED_NONCE="$(echo "$_headers" | grep "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)"
|
|
|
- _debug2 _CACHED_NONCE "$_CACHED_NONCE"
|
|
|
else
|
|
|
_debug2 "Use _CACHED_NONCE" "$_CACHED_NONCE"
|
|
|
fi
|
|
@@ -1958,12 +1967,16 @@ _setopt() {
|
|
|
_debug3 "$(grep -n "^$__opt$__sep" "$__conf")"
|
|
|
}
|
|
|
|
|
|
-#_save_conf file key value
|
|
|
+#_save_conf file key value base64encode
|
|
|
#save to conf
|
|
|
_save_conf() {
|
|
|
_s_c_f="$1"
|
|
|
_sdkey="$2"
|
|
|
_sdvalue="$3"
|
|
|
+ _b64encode="$4"
|
|
|
+ if [ "$_b64encode" ]; then
|
|
|
+ _sdvalue="${B64CONF_START}$(printf "%s" "${_sdvalue}" | _base64)${B64CONF_END}"
|
|
|
+ fi
|
|
|
if [ "$_s_c_f" ]; then
|
|
|
_setopt "$_s_c_f" "$_sdkey" "=" "'$_sdvalue'"
|
|
|
else
|
|
@@ -1988,19 +2001,20 @@ _read_conf() {
|
|
|
_r_c_f="$1"
|
|
|
_sdkey="$2"
|
|
|
if [ -f "$_r_c_f" ]; then
|
|
|
- (
|
|
|
- eval "$(grep "^$_sdkey *=" "$_r_c_f")"
|
|
|
- eval "printf \"%s\" \"\$$_sdkey\""
|
|
|
- )
|
|
|
+ _sdv="$(grep "^$_sdkey *=" "$_r_c_f" | cut -d = -f 2-1000 | tr -d "'")"
|
|
|
+ if _startswith "$_sdv" "${B64CONF_START}" && _endswith "$_sdv" "${B64CONF_END}"; then
|
|
|
+ _sdv="$(echo "$_sdv" | sed "s/${B64CONF_START}//" | sed "s/${B64CONF_END}//" | _dbase64)"
|
|
|
+ fi
|
|
|
+ printf "%s" "$_sdv"
|
|
|
else
|
|
|
_debug "config file is empty, can not read $_sdkey"
|
|
|
fi
|
|
|
}
|
|
|
|
|
|
-#_savedomainconf key value
|
|
|
+#_savedomainconf key value base64encode
|
|
|
#save to domain.conf
|
|
|
_savedomainconf() {
|
|
|
- _save_conf "$DOMAIN_CONF" "$1" "$2"
|
|
|
+ _save_conf "$DOMAIN_CONF" "$@"
|
|
|
}
|
|
|
|
|
|
#_cleardomainconf key
|
|
@@ -2013,14 +2027,14 @@ _readdomainconf() {
|
|
|
_read_conf "$DOMAIN_CONF" "$1"
|
|
|
}
|
|
|
|
|
|
-#_saveaccountconf key value
|
|
|
+#_saveaccountconf key value base64encode
|
|
|
_saveaccountconf() {
|
|
|
- _save_conf "$ACCOUNT_CONF_PATH" "$1" "$2"
|
|
|
+ _save_conf "$ACCOUNT_CONF_PATH" "$@"
|
|
|
}
|
|
|
|
|
|
-#key value
|
|
|
+#key value base64encode
|
|
|
_saveaccountconf_mutable() {
|
|
|
- _save_conf "$ACCOUNT_CONF_PATH" "SAVED_$1" "$2"
|
|
|
+ _save_conf "$ACCOUNT_CONF_PATH" "SAVED_$1" "$2" "$3"
|
|
|
#remove later
|
|
|
_clearaccountconf "$1"
|
|
|
}
|
|
@@ -2060,6 +2074,7 @@ _clearcaconf() {
|
|
|
_startserver() {
|
|
|
content="$1"
|
|
|
ncaddr="$2"
|
|
|
+ _debug "content" "$content"
|
|
|
_debug "ncaddr" "$ncaddr"
|
|
|
|
|
|
_debug "startserver: $$"
|
|
@@ -2086,8 +2101,14 @@ _startserver() {
|
|
|
SOCAT_OPTIONS="$SOCAT_OPTIONS,bind=${ncaddr}"
|
|
|
fi
|
|
|
|
|
|
+ _content_len="$(printf "%s" "$content" | wc -c)"
|
|
|
+ _debug _content_len "$_content_len"
|
|
|
_debug "_NC" "$_NC $SOCAT_OPTIONS"
|
|
|
- $_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; echo HTTP/1.0 200 OK; echo ; echo $content; echo;" &
|
|
|
+ $_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; \
|
|
|
+echo 'HTTP/1.0 200 OK'; \
|
|
|
+echo 'Content-Length\: $_content_len'; \
|
|
|
+echo ''; \
|
|
|
+printf '$content';" &
|
|
|
serverproc="$!"
|
|
|
}
|
|
|
|
|
@@ -3062,6 +3083,7 @@ _on_before_issue() {
|
|
|
_info "Standalone mode."
|
|
|
if [ -z "$Le_HTTPPort" ]; then
|
|
|
Le_HTTPPort=80
|
|
|
+ _cleardomainconf "Le_HTTPPort"
|
|
|
else
|
|
|
_savedomainconf "Le_HTTPPort" "$Le_HTTPPort"
|
|
|
fi
|
|
@@ -3269,7 +3291,7 @@ _regAccount() {
|
|
|
fi
|
|
|
|
|
|
_debug2 responseHeaders "$responseHeaders"
|
|
|
- _accUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")"
|
|
|
+ _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")"
|
|
|
_debug "_accUri" "$_accUri"
|
|
|
if [ -z "$_accUri" ]; then
|
|
|
_err "Can not find account id url."
|
|
@@ -3435,7 +3457,7 @@ __trigger_validation() {
|
|
|
_t_vtype="$3"
|
|
|
_debug2 _t_vtype "$_t_vtype"
|
|
|
if [ "$ACME_VERSION" = "2" ]; then
|
|
|
- _send_signed_request "$_t_url" "{\"keyAuthorization\": \"$_t_key_authz\"}"
|
|
|
+ _send_signed_request "$_t_url" "{}"
|
|
|
else
|
|
|
_send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"type\": \"$_t_vtype\", \"keyAuthorization\": \"$_t_key_authz\"}"
|
|
|
fi
|
|
@@ -3628,9 +3650,9 @@ issue() {
|
|
|
_savedomainconf "Le_Alt" "$_alt_domains"
|
|
|
_savedomainconf "Le_Webroot" "$_web_roots"
|
|
|
|
|
|
- _savedomainconf "Le_PreHook" "$_pre_hook"
|
|
|
- _savedomainconf "Le_PostHook" "$_post_hook"
|
|
|
- _savedomainconf "Le_RenewHook" "$_renew_hook"
|
|
|
+ _savedomainconf "Le_PreHook" "$_pre_hook" "base64"
|
|
|
+ _savedomainconf "Le_PostHook" "$_post_hook" "base64"
|
|
|
+ _savedomainconf "Le_RenewHook" "$_renew_hook" "base64"
|
|
|
|
|
|
if [ "$_local_addr" ]; then
|
|
|
_savedomainconf "Le_LocalAddress" "$_local_addr"
|
|
@@ -4205,20 +4227,66 @@ $_authorizations_map"
|
|
|
der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)"
|
|
|
|
|
|
if [ "$ACME_VERSION" = "2" ]; then
|
|
|
+ _info "Lets finalize the order, Le_OrderFinalize: $Le_OrderFinalize"
|
|
|
if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then
|
|
|
_err "Sign failed."
|
|
|
_on_issue_err "$_post_hook"
|
|
|
return 1
|
|
|
fi
|
|
|
if [ "$code" != "200" ]; then
|
|
|
- _err "Sign failed, code is not 200."
|
|
|
+ _err "Sign failed, finalize code is not 200."
|
|
|
_err "$response"
|
|
|
_on_issue_err "$_post_hook"
|
|
|
return 1
|
|
|
fi
|
|
|
- Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)"
|
|
|
+ Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)"
|
|
|
+ if [ -z "$Le_LinkOrder" ]; then
|
|
|
+ _err "Sign error, can not get order link location header"
|
|
|
+ _err "responseHeaders" "$responseHeaders"
|
|
|
+ _on_issue_err "$_post_hook"
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+ _savedomainconf "Le_LinkOrder" "$Le_LinkOrder"
|
|
|
+
|
|
|
+ _link_cert_retry=0
|
|
|
+ _MAX_CERT_RETRY=5
|
|
|
+ while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do
|
|
|
+ if _contains "$response" "\"status\":\"valid\""; then
|
|
|
+ _debug "Order status is valid."
|
|
|
+ Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)"
|
|
|
+ _debug Le_LinkCert "$Le_LinkCert"
|
|
|
+ if [ -z "$Le_LinkCert" ]; then
|
|
|
+ _err "Sign error, can not find Le_LinkCert"
|
|
|
+ _err "$response"
|
|
|
+ _on_issue_err "$_post_hook"
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+ break
|
|
|
+ elif _contains "$response" "\"processing\""; then
|
|
|
+ _info "Order status is processing, lets sleep and retry."
|
|
|
+ _sleep 2
|
|
|
+ else
|
|
|
+ _err "Sign error, wrong status"
|
|
|
+ _err "$response"
|
|
|
+ _on_issue_err "$_post_hook"
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+ if ! _send_signed_request "$Le_LinkOrder"; then
|
|
|
+ _err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder."
|
|
|
+ _err "$response"
|
|
|
+ _on_issue_err "$_post_hook"
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+ _link_cert_retry="$(_math $_link_cert_retry + 1)"
|
|
|
+ done
|
|
|
|
|
|
- _tempSignedResponse="$response"
|
|
|
+ if [ -z "$Le_LinkCert" ]; then
|
|
|
+ _err "Sign failed, can not get Le_LinkCert, retry time limit."
|
|
|
+ _err "$response"
|
|
|
+ _on_issue_err "$_post_hook"
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+ _info "Download cert, Le_LinkCert: $Le_LinkCert"
|
|
|
if ! _send_signed_request "$Le_LinkCert"; then
|
|
|
_err "Sign failed, can not download cert:$Le_LinkCert."
|
|
|
_err "$response"
|
|
@@ -4237,7 +4305,7 @@ $_authorizations_map"
|
|
|
_end_n="$(_math $_end_n + 1)"
|
|
|
sed -n "${_end_n},9999p" "$CERT_FULLCHAIN_PATH" >"$CA_CERT_PATH"
|
|
|
fi
|
|
|
- response="$_tempSignedResponse"
|
|
|
+
|
|
|
else
|
|
|
if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then
|
|
|
_err "Sign failed. $response"
|
|
@@ -4395,7 +4463,7 @@ $_authorizations_map"
|
|
|
_savedomainconf "Le_RealCertPath" "$_real_cert"
|
|
|
_savedomainconf "Le_RealCACertPath" "$_real_ca"
|
|
|
_savedomainconf "Le_RealKeyPath" "$_real_key"
|
|
|
- _savedomainconf "Le_ReloadCmd" "$_reload_cmd"
|
|
|
+ _savedomainconf "Le_ReloadCmd" "$_reload_cmd" "base64"
|
|
|
_savedomainconf "Le_RealFullChainPath" "$_real_fullchain"
|
|
|
if ! _installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd"; then
|
|
|
return 1
|
|
@@ -4462,6 +4530,10 @@ renew() {
|
|
|
fi
|
|
|
|
|
|
IS_RENEW="1"
|
|
|
+ Le_ReloadCmd="$(_readdomainconf Le_ReloadCmd)"
|
|
|
+ Le_PreHook="$(_readdomainconf Le_PreHook)"
|
|
|
+ Le_PostHook="$(_readdomainconf Le_PostHook)"
|
|
|
+ Le_RenewHook="$(_readdomainconf Le_RenewHook)"
|
|
|
issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias"
|
|
|
res="$?"
|
|
|
if [ "$res" != "0" ]; then
|
|
@@ -4742,7 +4814,7 @@ installcert() {
|
|
|
_savedomainconf "Le_RealCertPath" "$_real_cert"
|
|
|
_savedomainconf "Le_RealCACertPath" "$_real_ca"
|
|
|
_savedomainconf "Le_RealKeyPath" "$_real_key"
|
|
|
- _savedomainconf "Le_ReloadCmd" "$_reload_cmd"
|
|
|
+ _savedomainconf "Le_ReloadCmd" "$_reload_cmd" "base64"
|
|
|
_savedomainconf "Le_RealFullChainPath" "$_real_fullchain"
|
|
|
|
|
|
_installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd"
|
|
@@ -4826,7 +4898,7 @@ _installcert() {
|
|
|
export CERT_KEY_PATH
|
|
|
export CA_CERT_PATH
|
|
|
export CERT_FULLCHAIN_PATH
|
|
|
- export Le_Domain
|
|
|
+ export Le_Domain="$_main_domain"
|
|
|
cd "$DOMAIN_PATH" && eval "$_reload_cmd"
|
|
|
); then
|
|
|
_info "$(__green "Reload success")"
|