]> git.proxmox.com Git - mirror_acme.sh.git/blobdiff - acme.sh
String change
[mirror_acme.sh.git] / acme.sh
diff --git a/acme.sh b/acme.sh
index 45e0c24609ebaab453bf808131a55fee96f9994e..a1ad41951e8249d33b479db503ca5f7ce1e6bf59 100755 (executable)
--- a/acme.sh
+++ b/acme.sh
@@ -1,6 +1,6 @@
 #!/usr/bin/env sh
 
-VER=2.8.7
+VER=2.8.9
 
 PROJECT_NAME="acme.sh"
 
@@ -36,8 +36,8 @@ DEFAULT_CA=$CA_LETSENCRYPT_V2
 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST
 
 CA_NAMES="
-Letsencrypt.org,letsencrypt
-Letsencrypt.org_test,letsencrypt_test,letsencrypttest
+LetsEncrypt.org,letsencrypt
+LetsEncrypt.org_test,letsencrypt_test,letsencrypttest
 BuyPass.com,buypass
 BuyPass.com_test,buypass_test,buypasstest
 ZeroSSL.com,zerossl
@@ -160,6 +160,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"
 
+_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_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR"
@@ -956,9 +958,9 @@ _dbase64() {
 _checkcert() {
   _cf="$1"
   if [ "$DEBUG" ]; then
-    openssl x509 -noout -text -in "$_cf"
+    ${ACME_OPENSSL_BIN:-openssl} x509 -noout -text -in "$_cf"
   else
-    openssl x509 -noout -text -in "$_cf" >/dev/null 2>&1
+    ${ACME_OPENSSL_BIN:-openssl} x509 -noout -text -in "$_cf" >/dev/null 2>&1
   fi
 }
 
@@ -1375,7 +1377,7 @@ toPkcs() {
   domain="$1"
   pfxPassword="$2"
   if [ -z "$domain" ]; then
-    _usage "Usage: $PROJECT_ENTRY --toPkcs -d domain [--password pfx-password]"
+    _usage "Usage: $PROJECT_ENTRY --to-pkcs12 --domain <domain.tld> [--password <password>] [--ecc]"
     return 1
   fi
 
@@ -1396,7 +1398,7 @@ toPkcs8() {
   domain="$1"
 
   if [ -z "$domain" ]; then
-    _usage "Usage: $PROJECT_ENTRY --toPkcs8 -d domain [--ecc]"
+    _usage "Usage: $PROJECT_ENTRY --to-pkcs8 --domain <domain.tld> [--ecc]"
     return 1
   fi
 
@@ -1416,7 +1418,7 @@ toPkcs8() {
 createAccountKey() {
   _info "Creating account key"
   if [ -z "$1" ]; then
-    _usage "Usage: $PROJECT_ENTRY --createAccountKey --accountkeylength 2048"
+    _usage "Usage: $PROJECT_ENTRY --create-account-key [--accountkeylength <bits>]"
     return
   fi
 
@@ -1459,7 +1461,7 @@ _create_account_key() {
 createDomainKey() {
   _info "Creating domain key"
   if [ -z "$1" ]; then
-    _usage "Usage: $PROJECT_ENTRY --createDomainKey -d domain.com  [ --keylength 2048 ]"
+    _usage "Usage: $PROJECT_ENTRY --create-domain-key --domain <domain.tld> [--keylength <bits>]"
     return
   fi
 
@@ -1499,7 +1501,7 @@ createDomainKey() {
 createCSR() {
   _info "Creating csr"
   if [ -z "$1" ]; then
-    _usage "Usage: $PROJECT_ENTRY --createCSR -d domain1.com [-d domain2.com  -d domain3.com ... ]"
+    _usage "Usage: $PROJECT_ENTRY --create-csr --domain <domain.tld> [--domain <domain2.tld> ...]"
     return
   fi
 
@@ -1722,6 +1724,14 @@ _mktemp() {
   _err "Can not create temp file."
 }
 
+#clear all the https envs to cause _inithttp() to run next time.
+_resethttp() {
+  __HTTP_INITIALIZED=""
+  _ACME_CURL=""
+  _ACME_WGET=""
+  ACME_HTTP_NO_REDIRECTS=""
+}
+
 _inithttp() {
 
   if [ -z "$HTTP_HEADER" ] || ! touch "$HTTP_HEADER"; then
@@ -1737,7 +1747,10 @@ _inithttp() {
   fi
 
   if [ -z "$_ACME_CURL" ] && _exists "curl"; then
-    _ACME_CURL="curl -L --silent --dump-header $HTTP_HEADER "
+    _ACME_CURL="curl --silent --dump-header $HTTP_HEADER "
+    if [ -z "$ACME_HTTP_NO_REDIRECTS" ]; then
+      _ACME_CURL="$_ACME_CURL -L "
+    fi
     if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
       _CURL_DUMP="$(_mktemp)"
       _ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP "
@@ -1756,6 +1769,9 @@ _inithttp() {
 
   if [ -z "$_ACME_WGET" ] && _exists "wget"; then
     _ACME_WGET="wget -q"
+    if [ "$ACME_HTTP_NO_REDIRECTS" ]; then
+      _ACME_WGET="$_ACME_WGET --max-redirect 0 "
+    fi
     if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
       _ACME_WGET="$_ACME_WGET -d "
     fi
@@ -2086,7 +2102,7 @@ _send_signed_request() {
 
     _debug2 original "$response"
     if echo "$responseHeaders" | grep -i "Content-Type: *application/json" >/dev/null 2>&1; then
-      response="$(echo "$response" | _normalizeJson)"
+      response="$(echo "$response" | _json_decode | _normalizeJson)"
     fi
     _debug2 response "$response"
 
@@ -2503,6 +2519,7 @@ _initAPI() {
       _err "Can not init api."
       return 1
     fi
+    response=$(echo "$response" | _json_decode)
     _debug2 "response" "$response"
 
     ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'key-change" *: *"[^"]*"' | cut -d '"' -f 3)
@@ -2887,7 +2904,7 @@ Allow from all
     if _restoreApache; then
       _err "The apache config file is restored."
     else
-      _err "Sorry, The apache config file can not be restored, please report bug."
+      _err "Sorry, the apache config file can not be restored, please report bug."
     fi
     return 1
   fi
@@ -3943,6 +3960,8 @@ _check_dns_entries() {
   _end_time="$(_math "$_end_time" + 1200)" #let's check no more than 20 minutes.
 
   while [ "$(_time)" -le "$_end_time" ]; do
+    _info "You can use '--dnssleep' to disable public dns checks."
+    _info "See: $_DNSCHECK_WIKI"
     _left=""
     for entry in $dns_entries; do
       d=$(_getfield "$entry" 1)
@@ -3992,8 +4011,8 @@ _check_dns_entries() {
 #file
 _get_cert_issuers() {
   _cfile="$1"
-  if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7"; then
-    ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | openssl pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2
+  if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then
+    ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2
   else
     ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2
   fi
@@ -4005,13 +4024,18 @@ _match_issuer() {
   _missuer="$2"
   _fissuers="$(_get_cert_issuers $_cfile)"
   _debug2 _fissuers "$_fissuers"
+  if _contains "$_fissuers" "$_missuer"; then
+    return 0
+  fi
+  _fissuers="$(echo "$_fissuers" | _lower_case)"
+  _missuer="$(echo "$_missuer" | _lower_case)"
   _contains "$_fissuers" "$_missuer"
 }
 
 #webroot, domain domainlist  keylength
 issue() {
   if [ -z "$2" ]; then
-    _usage "Usage: $PROJECT_ENTRY --issue  -d  a.com  -w /path/to/webroot/a.com/ "
+    _usage "Usage: $PROJECT_ENTRY --issue --domain <domain.tld> --webroot <directory>"
     return 1
   fi
   if [ -z "$1" ]; then
@@ -4708,7 +4732,7 @@ $_authorizations_map"
       return 1
     fi
     if [ -z "$Le_LinkOrder" ]; then
-      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 \t" | cut -d ":" -f 2-)"
     fi
 
     _savedomainconf "Le_LinkOrder" "$Le_LinkOrder"
@@ -4972,7 +4996,7 @@ $_authorizations_map"
   fi
 }
 
-#in_out_cert   out_fullchain out out_ca
+#in_out_cert   out_fullchain   out_ca
 _split_cert_chain() {
   _certf="$1"
   _fullchainf="$2"
@@ -4992,7 +5016,7 @@ _split_cert_chain() {
 renew() {
   Le_Domain="$1"
   if [ -z "$Le_Domain" ]; then
-    _usage "Usage: $PROJECT_ENTRY --renew  -d domain.com [--ecc]"
+    _usage "Usage: $PROJECT_ENTRY --renew --domain <domain.tld> [--ecc]"
     return 1
   fi
 
@@ -5002,7 +5026,7 @@ renew() {
 
   _info "$(__green "Renew: '$Le_Domain'")"
   if [ ! -f "$DOMAIN_CONF" ]; then
-    _info "'$Le_Domain' is not a issued domain, skip."
+    _info "'$Le_Domain' is not an issued domain, skip."
     return $RENEW_SKIP
   fi
 
@@ -5048,6 +5072,7 @@ renew() {
   Le_PreHook="$(_readdomainconf Le_PreHook)"
   Le_PostHook="$(_readdomainconf Le_PostHook)"
   Le_RenewHook="$(_readdomainconf Le_RenewHook)"
+  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"
   res="$?"
   if [ "$res" != "0" ]; then
@@ -5080,7 +5105,7 @@ renewAll() {
   for di in "${CERT_HOME}"/*.*/; do
     _debug di "$di"
     if ! [ -d "$di" ]; then
-      _debug "Not directory, skip: $di"
+      _debug "Not directory, skip: $di"
       continue
     fi
     d=$(basename "$di")
@@ -5183,7 +5208,7 @@ signcsr() {
   _csrfile="$1"
   _csrW="$2"
   if [ -z "$_csrfile" ] || [ -z "$_csrW" ]; then
-    _usage "Usage: $PROJECT_ENTRY --signcsr  --csr mycsr.csr  -w /path/to/webroot/a.com/ "
+    _usage "Usage: $PROJECT_ENTRY --sign-csr --csr <csr-file> --webroot <directory>"
     return 1
   fi
 
@@ -5251,7 +5276,7 @@ showcsr() {
   _csrfile="$1"
   _csrd="$2"
   if [ -z "$_csrfile" ] && [ -z "$_csrd" ]; then
-    _usage "Usage: $PROJECT_ENTRY --showcsr  --csr mycsr.csr"
+    _usage "Usage: $PROJECT_ENTRY --show-csr --csr <csr-file>"
     return 1
   fi
 
@@ -5368,7 +5393,7 @@ deploy() {
   _hooks="$2"
   _isEcc="$3"
   if [ -z "$_hooks" ]; then
-    _usage "Usage: $PROJECT_ENTRY --deploy -d domain.com --deploy-hook cpanel [--ecc] "
+    _usage "Usage: $PROJECT_ENTRY --deploy --domain <domain.tld> --deploy-hook <hookname> [--ecc] "
     return 1
   fi
 
@@ -5389,7 +5414,7 @@ deploy() {
 installcert() {
   _main_domain="$1"
   if [ -z "$_main_domain" ]; then
-    _usage "Usage: $PROJECT_ENTRY --installcert -d domain.com  [--ecc] [--cert-file cert-file-path]  [--key-file key-file-path]  [--ca-file ca-cert-file-path]   [ --reloadCmd reloadCmd] [--fullchain-file fullchain-path]"
+    _usage "Usage: $PROJECT_ENTRY --install-cert --domain <domain.tld> [--ecc] [--cert-file <file>] [--key-file <file>] [--ca-file <file>] [ --reloadcmd <command>] [--fullchain-file <file>]"
     return 1
   fi
 
@@ -5668,7 +5693,7 @@ uninstallcronjob() {
 revoke() {
   Le_Domain="$1"
   if [ -z "$Le_Domain" ]; then
-    _usage "Usage: $PROJECT_ENTRY --revoke -d domain.com  [--ecc]"
+    _usage "Usage: $PROJECT_ENTRY --revoke --domain <domain.tld> [--ecc]"
     return 1
   fi
 
@@ -5739,7 +5764,7 @@ revoke() {
 remove() {
   Le_Domain="$1"
   if [ -z "$Le_Domain" ]; then
-    _usage "Usage: $PROJECT_ENTRY --remove -d domain.com [--ecc]"
+    _usage "Usage: $PROJECT_ENTRY --remove --domain <domain.tld> [--ecc]"
     return 1
   fi
 
@@ -5816,7 +5841,7 @@ _deactivate() {
     _URL_NAME="uri"
   fi
 
-  entries="$(echo "$response" | _egrep_o "[^{]*\"type\":\"[^\"]*\", *\"status\": *\"valid\", *\"$_URL_NAME\"[^}]*")"
+  entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")"
   if [ -z "$entries" ]; then
     _info "No valid entries found."
     if [ -z "$thumbprint" ]; then
@@ -5859,7 +5884,7 @@ _deactivate() {
     _debug _vtype "$_vtype"
     _info "Found $_vtype"
 
-    uri="$(echo "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')"
+    uri="$(echo "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*\"" | tr -d '" ' | cut -d : -f 2-)"
     _debug uri "$uri"
 
     if [ "$_d_type" ] && [ "$_d_type" != "$_vtype" ]; then
@@ -5899,7 +5924,7 @@ deactivate() {
   _initAPI
   _debug _d_domain_list "$_d_domain_list"
   if [ -z "$(echo $_d_domain_list | cut -d , -f 1)" ]; then
-    _usage "Usage: $PROJECT_ENTRY --deactivate -d domain.com [-d domain.com]"
+    _usage "Usage: $PROJECT_ENTRY --deactivate --domain <domain.tld> [--domain <domain2.tld> ...]"
     return 1
   fi
   for _d_dm in $(echo "$_d_domain_list" | tr ',' ' '); do
@@ -6080,7 +6105,7 @@ _installalias() {
 
 }
 
-# nocron confighome noprofile
+# nocron confighome noprofile accountemail
 install() {
 
   if [ -z "$LE_WORKING_DIR" ]; then
@@ -6090,6 +6115,8 @@ install() {
   _nocron="$1"
   _c_home="$2"
   _noprofile="$3"
+  _accountemail="$4"
+
   if ! _initpath; then
     _err "Install failed."
     return 1
@@ -6208,6 +6235,10 @@ install() {
     fi
   fi
 
+  if [ "$_accountemail" ]; then
+    _saveaccountconf "ACCOUNT_EMAIL" "$_accountemail"
+  fi
+
   _info OK
 }
 
@@ -6359,7 +6390,7 @@ setnotify() {
   _initpath
 
   if [ -z "$_nhook$_nlevel$_nmode" ]; then
-    _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook mailgun] [--notify-level $NOTIFY_LEVEL_DEFAULT] [--notify-mode $NOTIFY_MODE_DEFAULT]"
+    _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook <hookname>] [--notify-level <0|1|2|3>] [--notify-mode <0|1>]"
     _usage "$_NOTIFY_WIKI"
     return 1
   fi
@@ -6398,162 +6429,156 @@ setnotify() {
 showhelp() {
   _initpath
   version
-  echo "Usage: $PROJECT_ENTRY  command ...[parameters]....
+  echo "Usage: $PROJECT_ENTRY <command> ... [parameters ...]
 Commands:
-  --help, -h               Show this help message.
-  --version, -v            Show version info.
+  -h, --help               Show this help message.
+  -v, --version            Show version info.
   --install                Install $PROJECT_NAME to your system.
   --uninstall              Uninstall $PROJECT_NAME, and uninstall the cron job.
   --upgrade                Upgrade $PROJECT_NAME to the latest code from $PROJECT.
   --issue                  Issue a cert.
-  --signcsr                Issue a cert from an existing csr.
   --deploy                 Deploy the cert to your server.
-  --install-cert           Install the issued cert to apache/nginx or any other server.
-  --renew, -r              Renew a cert.
+  -i, --install-cert       Install the issued cert to apache/nginx or any other server.
+  -r, --renew              Renew a cert.
   --renew-all              Renew all the certs.
   --revoke                 Revoke a cert.
   --remove                 Remove the cert from list of certs known to $PROJECT_NAME.
   --list                   List all the certs.
-  --showcsr                Show the content of a csr.
-  --install-cronjob        Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job.
-  --uninstall-cronjob      Uninstall the cron job. The 'uninstall' command can do this automatically.
-  --cron                   Run cron job to renew all the certs.
-  --toPkcs                 Export the certificate and key to a pfx file.
-  --toPkcs8                Convert to pkcs8 format.
+  --to-pkcs12              Export the certificate and key to a pfx file.
+  --to-pkcs8               Convert to pkcs8 format.
+  --sign-csr               Issue a cert from an existing csr.
+  --show-csr               Show the content of a csr.
+  -ccr, --create-csr       Create CSR, professional use.
+  --create-domain-key      Create an domain private key, professional use.
   --update-account         Update account info.
   --register-account       Register account key.
   --deactivate-account     Deactivate the account.
   --create-account-key     Create an account private key, professional use.
-  --create-domain-key      Create an domain private key, professional use.
-  --createCSR, -ccsr       Create CSR , professional use.
-  --deactivate             Deactivate the domain authz, professional use.
+  --install-cronjob        Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job.
+  --uninstall-cronjob      Uninstall the cron job. The 'uninstall' command can do this automatically.
+  --cron                   Run cron job to renew all the certs.
   --set-notify             Set the cron notification hook, level or mode.
-  --set-default-ca         Used with '--server' , to set the default CA to use to use. 
+  --deactivate             Deactivate the domain authz, professional use.
+  --set-default-ca         Used with '--server', Set the default CA to use.
+                           See: $_SERVER_WIKI
 
 
 Parameters:
-  --domain, -d   domain.tld         Specifies a domain, used to issue, renew or revoke etc.
-  --challenge-alias domain.tld      The challenge domain alias for DNS alias mode.
+  -d, --domain <domain.tld>         Specifies a domain, used to issue, renew or revoke etc.
+  --challenge-alias <domain.tld>    The challenge domain alias for DNS alias mode.
                                     See: $_DNS_ALIAS_WIKI
 
-  --domain-alias domain.tld         The domain alias for DNS alias mode.
+  --domain-alias <domain.tld>       The domain alias for DNS alias mode.
                                     See: $_DNS_ALIAS_WIKI
 
-  --preferred-chain  CHAIN          If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
+  --preferred-chain <chain>         If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
                                     If no match, the default offered chain will be used. (default: empty)
                                     See: $_PREFERRED_CHAIN_WIKI
 
-  --force, -f                       Used to force to install or force to renew a cert immediately.
-  --staging, --test                 Use staging server, just for test.
-  --debug                           Output debug info.
+  -f, --force                       Force install, force cert renewal or override sudo restrictions.
+  --staging, --test                 Use staging server, for testing.
+  --debug [0|1|2|3]                 Output debug info. Defaults to 1 if argument is omitted.
   --output-insecure                 Output all the sensitive messages.
                                     By default all the credentials/sensitive messages are hidden from the output/debug/log for security.
-
-  --webroot, -w  /path/to/webroot   Specifies the web root folder for web root mode.
+  -w, --webroot <directory>         Specifies the web root folder for web root mode.
   --standalone                      Use standalone mode.
   --alpn                            Use standalone alpn mode.
   --stateless                       Use stateless mode.
                                     See: $_STATELESS_WIKI
 
   --apache                          Use apache mode.
-  --dns [dns_hook]                  Use dns mode or dns api.
+  --dns [dns_hook]                  Use dns manual mode or dns api. Defaults to manual mode when argument is omitted.
                                     See: $_DNS_API_WIKI
 
-  --dnssleep   300                  The time in seconds to wait for all the txt records to propagate in dns api mode.
+  --dnssleep <seconds>              The time in seconds to wait for all the txt records to propagate in dns api mode.
                                     It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically.
+  -k, --keylength <bits>            Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521.
+  -ak, --accountkeylength <bits>    Specifies the account key length: 2048, 3072, 4096
+  --log [file]                      Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted.
+  --log-level <1|2>                 Specifies the log level, default is 1.
+  --syslog <0|3|6|7>                Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug.
+  --eab-kid <eab_key_id>            Key Identifier for External Account Binding.
+  --eab-hmac-key <eab_hmac_key>     HMAC key for External Account Binding.
 
-  --keylength, -k [2048]            Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521.
-  --accountkeylength, -ak [2048]    Specifies the account key length: 2048, 3072, 4096
-  --log    [/path/to/logfile]       Specifies the log file. The default is: \"$DEFAULT_LOG_FILE\" if you don't give a file path here.
-  --log-level 1|2                   Specifies the log level, default is 1.
-  --syslog [0|3|6|7]                Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug.
 
-  --eab-kid EAB_KID                 Key Identifier for External Account Binding.
-  --eab-hmac-key EAB_HMAC_KEY       HMAC key for External Account Binding.
-            
-            
   These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert:
 
-  --cert-file                       After issue/renew, the cert will be copied to this path.
-  --key-file                        After issue/renew, the key will be copied to this path.
-  --ca-file                         After issue/renew, the intermediate cert will be copied to this path.
-  --fullchain-file                  After issue/renew, the fullchain cert will be copied to this path.
+  --cert-file <file>                Path to copy the cert file to after issue/renew..
+  --key-file <file>                 Path to copy the key file to after issue/renew.
+  --ca-file <file>                  Path to copy the intermediate cert file to after issue/renew.
+  --fullchain-file <file>           Path to copy the fullchain cert file to after issue/renew.
+  --reloadcmd <command>             Command to execute after issue/renew to reload the server.
 
-  --reloadcmd \"service nginx reload\" After issue/renew, it's used to reload the server.
-
-  --server SERVER                   ACME Directory Resource URI. (default: $DEFAULT_CA)
+  --server <server_uri>             ACME Directory Resource URI. (default: $DEFAULT_CA)
                                     See: $_SERVER_WIKI
 
-  --accountconf                     Specifies a customized account config file.
-  --home                            Specifies the home dir for $PROJECT_NAME.
-  --cert-home                       Specifies the home dir to save all the certs, only valid for '--install' command.
-  --config-home                     Specifies the home dir to save all the configurations.
-  --useragent                       Specifies the user agent string. it will be saved for future use too.
-  --accountemail, -m                Specifies the account email, only valid for the '--install' and '--update-account' command.
-  --accountkey                      Specifies the account key path, only valid for the '--install' command.
-  --days                            Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days.
-  --httpport                        Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
-  --tlsport                         Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer.
-  --local-address                   Specifies the standalone/tls server listening address, in case you have multiple ip addresses.
+  --accountconf <file>              Specifies a customized account config file.
+  --home <directory>                Specifies the home dir for $PROJECT_NAME.
+  --cert-home <directory>           Specifies the home dir to save all the certs, only valid for '--install' command.
+  --config-home <directory>         Specifies the home dir to save all the configurations.
+  --useragent <string>              Specifies the user agent string. it will be saved for future use too.
+  -m, --email <email>               Specifies the account email, only valid for the '--install' and '--update-account' command.
+  --accountkey <file>               Specifies the account key path, only valid for the '--install' command.
+  --days <ndays>                    Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days.
+  --httpport <port>                 Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
+  --tlsport <port>                  Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer.
+  --local-address <ip>              Specifies the standalone/tls server listening address, in case you have multiple ip addresses.
   --listraw                         Only used for '--list' command, list the certs in raw format.
-  --stopRenewOnError, -se           Only valid for '--renew-all' command. Stop if one cert has error in renewal.
+  -se, --stop-renew-on-error        Only valid for '--renew-all' command. Stop if one cert has error in renewal.
   --insecure                        Do not check the server certificate, in some devices, the api server's certificate may not be trusted.
-  --ca-bundle                       Specifies the path to the CA certificate bundle to verify api server's certificate.
-  --ca-path                         Specifies directory containing CA certificates in PEM format, used by wget or curl.
-  --nocron                          Only valid for '--install' command, which means: do not install the default cron job.
+  --ca-bundle <file>                Specifies the path to the CA certificate bundle to verify api server's certificate.
+  --ca-path <directory>             Specifies directory containing CA certificates in PEM format, used by wget or curl.
+  --no-cron                         Only valid for '--install' command, which means: do not install the default cron job.
                                     In this case, the certs will not be renewed automatically.
-  
-  --noprofile                       Only valid for '--install' command, which means: do not install aliases to user profile.
+  --no-profile                      Only valid for '--install' command, which means: do not install aliases to user profile.
   --no-color                        Do not output color text.
   --force-color                     Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
-  --ecc                             Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR'
-  --csr                             Specifies the input csr.
-  --pre-hook                        Command to be run before obtaining any certificates.
-  --post-hook                       Command to be run after attempting to obtain/renew certificates. No matter the obtain/renew is success or failed.
-  --renew-hook                      Command to be run once for each successfully renewed certificate.
-  --deploy-hook                     The hook file to deploy cert
-  --ocsp-must-staple, --ocsp        Generate ocsp must Staple extension.
-  --always-force-new-domain-key     Generate new domain key when renewal. Otherwise, the domain key is not changed by default.
-  --auto-upgrade   [0|1]            Valid for '--upgrade' command, indicating whether to upgrade automatically in future.
+  --ecc                             Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--to-pkcs12' and '--create-csr'
+  --csr <file>                      Specifies the input csr.
+  --pre-hook <command>              Command to be run before obtaining any certificates.
+  --post-hook <command>             Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed.
+  --renew-hook <command>            Command to be run after each successfully renewed certificate.
+  --deploy-hook <hookname>          The hook file to deploy cert
+  --ocsp, --ocsp-must-staple        Generate OCSP-Must-Staple extension.
+  --always-force-new-domain-key     Generate new domain key on renewal. Otherwise, the domain key is not changed by default.
+  --auto-upgrade [0|1]              Valid for '--upgrade' command, indicating whether to upgrade automatically in future. Defaults to 1 if argument is omitted.
   --listen-v4                       Force standalone/tls server to listen at ipv4.
   --listen-v6                       Force standalone/tls server to listen at ipv6.
-  --openssl-bin                     Specifies a custom openssl bin location.
+  --openssl-bin <file>              Specifies a custom openssl bin location.
   --use-wget                        Force to use wget, if you have both curl and wget installed.
-  --yes-I-know-dns-manual-mode-enough-go-ahead-please  Force to use dns manual mode.
+  --yes-I-know-dns-manual-mode-enough-go-ahead-please  Force use of dns manual mode.
                                     See:  $_DNS_MANUAL_WIKI
 
-  --branch, -b                      Only valid for '--upgrade' command, specifies the branch name to upgrade to.
-
-  --notify-level  0|1|2|3           Set the notification level:  Default value is $NOTIFY_LEVEL_DEFAULT.
-                                     0: disabled, no notification will be sent.
-                                     1: send notifications only when there is an error.
-                                     2: send notifications when a cert is successfully renewed, or there is an error.
-                                     3: send notifications when a cert is skipped, renewed, or error.
-
-  --notify-mode   0|1               Set notification mode. Default value is $NOTIFY_MODE_DEFAULT.
-                                     0: Bulk mode. Send all the domain's notifications in one message(mail).
-                                     1: Cert mode. Send a message for every single cert.
-
-  --notify-hook   [hookname]        Set the notify hook
-  --revoke-reason [0-10]            The reason for '--revoke' command.
+  -b, --branch <branch>             Only valid for '--upgrade' command, specifies the branch name to upgrade to.
+  --notify-level <0|1|2|3>          Set the notification level:  Default value is $NOTIFY_LEVEL_DEFAULT.
+                                    0: disabled, no notification will be sent.
+                                    1: send notifications only when there is an error.
+                                    2: send notifications when a cert is successfully renewed, or there is an error.
+                                    3: send notifications when a cert is skipped, renewed, or error.
+  --notify-mode <0|1>               Set notification mode. Default value is $NOTIFY_MODE_DEFAULT.
+                                    0: Bulk mode. Send all the domain's notifications in one message(mail).
+                                    1: Cert mode. Send a message for every single cert.
+  --notify-hook <hookname>          Set the notify hook
+  --revoke-reason <0-10>            The reason for revocation, can be used in conjunction with the '--revoke' command.
                                     See: $_REVOKE_WIKI
 
+  --password <password>             Add a password to exported pfx file. Use with --to-pkcs12.
+
 
 "
 }
 
-# nocron noprofile
-_installOnline() {
+installOnline() {
   _info "Installing from online archive."
-  _nocron="$1"
-  _noprofile="$2"
-  if [ ! "$BRANCH" ]; then
-    BRANCH="master"
+
+  _branch="$BRANCH"
+  if [ -z "$_branch" ]; then
+    _branch="master"
   fi
 
-  target="$PROJECT/archive/$BRANCH.tar.gz"
+  target="$PROJECT/archive/$_branch.tar.gz"
   _info "Downloading $target"
-  localname="$BRANCH.tar.gz"
+  localname="$_branch.tar.gz"
   if ! _get "$target" >$localname; then
     _err "Download error."
     return 1
@@ -6565,9 +6590,9 @@ _installOnline() {
       exit 1
     fi
 
-    cd "$PROJECT_NAME-$BRANCH"
+    cd "$PROJECT_NAME-$_branch"
     chmod +x $PROJECT_ENTRY
-    if ./$PROJECT_ENTRY install "$_nocron" "" "$_noprofile"; then
+    if ./$PROJECT_ENTRY --install "$@"; then
       _info "Install success!"
       _initpath
       _saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)"
@@ -6575,7 +6600,7 @@ _installOnline() {
 
     cd ..
 
-    rm -rf "$PROJECT_NAME-$BRANCH"
+    rm -rf "$PROJECT_NAME-$_branch"
     rm -f "$localname"
   )
 }
@@ -6603,7 +6628,7 @@ upgrade() {
     [ -z "$FORCE" ] && [ "$(_getUpgradeHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0
     export LE_WORKING_DIR
     cd "$LE_WORKING_DIR"
-    _installOnline "nocron" "noprofile"
+    installOnline "--nocron" "--noprofile"
   ); then
     _info "Upgrade success!"
     exit 0
@@ -6647,8 +6672,8 @@ _checkSudo() {
       return 0
     fi
     if [ -n "$SUDO_COMMAND" ]; then
-      #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s`
-      _endswith "$SUDO_COMMAND" /bin/su || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1
+      #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s`, or `sudo su acmeuser1`
+      _endswith "$SUDO_COMMAND" /bin/su || _contains "$SUDO_COMMAND" "/bin/su " || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1
       return $?
     fi
     #otherwise
@@ -6783,6 +6808,11 @@ _process() {
     --install)
       _CMD="install"
       ;;
+    --install-online)
+      shift
+      installOnline "$@"
+      return
+      ;;
     --uninstall)
       _CMD="uninstall"
       ;;
@@ -6795,19 +6825,19 @@ _process() {
     --deploy)
       _CMD="deploy"
       ;;
-    --signcsr)
+    --sign-csr | --signcsr)
       _CMD="signcsr"
       ;;
-    --showcsr)
+    --show-csr | --showcsr)
       _CMD="showcsr"
       ;;
-    --installcert | -i | --install-cert)
+    -i | --install-cert | --installcert)
       _CMD="installcert"
       ;;
     --renew | -r)
       _CMD="renew"
       ;;
-    --renewAll | --renewall | --renew-all)
+    --renew-all | --renewAll | --renewall)
       _CMD="renewAll"
       ;;
     --revoke)
@@ -6819,37 +6849,37 @@ _process() {
     --list)
       _CMD="list"
       ;;
-    --installcronjob | --install-cronjob)
+    --install-cronjob | --installcronjob)
       _CMD="installcronjob"
       ;;
-    --uninstallcronjob | --uninstall-cronjob)
+    --uninstall-cronjob | --uninstallcronjob)
       _CMD="uninstallcronjob"
       ;;
     --cron)
       _CMD="cron"
       ;;
-    --toPkcs)
+    --to-pkcs12 | --to-pkcs | --toPkcs)
       _CMD="toPkcs"
       ;;
-    --toPkcs8)
+    --to-pkcs8 | --toPkcs8)
       _CMD="toPkcs8"
       ;;
-    --createAccountKey | --createaccountkey | -cak | --create-account-key)
+    --create-account-key | --createAccountKey | --createaccountkey | -cak)
       _CMD="createAccountKey"
       ;;
-    --createDomainKey | --createdomainkey | -cdk | --create-domain-key)
+    --create-domain-key | --createDomainKey | --createdomainkey | -cdk)
       _CMD="createDomainKey"
       ;;
-    --createCSR | --createcsr | -ccr)
+    -ccr | --create-csr | --createCSR | --createcsr)
       _CMD="createCSR"
       ;;
     --deactivate)
       _CMD="deactivate"
       ;;
-    --updateaccount | --update-account)
+    --update-account | --updateaccount)
       _CMD="updateaccount"
       ;;
-    --registeraccount | --register-account)
+    --register-account | --registeraccount)
       _CMD="registeraccount"
       ;;
     --deactivate-account)
@@ -6861,7 +6891,7 @@ _process() {
     --set-default-ca)
       _CMD="setdefaultca"
       ;;
-    --domain | -d)
+    -d | --domain)
       _dvalue="$2"
 
       if [ "$_dvalue" ]; then
@@ -6892,7 +6922,7 @@ _process() {
       shift
       ;;
 
-    --force | -f)
+    -f | --force)
       FORCE="1"
       ;;
     --staging | --test)
@@ -6914,7 +6944,7 @@ _process() {
     --output-insecure)
       export OUTPUT_INSECURE=1
       ;;
-    --webroot | -w)
+    -w | --webroot)
       wvalue="$2"
       if [ -z "$_webroot" ]; then
         _webroot="$wvalue"
