|
|
@ -13,8 +13,15 @@ _SCRIPT_="$0" |
|
|
|
|
|
|
|
_SUB_FOLDERS="dnsapi deploy" |
|
|
|
|
|
|
|
_OLD_CA_HOST="https://acme-v01.api.letsencrypt.org" |
|
|
|
DEFAULT_CA="https://acme-v01.api.letsencrypt.org/directory" |
|
|
|
LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory" |
|
|
|
LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory" |
|
|
|
|
|
|
|
LETSENCRYPT_CA_V2="https://acme-v02.api.letsencrypt.org/directory" |
|
|
|
LETSENCRYPT_STAGING_CA_V2="https://acme-staging-v02.api.letsencrypt.org/directory" |
|
|
|
|
|
|
|
DEFAULT_CA=$LETSENCRYPT_CA_V1 |
|
|
|
DEFAULT_STAGING_CA=$LETSENCRYPT_STAGING_CA_V1 |
|
|
|
|
|
|
|
|
|
|
|
DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" |
|
|
|
DEFAULT_ACCOUNT_EMAIL="" |
|
|
@ -24,13 +31,13 @@ DEFAULT_DOMAIN_KEY_LENGTH=2048 |
|
|
|
|
|
|
|
DEFAULT_OPENSSL_BIN="openssl" |
|
|
|
|
|
|
|
STAGE_CA="https://acme-staging.api.letsencrypt.org/directory" |
|
|
|
_OLD_CA_HOST="https://acme-v01.api.letsencrypt.org" |
|
|
|
_OLD_STAGE_CA_HOST="https://acme-staging.api.letsencrypt.org" |
|
|
|
|
|
|
|
VTYPE_HTTP="http-01" |
|
|
|
VTYPE_DNS="dns-01" |
|
|
|
VTYPE_TLS="tls-sni-01" |
|
|
|
#VTYPE_TLS2="tls-sni-02" |
|
|
|
VTYPE_TLS2="tls-sni-02" |
|
|
|
|
|
|
|
LOCAL_ANY_ADDRESS="0.0.0.0" |
|
|
|
|
|
|
@ -1044,13 +1051,14 @@ _createcsr() { |
|
|
|
if [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then |
|
|
|
#single domain |
|
|
|
_info "Single domain" "$domain" |
|
|
|
printf -- "\nsubjectAltName=DNS:$domain" >>"$csrconf" |
|
|
|
else |
|
|
|
domainlist="$(_idn "$domainlist")" |
|
|
|
_debug2 domainlist "$domainlist" |
|
|
|
if _contains "$domainlist" ","; then |
|
|
|
alt="DNS:$(echo "$domainlist" | sed "s/,/,DNS:/g")" |
|
|
|
alt="DNS:$domain,DNS:$(echo "$domainlist" | sed "s/,/,DNS:/g")" |
|
|
|
else |
|
|
|
alt="DNS:$domainlist" |
|
|
|
alt="DNS:$domain,DNS:$domainlist" |
|
|
|
fi |
|
|
|
#multi |
|
|
|
_info "Multi domain" "$alt" |
|
|
@ -1421,7 +1429,7 @@ _calcjwk() { |
|
|
|
|
|
|
|
JWK_HEADER='{"alg": "RS256", "jwk": '$jwk'}' |
|
|
|
JWK_HEADERPLACE_PART1='{"nonce": "' |
|
|
|
JWK_HEADERPLACE_PART2='", "alg": "RS256", "jwk": '$jwk'}' |
|
|
|
JWK_HEADERPLACE_PART2='", "alg": "RS256"' |
|
|
|
elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then |
|
|
|
_debug "EC key" |
|
|
|
crv="$(${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" | cut -d ":" -f 2 | tr -d " \r\n")" |
|
|
@ -1490,7 +1498,7 @@ _calcjwk() { |
|
|
|
|
|
|
|
JWK_HEADER='{"alg": "ES'$__ECC_KEY_LEN'", "jwk": '$jwk'}' |
|
|
|
JWK_HEADERPLACE_PART1='{"nonce": "' |
|
|
|
JWK_HEADERPLACE_PART2='", "alg": "ES'$__ECC_KEY_LEN'", "jwk": '$jwk'}' |
|
|
|
JWK_HEADERPLACE_PART2='", "alg": "ES'$__ECC_KEY_LEN'"' |
|
|
|
else |
|
|
|
_err "Only RSA or EC key is supported." |
|
|
|
return 1 |
|
|
@ -1580,7 +1588,7 @@ _inithttp() { |
|
|
|
# body url [needbase64] [POST|PUT] |
|
|
|
_post() { |
|
|
|
body="$1" |
|
|
|
url="$2" |
|
|
|
_post_url="$2" |
|
|
|
needbase64="$3" |
|
|
|
httpmethod="$4" |
|
|
|
|
|
|
@ -1588,7 +1596,7 @@ _post() { |
|
|
|
httpmethod="POST" |
|
|
|
fi |
|
|
|
_debug $httpmethod |
|
|
|
_debug "url" "$url" |
|
|
|
_debug "_post_url" "$_post_url" |
|
|
|
_debug2 "body" "$body" |
|
|
|
|
|
|
|
_inithttp |
|
|
@ -1600,9 +1608,9 @@ _post() { |
|
|
|
fi |
|
|
|
_debug "_CURL" "$_CURL" |
|
|
|
if [ "$needbase64" ]; then |
|
|
|
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$url" | _base64)" |
|
|
|
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" |
|
|
|
else |
|
|
|
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$url")" |
|
|
|
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" |
|
|
|
fi |
|
|
|
_ret="$?" |
|
|
|
if [ "$_ret" != "0" ]; then |
|
|
@ -1620,15 +1628,15 @@ _post() { |
|
|
|
_debug "_WGET" "$_WGET" |
|
|
|
if [ "$needbase64" ]; then |
|
|
|
if [ "$httpmethod" = "POST" ]; then |
|
|
|
response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$url" 2>"$HTTP_HEADER" | _base64)" |
|
|
|
response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" |
|
|
|
else |
|
|
|
response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$url" 2>"$HTTP_HEADER" | _base64)" |
|
|
|
response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" |
|
|
|
fi |
|
|
|
else |
|
|
|
if [ "$httpmethod" = "POST" ]; then |
|
|
|
response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$url" 2>"$HTTP_HEADER")" |
|
|
|
response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")" |
|
|
|
else |
|
|
|
response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$url" 2>"$HTTP_HEADER")" |
|
|
|
response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")" |
|
|
|
fi |
|
|
|
fi |
|
|
|
_ret="$?" |
|
|
@ -1776,7 +1784,15 @@ _send_signed_request() { |
|
|
|
nonce="$_CACHED_NONCE" |
|
|
|
_debug2 nonce "$nonce" |
|
|
|
|
|
|
|
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2" |
|
|
|
if [ "$ACME_VERSION" = "2" ]; then |
|
|
|
if [ "$url" = "$ACME_NEW_ACCOUNT" ]; then |
|
|
|
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}' |
|
|
|
else |
|
|
|
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"kid\": \"$ACCOUNT_URL\""'}' |
|
|
|
fi |
|
|
|
else |
|
|
|
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}' |
|
|
|
fi |
|
|
|
_debug3 protected "$protected" |
|
|
|
|
|
|
|
protected64="$(printf "%s" "$protected" | _base64 | _url_replace)" |
|
|
@ -1791,7 +1807,11 @@ _send_signed_request() { |
|
|
|
sig="$(printf "%s" "$_sig_t" | _url_replace)" |
|
|
|
_debug3 sig "$sig" |
|
|
|
|
|
|
|
if [ "$ACME_VERSION" = "2" ]; then |
|
|
|
body="{\"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" |
|
|
|
else |
|
|
|
body="{\"header\": $JWK_HEADER, \"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" |
|
|
|
fi |
|
|
|
_debug3 body "$body" |
|
|
|
|
|
|
|
response="$(_post "$body" "$url" "$needbase64")" |
|
|
@ -2170,9 +2190,15 @@ _initAPI() { |
|
|
|
_debug2 "response" "$response" |
|
|
|
|
|
|
|
ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'key-change" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
if [ -z "$ACME_KEY_CHANGE" ]; then |
|
|
|
ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'keyChange" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
fi |
|
|
|
export ACME_KEY_CHANGE |
|
|
|
|
|
|
|
ACME_NEW_AUTHZ=$(echo "$response" | _egrep_o 'new-authz" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
if [ -z "$ACME_NEW_AUTHZ" ]; then |
|
|
|
ACME_NEW_AUTHZ=$(echo "$response" | _egrep_o 'newAuthz" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
fi |
|
|
|
export ACME_NEW_AUTHZ |
|
|
|
|
|
|
|
ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'new-cert" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
@ -2180,6 +2206,9 @@ _initAPI() { |
|
|
|
if [ -z "$ACME_NEW_ORDER" ]; then |
|
|
|
ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'new-order" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
ACME_NEW_ORDER_RES="new-order" |
|
|
|
if [ -z "$ACME_NEW_ORDER" ]; then |
|
|
|
ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'newOrder" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
fi |
|
|
|
fi |
|
|
|
export ACME_NEW_ORDER |
|
|
|
export ACME_NEW_ORDER_RES |
|
|
@ -2189,17 +2218,32 @@ _initAPI() { |
|
|
|
if [ -z "$ACME_NEW_ACCOUNT" ]; then |
|
|
|
ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'new-account" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
ACME_NEW_ACCOUNT_RES="new-account" |
|
|
|
if [ -z "$ACME_NEW_ACCOUNT" ]; then |
|
|
|
ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'newAccount" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
if [ "$ACME_NEW_ACCOUNT" ]; then |
|
|
|
export ACME_VERSION=2 |
|
|
|
fi |
|
|
|
fi |
|
|
|
fi |
|
|
|
export ACME_NEW_ACCOUNT |
|
|
|
export ACME_NEW_ACCOUNT_RES |
|
|
|
|
|
|
|
ACME_REVOKE_CERT=$(echo "$response" | _egrep_o 'revoke-cert" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
if [ -z "$ACME_REVOKE_CERT" ]; then |
|
|
|
ACME_REVOKE_CERT=$(echo "$response" | _egrep_o 'revokeCert" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
fi |
|
|
|
export ACME_REVOKE_CERT |
|
|
|
|
|
|
|
ACME_NEW_NONCE=$(echo "$response" | _egrep_o 'new-nonce" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
if [ -z "$ACME_NEW_NONCE" ]; then |
|
|
|
ACME_NEW_NONCE=$(echo "$response" | _egrep_o 'newNonce" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
fi |
|
|
|
export ACME_NEW_NONCE |
|
|
|
|
|
|
|
ACME_AGREEMENT=$(echo "$response" | _egrep_o 'terms-of-service" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
if [ -z "$ACME_AGREEMENT" ]; then |
|
|
|
ACME_AGREEMENT=$(echo "$response" | _egrep_o 'termsOfService" *: *"[^"]*"' | cut -d '"' -f 3) |
|
|
|
fi |
|
|
|
export ACME_AGREEMENT |
|
|
|
|
|
|
|
_debug "ACME_KEY_CHANGE" "$ACME_KEY_CHANGE" |
|
|
@ -2208,6 +2252,8 @@ _initAPI() { |
|
|
|
_debug "ACME_NEW_ACCOUNT" "$ACME_NEW_ACCOUNT" |
|
|
|
_debug "ACME_REVOKE_CERT" "$ACME_REVOKE_CERT" |
|
|
|
_debug "ACME_AGREEMENT" "$ACME_AGREEMENT" |
|
|
|
_debug "ACME_NEW_NONCE" "$ACME_NEW_NONCE" |
|
|
|
_debug "ACME_VERSION" "$ACME_VERSION" |
|
|
|
|
|
|
|
fi |
|
|
|
} |
|
|
@ -2236,7 +2282,7 @@ _initpath() { |
|
|
|
if [ -z "$STAGE" ]; then |
|
|
|
ACME_DIRECTORY="$DEFAULT_CA" |
|
|
|
else |
|
|
|
ACME_DIRECTORY="$STAGE_CA" |
|
|
|
ACME_DIRECTORY="$DEFAULT_STAGING_CA" |
|
|
|
_info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" |
|
|
|
fi |
|
|
|
fi |
|
|
@ -2951,6 +2997,7 @@ _on_issue_err() { |
|
|
|
_chk_post_hook="$1" |
|
|
|
_chk_vlist="$2" |
|
|
|
_debug _on_issue_err |
|
|
|
_cleardomainconf "ORDER_FINALIZE" |
|
|
|
if [ "$LOG_FILE" ]; then |
|
|
|
_err "Please check log file for more details: $LOG_FILE" |
|
|
|
else |
|
|
@ -3052,6 +3099,8 @@ _regAccount() { |
|
|
|
_initpath |
|
|
|
_reg_length="$1" |
|
|
|
_debug3 _regAccount "$_regAccount" |
|
|
|
_initAPI |
|
|
|
|
|
|
|
mkdir -p "$CA_DIR" |
|
|
|
if [ ! -f "$ACCOUNT_KEY_PATH" ] && [ -f "$_OLD_ACCOUNT_KEY" ]; then |
|
|
|
_info "mv $_OLD_ACCOUNT_KEY to $ACCOUNT_KEY_PATH" |
|
|
@ -3073,12 +3122,19 @@ _regAccount() { |
|
|
|
if ! _calcjwk "$ACCOUNT_KEY_PATH"; then |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
_initAPI |
|
|
|
|
|
|
|
if [ "$ACME_VERSION" = "2" ]; then |
|
|
|
regjson='{"termsOfServiceAgreed": true}' |
|
|
|
if [ "$ACCOUNT_EMAIL" ]; then |
|
|
|
regjson='{"contact": ["mailto: '$ACCOUNT_EMAIL'"], "termsOfServiceAgreed": true}' |
|
|
|
fi |
|
|
|
else |
|
|
|
_reg_res="$ACME_NEW_ACCOUNT_RES" |
|
|
|
regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' |
|
|
|
if [ "$ACCOUNT_EMAIL" ]; then |
|
|
|
regjson='{"resource": "'$_reg_res'", "contact": ["mailto: '$ACCOUNT_EMAIL'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' |
|
|
|
fi |
|
|
|
fi |
|
|
|
|
|
|
|
_info "Registering account" |
|
|
|
|
|
|
@ -3100,8 +3156,8 @@ _regAccount() { |
|
|
|
_accUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")" |
|
|
|
_debug "_accUri" "$_accUri" |
|
|
|
_savecaconf "ACCOUNT_URL" "$_accUri" |
|
|
|
export ACCOUNT_URL="$ACCOUNT_URL" |
|
|
|
|
|
|
|
echo "$response" >"$ACCOUNT_JSON_PATH" |
|
|
|
CA_KEY_HASH="$(__calcAccountKeyHash)" |
|
|
|
_debug "Calc CA_KEY_HASH" "$CA_KEY_HASH" |
|
|
|
_savecaconf CA_KEY_HASH "$CA_KEY_HASH" |
|
|
@ -3113,7 +3169,6 @@ _regAccount() { |
|
|
|
|
|
|
|
ACCOUNT_THUMBPRINT="$(__calc_account_thumbprint)" |
|
|
|
_info "ACCOUNT_THUMBPRINT" "$ACCOUNT_THUMBPRINT" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#Implement deactivate account |
|
|
@ -3251,7 +3306,11 @@ __trigger_validation() { |
|
|
|
_debug2 _t_url "$_t_url" |
|
|
|
_t_key_authz="$2" |
|
|
|
_debug2 _t_key_authz "$_t_key_authz" |
|
|
|
if [ "$ACME_VERSION" = "2" ]; then |
|
|
|
_send_signed_request "$_t_url" "{\"keyAuthorization\": \"$_t_key_authz\"}" |
|
|
|
else |
|
|
|
_send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"keyAuthorization\": \"$_t_key_authz\"}" |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
#webroot, domain domainlist keylength |
|
|
@ -3393,33 +3452,108 @@ issue() { |
|
|
|
sep='#' |
|
|
|
dvsep=',' |
|
|
|
if [ -z "$vlist" ]; then |
|
|
|
if [ "$ACME_VERSION" = "2" ] && [ -z "$ORDER_FINALIZE" ]; then |
|
|
|
#make new order request |
|
|
|
_identifiers="{\"type\":\"dns\",\"value\":\"$_main_domain\"}" |
|
|
|
for d in $(echo "$_alt_domains" | tr ',' ' '); do |
|
|
|
#todo: check wildcard ? |
|
|
|
if [ "$d" ]; then |
|
|
|
_identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$d\"}" |
|
|
|
fi |
|
|
|
done |
|
|
|
_debug2 _identifiers "$_identifiers" |
|
|
|
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then |
|
|
|
_err "Create new order error." |
|
|
|
_clearup |
|
|
|
_on_issue_err "$_post_hook" |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
|
|
|
|
ORDER_FINALIZE="$(echo "$response"| tr -d '\r\n' | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4)" |
|
|
|
_debug ORDER_FINALIZE "$ORDER_FINALIZE" |
|
|
|
if [ -z "$ORDER_FINALIZE" ]; then |
|
|
|
_err "ORDER_FINALIZE not found." |
|
|
|
_clearup |
|
|
|
_on_issue_err "$_post_hook" |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
|
|
|
|
#for dns manual mode |
|
|
|
_savedomainconf "ORDER_FINALIZE" "$ORDER_FINALIZE" |
|
|
|
|
|
|
|
_authorizations_seg="$(echo "$response"| tr -d '\r\n' | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" |
|
|
|
_debug2 _authorizations_seg "$_authorizations_seg" |
|
|
|
if [ -z "$_authorizations_seg" ]; then |
|
|
|
_err "_authorizations_seg not found." |
|
|
|
_clearup |
|
|
|
_on_issue_err "$_post_hook" |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
|
|
|
|
#domain and authz map |
|
|
|
_authorizations_map="" |
|
|
|
for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' ' ); do |
|
|
|
_debug2 "_authz_url" "$_authz_url" |
|
|
|
if ! response="$(_get "$_authz_url")"; then |
|
|
|
_err "get to authz error." |
|
|
|
_clearup |
|
|
|
_on_issue_err "$_post_hook" |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
|
|
|
|
response="$(echo "$response" | _normalizeJson)" |
|
|
|
_debug2 response "$response" |
|
|
|
_d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2 | tr -d ' "')" |
|
|
|
_debug2 _d "$_d" |
|
|
|
_authorizations_map="$_d,$response |
|
|
|
$_authorizations_map" |
|
|
|
done |
|
|
|
_debug2 _authorizations_map "$_authorizations_map" |
|
|
|
fi |
|
|
|
|
|
|
|
alldomains=$(echo "$_main_domain,$_alt_domains" | tr ',' ' ') |
|
|
|
_index=1 |
|
|
|
_index=0 |
|
|
|
_currentRoot="" |
|
|
|
for d in $alldomains; do |
|
|
|
_info "Getting webroot for domain" "$d" |
|
|
|
_index=$(_math $_index + 1) |
|
|
|
_w="$(echo $_web_roots | cut -d , -f $_index)" |
|
|
|
_debug _w "$_w" |
|
|
|
if [ "$_w" ]; then |
|
|
|
_currentRoot="$_w" |
|
|
|
fi |
|
|
|
_debug "_currentRoot" "$_currentRoot" |
|
|
|
_index=$(_math $_index + 1) |
|
|
|
|
|
|
|
vtype="$VTYPE_HTTP" |
|
|
|
#todo, v2 wildcard force to use dns |
|
|
|
if _startswith "$_currentRoot" "dns"; then |
|
|
|
vtype="$VTYPE_DNS" |
|
|
|
fi |
|
|
|
|
|
|
|
if [ "$_currentRoot" = "$W_TLS" ]; then |
|
|
|
if [ "$ACME_VERSION" = "2" ]; then |
|
|
|
vtype="$VTYPE_TLS2" |
|
|
|
else |
|
|
|
vtype="$VTYPE_TLS" |
|
|
|
fi |
|
|
|
fi |
|
|
|
|
|
|
|
if [ "$ACME_VERSION" = "2" ]; then |
|
|
|
response="$(echo "$_authorizations_map" | grep "^$d," | sed "s/$d,//")" |
|
|
|
_debug2 "response" "$response" |
|
|
|
if [ -z "$response" ]; then |
|
|
|
_err "get to authz error." |
|
|
|
_clearup |
|
|
|
_on_issue_err "$_post_hook" |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
else |
|
|
|
if ! __get_domain_new_authz "$d"; then |
|
|
|
_clearup |
|
|
|
_on_issue_err "$_post_hook" |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
fi |
|
|
|
|
|
|
|
if [ -z "$thumbprint" ]; then |
|
|
|
thumbprint="$(__calc_account_thumbprint)" |
|
|
@ -3436,14 +3570,18 @@ issue() { |
|
|
|
token="$(printf "%s\n" "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" |
|
|
|
_debug token "$token" |
|
|
|
|
|
|
|
if [ "$ACME_VERSION" = "2" ]; then |
|
|
|
uri="$(printf "%s\n" "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" |
|
|
|
else |
|
|
|
uri="$(printf "%s\n" "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)" |
|
|
|
fi |
|
|
|
_debug uri "$uri" |
|
|
|
|
|
|
|
keyauthorization="$token.$thumbprint" |
|
|
|
_debug keyauthorization "$keyauthorization" |
|
|
|
|
|
|
|
if printf "%s" "$response" | grep '"status":"valid"' >/dev/null 2>&1; then |
|
|
|
_debug "$d is already verified, skip." |
|
|
|
_debug "$d is already verified." |
|
|
|
keyauthorization="$STATE_VERIFIED" |
|
|
|
_debug keyauthorization "$keyauthorization" |
|
|
|
fi |
|
|
@ -3685,13 +3823,17 @@ issue() { |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
|
|
|
|
if [ ! -z "$code" ] && [ ! "$code" = '202' ]; then |
|
|
|
if [ "$code" ] && [ "$code" != '202' ]; then |
|
|
|
if [ "$ACME_VERSION" = "2" ] && [ "$code" = '200' ]; then |
|
|
|
_debug "trigger validation code: $code" |
|
|
|
else |
|
|
|
_err "$d:Challenge error: $response" |
|
|
|
_clearupwebbroot "$_currentRoot" "$removelevel" "$token" |
|
|
|
_clearup |
|
|
|
_on_issue_err "$_post_hook" "$vlist" |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
fi |
|
|
|
|
|
|
|
waittimes=0 |
|
|
|
if [ -z "$MAX_RETRY_TIMES" ]; then |
|
|
@ -3773,18 +3915,32 @@ issue() { |
|
|
|
_info "Verify finished, start to sign." |
|
|
|
der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" |
|
|
|
|
|
|
|
if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then |
|
|
|
if [ "$ACME_VERSION" = "2" ]; then |
|
|
|
if ! _send_signed_request "${ORDER_FINALIZE}" "{\"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." |
|
|
|
_on_issue_err "$_post_hook" |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
Le_LinkCert="$(echo "$response"| tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" |
|
|
|
|
|
|
|
if ! _get "$Le_LinkCert" > "$CERT_PATH"; then |
|
|
|
_err "Sign failed, code is not 200." |
|
|
|
_on_issue_err "$_post_hook" |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
else |
|
|
|
if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then |
|
|
|
_err "Sign failed." |
|
|
|
_on_issue_err "$_post_hook" |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
_rcert="$response" |
|
|
|
Le_LinkCert="$(grep -i '^Location.*$' "$HTTP_HEADER" | _head_n 1 | tr -d "\r\n" | cut -d " " -f 2)" |
|
|
|
_debug "Le_LinkCert" "$Le_LinkCert" |
|
|
|
_savedomainconf "Le_LinkCert" "$Le_LinkCert" |
|
|
|
|
|
|
|
if [ "$Le_LinkCert" ]; then |
|
|
|
echo "$BEGIN_CERT" >"$CERT_PATH" |
|
|
|
|
|
|
|
#if ! _get "$Le_LinkCert" | _base64 "multiline" >> "$CERT_PATH" ; then |
|
|
@ -3798,6 +3954,12 @@ issue() { |
|
|
|
fi |
|
|
|
|
|
|
|
echo "$END_CERT" >>"$CERT_PATH" |
|
|
|
fi |
|
|
|
|
|
|
|
_debug "Le_LinkCert" "$Le_LinkCert" |
|
|
|
_savedomainconf "Le_LinkCert" "$Le_LinkCert" |
|
|
|
|
|
|
|
if [ "$Le_LinkCert" ]; then |
|
|
|
_info "$(__green "Cert success.")" |
|
|
|
cat "$CERT_PATH" |
|
|
|
|
|
|
@ -3825,6 +3987,8 @@ issue() { |
|
|
|
_cleardomainconf "Le_Vlist" |
|
|
|
|
|
|
|
Le_LinkIssuer=$(grep -i '^Link' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2 | cut -d ';' -f 1 | tr -d '<>') |
|
|
|
|
|
|
|
if [ "$Le_LinkIssuer" ]; then |
|
|
|
if ! _contains "$Le_LinkIssuer" ":"; then |
|
|
|
_info "$(__red "Relative issuer link found.")" |
|
|
|
Le_LinkIssuer="$_ACME_SERVER_HOST$Le_LinkIssuer" |
|
|
@ -3832,11 +3996,16 @@ issue() { |
|
|
|
_debug Le_LinkIssuer "$Le_LinkIssuer" |
|
|
|
_savedomainconf "Le_LinkIssuer" "$Le_LinkIssuer" |
|
|
|
|
|
|
|
if [ "$Le_LinkIssuer" ]; then |
|
|
|
_link_issuer_retry=0 |
|
|
|
_MAX_ISSUER_RETRY=5 |
|
|
|
while [ "$_link_issuer_retry" -lt "$_MAX_ISSUER_RETRY" ]; do |
|
|
|
_debug _link_issuer_retry "$_link_issuer_retry" |
|
|
|
|
|
|
|
if [ "$ACME_VERSION" = "2" ]; then |
|
|
|
if _get "$Le_LinkIssuer" >"$CA_CERT_PATH"; then |
|
|
|
break |
|
|
|
fi |
|
|
|
else |
|
|
|
if _get "$Le_LinkIssuer" >"$CA_CERT_PATH.der"; then |
|
|
|
echo "$BEGIN_CERT" >"$CA_CERT_PATH" |
|
|
|
_base64 "multiline" <"$CA_CERT_PATH.der" >>"$CA_CERT_PATH" |
|
|
@ -3849,6 +4018,7 @@ issue() { |
|
|
|
rm -f "$CA_CERT_PATH.der" |
|
|
|
break |
|
|
|
fi |
|
|
|
fi |
|
|
|
_link_issuer_retry=$(_math $_link_issuer_retry + 1) |
|
|
|
_sleep "$_link_issuer_retry" |
|
|
|
done |
|
|
@ -3957,7 +4127,7 @@ renew() { |
|
|
|
_savedomainconf Le_API "$Le_API" |
|
|
|
fi |
|
|
|
if [ "$_OLD_STAGE_CA_HOST" = "$Le_API" ]; then |
|
|
|
export Le_API="$STAGE_CA" |
|
|
|
export Le_API="$DEFAULT_STAGING_CA" |
|
|
|
_savedomainconf Le_API "$Le_API" |
|
|
|
fi |
|
|
|
export ACME_DIRECTORY="$Le_API" |
|
|
|