@ -1,6 +1,6 @@
#!/usr/bin/env sh
#!/usr/bin/env sh
VER = 3.0.3
VER = 3.0.5
PROJECT_NAME = "acme.sh"
PROJECT_NAME = "acme.sh"
@ -20,8 +20,6 @@ _SUB_FOLDER_DEPLOY="deploy"
_SUB_FOLDERS = " $_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY "
_SUB_FOLDERS = " $_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY "
CA_LETSENCRYPT_V1 = "https://acme-v01.api.letsencrypt.org/directory"
CA_LETSENCRYPT_V2 = "https://acme-v02.api.letsencrypt.org/directory"
CA_LETSENCRYPT_V2 = "https://acme-v02.api.letsencrypt.org/directory"
CA_LETSENCRYPT_V2_TEST = "https://acme-staging-v02.api.letsencrypt.org/directory"
CA_LETSENCRYPT_V2_TEST = "https://acme-staging-v02.api.letsencrypt.org/directory"
@ -34,6 +32,9 @@ _ZERO_EAB_ENDPOINT="https://api.zerossl.com/acme/eab-credentials-email"
CA_SSLCOM_RSA = "https://acme.ssl.com/sslcom-dv-rsa"
CA_SSLCOM_RSA = "https://acme.ssl.com/sslcom-dv-rsa"
CA_SSLCOM_ECC = "https://acme.ssl.com/sslcom-dv-ecc"
CA_SSLCOM_ECC = "https://acme.ssl.com/sslcom-dv-ecc"
CA_GOOGLE = "https://dv.acme-v02.api.pki.goog/directory"
CA_GOOGLE_TEST = "https://dv.acme-v02.test-api.pki.goog/directory"
DEFAULT_CA = $CA_ZEROSSL
DEFAULT_CA = $CA_ZEROSSL
DEFAULT_STAGING_CA = $CA_LETSENCRYPT_V2_TEST
DEFAULT_STAGING_CA = $CA_LETSENCRYPT_V2_TEST
@ -44,9 +45,11 @@ LetsEncrypt.org_test,letsencrypt_test,letsencrypttest
BuyPass.com,buypass
BuyPass.com,buypass
BuyPass.com_test,buypass_test,buypasstest
BuyPass.com_test,buypass_test,buypasstest
SSL.com,sslcom
SSL.com,sslcom
Google.com,google
Google.com_test,googletest,google_test
"
"
CA_SERVERS = " $CA_ZEROSSL , $CA_LETSENCRYPT_V2 , $CA_LETSENCRYPT_V2_TEST , $CA_BUYPASS , $CA_BUYPASS_TEST , $CA_SSLCOM_RSA "
CA_SERVERS = " $CA_ZEROSSL , $CA_LETSENCRYPT_V2 , $CA_LETSENCRYPT_V2_TEST , $CA_BUYPASS , $CA_BUYPASS_TEST , $CA_SSLCOM_RSA ,$CA_GOOGLE , $CA_GOOGLE_TEST "
DEFAULT_USER_AGENT = " $PROJECT_NAME / $VER ( $PROJECT ) "
DEFAULT_USER_AGENT = " $PROJECT_NAME / $VER ( $PROJECT ) "
@ -172,6 +175,8 @@ _SERVER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Server"
_PREFERRED_CHAIN_WIKI = "https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain"
_PREFERRED_CHAIN_WIKI = "https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain"
_VALIDITY_WIKI = "https://github.com/acmesh-official/acme.sh/wiki/Validity"
_DNSCHECK_WIKI = "https://github.com/acmesh-official/acme.sh/wiki/dnscheck"
_DNSCHECK_WIKI = "https://github.com/acmesh-official/acme.sh/wiki/dnscheck"
_DNS_MANUAL_ERR = "The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead."
_DNS_MANUAL_ERR = "The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead."
@ -976,9 +981,9 @@ _base64() {
#Usage: multiline
#Usage: multiline
_dbase64( ) {
_dbase64( ) {
if [ " $1 " ] ; then
if [ " $1 " ] ; then
${ ACME_OPENSSL_BIN :- openssl } base64 -d -A
else
${ ACME_OPENSSL_BIN :- openssl } base64 -d
${ ACME_OPENSSL_BIN :- openssl } base64 -d
else
${ ACME_OPENSSL_BIN :- openssl } base64 -d -A
fi
fi
}
}
@ -1598,23 +1603,22 @@ _durl_replace_base64() {
_time2str( ) {
_time2str( ) {
#BSD
#BSD
if date -u -r " $1 " 2>/dev/null; then
if date -u -r " $1 " -j "+%Y-%m-%dT%H:%M:%SZ" 2>/dev/null; then
return
return
fi
fi
#Linux
#Linux
if date -u -d@" $1 " 2>/dev/null; then
if date -u -- date= @" $1 " "+%Y-%m-%dT%H:%M:%SZ " 2>/dev/null; then
return
return
fi
fi
#Solaris
#Solaris
if _exists adb; then
if printf "%(%Y-%m-%dT%H:%M:%SZ)T\n" $1 2>/dev/null; then
_t_s_a = $( echo " 0t ${ 1 } =Y " | adb)
return
echo " $_t_s_a "
fi
fi
#Busybox
#Busybox
if echo " $1 " | awk '{ print strftime("% c ", $0); }' 2>/dev/null; then
if echo " $1 " | awk '{ print strftime("% Y-%m-%dT%H:%M:%SZ ", $0); }' 2>/dev/null; then
return
return
fi
fi
}
}
@ -1773,6 +1777,27 @@ _time() {
date -u "+%s"
date -u "+%s"
}
}
#support 2 formats:
# 2022-04-01 08:10:33 to 1648800633
#or 2022-04-01T08:10:33Z to 1648800633
_date2time( ) {
#Linux
if date -u -d " $( echo " $1 " | tr -d "Z" | tr "T" ' ' ) " +"%s" 2>/dev/null; then
return
fi
#Solaris
if gdate -u -d " $( echo " $1 " | tr -d "Z" | tr "T" ' ' ) " +"%s" 2>/dev/null; then
return
fi
#Mac/BSD
if date -u -j -f "%Y-%m-%d %H:%M:%S" " $( echo " $1 " | tr -d "Z" | tr "T" ' ' ) " +"%s" 2>/dev/null; then
return
fi
_err " Can not parse _date2time $1 "
return 1
}
_utc_date( ) {
_utc_date( ) {
date -u "+%Y-%m-%d %H:%M:%S"
date -u "+%Y-%m-%d %H:%M:%S"
}
}
@ -1845,7 +1870,9 @@ _inithttp() {
_ACME_WGET = " $_ACME_WGET --max-redirect 0 "
_ACME_WGET = " $_ACME_WGET --max-redirect 0 "
fi
fi
if [ " $DEBUG " ] && [ " $DEBUG " -ge "2" ] ; then
if [ " $DEBUG " ] && [ " $DEBUG " -ge "2" ] ; then
_ACME_WGET = " $_ACME_WGET -d "
if [ " $_ACME_WGET " ] && _contains " $( $_ACME_WGET --help 2>& 1) " "--debug" ; then
_ACME_WGET = " $_ACME_WGET -d "
fi
fi
fi
if [ " $CA_PATH " ] ; then
if [ " $CA_PATH " ] ; then
_ACME_WGET = " $_ACME_WGET --ca-directory= $CA_PATH "
_ACME_WGET = " $_ACME_WGET --ca-directory= $CA_PATH "
@ -2662,6 +2689,12 @@ _initAPI() {
return 1
return 1
}
}
_clearCA( ) {
export CA_CONF =
export ACCOUNT_KEY_PATH =
export ACCOUNT_JSON_PATH =
}
#[domain] [keylength or isEcc flag]
#[domain] [keylength or isEcc flag]
_initpath( ) {
_initpath( ) {
domain = " $1 "
domain = " $1 "
@ -3751,7 +3784,7 @@ updateaccount() {
_email = " $( _getAccountEmail) "
_email = " $( _getAccountEmail) "
if [ " $ ACCOUNT_EMAIL " ] ; then
if [ " $ _email " ] ; then
updjson = '{"contact": ["mailto:' $_email '"]}'
updjson = '{"contact": ["mailto:' $_email '"]}'
else
else
updjson = '{"contact": []}'
updjson = '{"contact": []}'
@ -3761,7 +3794,7 @@ updateaccount() {
if [ " $code " = '200' ] ; then
if [ " $code " = '200' ] ; then
echo " $response " >" $ACCOUNT_JSON_PATH "
echo " $response " >" $ACCOUNT_JSON_PATH "
_info " a ccount update success for $_accUri . "
_info " A ccount update success for $_accUri . "
else
else
_info "Error. The account was not updated."
_info "Error. The account was not updated."
return 1
return 1
@ -4200,6 +4233,40 @@ _getIdType() {
fi
fi
}
}
# beginTime dateTo
# beginTime is full string format("2022-04-01T08:10:33Z"), beginTime can be empty, to use current time
# dateTo can be ether in full string format("2022-04-01T08:10:33Z") or in delta format(+5d or +20h)
_convertValidaty( ) {
_beginTime = " $1 "
_dateTo = " $2 "
_debug2 "_beginTime" " $_beginTime "
_debug2 "_dateTo" " $_dateTo "
if _startswith " $_dateTo " "+" ; then
_v_begin = $( _time)
if [ " $_beginTime " ] ; then
_v_begin = " $( _date2time " $_beginTime " ) "
fi
_debug2 "_v_begin" " $_v_begin "
if _endswith " $_dateTo " "h" ; then
_v_end = $( _math " $_v_begin + 60 * 60 * $( echo " $_dateTo " | tr -d '+h' ) " )
elif _endswith " $_dateTo " "d" ; then
_v_end = $( _math " $_v_begin + 60 * 60 * 24 * $( echo " $_dateTo " | tr -d '+d' ) " )
else
_err " Not recognized format for _dateTo: $_dateTo "
return 1
fi
_debug2 "_v_end" " $_v_end "
_time2str " $_v_end "
else
if [ " $( _time) " -gt " $( _date2time " $_dateTo " ) " ] ; then
_err " The validaty to is in the past: _dateTo = $_dateTo "
return 1
fi
echo " $_dateTo "
fi
}
#webroot, domain domainlist keylength
#webroot, domain domainlist keylength
issue( ) {
issue( ) {
if [ -z " $2 " ] ; then
if [ -z " $2 " ] ; then
@ -4233,6 +4300,8 @@ issue() {
_local_addr = " ${ 13 } "
_local_addr = " ${ 13 } "
_challenge_alias = " ${ 14 } "
_challenge_alias = " ${ 14 } "
_preferred_chain = " ${ 15 } "
_preferred_chain = " ${ 15 } "
_valid_from = " ${ 16 } "
_valid_to = " ${ 17 } "
if [ -z " $_ACME_IS_RENEW " ] ; then
if [ -z " $_ACME_IS_RENEW " ] ; then
_initpath " $_main_domain " " $_key_length "
_initpath " $_main_domain " " $_key_length "
@ -4252,11 +4321,24 @@ issue() {
Le_NextRenewTime = $( _readdomainconf Le_NextRenewTime)
Le_NextRenewTime = $( _readdomainconf Le_NextRenewTime)
_debug Le_NextRenewTime " $Le_NextRenewTime "
_debug Le_NextRenewTime " $Le_NextRenewTime "
if [ -z " $FORCE " ] && [ " $Le_NextRenewTime " ] && [ " $( _time) " -lt " $Le_NextRenewTime " ] ; then
if [ -z " $FORCE " ] && [ " $Le_NextRenewTime " ] && [ " $( _time) " -lt " $Le_NextRenewTime " ] ; then
_valid_to_saved = $( _readdomainconf Le_Valid_to)
if [ " $_valid_to_saved " ] && ! _startswith " $_valid_to_saved " "+" ; then
_info " The domain is set to be valid to: $_valid_to_saved "
_info "It can not be renewed automatically"
_info " See: $_VALIDITY_WIKI "
return $RENEW_SKIP
fi
_saved_domain = $( _readdomainconf Le_Domain)
_saved_domain = $( _readdomainconf Le_Domain)
_debug _saved_domain " $_saved_domain "
_debug _saved_domain " $_saved_domain "
_saved_alt = $( _readdomainconf Le_Alt)
_saved_alt = $( _readdomainconf Le_Alt)
_debug _saved_alt " $_saved_alt "
_debug _saved_alt " $_saved_alt "
if [ " $_saved_domain , $_saved_alt " = " $_main_domain , $_alt_domains " ] ; then
_normized_saved_domains = " $( echo " $_saved_domain , $_saved_alt " | tr "," "\n" | sort | tr '\n' ',' ) "
_debug _normized_saved_domains " $_normized_saved_domains "
_normized_domains = " $( echo " $_main_domain , $_alt_domains " | tr "," "\n" | sort | tr '\n' ',' ) "
_debug _normized_domains " $_normized_domains "
if [ " $_normized_saved_domains " = " $_normized_domains " ] ; then
_info "Domains not changed."
_info "Domains not changed."
_info " Skip, Next renewal time is: $( __green " $( _readdomainconf Le_NextRenewTimeStr) " ) "
_info " Skip, Next renewal time is: $( __green " $( _readdomainconf Le_NextRenewTimeStr) " ) "
_info " Add ' $( __red '--force' ) ' to force to renew. "
_info " Add ' $( __red '--force' ) ' to force to renew. "
@ -4304,10 +4386,6 @@ issue() {
_alt_domains = ""
_alt_domains = ""
fi
fi
if [ " $_key_length " = " $NO_VALUE " ] ; then
_key_length = ""
fi
if ! _on_before_issue " $_web_roots " " $_main_domain " " $_alt_domains " " $_pre_hook " " $_local_addr " ; then
if ! _on_before_issue " $_web_roots " " $_main_domain " " $_alt_domains " " $_pre_hook " " $_local_addr " ; then
_err "_on_before_issue."
_err "_on_before_issue."
return 1
return 1
@ -4328,7 +4406,13 @@ issue() {
if [ -f " $CSR_PATH " ] && [ ! -f " $CERT_KEY_PATH " ] ; then
if [ -f " $CSR_PATH " ] && [ ! -f " $CERT_KEY_PATH " ] ; then
_info "Signing from existing CSR."
_info "Signing from existing CSR."
else
else
# When renewing from an old version, the empty Le_Keylength means 2048.
# Note, do not use DEFAULT_DOMAIN_KEY_LENGTH as that value may change over
# time but an empty value implies 2048 specifically.
_key = $( _readdomainconf Le_Keylength)
_key = $( _readdomainconf Le_Keylength)
if [ -z " $_key " ] ; then
_key = 2048
fi
_debug " Read key length: $_key "
_debug " Read key length: $_key "
if [ ! -f " $CERT_KEY_PATH " ] || [ " $_key_length " != " $_key " ] || [ " $Le_ForceNewDomainKey " = "1" ] ; then
if [ ! -f " $CERT_KEY_PATH " ] || [ " $_key_length " != " $_key " ] || [ " $Le_ForceNewDomainKey " = "1" ] ; then
if ! createDomainKey " $_main_domain " " $_key_length " ; then
if ! createDomainKey " $_main_domain " " $_key_length " ; then
@ -4368,12 +4452,52 @@ issue() {
_identifiers = " $_identifiers ,{\"type\":\" $( _getIdType " $d " ) \",\"value\":\" $( _idn " $d " ) \"} "
_identifiers = " $_identifiers ,{\"type\":\" $( _getIdType " $d " ) \",\"value\":\" $( _idn " $d " ) \"} "
done
done
_debug2 _identifiers " $_identifiers "
_debug2 _identifiers " $_identifiers "
if ! _send_signed_request " $ACME_NEW_ORDER " " {\"identifiers\": [ $_identifiers ]} " ; then
_notBefore = ""
_notAfter = ""
if [ " $_valid_from " ] ; then
_savedomainconf "Le_Valid_From" " $_valid_from "
_debug2 "_valid_from" " $_valid_from "
_notBefore = " $( _convertValidaty "" " $_valid_from " ) "
if [ " $? " != "0" ] ; then
_err " Can not parse _valid_from: $_valid_from "
return 1
fi
if [ " $( _time) " -gt " $( _date2time " $_notBefore " ) " ] ; then
_notBefore = ""
fi
else
_cleardomainconf "Le_Valid_From"
fi
_debug2 _notBefore " $_notBefore "
if [ " $_valid_to " ] ; then
_debug2 "_valid_to" " $_valid_to "
_savedomainconf "Le_Valid_To" " $_valid_to "
_notAfter = " $( _convertValidaty " $_notBefore " " $_valid_to " ) "
if [ " $? " != "0" ] ; then
_err " Can not parse _valid_to: $_valid_to "
return 1
fi
else
_cleardomainconf "Le_Valid_To"
fi
_debug2 "_notAfter" " $_notAfter "
_newOrderObj = " {\"identifiers\": [ $_identifiers ] "
if [ " $_notBefore " ] ; then
_newOrderObj = " $_newOrderObj ,\"notBefore\": \" $_notBefore \" "
fi
if [ " $_notAfter " ] ; then
_newOrderObj = " $_newOrderObj ,\"notAfter\": \" $_notAfter \" "
fi
if ! _send_signed_request " $ACME_NEW_ORDER " " $_newOrderObj } " ; then
_err "Create new order error."
_err "Create new order error."
_clearup
_clearup
_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_LinkOrder = " $( echo " $responseHeaders " | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n " | cut -d ":" -f 2-) "
_debug Le_LinkOrder " $Le_LinkOrder "
_debug Le_LinkOrder " $Le_LinkOrder "
Le_OrderFinalize = " $( echo " $response " | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4) "
Le_OrderFinalize = " $( echo " $response " | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4) "
@ -4412,7 +4536,7 @@ issue() {
response = " $( echo " $response " | _normalizeJson) "
response = " $( echo " $response " | _normalizeJson) "
_debug2 response " $response "
_debug2 response " $response "
_d = " $( echo " $response " | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2 | tr -d ' "' ) "
_d = " $( echo " $response " | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2- | tr -d ' "' ) "
if _contains " $response " "\"wildcard\" *: *true" ; then
if _contains " $response " "\"wildcard\" *: *true" ; then
_d = " *. $_d "
_d = " *. $_d "
fi
fi
@ -4562,6 +4686,7 @@ $_authorizations_map"
_dns_root_d = " $( echo " $_dns_root_d " | sed 's/*.//' ) "
_dns_root_d = " $( echo " $_dns_root_d " | sed 's/*.//' ) "
fi
fi
_d_alias = " $( _getfield " $_challenge_alias " " $_alias_index " ) "
_d_alias = " $( _getfield " $_challenge_alias " " $_alias_index " ) "
test " $_d_alias " = " $NO_VALUE " && _d_alias = ""
_alias_index = " $( _math " $_alias_index " + 1) "
_alias_index = " $( _math " $_alias_index " + 1) "
_debug "_d_alias" " $_d_alias "
_debug "_d_alias" " $_d_alias "
if [ " $_d_alias " ] ; then
if [ " $_d_alias " ] ; then
@ -4856,7 +4981,7 @@ $_authorizations_map"
return 1
return 1
fi
fi
_debug "sleep 2 secs to verify again"
_debug "sleep 2 secs to verify again"
sleep 2
_ sleep 2
_debug "checking"
_debug "checking"
_send_signed_request " $uri "
_send_signed_request " $uri "
@ -5033,7 +5158,7 @@ $_authorizations_map"
Le_CertCreateTime = $( _time)
Le_CertCreateTime = $( _time)
_savedomainconf "Le_CertCreateTime" " $Le_CertCreateTime "
_savedomainconf "Le_CertCreateTime" " $Le_CertCreateTime "
Le_CertCreateTimeStr = $( date -u )
Le_CertCreateTimeStr = $( _time2str " $Le_CertCreateTime " )
_savedomainconf "Le_CertCreateTimeStr" " $Le_CertCreateTimeStr "
_savedomainconf "Le_CertCreateTimeStr" " $Le_CertCreateTimeStr "
if [ -z " $Le_RenewalDays " ] || [ " $Le_RenewalDays " -lt "0" ] ; then
if [ -z " $Le_RenewalDays " ] || [ " $Le_RenewalDays " -lt "0" ] ; then
@ -5073,13 +5198,20 @@ $_authorizations_map"
else
else
_cleardomainconf Le_ForceNewDomainKey
_cleardomainconf Le_ForceNewDomainKey
fi
fi
if [ " $_notAfter " ] ; then
Le_NextRenewTime = $( _math " $Le_CertCreateTime " + " $Le_RenewalDays " \* 24 \* 60 \* 60)
Le_NextRenewTime = $( _date2time " $_notAfter " )
Le_NextRenewTimeStr = " $_notAfter "
Le_NextRenewTimeStr = $( _time2str " $Le_NextRenewTime " )
if [ " $_valid_to " ] && ! _startswith " $_valid_to " "+" ; then
_info " The domain is set to be valid to: $_valid_to "
_info "It can not be renewed automatically"
_info " See: $_VALIDITY_WIKI "
fi
else
Le_NextRenewTime = $( _math " $Le_CertCreateTime " + " $Le_RenewalDays " \* 24 \* 60 \* 60)
Le_NextRenewTimeStr = $( _time2str " $Le_NextRenewTime " )
Le_NextRenewTime = $( _math " $Le_NextRenewTime " - 86400)
fi
_savedomainconf "Le_NextRenewTimeStr" " $Le_NextRenewTimeStr "
_savedomainconf "Le_NextRenewTimeStr" " $Le_NextRenewTimeStr "
Le_NextRenewTime = $( _math " $Le_NextRenewTime " - 86400)
_savedomainconf "Le_NextRenewTime" " $Le_NextRenewTime "
_savedomainconf "Le_NextRenewTime" " $Le_NextRenewTime "
if [ " $_real_cert $_real_key $_real_ca $_reload_cmd $_real_fullchain " ] ; then
if [ " $_real_cert $_real_key $_real_ca $_reload_cmd $_real_fullchain " ] ; then
@ -5115,17 +5247,20 @@ _split_cert_chain() {
fi
fi
}
}
#domain [isEcc]
#domain [isEcc] [server]
renew( ) {
renew( ) {
Le_Domain = " $1 "
Le_Domain = " $1 "
if [ -z " $Le_Domain " ] ; then
if [ -z " $Le_Domain " ] ; then
_usage " Usage: $PROJECT_ENTRY --renew --domain <domain.tld> [--ecc] "
_usage " Usage: $PROJECT_ENTRY --renew --domain <domain.tld> [--ecc] [--server server] "
return 1
return 1
fi
fi
_isEcc = " $2 "
_isEcc = " $2 "
_renewServer = " $3 "
_debug "_renewServer" " $_renewServer "
_initpath " $Le_Domain " " $_isEcc "
_initpath " $Le_Domain " " $_isEcc "
_set_level = ${ NOTIFY_LEVEL :- $NOTIFY_LEVEL_DEFAULT }
_set_level = ${ NOTIFY_LEVEL :- $NOTIFY_LEVEL_DEFAULT }
_info " $( __green " Renew: ' $Le_Domain ' " ) "
_info " $( __green " Renew: ' $Le_Domain ' " ) "
if [ ! -f " $DOMAIN_CONF " ] ; then
if [ ! -f " $DOMAIN_CONF " ] ; then
@ -5139,24 +5274,34 @@ renew() {
. " $DOMAIN_CONF "
. " $DOMAIN_CONF "
_debug Le_API " $Le_API "
_debug Le_API " $Le_API "
if [ -z " $Le_API " ] || [ " $CA_LETSENCRYPT_V1 " = " $Le_API " ] ; then
#if this is from an old version, Le_API is empty,
case " $Le_API " in
#so, we force to use letsencrypt server
" $CA_LETSENCRYPT_V2_TEST " )
_info " Switching back to $CA_LETSENCRYPT_V2 "
Le_API = " $CA_LETSENCRYPT_V2 "
Le_API = " $CA_LETSENCRYPT_V2 "
fi
; ;
" $CA_BUYPASS_TEST " )
_info " Switching back to $CA_BUYPASS "
Le_API = " $CA_BUYPASS "
; ;
" $CA_GOOGLE_TEST " )
_info " Switching back to $CA_GOOGLE "
Le_API = " $CA_GOOGLE "
; ;
esac
if [ " $Le_API " ] ; then
if [ " $_server " ] ; then
if [ " $Le_API " != " $ACME_DIRECTORY " ] ; then
Le_API = " $_server "
_clearAPI
fi
export ACME_DIRECTORY = " $Le_API "
#reload ca configs
ACCOUNT_KEY_PATH = ""
ACCOUNT_JSON_PATH = ""
CA_CONF = ""
_debug3 "initpath again."
_initpath " $Le_Domain " " $_isEcc "
fi
fi
_info " Renew to Le_API= $Le_API "
_clearAPI
_clearCA
export ACME_DIRECTORY = " $Le_API "
#reload ca configs
_debug2 "initpath again."
_initpath " $Le_Domain " " $_isEcc "
if [ -z " $FORCE " ] && [ " $Le_NextRenewTime " ] && [ " $( _time) " -lt " $Le_NextRenewTime " ] ; then
if [ -z " $FORCE " ] && [ " $Le_NextRenewTime " ] && [ " $( _time) " -lt " $Le_NextRenewTime " ] ; then
_info " Skip, Next renewal time is: $( __green " $Le_NextRenewTimeStr " ) "
_info " Skip, Next renewal time is: $( __green " $Le_NextRenewTimeStr " ) "
@ -5180,7 +5325,14 @@ renew() {
Le_PostHook = " $( _readdomainconf Le_PostHook) "
Le_PostHook = " $( _readdomainconf Le_PostHook) "
Le_RenewHook = " $( _readdomainconf Le_RenewHook) "
Le_RenewHook = " $( _readdomainconf Le_RenewHook) "
Le_Preferred_Chain = " $( _readdomainconf Le_Preferred_Chain) "
Le_Preferred_Chain = " $( _readdomainconf Le_Preferred_Chain) "
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 " " $Le_Preferred_Chain "
# When renewing from an old version, the empty Le_Keylength means 2048.
# Note, do not use DEFAULT_DOMAIN_KEY_LENGTH as that value may change over
# time but an empty value implies 2048 specifically.
Le_Keylength = " $( _readdomainconf Le_Keylength) "
if [ -z " $Le_Keylength " ] ; then
Le_Keylength = 2048
fi
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 " " $Le_Preferred_Chain " " $Le_Valid_From " " $Le_Valid_To "
res = " $? "
res = " $? "
if [ " $res " != "0" ] ; then
if [ " $res " != "0" ] ; then
return " $res "
return " $res "
@ -5207,11 +5359,16 @@ renew() {
return " $res "
return " $res "
}
}
#renewAll [stopRenewOnError]
#renewAll [stopRenewOnError] [server]
renewAll( ) {
renewAll( ) {
_initpath
_initpath
_clearCA
_stopRenewOnError = " $1 "
_stopRenewOnError = " $1 "
_debug "_stopRenewOnError" " $_stopRenewOnError "
_debug "_stopRenewOnError" " $_stopRenewOnError "
_server = " $2 "
_debug "_server" " $_server "
_ret = "0"
_ret = "0"
_success_msg = ""
_success_msg = ""
_error_msg = ""
_error_msg = ""
@ -5234,7 +5391,7 @@ renewAll() {
_isEcc = $( echo " $d " | cut -d " $ECC_SEP " -f 2)
_isEcc = $( echo " $d " | cut -d " $ECC_SEP " -f 2)
d = $( echo " $d " | cut -d " $ECC_SEP " -f 1)
d = $( echo " $d " | cut -d " $ECC_SEP " -f 1)
fi
fi
renew " $d " " $_isEcc "
renew " $d " " $_isEcc " " $_server "
)
)
rc = " $? "
rc = " $? "
_debug " Return code: $rc "
_debug " Return code: $rc "
@ -5400,10 +5557,13 @@ showcsr() {
_initpath
_initpath
_csrsubj = $( _readSubjectFromCSR " $_csrfile " )
_csrsubj = $( _readSubjectFromCSR " $_csrfile " )
if [ " $? " != "0" ] || [ -z " $_csrsubj " ] ; then
if [ " $? " != "0" ] ; then
_err " Can not read subject from csr: $_csrfile "
_err " Can not read subject from csr: $_csrfile "
return 1
return 1
fi
fi
if [ -z " $_csrsubj " ] ; then
_info "The Subject is empty"
fi
_info " Subject= $_csrsubj "
_info " Subject= $_csrsubj "
@ -5592,7 +5752,9 @@ _installcert() {
if [ -f " $_real_cert " ] && [ ! " $_ACME_IS_RENEW " ] ; then
if [ -f " $_real_cert " ] && [ ! " $_ACME_IS_RENEW " ] ; then
cp " $_real_cert " " $_backup_path /cert.bak "
cp " $_real_cert " " $_backup_path /cert.bak "
fi
fi
cat " $CERT_PATH " >" $_real_cert " || return 1
if [ " $CERT_PATH " != " $_real_cert " ] ; then
cat " $CERT_PATH " >" $_real_cert " || return 1
fi
fi
fi
if [ " $_real_ca " ] ; then
if [ " $_real_ca " ] ; then
@ -5604,7 +5766,9 @@ _installcert() {
if [ -f " $_real_ca " ] && [ ! " $_ACME_IS_RENEW " ] ; then
if [ -f " $_real_ca " ] && [ ! " $_ACME_IS_RENEW " ] ; then
cp " $_real_ca " " $_backup_path /ca.bak "
cp " $_real_ca " " $_backup_path /ca.bak "
fi
fi
cat " $CA_CERT_PATH " >" $_real_ca " || return 1
if [ " $CA_CERT_PATH " != " $_real_ca " ] ; then
cat " $CA_CERT_PATH " >" $_real_ca " || return 1
fi
fi
fi
fi
fi
@ -5613,12 +5777,14 @@ _installcert() {
if [ -f " $_real_key " ] && [ ! " $_ACME_IS_RENEW " ] ; then
if [ -f " $_real_key " ] && [ ! " $_ACME_IS_RENEW " ] ; then
cp " $_real_key " " $_backup_path /key.bak "
cp " $_real_key " " $_backup_path /key.bak "
fi
fi
if [ -f " $_real_key " ] ; then
if [ " $CERT_KEY_PATH " != " $_real_key " ] ; then
cat " $CERT_KEY_PATH " >" $_real_key " || return 1
if [ -f " $_real_key " ] ; then
else
cat " $CERT_KEY_PATH " >" $_real_key " || return 1
touch " $_real_key " || return 1
else
chmod 600 " $_real_key "
touch " $_real_key " || return 1
cat " $CERT_KEY_PATH " >" $_real_key " || return 1
chmod 600 " $_real_key "
cat " $CERT_KEY_PATH " >" $_real_key " || return 1
fi
fi
fi
fi
fi
@ -5627,7 +5793,9 @@ _installcert() {
if [ -f " $_real_fullchain " ] && [ ! " $_ACME_IS_RENEW " ] ; then
if [ -f " $_real_fullchain " ] && [ ! " $_ACME_IS_RENEW " ] ; then
cp " $_real_fullchain " " $_backup_path /fullchain.bak "
cp " $_real_fullchain " " $_backup_path /fullchain.bak "
fi
fi
cat " $CERT_FULLCHAIN_PATH " >" $_real_fullchain " || return 1
if [ " $_real_fullchain " != " $CERT_FULLCHAIN_PATH " ] ; then
cat " $CERT_FULLCHAIN_PATH " >" $_real_fullchain " || return 1
fi
fi
fi
if [ " $_reload_cmd " ] ; then
if [ " $_reload_cmd " ] ; then
@ -6616,6 +6784,11 @@ Parameters:
If no match, the default offered chain will be used. ( default: empty)
If no match, the default offered chain will be used. ( default: empty)
See: $_PREFERRED_CHAIN_WIKI
See: $_PREFERRED_CHAIN_WIKI
--valid-to <date-time> Request the NotAfter field of the cert.
See: $_VALIDITY_WIKI
--valid-from <date-time> Request the NotBefore field of the cert.
See: $_VALIDITY_WIKI
-f, --force Force install, force cert renewal or override sudo restrictions.
-f, --force Force install, force cert renewal or override sudo restrictions.
--staging, --test Use staging server, for testing.
--staging, --test Use staging server, for testing.
--debug [ 0| 1| 2| 3] Output debug info. Defaults to 1 if argument is omitted.
--debug [ 0| 1| 2| 3] Output debug info. Defaults to 1 if argument is omitted.
@ -6807,6 +6980,10 @@ _processAccountConf() {
}
}
_checkSudo( ) {
_checkSudo( ) {
if [ -z "__INTERACTIVE" ] ; then
#don't check if it's not in an interactive shell
return 0
fi
if [ " $SUDO_GID " ] && [ " $SUDO_COMMAND " ] && [ " $SUDO_USER " ] && [ " $SUDO_UID " ] ; then
if [ " $SUDO_GID " ] && [ " $SUDO_COMMAND " ] && [ " $SUDO_USER " ] && [ " $SUDO_UID " ] ; then
if [ " $SUDO_USER " = "root" ] && [ " $SUDO_UID " = "0" ] ; then
if [ " $SUDO_USER " = "root" ] && [ " $SUDO_UID " = "0" ] ; then
#it's root using sudo, no matter it's using sudo or not, just fine
#it's root using sudo, no matter it's using sudo or not, just fine
@ -6928,8 +7105,8 @@ _process() {
_altdomains = " $NO_VALUE "
_altdomains = " $NO_VALUE "
_webroot = ""
_webroot = ""
_challenge_alias = ""
_challenge_alias = ""
_keylength = " "
_keylength = " $DEFAULT_DOMAIN_KEY_LENGTH "
_accountkeylength = " "
_accountkeylength = " $DEFAULT_ACCOUNT_KEY_LENGTH "
_cert_file = ""
_cert_file = ""
_key_file = ""
_key_file = ""
_ca_file = ""
_ca_file = ""
@ -6976,6 +7153,8 @@ _process() {
_eab_kid = ""
_eab_kid = ""
_eab_hmac_key = ""
_eab_hmac_key = ""
_preferred_chain = ""
_preferred_chain = ""
_valid_from = ""
_valid_to = ""
while [ ${# } -gt 0 ] ; do
while [ ${# } -gt 0 ] ; do
case " ${ 1 } " in
case " ${ 1 } " in
@ -7283,6 +7462,14 @@ _process() {
Le_RenewalDays = " $_days "
Le_RenewalDays = " $_days "
shift
shift
; ;
; ;
--valid-from)
_valid_from = " $2 "
shift
; ;
--valid-to)
_valid_to = " $2 "
shift
; ;
--httpport)
--httpport)
_httpport = " $2 "
_httpport = " $2 "
Le_HTTPPort = " $_httpport "
Le_HTTPPort = " $_httpport "
@ -7485,6 +7672,7 @@ _process() {
if [ " $_server " ] ; then
if [ " $_server " ] ; then
_selectServer " $_server " " ${ _ecc :- $_keylength } "
_selectServer " $_server " " ${ _ecc :- $_keylength } "
_server = " $ACME_DIRECTORY "
fi
fi
if [ " ${ _CMD } " != "install" ] ; then
if [ " ${ _CMD } " != "install" ] ; then
@ -7544,7 +7732,7 @@ _process() {
uninstall) uninstall " $_nocron " ; ;
uninstall) uninstall " $_nocron " ; ;
upgrade) upgrade ; ;
upgrade) upgrade ; ;
issue)
issue)
issue " $_webroot " " $_domain " " $_altdomains " " $_keylength " " $_cert_file " " $_key_file " " $_ca_file " " $_reloadcmd " " $_fullchain_file " " $_pre_hook " " $_post_hook " " $_renew_hook " " $_local_address " " $_challenge_alias " " $_preferred_chain "
issue " $_webroot " " $_domain " " $_altdomains " " $_keylength " " $_cert_file " " $_key_file " " $_ca_file " " $_reloadcmd " " $_fullchain_file " " $_pre_hook " " $_post_hook " " $_renew_hook " " $_local_address " " $_challenge_alias " " $_preferred_chain " " $_valid_from " " $_valid_to "
; ;
; ;
deploy)
deploy)
deploy " $_domain " " $_deploy_hook " " $_ecc "
deploy " $_domain " " $_deploy_hook " " $_ecc "
@ -7559,10 +7747,10 @@ _process() {
installcert " $_domain " " $_cert_file " " $_key_file " " $_ca_file " " $_reloadcmd " " $_fullchain_file " " $_ecc "
installcert " $_domain " " $_cert_file " " $_key_file " " $_ca_file " " $_reloadcmd " " $_fullchain_file " " $_ecc "
; ;
; ;
renew)
renew)
renew " $_domain " " $_ecc "
renew " $_domain " " $_ecc " " $_server "
; ;
; ;
renewAll)
renewAll)
renewAll " $_stopRenewOnError "
renewAll " $_stopRenewOnError " " $_server "
; ;
; ;
revoke)
revoke)
revoke " $_domain " " $_ecc " " $_revoke_reason "
revoke " $_domain " " $_ecc " " $_revoke_reason "