@@ -7004,7 +7034,7 @@ _process() {
       _keylength="$2"
       shift
       ;;
-    --accountkeylength | -ak)
+    -ak | --accountkeylength)
       _accountkeylength="$2"
       shift
       ;;
@@ -7042,7 +7072,7 @@ _process() {
       LE_WORKING_DIR="$2"
       shift
       ;;
-    --certhome | --cert-home)
+    --cert-home | --certhome)
       _certhome="$2"
       CERT_HOME="$_certhome"
       shift
@@ -7057,9 +7087,9 @@ _process() {
       USER_AGENT="$_useragent"
       shift
       ;;
-    --accountemail | -m)
+    -m | --email | --accountemail)
       _accountemail="$2"
-      ACCOUNT_EMAIL="$_accountemail"
+      export ACCOUNT_EMAIL="$_accountemail"
       shift
       ;;
     --accountkey)
@@ -7085,7 +7115,7 @@ _process() {
     --listraw)
       _listraw="raw"
       ;;
-    --stopRenewOnError | --stoprenewonerror | -se)
+    -se | --stop-renew-on-error | --stopRenewOnError | --stoprenewonerror)
       _stopRenewOnError="1"
       ;;
     --insecure)
@@ -7102,10 +7132,10 @@ _process() {
       CA_PATH="$_ca_path"
       shift
       ;;
-    --nocron)
+    --no-cron | --nocron)
       _nocron="1"
       ;;
-    --noprofile)
+    --no-profile | --noprofile)
       _noprofile="1"
       ;;
     --no-color)
@@ -7325,7 +7355,7 @@ _process() {
   fi
   _debug "Running cmd: ${_CMD}"
   case "${_CMD}" in
-  install) install "$_nocron" "$_confighome" "$_noprofile" ;;
+  install) install "$_nocron" "$_confighome" "$_noprofile" "$_accountemail" ;;
   uninstall) uninstall "$_nocron" ;;
   upgrade) upgrade ;;
   issue)
@@ -7438,12 +7468,6 @@ _process() {
 
 }
 
-if [ "$INSTALLONLINE" ]; then
-  INSTALLONLINE=""
-  _installOnline
-  exit
-fi
-
 main() {
   [ -z "$1" ] && showhelp && return
   if _startswith "$1" '-'; then _process "$@"; else "$@"; fi