@ -9,6 +9,9 @@ PROJECT_ENTRY="acme.sh"
PROJECT = " https://github.com/Neilpang/ $PROJECT_NAME "
PROJECT = " https://github.com/Neilpang/ $PROJECT_NAME "
DEFAULT_INSTALL_HOME = " $HOME /. $PROJECT_NAME "
DEFAULT_INSTALL_HOME = " $HOME /. $PROJECT_NAME "
_WINDOWS_SCHEDULER_NAME = " $PROJECT_NAME .cron "
_SCRIPT_ = " $0 "
_SCRIPT_ = " $0 "
_SUB_FOLDERS = "dnsapi deploy"
_SUB_FOLDERS = "dnsapi deploy"
@ -19,8 +22,8 @@ LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory"
LETSENCRYPT_CA_V2 = "https://acme-v02.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"
LETSENCRYPT_STAGING_CA_V2 = "https://acme-staging-v02.api.letsencrypt.org/directory"
DEFAULT_CA = $LETSENCRYPT_CA_V 1
DEFAULT_CA = $LETSENCRYPT_CA_V 2
DEFAULT_STAGING_CA = $LETSENCRYPT_STAGING_CA_V 1
DEFAULT_STAGING_CA = $LETSENCRYPT_STAGING_CA_V 2
DEFAULT_USER_AGENT = " $PROJECT_NAME / $VER ( $PROJECT ) "
DEFAULT_USER_AGENT = " $PROJECT_NAME / $VER ( $PROJECT ) "
DEFAULT_ACCOUNT_EMAIL = ""
DEFAULT_ACCOUNT_EMAIL = ""
@ -66,6 +69,9 @@ END_CERT="-----END CERTIFICATE-----"
CONTENT_TYPE_JSON = "application/jose+json"
CONTENT_TYPE_JSON = "application/jose+json"
RENEW_SKIP = 2
RENEW_SKIP = 2
B64CONF_START = "__ACME_BASE64__START_"
B64CONF_END = "__ACME_BASE64__END_"
ECC_SEP = "_"
ECC_SEP = "_"
ECC_SUFFIX = " ${ ECC_SEP } ecc "
ECC_SUFFIX = " ${ ECC_SEP } ecc "
@ -1827,23 +1833,29 @@ _send_signed_request() {
nonceurl = " $ACME_NEW_NONCE "
nonceurl = " $ACME_NEW_NONCE "
if _post "" " $nonceurl " "" "HEAD" " $__request_conent_type " ; then
if _post "" " $nonceurl " "" "HEAD" " $__request_conent_type " ; then
_headers = " $( cat " $HTTP_HEADER " ) "
_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
fi
fi
if [ -z " $_ headers " ] ; then
if [ -z " $_ CACHED_NONCE " ] ; then
_debug2 "Get nonce with GET. ACME_DIRECTORY" " $ACME_DIRECTORY "
_debug2 "Get nonce with GET. ACME_DIRECTORY" " $ACME_DIRECTORY "
nonceurl = " $ACME_DIRECTORY "
nonceurl = " $ACME_DIRECTORY "
_headers = " $( _get " $nonceurl " "onlyheader" ) "
_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
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
if [ " $? " != "0" ] ; then
_err " Can not connect to $nonceurl to get nonce. "
_err " Can not connect to $nonceurl to get nonce. "
return 1
return 1
fi
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
else
_debug2 "Use _CACHED_NONCE" " $_CACHED_NONCE "
_debug2 "Use _CACHED_NONCE" " $_CACHED_NONCE "
fi
fi
@ -1958,12 +1970,16 @@ _setopt() {
_debug3 " $( grep -n " ^ $__opt $__sep " " $__conf " ) "
_debug3 " $( grep -n " ^ $__opt $__sep " " $__conf " ) "
}
}
#_save_conf file key value
#_save_conf file key value base64encode
#save to conf
#save to conf
_save_conf( ) {
_save_conf( ) {
_s_c_f = " $1 "
_s_c_f = " $1 "
_sdkey = " $2 "
_sdkey = " $2 "
_sdvalue = " $3 "
_sdvalue = " $3 "
_b64encode = " $4 "
if [ " $_sdvalue " ] && [ " $_b64encode " ] ; then
_sdvalue = " ${ B64CONF_START } $( printf "%s" " ${ _sdvalue } " | _base64) ${ B64CONF_END } "
fi
if [ " $_s_c_f " ] ; then
if [ " $_s_c_f " ] ; then
_setopt " $_s_c_f " " $_sdkey " "=" " ' $_sdvalue ' "
_setopt " $_s_c_f " " $_sdkey " "=" " ' $_sdvalue ' "
else
else
@ -1988,19 +2004,20 @@ _read_conf() {
_r_c_f = " $1 "
_r_c_f = " $1 "
_sdkey = " $2 "
_sdkey = " $2 "
if [ -f " $_r_c_f " ] ; then
if [ -f " $_r_c_f " ] ; then
(
_sdv = " $( grep " ^ $_sdkey *= " " $_r_c_f " | cut -d = -f 2-1000 | tr -d "'" ) "
eval " $( grep " ^ $_sdkey *= " " $_r_c_f " ) "
if _startswith " $_sdv " " ${ B64CONF_START } " && _endswith " $_sdv " " ${ B64CONF_END } " ; then
eval " printf \"%s\" \"\$ $_sdkey \" "
_sdv = " $( echo " $_sdv " | sed " s/ ${ B64CONF_START } // " | sed " s/ ${ B64CONF_END } // " | _dbase64) "
)
fi
printf "%s" " $_sdv "
else
else
_debug " config file is empty, can not read $_sdkey "
_debug " config file is empty, can not read $_sdkey "
fi
fi
}
}
#_savedomainconf key value
#_savedomainconf key value base64encode
#save to domain.conf
#save to domain.conf
_savedomainconf( ) {
_savedomainconf( ) {
_save_conf " $DOMAIN_CONF " " $ 1" " $2 "
_save_conf " $DOMAIN_CONF " " $ @ "
}
}
#_cleardomainconf key
#_cleardomainconf key
@ -2013,14 +2030,14 @@ _readdomainconf() {
_read_conf " $DOMAIN_CONF " " $1 "
_read_conf " $DOMAIN_CONF " " $1 "
}
}
#_saveaccountconf key value
#_saveaccountconf key value base64encode
_saveaccountconf( ) {
_saveaccountconf( ) {
_save_conf " $ACCOUNT_CONF_PATH " " $ 1" " $2 "
_save_conf " $ACCOUNT_CONF_PATH " " $ @ "
}
}
#key value
#key value base64encode
_saveaccountconf_mutable( ) {
_saveaccountconf_mutable( ) {
_save_conf " $ACCOUNT_CONF_PATH " " SAVED_ $1 " " $2 "
_save_conf " $ACCOUNT_CONF_PATH " " SAVED_ $1 " " $2 " " $3 "
#remove later
#remove later
_clearaccountconf " $1 "
_clearaccountconf " $1 "
}
}
@ -2060,6 +2077,7 @@ _clearcaconf() {
_startserver( ) {
_startserver( ) {
content = " $1 "
content = " $1 "
ncaddr = " $2 "
ncaddr = " $2 "
_debug "content" " $content "
_debug "ncaddr" " $ncaddr "
_debug "ncaddr" " $ncaddr "
_debug " startserver: $$ "
_debug " startserver: $$ "
@ -2086,8 +2104,14 @@ _startserver() {
SOCAT_OPTIONS = " $SOCAT_OPTIONS ,bind= ${ ncaddr } "
SOCAT_OPTIONS = " $SOCAT_OPTIONS ,bind= ${ ncaddr } "
fi
fi
_content_len = " $( printf "%s" " $content " | wc -c) "
_debug _content_len " $_content_len "
_debug "_NC" " $_NC $SOCAT_OPTIONS "
_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 = " $! "
serverproc = " $! "
}
}
@ -3062,6 +3086,7 @@ _on_before_issue() {
_info "Standalone mode."
_info "Standalone mode."
if [ -z " $Le_HTTPPort " ] ; then
if [ -z " $Le_HTTPPort " ] ; then
Le_HTTPPort = 80
Le_HTTPPort = 80
_cleardomainconf "Le_HTTPPort"
else
else
_savedomainconf "Le_HTTPPort" " $Le_HTTPPort "
_savedomainconf "Le_HTTPPort" " $Le_HTTPPort "
fi
fi
@ -3269,7 +3294,7 @@ _regAccount() {
fi
fi
_debug2 responseHeaders " $responseHeaders "
_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 "
_debug "_accUri" " $_accUri "
if [ -z " $_accUri " ] ; then
if [ -z " $_accUri " ] ; then
_err "Can not find account id url."
_err "Can not find account id url."
@ -3435,7 +3460,7 @@ __trigger_validation() {
_t_vtype = " $3 "
_t_vtype = " $3 "
_debug2 _t_vtype " $_t_vtype "
_debug2 _t_vtype " $_t_vtype "
if [ " $ACME_VERSION " = "2" ] ; then
if [ " $ACME_VERSION " = "2" ] ; then
_send_signed_request " $_t_url " " {\"keyAuthorization\": \"$_t_key_authz \" } "
_send_signed_request " $_t_url " " {}"
else
else
_send_signed_request " $_t_url " " {\"resource\": \"challenge\", \"type\": \" $_t_vtype \", \"keyAuthorization\": \" $_t_key_authz \"} "
_send_signed_request " $_t_url " " {\"resource\": \"challenge\", \"type\": \" $_t_vtype \", \"keyAuthorization\": \" $_t_key_authz \"} "
fi
fi
@ -3628,9 +3653,9 @@ issue() {
_savedomainconf "Le_Alt" " $_alt_domains "
_savedomainconf "Le_Alt" " $_alt_domains "
_savedomainconf "Le_Webroot" " $_web_roots "
_savedomainconf "Le_Webroot" " $_web_roots "
_savedomainconf "Le_PreHook" " $_pre_hook "
_savedomainconf "Le_PreHook" " $_pre_hook " "base64"
_savedomainconf "Le_PostHook" " $_post_hook "
_savedomainconf "Le_PostHook" " $_post_hook " "base64"
_savedomainconf "Le_RenewHook" " $_renew_hook "
_savedomainconf "Le_RenewHook" " $_renew_hook " "base64"
if [ " $_local_addr " ] ; then
if [ " $_local_addr " ] ; then
_savedomainconf "Le_LocalAddress" " $_local_addr "
_savedomainconf "Le_LocalAddress" " $_local_addr "
@ -3643,8 +3668,12 @@ issue() {
_cleardomainconf "Le_ChallengeAlias"
_cleardomainconf "Le_ChallengeAlias"
fi
fi
Le_API = " $ACME_DIRECTORY "
if [ " $ACME_DIRECTORY " != " $DEFAULT_CA " ] ; then
_savedomainconf "Le_API" " $Le_API "
Le_API = " $ACME_DIRECTORY "
_savedomainconf "Le_API" " $Le_API "
else
_cleardomainconf Le_API
fi
if [ " $_alt_domains " = " $NO_VALUE " ] ; then
if [ " $_alt_domains " = " $NO_VALUE " ] ; then
_alt_domains = ""
_alt_domains = ""
@ -3721,8 +3750,9 @@ issue() {
_on_issue_err " $_post_hook "
_on_issue_err " $_post_hook "
return 1
return 1
fi
fi
Le_LinkOrder = " $( echo " $responseHeaders " | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2) "
Le_OrderFinalize = " $( echo " $response " | tr -d '\r\n' | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4) "
_debug Le_LinkOrder " $Le_LinkOrder "
Le_OrderFinalize = " $( echo " $response " | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4) "
_debug Le_OrderFinalize " $Le_OrderFinalize "
_debug Le_OrderFinalize " $Le_OrderFinalize "
if [ -z " $Le_OrderFinalize " ] ; then
if [ -z " $Le_OrderFinalize " ] ; then
_err " Create new order error. Le_OrderFinalize not found. $response "
_err " Create new order error. Le_OrderFinalize not found. $response "
@ -3734,7 +3764,7 @@ issue() {
#for dns manual mode
#for dns manual mode
_savedomainconf "Le_OrderFinalize" " $Le_OrderFinalize "
_savedomainconf "Le_OrderFinalize" " $Le_OrderFinalize "
_authorizations_seg = " $( echo " $response " | tr -d '\r\n' | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"' ) "
_authorizations_seg = " $( echo " $response " | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"' ) "
_debug2 _authorizations_seg " $_authorizations_seg "
_debug2 _authorizations_seg " $_authorizations_seg "
if [ -z " $_authorizations_seg " ] ; then
if [ -z " $_authorizations_seg " ] ; then
_err "_authorizations_seg not found."
_err "_authorizations_seg not found."
@ -3820,7 +3850,7 @@ $_authorizations_map"
thumbprint = " $( __calc_account_thumbprint) "
thumbprint = " $( __calc_account_thumbprint) "
fi
fi
entry = " $( printf "%s\n" " $response " | _egrep_o '[^\{]*"type":"' $vtype '"[^\}]*' ) "
entry = " $( echo " $response " | _egrep_o '[^\{]*"type":"' $vtype '"[^\}]*' ) "
_debug entry " $entry "
_debug entry " $entry "
if [ -z " $entry " ] ; then
if [ -z " $entry " ] ; then
_err " Error, can not get domain token entry $d "
_err " Error, can not get domain token entry $d "
@ -3832,7 +3862,7 @@ $_authorizations_map"
_on_issue_err " $_post_hook "
_on_issue_err " $_post_hook "
return 1
return 1
fi
fi
token = " $( printf "%s\n" " $entry " | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"' ) "
token = " $( echo " $entry " | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"' ) "
_debug token " $token "
_debug token " $token "
if [ -z " $token " ] ; then
if [ -z " $token " ] ; then
@ -3842,9 +3872,9 @@ $_authorizations_map"
return 1
return 1
fi
fi
if [ " $ACME_VERSION " = "2" ] ; then
if [ " $ACME_VERSION " = "2" ] ; then
uri = " $( printf "%s\n" " $entry " | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1) "
uri = " $( echo " $entry " | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1) "
else
else
uri = " $( printf "%s\n" " $entry " | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4) "
uri = " $( echo " $entry " | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4) "
fi
fi
_debug uri " $uri "
_debug uri " $uri "
@ -3902,21 +3932,21 @@ $_authorizations_map"
else
else
txtdomain = " _acme-challenge. $_d_alias "
txtdomain = " _acme-challenge. $_d_alias "
fi
fi
dns_entr ies= " ${ dns_entries } ${ _dns_root_d } ${ dvsep } _acme-challenge. $_dns_root_d $dvsep $txtdomain $dvsep $_currentRoot "
dns_entr y= " ${ _dns_root_d } ${ dvsep } _acme-challenge. $_dns_root_d $dvsep $txtdomain $dvsep $_currentRoot "
else
else
txtdomain = " _acme-challenge. $_dns_root_d "
txtdomain = " _acme-challenge. $_dns_root_d "
dns_entr ies= " ${ dns_entries } ${ _dns_root_d } ${ dvsep } _acme-challenge. $_dns_root_d $dvsep $dvsep $_currentRoot "
dns_entr y= " ${ _dns_root_d } ${ dvsep } _acme-challenge. $_dns_root_d $dvsep $dvsep $_currentRoot "
fi
fi
_debug txtdomain " $txtdomain "
_debug txtdomain " $txtdomain "
txt = " $( printf "%s" " $keyauthorization " | _digest "sha256" | _url_replace) "
txt = " $( printf "%s" " $keyauthorization " | _digest "sha256" | _url_replace) "
_debug txt " $txt "
_debug txt " $txt "
d_api = " $( _findHook " $_dns_root_d " dnsapi " $_currentRoot " ) "
d_api = " $( _findHook " $_dns_root_d " dnsapi " $_currentRoot " ) "
_debug d_api " $d_api "
_debug d_api " $d_api "
dns_entries = " $dns_entries $dvsep $txt ${ dvsep } $d_api
"
dns_entry = " $dns_entry $dvsep $txt ${ dvsep } $d_api "
_debug2 " $dns_entries "
_debug2 dns_entry " $dns_entry "
if [ " $d_api " ] ; then
if [ " $d_api " ] ; then
_info " Found domain api file: $d_api "
_info " Found domain api file: $d_api "
else
else
@ -3955,6 +3985,9 @@ $_authorizations_map"
_clearup
_clearup
return 1
return 1
fi
fi
dns_entries = " $dns_entries $dns_entry
"
_debug2 " $dns_entries "
dnsadded = '1'
dnsadded = '1'
fi
fi
done
done
@ -4165,7 +4198,7 @@ $_authorizations_map"
fi
fi
if [ " $status " = "invalid" ] ; then
if [ " $status " = "invalid" ] ; then
error = " $( echo " $response " | tr -d "\r\n" | _egrep_o '"error":\{[^\}]*' ) "
error = " $( echo " $response " | _egrep_o '"error":\{[^\}]*' ) "
_debug2 error " $error "
_debug2 error " $error "
errordetail = " $( echo " $error " | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4) "
errordetail = " $( echo " $error " | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4) "
_debug2 errordetail " $errordetail "
_debug2 errordetail " $errordetail "
@ -4205,20 +4238,71 @@ $_authorizations_map"
der = " $( _getfile " ${ CSR_PATH } " " ${ BEGIN_CSR } " " ${ END_CSR } " | tr -d "\r\n" | _url_replace) "
der = " $( _getfile " ${ CSR_PATH } " " ${ BEGIN_CSR } " " ${ END_CSR } " | tr -d "\r\n" | _url_replace) "
if [ " $ACME_VERSION " = "2" ] ; then
if [ " $ACME_VERSION " = "2" ] ; then
_info " Lets finalize the order, Le_OrderFinalize: $Le_OrderFinalize "
if ! _send_signed_request " ${ Le_OrderFinalize } " " {\"csr\": \" $der \"} " ; then
if ! _send_signed_request " ${ Le_OrderFinalize } " " {\"csr\": \" $der \"} " ; then
_err "Sign failed."
_err "Sign failed."
_on_issue_err " $_post_hook "
_on_issue_err " $_post_hook "
return 1
return 1
fi
fi
if [ " $code " != "200" ] ; then
if [ " $code " != "200" ] ; then
_err "Sign failed, code is not 200."
_err "Sign failed, finalize code is not 200."
_err " $response "
_err " $response "
_on_issue_err " $_post_hook "
_on_issue_err " $_post_hook "
return 1
return 1
fi
fi
Le_LinkCert = " $( echo " $response " | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4) "
if [ -z " $Le_LinkOrder " ] ; then
Le_LinkOrder = " $( echo " $responseHeaders " | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2) "
fi
_savedomainconf "Le_LinkOrder" " $Le_LinkOrder "
_tempSignedResponse = " $response "
_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 " | _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
#the order is processing, so we are going to poll order status
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
_info " Polling order status: $Le_LinkOrder "
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
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
if ! _send_signed_request " $Le_LinkCert " ; then
_err " Sign failed, can not download cert: $Le_LinkCert . "
_err " Sign failed, can not download cert: $Le_LinkCert . "
_err " $response "
_err " $response "
@ -4237,7 +4321,7 @@ $_authorizations_map"
_end_n = " $( _math $_end_n + 1) "
_end_n = " $( _math $_end_n + 1) "
sed -n " ${ _end_n } ,9999p " " $CERT_FULLCHAIN_PATH " >" $CA_CERT_PATH "
sed -n " ${ _end_n } ,9999p " " $CERT_FULLCHAIN_PATH " >" $CA_CERT_PATH "
fi
fi
response = " $_tempSignedResponse "
else
else
if ! _send_signed_request " ${ ACME_NEW_ORDER } " " {\"resource\": \" $ACME_NEW_ORDER_RES \", \"csr\": \" $der \"} " "needbase64" ; then
if ! _send_signed_request " ${ ACME_NEW_ORDER } " " {\"resource\": \" $ACME_NEW_ORDER_RES \", \"csr\": \" $der \"} " "needbase64" ; then
_err " Sign failed. $response "
_err " Sign failed. $response "
@ -4395,7 +4479,7 @@ $_authorizations_map"
_savedomainconf "Le_RealCertPath" " $_real_cert "
_savedomainconf "Le_RealCertPath" " $_real_cert "
_savedomainconf "Le_RealCACertPath" " $_real_ca "
_savedomainconf "Le_RealCACertPath" " $_real_ca "
_savedomainconf "Le_RealKeyPath" " $_real_key "
_savedomainconf "Le_RealKeyPath" " $_real_key "
_savedomainconf "Le_ReloadCmd" " $_reload_cmd "
_savedomainconf "Le_ReloadCmd" " $_reload_cmd " "base64"
_savedomainconf "Le_RealFullChainPath" " $_real_fullchain "
_savedomainconf "Le_RealFullChainPath" " $_real_fullchain "
if ! _installcert " $_main_domain " " $_real_cert " " $_real_key " " $_real_ca " " $_real_fullchain " " $_reload_cmd " ; then
if ! _installcert " $_main_domain " " $_real_cert " " $_real_key " " $_real_ca " " $_real_fullchain " " $_reload_cmd " ; then
return 1
return 1
@ -4432,6 +4516,16 @@ renew() {
. " $DOMAIN_CONF "
. " $DOMAIN_CONF "
_debug Le_API " $Le_API "
_debug Le_API " $Le_API "
if [ " $Le_API " = " $LETSENCRYPT_CA_V1 " ] ; then
_cleardomainconf Le_API
Le_API = " $DEFAULT_CA "
fi
if [ " $Le_API " = " $LETSENCRYPT_STAGING_CA_V1 " ] ; then
_cleardomainconf Le_API
Le_API = " $DEFAULT_STAGING_CA "
fi
if [ " $Le_API " ] ; then
if [ " $Le_API " ] ; then
if [ " $_OLD_CA_HOST " = " $Le_API " ] ; then
if [ " $_OLD_CA_HOST " = " $Le_API " ] ; then
export Le_API = " $DEFAULT_CA "
export Le_API = " $DEFAULT_CA "
@ -4462,6 +4556,10 @@ renew() {
fi
fi
IS_RENEW = "1"
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 "
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 = " $? "
res = " $? "
if [ " $res " != "0" ] ; then
if [ " $res " != "0" ] ; then
@ -4742,7 +4840,7 @@ installcert() {
_savedomainconf "Le_RealCertPath" " $_real_cert "
_savedomainconf "Le_RealCertPath" " $_real_cert "
_savedomainconf "Le_RealCACertPath" " $_real_ca "
_savedomainconf "Le_RealCACertPath" " $_real_ca "
_savedomainconf "Le_RealKeyPath" " $_real_key "
_savedomainconf "Le_RealKeyPath" " $_real_key "
_savedomainconf "Le_ReloadCmd" " $_reload_cmd "
_savedomainconf "Le_ReloadCmd" " $_reload_cmd " "base64"
_savedomainconf "Le_RealFullChainPath" " $_real_fullchain "
_savedomainconf "Le_RealFullChainPath" " $_real_fullchain "
_installcert " $_main_domain " " $_real_cert " " $_real_key " " $_real_ca " " $_real_fullchain " " $_reload_cmd "
_installcert " $_main_domain " " $_real_cert " " $_real_key " " $_real_ca " " $_real_fullchain " " $_reload_cmd "
@ -4826,7 +4924,7 @@ _installcert() {
export CERT_KEY_PATH
export CERT_KEY_PATH
export CA_CERT_PATH
export CA_CERT_PATH
export CERT_FULLCHAIN_PATH
export CERT_FULLCHAIN_PATH
export Le_Domain
export Le_Domain= " $_main_domain "
cd " $DOMAIN_PATH " && eval " $_reload_cmd "
cd " $DOMAIN_PATH " && eval " $_reload_cmd "
) ; then
) ; then
_info " $( __green "Reload success" ) "
_info " $( __green "Reload success" ) "
@ -4837,35 +4935,107 @@ _installcert() {
}
}
__read_password( ) {
unset _pp
prompt = "Enter Password:"
while IFS = read -p " $prompt " -r -s -n 1 char; do
if [ " $char " = $'\0' ] ; then
break
fi
prompt = '*'
_pp = " $_pp $char "
done
echo " $_pp "
}
_install_win_taskscheduler( ) {
_lesh = " $1 "
_centry = " $2 "
_randomminute = " $3 "
if ! _exists cygpath; then
_err "cygpath not found"
return 1
fi
if ! _exists schtasks; then
_err "schtasks.exe is not found, are you on Windows?"
return 1
fi
_winbash = " $( cygpath -w $( which bash) ) "
_debug _winbash " $_winbash "
if [ -z " $_winbash " ] ; then
_err "can not find bash path"
return 1
fi
_myname = " $( whoami) "
_debug "_myname" " $_myname "
if [ -z " $_myname " ] ; then
_err "can not find my user name"
return 1
fi
_debug "_lesh" " $_lesh "
_info "To install scheduler task in your Windows account, you must input your windows password."
_info " $PROJECT_NAME doesn't save your password. "
_info " Please input your Windows password for: $( __green " $_myname " ) "
_password = " $( __read_password) "
#SCHTASKS.exe '/create' '/SC' 'DAILY' '/TN' "$_WINDOWS_SCHEDULER_NAME" '/F' '/ST' "00:$_randomminute" '/RU' "$_myname" '/RP' "$_password" '/TR' "$_winbash -l -c '$_lesh --cron --home \"$LE_WORKING_DIR\" $_centry'" >/dev/null
echo SCHTASKS.exe '/create' '/SC' 'DAILY' '/TN' " $_WINDOWS_SCHEDULER_NAME " '/F' '/ST' " 00: $_randomminute " '/RU' " $_myname " '/RP' " $_password " '/TR' " \" $_winbash -l -c ' $_lesh --cron --home \" $LE_WORKING_DIR \" $_centry '\" " | cmd.exe >/dev/null
echo
}
_uninstall_win_taskscheduler( ) {
if ! _exists schtasks; then
_err "schtasks.exe is not found, are you on Windows?"
return 1
fi
if ! echo SCHTASKS /query /tn " $_WINDOWS_SCHEDULER_NAME " | cmd.exe >/dev/null; then
_debug " scheduler $_WINDOWS_SCHEDULER_NAME is not found. "
else
_info " Removing $_WINDOWS_SCHEDULER_NAME "
echo SCHTASKS /delete /f /tn " $_WINDOWS_SCHEDULER_NAME " | cmd.exe >/dev/null
fi
}
#confighome
#confighome
installcronjob( ) {
installcronjob( ) {
_c_home = " $1 "
_c_home = " $1 "
_initpath
_initpath
_CRONTAB = "crontab"
_CRONTAB = "crontab"
if [ -f " $LE_WORKING_DIR / $PROJECT_ENTRY " ] ; then
lesh = " \" $LE_WORKING_DIR \"/ $PROJECT_ENTRY "
else
_err " Can not install cronjob, $PROJECT_ENTRY not found. "
return 1
fi
if [ " $_c_home " ] ; then
_c_entry = " --config-home \" $_c_home \" "
fi
_t = $( _time)
random_minute = $( _math $_t % 60)
if ! _exists " $_CRONTAB " && _exists "fcrontab" ; then
if ! _exists " $_CRONTAB " && _exists "fcrontab" ; then
_CRONTAB = "fcrontab"
_CRONTAB = "fcrontab"
fi
fi
if ! _exists " $_CRONTAB " ; then
if ! _exists " $_CRONTAB " ; then
if _exists cygpath && _exists schtasks.exe; then
_info "It seems you are on Windows, let's install Windows scheduler task."
if _install_win_taskscheduler " $lesh " " $_c_entry " " $random_minute " ; then
_info "Install Windows scheduler task success."
return 0
else
_err "Install Windows scheduler task failed."
return 1
fi
fi
_err "crontab/fcrontab doesn't exist, so, we can not install cron jobs."
_err "crontab/fcrontab doesn't exist, so, we can not install cron jobs."
_err "All your certs will not be renewed automatically."
_err "All your certs will not be renewed automatically."
_err " You must add your own cron job to call ' $PROJECT_ENTRY --cron' everyday. "
_err " You must add your own cron job to call ' $PROJECT_ENTRY --cron' everyday. "
return 1
return 1
fi
fi
_info "Installing cron job"
_info "Installing cron job"
if ! $_CRONTAB -l | grep " $PROJECT_ENTRY --cron " ; then
if ! $_CRONTAB -l | grep " $PROJECT_ENTRY --cron " ; then
if [ -f " $LE_WORKING_DIR / $PROJECT_ENTRY " ] ; then
lesh = " \" $LE_WORKING_DIR \"/ $PROJECT_ENTRY "
else
_err " Can not install cronjob, $PROJECT_ENTRY not found. "
return 1
fi
if [ " $_c_home " ] ; then
_c_entry = " --config-home \" $_c_home \" "
fi
_t = $( _time)
random_minute = $( _math $_t % 60)
if _exists uname && uname -a | grep SunOS >/dev/null; then
if _exists uname && uname -a | grep SunOS >/dev/null; then
$_CRONTAB -l | {
$_CRONTAB -l | {
cat
cat
@ -4893,6 +5063,16 @@ uninstallcronjob() {
fi
fi
if ! _exists " $_CRONTAB " ; then
if ! _exists " $_CRONTAB " ; then
if _exists cygpath && _exists schtasks.exe; then
_info "It seems you are on Windows, let's uninstall Windows scheduler task."
if _uninstall_win_taskscheduler; then
_info "Uninstall Windows scheduler task success."
return 0
else
_err "Uninstall Windows scheduler task failed."
return 1
fi
fi
return
return
fi
fi
_info "Removing cron job"
_info "Removing cron job"
@ -5024,7 +5204,7 @@ _deactivate() {
_err "Can not get domain new order."
_err "Can not get domain new order."
return 1
return 1
fi
fi
_authorizations_seg = " $( echo " $response " | tr -d '\r\n' | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"' ) "
_authorizations_seg = " $( echo " $response " | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"' ) "
_debug2 _authorizations_seg " $_authorizations_seg "
_debug2 _authorizations_seg " $_authorizations_seg "
if [ -z " $_authorizations_seg " ] ; then
if [ -z " $_authorizations_seg " ] ; then
_err "_authorizations_seg not found."
_err "_authorizations_seg not found."
@ -5070,16 +5250,16 @@ _deactivate() {
fi
fi
_debug "Trigger validation."
_debug "Trigger validation."
vtype = " $VTYPE_DNS "
vtype = " $VTYPE_DNS "
entry = " $( printf "%s\n" " $response " | _egrep_o '[^\{]*"type":"' $vtype '"[^\}]*' ) "
entry = " $( echo " $response " | _egrep_o '[^\{]*"type":"' $vtype '"[^\}]*' ) "
_debug entry " $entry "
_debug entry " $entry "
if [ -z " $entry " ] ; then
if [ -z " $entry " ] ; then
_err " Error, can not get domain token $d "
_err " Error, can not get domain token $d "
return 1
return 1
fi
fi
token = " $( printf "%s\n" " $entry " | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"' ) "
token = " $( echo " $entry " | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"' ) "
_debug token " $token "
_debug token " $token "
uri = " $( printf "%s\n" " $entry " | _egrep_o " \" $_URL_NAME \":\"[^\"]* " | cut -d : -f 2,3 | tr -d '"' ) "
uri = " $( echo " $entry " | _egrep_o " \" $_URL_NAME \":\"[^\"]* " | cut -d : -f 2,3 | tr -d '"' ) "
_debug uri " $uri "
_debug uri " $uri "
keyauthorization = " $token . $thumbprint "
keyauthorization = " $token . $thumbprint "
@ -5101,11 +5281,11 @@ _deactivate() {
break
break
fi
fi
_vtype = " $( printf "%s\n" " $entry " | _egrep_o '"type": *"[^"]*"' | cut -d : -f 2 | tr -d '"' ) "
_vtype = " $( echo " $entry " | _egrep_o '"type": *"[^"]*"' | cut -d : -f 2 | tr -d '"' ) "
_debug _vtype " $_vtype "
_debug _vtype " $_vtype "
_info " Found $_vtype "
_info " Found $_vtype "
uri = " $( printf "%s\n" " $entry " | _egrep_o " \" $_URL_NAME \":\"[^\"]* " | cut -d : -f 2,3 | tr -d '"' ) "
uri = " $( echo " $entry " | _egrep_o " \" $_URL_NAME \":\"[^\"]* " | cut -d : -f 2,3 | tr -d '"' ) "
_debug uri " $uri "
_debug uri " $uri "
if [ " $_d_type " ] && [ " $_d_type " != " $_vtype " ] ; then
if [ " $_d_type " ] && [ " $_d_type " != " $_vtype " ] ; then
@ -5220,13 +5400,17 @@ _precheck() {
if [ -z " $_nocron " ] ; then
if [ -z " $_nocron " ] ; then
if ! _exists "crontab" && ! _exists "fcrontab" ; then
if ! _exists "crontab" && ! _exists "fcrontab" ; then
_err "It is recommended to install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'."
if _exists cygpath && _exists schtasks.exe; then
_err "We need to set cron job to renew the certs automatically."
_info "It seems you are on Windows, we will install Windows scheduler task."
_err "Otherwise, your certs will not be able to be renewed automatically."
else
if [ -z " $FORCE " ] ; then
_err "It is recommended to install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'."
_err "Please add '--force' and try install again to go without crontab."
_err "We need to set cron job to renew the certs automatically."
_err " ./ $PROJECT_ENTRY --install --force "
_err "Otherwise, your certs will not be able to be renewed automatically."
return 1
if [ -z " $FORCE " ] ; then
_err "Please add '--force' and try install again to go without crontab."
_err " ./ $PROJECT_ENTRY --install --force "
return 1
fi
fi
fi
fi
fi
fi
fi