mirror of
				https://github.com/hiskang/acme.sh
				synced 2025-11-04 12:28:12 +00:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/master' into ssh-deploy
This commit is contained in:
		
						commit
						b30c1daf72
					
				@ -26,9 +26,9 @@ install:
 | 
			
		||||
      _old_path="$PATH";
 | 
			
		||||
      echo "PATH=$PATH";
 | 
			
		||||
      export PATH="";
 | 
			
		||||
      export OPENSSL_BIN="/usr/local/openssl";
 | 
			
		||||
      export ACME_OPENSSL_BIN="/usr/local/openssl";
 | 
			
		||||
      openssl version 2>&1 || true;
 | 
			
		||||
      $OPENSSL_BIN version 2>&1 || true;
 | 
			
		||||
      $ACME_OPENSSL_BIN version 2>&1 || true;
 | 
			
		||||
      export PATH="$_old_path";
 | 
			
		||||
    fi
 | 
			
		||||
  
 | 
			
		||||
@ -44,7 +44,7 @@ script:
 | 
			
		||||
  - cd ..
 | 
			
		||||
  - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest
 | 
			
		||||
  - if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi
 | 
			
		||||
  - if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi
 | 
			
		||||
  - if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ACME_OPENSSL_BIN="$ACME_OPENSSL_BIN" ./letest.sh ; fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
matrix:
 | 
			
		||||
 | 
			
		||||
@ -293,6 +293,8 @@ You don't have to do anything manually!
 | 
			
		||||
1. Linode.com API
 | 
			
		||||
1. FreeDNS (https://freedns.afraid.org/)
 | 
			
		||||
1. cyon.ch
 | 
			
		||||
1. Domain-Offensive/Resellerinterface/Domainrobot API
 | 
			
		||||
1. Gandi LiveDNS API
 | 
			
		||||
 | 
			
		||||
**More APIs coming soon...**
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										240
									
								
								acme.sh
									
									
									
									
									
								
							
							
						
						
									
										240
									
								
								acme.sh
									
									
									
									
									
								
							@ -137,16 +137,16 @@ _printargs() {
 | 
			
		||||
 | 
			
		||||
_dlg_versions() {
 | 
			
		||||
  echo "Diagnosis versions: "
 | 
			
		||||
  echo "openssl:$OPENSSL_BIN"
 | 
			
		||||
  if _exists "$OPENSSL_BIN"; then
 | 
			
		||||
    $OPENSSL_BIN version 2>&1
 | 
			
		||||
  echo "openssl:$ACME_OPENSSL_BIN"
 | 
			
		||||
  if _exists "$ACME_OPENSSL_BIN"; then
 | 
			
		||||
    $ACME_OPENSSL_BIN version 2>&1
 | 
			
		||||
  else
 | 
			
		||||
    echo "$OPENSSL_BIN doesn't exists."
 | 
			
		||||
    echo "$ACME_OPENSSL_BIN doesn't exists."
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  echo "apache:"
 | 
			
		||||
  if [ "$_APACHECTL" ] && _exists "$_APACHECTL"; then
 | 
			
		||||
    _APACHECTL -V 2>&1
 | 
			
		||||
    $_APACHECTL -V 2>&1
 | 
			
		||||
  else
 | 
			
		||||
    echo "apache doesn't exists."
 | 
			
		||||
  fi
 | 
			
		||||
@ -780,19 +780,19 @@ _base64() {
 | 
			
		||||
  [ "" ] #urgly
 | 
			
		||||
  if [ "$1" ]; then
 | 
			
		||||
    _debug3 "base64 multiline:'$1'"
 | 
			
		||||
    $OPENSSL_BIN base64 -e
 | 
			
		||||
    $ACME_OPENSSL_BIN base64 -e
 | 
			
		||||
  else
 | 
			
		||||
    _debug3 "base64 single line."
 | 
			
		||||
    $OPENSSL_BIN base64 -e | tr -d '\r\n'
 | 
			
		||||
    $ACME_OPENSSL_BIN base64 -e | tr -d '\r\n'
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#Usage: multiline
 | 
			
		||||
_dbase64() {
 | 
			
		||||
  if [ "$1" ]; then
 | 
			
		||||
    $OPENSSL_BIN base64 -d -A
 | 
			
		||||
    $ACME_OPENSSL_BIN base64 -d -A
 | 
			
		||||
  else
 | 
			
		||||
    $OPENSSL_BIN base64 -d
 | 
			
		||||
    $ACME_OPENSSL_BIN base64 -d
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -809,9 +809,9 @@ _digest() {
 | 
			
		||||
 | 
			
		||||
  if [ "$alg" = "sha256" ] || [ "$alg" = "sha1" ] || [ "$alg" = "md5" ]; then
 | 
			
		||||
    if [ "$outputhex" ]; then
 | 
			
		||||
      $OPENSSL_BIN dgst -"$alg" -hex | cut -d = -f 2 | tr -d ' '
 | 
			
		||||
      $ACME_OPENSSL_BIN dgst -"$alg" -hex | cut -d = -f 2 | tr -d ' '
 | 
			
		||||
    else
 | 
			
		||||
      $OPENSSL_BIN dgst -"$alg" -binary | _base64
 | 
			
		||||
      $ACME_OPENSSL_BIN dgst -"$alg" -binary | _base64
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    _err "$alg is not supported yet"
 | 
			
		||||
@ -834,9 +834,9 @@ _hmac() {
 | 
			
		||||
 | 
			
		||||
  if [ "$alg" = "sha256" ] || [ "$alg" = "sha1" ]; then
 | 
			
		||||
    if [ "$outputhex" ]; then
 | 
			
		||||
      ($OPENSSL_BIN dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" 2>/dev/null || $OPENSSL_BIN dgst -"$alg" -hmac "$(printf "%s" "$secret_hex" | _h2b)") | cut -d = -f 2 | tr -d ' '
 | 
			
		||||
      ($ACME_OPENSSL_BIN dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" 2>/dev/null || $ACME_OPENSSL_BIN dgst -"$alg" -hmac "$(printf "%s" "$secret_hex" | _h2b)") | cut -d = -f 2 | tr -d ' '
 | 
			
		||||
    else
 | 
			
		||||
      $OPENSSL_BIN dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" -binary 2>/dev/null || $OPENSSL_BIN dgst -"$alg" -hmac "$(printf "%s" "$secret_hex" | _h2b)" -binary
 | 
			
		||||
      $ACME_OPENSSL_BIN dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" -binary 2>/dev/null || $ACME_OPENSSL_BIN dgst -"$alg" -hmac "$(printf "%s" "$secret_hex" | _h2b)" -binary
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    _err "$alg is not supported yet"
 | 
			
		||||
@ -855,7 +855,7 @@ _sign() {
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _sign_openssl="$OPENSSL_BIN   dgst -sign $keyfile "
 | 
			
		||||
  _sign_openssl="$ACME_OPENSSL_BIN   dgst -sign $keyfile "
 | 
			
		||||
  if [ "$alg" = "sha256" ]; then
 | 
			
		||||
    _sign_openssl="$_sign_openssl -$alg"
 | 
			
		||||
  else
 | 
			
		||||
@ -866,7 +866,7 @@ _sign() {
 | 
			
		||||
  if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then
 | 
			
		||||
    $_sign_openssl | _base64
 | 
			
		||||
  elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then
 | 
			
		||||
    if ! _signedECText="$($_sign_openssl | $OPENSSL_BIN asn1parse -inform DER)"; then
 | 
			
		||||
    if ! _signedECText="$($_sign_openssl | $ACME_OPENSSL_BIN asn1parse -inform DER)"; then
 | 
			
		||||
      _err "Sign failed: $_sign_openssl"
 | 
			
		||||
      _err "Key file: $keyfile"
 | 
			
		||||
      _err "Key content:$(wc -l <"$keyfile") lises"
 | 
			
		||||
@ -927,12 +927,21 @@ _createkey() {
 | 
			
		||||
 | 
			
		||||
  _debug "Use length $length"
 | 
			
		||||
 | 
			
		||||
  if ! touch "$f" >/dev/null 2>&1; then
 | 
			
		||||
    _f_path="$(dirname "$f")"
 | 
			
		||||
    _debug _f_path "$_f_path"
 | 
			
		||||
    if ! mkdir -p "$_f_path"; then
 | 
			
		||||
      _err "Can not create path: $_f_path"
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if _isEccKey "$length"; then
 | 
			
		||||
    _debug "Using ec name: $eccname"
 | 
			
		||||
    $OPENSSL_BIN ecparam -name "$eccname" -genkey 2>/dev/null >"$f"
 | 
			
		||||
    $ACME_OPENSSL_BIN ecparam -name "$eccname" -genkey 2>/dev/null >"$f"
 | 
			
		||||
  else
 | 
			
		||||
    _debug "Using RSA: $length"
 | 
			
		||||
    $OPENSSL_BIN genrsa "$length" 2>/dev/null >"$f"
 | 
			
		||||
    $ACME_OPENSSL_BIN genrsa "$length" 2>/dev/null >"$f"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ "$?" != "0" ]; then
 | 
			
		||||
@ -1019,9 +1028,9 @@ _createcsr() {
 | 
			
		||||
  _csr_cn="$(_idn "$domain")"
 | 
			
		||||
  _debug2 _csr_cn "$_csr_cn"
 | 
			
		||||
  if _contains "$(uname -a)" "MINGW"; then
 | 
			
		||||
    $OPENSSL_BIN req -new -sha256 -key "$csrkey" -subj "//CN=$_csr_cn" -config "$csrconf" -out "$csr"
 | 
			
		||||
    $ACME_OPENSSL_BIN req -new -sha256 -key "$csrkey" -subj "//CN=$_csr_cn" -config "$csrconf" -out "$csr"
 | 
			
		||||
  else
 | 
			
		||||
    $OPENSSL_BIN req -new -sha256 -key "$csrkey" -subj "/CN=$_csr_cn" -config "$csrconf" -out "$csr"
 | 
			
		||||
    $ACME_OPENSSL_BIN req -new -sha256 -key "$csrkey" -subj "/CN=$_csr_cn" -config "$csrconf" -out "$csr"
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1033,7 +1042,7 @@ _signcsr() {
 | 
			
		||||
  cert="$4"
 | 
			
		||||
  _debug "_signcsr"
 | 
			
		||||
 | 
			
		||||
  _msg="$($OPENSSL_BIN x509 -req -days 365 -in "$csr" -signkey "$key" -extensions v3_req -extfile "$conf" -out "$cert" 2>&1)"
 | 
			
		||||
  _msg="$($ACME_OPENSSL_BIN x509 -req -days 365 -in "$csr" -signkey "$key" -extensions v3_req -extfile "$conf" -out "$cert" 2>&1)"
 | 
			
		||||
  _ret="$?"
 | 
			
		||||
  _debug "$_msg"
 | 
			
		||||
  return $_ret
 | 
			
		||||
@ -1046,7 +1055,7 @@ _readSubjectFromCSR() {
 | 
			
		||||
    _usage "_readSubjectFromCSR mycsr.csr"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  $OPENSSL_BIN req -noout -in "$_csrfile" -subject | _egrep_o "CN *=.*" | cut -d = -f 2 | cut -d / -f 1 | tr -d '\n'
 | 
			
		||||
  $ACME_OPENSSL_BIN req -noout -in "$_csrfile" -subject | _egrep_o "CN *=.*" | cut -d = -f 2 | cut -d / -f 1 | tr -d '\n'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#_csrfile
 | 
			
		||||
@ -1061,7 +1070,7 @@ _readSubjectAltNamesFromCSR() {
 | 
			
		||||
  _csrsubj="$(_readSubjectFromCSR "$_csrfile")"
 | 
			
		||||
  _debug _csrsubj "$_csrsubj"
 | 
			
		||||
 | 
			
		||||
  _dnsAltnames="$($OPENSSL_BIN req -noout -text -in "$_csrfile" | grep "^ *DNS:.*" | tr -d ' \n')"
 | 
			
		||||
  _dnsAltnames="$($ACME_OPENSSL_BIN req -noout -text -in "$_csrfile" | grep "^ *DNS:.*" | tr -d ' \n')"
 | 
			
		||||
  _debug _dnsAltnames "$_dnsAltnames"
 | 
			
		||||
 | 
			
		||||
  if _contains "$_dnsAltnames," "DNS:$_csrsubj,"; then
 | 
			
		||||
@ -1082,7 +1091,7 @@ _readKeyLengthFromCSR() {
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _outcsr="$($OPENSSL_BIN req -noout -text -in "$_csrfile")"
 | 
			
		||||
  _outcsr="$($ACME_OPENSSL_BIN req -noout -text -in "$_csrfile")"
 | 
			
		||||
  if _contains "$_outcsr" "Public Key Algorithm: id-ecPublicKey"; then
 | 
			
		||||
    _debug "ECC CSR"
 | 
			
		||||
    echo "$_outcsr" | _egrep_o "^ *ASN1 OID:.*" | cut -d ':' -f 2 | tr -d ' '
 | 
			
		||||
@ -1136,9 +1145,9 @@ toPkcs() {
 | 
			
		||||
  _initpath "$domain" "$_isEcc"
 | 
			
		||||
 | 
			
		||||
  if [ "$pfxPassword" ]; then
 | 
			
		||||
    $OPENSSL_BIN pkcs12 -export -out "$CERT_PFX_PATH" -inkey "$CERT_KEY_PATH" -in "$CERT_PATH" -certfile "$CA_CERT_PATH" -password "pass:$pfxPassword"
 | 
			
		||||
    $ACME_OPENSSL_BIN pkcs12 -export -out "$CERT_PFX_PATH" -inkey "$CERT_KEY_PATH" -in "$CERT_PATH" -certfile "$CA_CERT_PATH" -password "pass:$pfxPassword"
 | 
			
		||||
  else
 | 
			
		||||
    $OPENSSL_BIN pkcs12 -export -out "$CERT_PFX_PATH" -inkey "$CERT_KEY_PATH" -in "$CERT_PATH" -certfile "$CA_CERT_PATH"
 | 
			
		||||
    $ACME_OPENSSL_BIN pkcs12 -export -out "$CERT_PFX_PATH" -inkey "$CERT_KEY_PATH" -in "$CERT_PATH" -certfile "$CA_CERT_PATH"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ "$?" = "0" ]; then
 | 
			
		||||
@ -1147,6 +1156,27 @@ toPkcs() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#domain [isEcc]
 | 
			
		||||
toPkcs8() {
 | 
			
		||||
  domain="$1"
 | 
			
		||||
 | 
			
		||||
  if [ -z "$domain" ]; then
 | 
			
		||||
    _usage "Usage: $PROJECT_ENTRY --toPkcs8 -d domain [--ecc]"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _isEcc="$2"
 | 
			
		||||
 | 
			
		||||
  _initpath "$domain" "$_isEcc"
 | 
			
		||||
 | 
			
		||||
  $ACME_OPENSSL_BIN pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in "$CERT_KEY_PATH" -out "$CERT_PKCS8_PATH"
 | 
			
		||||
 | 
			
		||||
  if [ "$?" = "0" ]; then
 | 
			
		||||
    _info "Success, $CERT_PKCS8_PATH"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[2048]  
 | 
			
		||||
createAccountKey() {
 | 
			
		||||
  _info "Creating account key"
 | 
			
		||||
@ -1249,12 +1279,12 @@ _url_replace() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_time2str() {
 | 
			
		||||
  #BSD
 | 
			
		||||
  #Linux
 | 
			
		||||
  if date -u -d@"$1" 2>/dev/null; then
 | 
			
		||||
    return
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  #Linux
 | 
			
		||||
  #BSD
 | 
			
		||||
  if date -u -r "$1" 2>/dev/null; then
 | 
			
		||||
    return
 | 
			
		||||
  fi
 | 
			
		||||
@ -1300,7 +1330,7 @@ _calcjwk() {
 | 
			
		||||
 | 
			
		||||
  if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then
 | 
			
		||||
    _debug "RSA key"
 | 
			
		||||
    pub_exp=$($OPENSSL_BIN rsa -in "$keyfile" -noout -text | grep "^publicExponent:" | cut -d '(' -f 2 | cut -d 'x' -f 2 | cut -d ')' -f 1)
 | 
			
		||||
    pub_exp=$($ACME_OPENSSL_BIN rsa -in "$keyfile" -noout -text | grep "^publicExponent:" | cut -d '(' -f 2 | cut -d 'x' -f 2 | cut -d ')' -f 1)
 | 
			
		||||
    if [ "${#pub_exp}" = "5" ]; then
 | 
			
		||||
      pub_exp=0$pub_exp
 | 
			
		||||
    fi
 | 
			
		||||
@ -1309,7 +1339,7 @@ _calcjwk() {
 | 
			
		||||
    e=$(echo "$pub_exp" | _h2b | _base64)
 | 
			
		||||
    _debug3 e "$e"
 | 
			
		||||
 | 
			
		||||
    modulus=$($OPENSSL_BIN rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2)
 | 
			
		||||
    modulus=$($ACME_OPENSSL_BIN rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2)
 | 
			
		||||
    _debug3 modulus "$modulus"
 | 
			
		||||
    n="$(printf "%s" "$modulus" | _h2b | _base64 | _url_replace)"
 | 
			
		||||
    _debug3 n "$n"
 | 
			
		||||
@ -1322,12 +1352,12 @@ _calcjwk() {
 | 
			
		||||
    JWK_HEADERPLACE_PART2='", "alg": "RS256", "jwk": '$jwk'}'
 | 
			
		||||
  elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then
 | 
			
		||||
    _debug "EC key"
 | 
			
		||||
    crv="$($OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" | cut -d ":" -f 2 | tr -d " \r\n")"
 | 
			
		||||
    crv="$($ACME_OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" | cut -d ":" -f 2 | tr -d " \r\n")"
 | 
			
		||||
    _debug3 crv "$crv"
 | 
			
		||||
 | 
			
		||||
    if [ -z "$crv" ]; then
 | 
			
		||||
      _debug "Let's try ASN1 OID"
 | 
			
		||||
      crv_oid="$($OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep "^ASN1 OID:" | cut -d ":" -f 2 | tr -d " \r\n")"
 | 
			
		||||
      crv_oid="$($ACME_OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep "^ASN1 OID:" | cut -d ":" -f 2 | tr -d " \r\n")"
 | 
			
		||||
      _debug3 crv_oid "$crv_oid"
 | 
			
		||||
      case "${crv_oid}" in
 | 
			
		||||
        "prime256v1")
 | 
			
		||||
@ -1347,15 +1377,15 @@ _calcjwk() {
 | 
			
		||||
      _debug3 crv "$crv"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    pubi="$($OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep -n pub: | cut -d : -f 1)"
 | 
			
		||||
    pubi="$($ACME_OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep -n pub: | cut -d : -f 1)"
 | 
			
		||||
    pubi=$(_math "$pubi" + 1)
 | 
			
		||||
    _debug3 pubi "$pubi"
 | 
			
		||||
 | 
			
		||||
    pubj="$($OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep -n "ASN1 OID:" | cut -d : -f 1)"
 | 
			
		||||
    pubj="$($ACME_OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep -n "ASN1 OID:" | cut -d : -f 1)"
 | 
			
		||||
    pubj=$(_math "$pubj" - 1)
 | 
			
		||||
    _debug3 pubj "$pubj"
 | 
			
		||||
 | 
			
		||||
    pubtext="$($OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | sed -n "$pubi,${pubj}p" | tr -d " \n\r")"
 | 
			
		||||
    pubtext="$($ACME_OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | sed -n "$pubi,${pubj}p" | tr -d " \n\r")"
 | 
			
		||||
    _debug3 pubtext "$pubtext"
 | 
			
		||||
 | 
			
		||||
    xlen="$(printf "%s" "$pubtext" | tr -d ':' | wc -c)"
 | 
			
		||||
@ -1455,6 +1485,11 @@ _inithttp() {
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  #from wget 1.14: do not skip body on 404 error
 | 
			
		||||
  if [ "$_ACME_WGET" ] && _contains "$($_ACME_WGET --help 2>&1)" "--content-on-error"; then
 | 
			
		||||
    _ACME_WGET="$_ACME_WGET --content-on-error "
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  __HTTP_INITIALIZED=1
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1475,7 +1510,7 @@ _post() {
 | 
			
		||||
 | 
			
		||||
  _inithttp
 | 
			
		||||
 | 
			
		||||
  if [ "$_ACME_CURL" ]; then
 | 
			
		||||
  if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
 | 
			
		||||
    _CURL="$_ACME_CURL"
 | 
			
		||||
    if [ "$HTTPS_INSECURE" ]; then
 | 
			
		||||
      _CURL="$_CURL --insecure  "
 | 
			
		||||
@ -1516,7 +1551,7 @@ _post() {
 | 
			
		||||
    _ret="$?"
 | 
			
		||||
    if [ "$_ret" = "8" ]; then
 | 
			
		||||
      _ret=0
 | 
			
		||||
      _debug "wget returns 8, the server returns a 'Bad request' respons, lets process the response later."
 | 
			
		||||
      _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
 | 
			
		||||
    fi
 | 
			
		||||
    if [ "$_ret" != "0" ]; then
 | 
			
		||||
      _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
 | 
			
		||||
@ -1542,7 +1577,7 @@ _get() {
 | 
			
		||||
 | 
			
		||||
  _inithttp
 | 
			
		||||
 | 
			
		||||
  if [ "$_ACME_CURL" ]; then
 | 
			
		||||
  if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
 | 
			
		||||
    _CURL="$_ACME_CURL"
 | 
			
		||||
    if [ "$HTTPS_INSECURE" ]; then
 | 
			
		||||
      _CURL="$_CURL --insecure  "
 | 
			
		||||
@ -1579,9 +1614,9 @@ _get() {
 | 
			
		||||
      $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -O - "$url"
 | 
			
		||||
    fi
 | 
			
		||||
    ret=$?
 | 
			
		||||
    if [ "$_ret" = "8" ]; then
 | 
			
		||||
      _ret=0
 | 
			
		||||
      _debug "wget returns 8, the server returns a 'Bad request' respons, lets process the response later."
 | 
			
		||||
    if [ "$ret" = "8" ]; then
 | 
			
		||||
      ret=0
 | 
			
		||||
      _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
 | 
			
		||||
    fi
 | 
			
		||||
    if [ "$ret" != "0" ]; then
 | 
			
		||||
      _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret"
 | 
			
		||||
@ -1964,7 +1999,7 @@ _starttlsserver() {
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  __S_OPENSSL="$OPENSSL_BIN s_server -cert $TLS_CERT  -key $TLS_KEY "
 | 
			
		||||
  __S_OPENSSL="$ACME_OPENSSL_BIN s_server -cert $TLS_CERT  -key $TLS_KEY "
 | 
			
		||||
  if [ "$opaddr" ]; then
 | 
			
		||||
    __S_OPENSSL="$__S_OPENSSL -accept $opaddr:$port"
 | 
			
		||||
  else
 | 
			
		||||
@ -2143,8 +2178,8 @@ _initpath() {
 | 
			
		||||
    CERT_HOME="$_DEFAULT_CERT_HOME"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ -z "$OPENSSL_BIN" ]; then
 | 
			
		||||
    OPENSSL_BIN="$DEFAULT_OPENSSL_BIN"
 | 
			
		||||
  if [ -z "$ACME_OPENSSL_BIN" ] || [ ! -f "$ACME_OPENSSL_BIN" ] || [ ! -x "$ACME_OPENSSL_BIN" ]; then
 | 
			
		||||
    ACME_OPENSSL_BIN="$DEFAULT_OPENSSL_BIN"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ -z "$1" ]; then
 | 
			
		||||
@ -2200,6 +2235,9 @@ _initpath() {
 | 
			
		||||
  if [ -z "$CERT_PFX_PATH" ]; then
 | 
			
		||||
    CERT_PFX_PATH="$DOMAIN_PATH/$domain.pfx"
 | 
			
		||||
  fi
 | 
			
		||||
  if [ -z "$CERT_PKCS8_PATH" ]; then
 | 
			
		||||
    CERT_PKCS8_PATH="$DOMAIN_PATH/$domain.pkcs8"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ -z "$TLS_CONF" ]; then
 | 
			
		||||
    TLS_CONF="$DOMAIN_PATH/tls.valdation.conf"
 | 
			
		||||
@ -2795,6 +2833,7 @@ _on_before_issue() {
 | 
			
		||||
 | 
			
		||||
_on_issue_err() {
 | 
			
		||||
  _chk_post_hook="$1"
 | 
			
		||||
  _chk_vlist="$2"
 | 
			
		||||
  _debug _on_issue_err
 | 
			
		||||
  if [ "$LOG_FILE" ]; then
 | 
			
		||||
    _err "Please check log file for more details: $LOG_FILE"
 | 
			
		||||
@ -2803,10 +2842,6 @@ _on_issue_err() {
 | 
			
		||||
    _err "See: $_DEBUG_WIKI"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ "$DEBUG" ] && [ "$DEBUG" -gt "0" ]; then
 | 
			
		||||
    _debug "$(_dlg_versions)"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  #run the post hook
 | 
			
		||||
  if [ "$_chk_post_hook" ]; then
 | 
			
		||||
    _info "Run post hook:'$_chk_post_hook'"
 | 
			
		||||
@ -2817,6 +2852,28 @@ _on_issue_err() {
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  #trigger the validation to flush the pending authz
 | 
			
		||||
  if [ "$_chk_vlist" ]; then
 | 
			
		||||
    (
 | 
			
		||||
      _debug2 "_chk_vlist" "$_chk_vlist"
 | 
			
		||||
      _debug2 "start to deactivate authz"
 | 
			
		||||
      ventries=$(echo "$_chk_vlist" | tr "$dvsep" ' ')
 | 
			
		||||
      for ventry in $ventries; do
 | 
			
		||||
        d=$(echo "$ventry" | cut -d "$sep" -f 1)
 | 
			
		||||
        keyauthorization=$(echo "$ventry" | cut -d "$sep" -f 2)
 | 
			
		||||
        uri=$(echo "$ventry" | cut -d "$sep" -f 3)
 | 
			
		||||
        vtype=$(echo "$ventry" | cut -d "$sep" -f 4)
 | 
			
		||||
        _currentRoot=$(echo "$ventry" | cut -d "$sep" -f 5)
 | 
			
		||||
        __trigger_validaton "$uri" "$keyauthorization"
 | 
			
		||||
      done
 | 
			
		||||
    )
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ "$DEBUG" ] && [ "$DEBUG" -gt "0" ]; then
 | 
			
		||||
    _debug "$(_dlg_versions)"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_on_issue_success() {
 | 
			
		||||
@ -3029,6 +3086,16 @@ __get_domain_new_authz() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#uri keyAuthorization
 | 
			
		||||
__trigger_validaton() {
 | 
			
		||||
  _debug2 "tigger domain validation."
 | 
			
		||||
  _t_url="$1"
 | 
			
		||||
  _debug2 _t_url "$_t_url"
 | 
			
		||||
  _t_key_authz="$2"
 | 
			
		||||
  _debug2 _t_key_authz "$_t_key_authz"
 | 
			
		||||
  _send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"keyAuthorization\": \"$_t_key_authz\"}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#webroot, domain domainlist  keylength 
 | 
			
		||||
issue() {
 | 
			
		||||
  if [ -z "$2" ]; then
 | 
			
		||||
@ -3342,7 +3409,7 @@ issue() {
 | 
			
		||||
        _startserver "$keyauthorization" "$_ncaddr" &
 | 
			
		||||
        if [ "$?" != "0" ]; then
 | 
			
		||||
          _clearup
 | 
			
		||||
          _on_issue_err "$_post_hook"
 | 
			
		||||
          _on_issue_err "$_post_hook" "$vlist"
 | 
			
		||||
          return 1
 | 
			
		||||
        fi
 | 
			
		||||
        serverproc="$!"
 | 
			
		||||
@ -3358,7 +3425,7 @@ issue() {
 | 
			
		||||
        BACKUP_NGINX_CONF=""
 | 
			
		||||
        if ! _setNginx "$d" "$_currentRoot" "$thumbprint"; then
 | 
			
		||||
          _clearup
 | 
			
		||||
          _on_issue_err "$_post_hook"
 | 
			
		||||
          _on_issue_err "$_post_hook" "$vlist"
 | 
			
		||||
          return 1
 | 
			
		||||
        fi
 | 
			
		||||
 | 
			
		||||
@ -3393,7 +3460,7 @@ issue() {
 | 
			
		||||
          _err "$d:Can not write token to file : $wellknown_path/$token"
 | 
			
		||||
          _clearupwebbroot "$_currentRoot" "$removelevel" "$token"
 | 
			
		||||
          _clearup
 | 
			
		||||
          _on_issue_err "$_post_hook"
 | 
			
		||||
          _on_issue_err "$_post_hook" "$vlist"
 | 
			
		||||
          return 1
 | 
			
		||||
        fi
 | 
			
		||||
 | 
			
		||||
@ -3438,16 +3505,16 @@ issue() {
 | 
			
		||||
        _err "Start tls server error."
 | 
			
		||||
        _clearupwebbroot "$_currentRoot" "$removelevel" "$token"
 | 
			
		||||
        _clearup
 | 
			
		||||
        _on_issue_err "$_post_hook"
 | 
			
		||||
        _on_issue_err "$_post_hook" "$vlist"
 | 
			
		||||
        return 1
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ! _send_signed_request "$uri" "{\"resource\": \"challenge\", \"keyAuthorization\": \"$keyauthorization\"}"; then
 | 
			
		||||
    if ! __trigger_validaton "$uri" "$keyauthorization"; then
 | 
			
		||||
      _err "$d:Can not get challenge: $response"
 | 
			
		||||
      _clearupwebbroot "$_currentRoot" "$removelevel" "$token"
 | 
			
		||||
      _clearup
 | 
			
		||||
      _on_issue_err "$_post_hook"
 | 
			
		||||
      _on_issue_err "$_post_hook" "$vlist"
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
@ -3455,7 +3522,7 @@ issue() {
 | 
			
		||||
      _err "$d:Challenge error: $response"
 | 
			
		||||
      _clearupwebbroot "$_currentRoot" "$removelevel" "$token"
 | 
			
		||||
      _clearup
 | 
			
		||||
      _on_issue_err "$_post_hook"
 | 
			
		||||
      _on_issue_err "$_post_hook" "$vlist"
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
@ -3470,7 +3537,7 @@ issue() {
 | 
			
		||||
        _err "$d:Timeout"
 | 
			
		||||
        _clearupwebbroot "$_currentRoot" "$removelevel" "$token"
 | 
			
		||||
        _clearup
 | 
			
		||||
        _on_issue_err
 | 
			
		||||
        _on_issue_err "$_post_hook" "$vlist"
 | 
			
		||||
        return 1
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
@ -3482,7 +3549,7 @@ issue() {
 | 
			
		||||
        _err "$d:Verify error:$response"
 | 
			
		||||
        _clearupwebbroot "$_currentRoot" "$removelevel" "$token"
 | 
			
		||||
        _clearup
 | 
			
		||||
        _on_issue_err "$_post_hook"
 | 
			
		||||
        _on_issue_err "$_post_hook" "$vlist"
 | 
			
		||||
        return 1
 | 
			
		||||
      fi
 | 
			
		||||
      _debug2 original "$response"
 | 
			
		||||
@ -3517,7 +3584,7 @@ issue() {
 | 
			
		||||
        fi
 | 
			
		||||
        _clearupwebbroot "$_currentRoot" "$removelevel" "$token"
 | 
			
		||||
        _clearup
 | 
			
		||||
        _on_issue_err "$_post_hook"
 | 
			
		||||
        _on_issue_err "$_post_hook" "$vlist"
 | 
			
		||||
        return 1
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
@ -3527,7 +3594,7 @@ issue() {
 | 
			
		||||
        _err "$d:Verify error:$response"
 | 
			
		||||
        _clearupwebbroot "$_currentRoot" "$removelevel" "$token"
 | 
			
		||||
        _clearup
 | 
			
		||||
        _on_issue_err "$_post_hook"
 | 
			
		||||
        _on_issue_err "$_post_hook" "$vlist"
 | 
			
		||||
        return 1
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
@ -3653,7 +3720,7 @@ issue() {
 | 
			
		||||
    _savedomainconf "Le_RealKeyPath" "$_real_key"
 | 
			
		||||
    _savedomainconf "Le_ReloadCmd" "$_reload_cmd"
 | 
			
		||||
    _savedomainconf "Le_RealFullChainPath" "$_real_fullchain"
 | 
			
		||||
    _installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain"
 | 
			
		||||
    _installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -3964,16 +4031,18 @@ installcert() {
 | 
			
		||||
  _savedomainconf "Le_ReloadCmd" "$_reload_cmd"
 | 
			
		||||
  _savedomainconf "Le_RealFullChainPath" "$_real_fullchain"
 | 
			
		||||
 | 
			
		||||
  _installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain"
 | 
			
		||||
  _installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#domain  cert  key  ca  fullchain reloadcmd backup-prefix
 | 
			
		||||
_installcert() {
 | 
			
		||||
  _main_domain="$1"
 | 
			
		||||
  _real_cert="$2"
 | 
			
		||||
  _real_key="$3"
 | 
			
		||||
  _real_ca="$4"
 | 
			
		||||
  _reload_cmd="$5"
 | 
			
		||||
  _real_fullchain="$6"
 | 
			
		||||
  _real_fullchain="$5"
 | 
			
		||||
  _reload_cmd="$6"
 | 
			
		||||
  _backup_prefix="$7"
 | 
			
		||||
 | 
			
		||||
  if [ "$_real_cert" = "$NO_VALUE" ]; then
 | 
			
		||||
    _real_cert=""
 | 
			
		||||
@ -3991,11 +4060,13 @@ _installcert() {
 | 
			
		||||
    _real_fullchain=""
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _backup_path="$DOMAIN_BACKUP_PATH/$_backup_prefix"
 | 
			
		||||
  mkdir -p "$_backup_path"
 | 
			
		||||
 | 
			
		||||
  if [ "$_real_cert" ]; then
 | 
			
		||||
    _info "Installing cert to:$_real_cert"
 | 
			
		||||
    if [ -f "$_real_cert" ] && [ ! "$IS_RENEW" ]; then
 | 
			
		||||
      mkdir -p "$DOMAIN_BACKUP_PATH"
 | 
			
		||||
      cp "$_real_cert" "$DOMAIN_BACKUP_PATH/cert.bak"
 | 
			
		||||
      cp "$_real_cert" "$_backup_path/cert.bak"
 | 
			
		||||
    fi
 | 
			
		||||
    cat "$CERT_PATH" >"$_real_cert"
 | 
			
		||||
  fi
 | 
			
		||||
@ -4007,8 +4078,7 @@ _installcert() {
 | 
			
		||||
      cat "$CA_CERT_PATH" >>"$_real_ca"
 | 
			
		||||
    else
 | 
			
		||||
      if [ -f "$_real_ca" ] && [ ! "$IS_RENEW" ]; then
 | 
			
		||||
        mkdir -p "$DOMAIN_BACKUP_PATH"
 | 
			
		||||
        cp "$_real_ca" "$DOMAIN_BACKUP_PATH/ca.bak"
 | 
			
		||||
        cp "$_real_ca" "$_backup_path/ca.bak"
 | 
			
		||||
      fi
 | 
			
		||||
      cat "$CA_CERT_PATH" >"$_real_ca"
 | 
			
		||||
    fi
 | 
			
		||||
@ -4017,8 +4087,7 @@ _installcert() {
 | 
			
		||||
  if [ "$_real_key" ]; then
 | 
			
		||||
    _info "Installing key to:$_real_key"
 | 
			
		||||
    if [ -f "$_real_key" ] && [ ! "$IS_RENEW" ]; then
 | 
			
		||||
      mkdir -p "$DOMAIN_BACKUP_PATH"
 | 
			
		||||
      cp "$_real_key" "$DOMAIN_BACKUP_PATH/key.bak"
 | 
			
		||||
      cp "$_real_key" "$_backup_path/key.bak"
 | 
			
		||||
    fi
 | 
			
		||||
    cat "$CERT_KEY_PATH" >"$_real_key"
 | 
			
		||||
  fi
 | 
			
		||||
@ -4026,8 +4095,7 @@ _installcert() {
 | 
			
		||||
  if [ "$_real_fullchain" ]; then
 | 
			
		||||
    _info "Installing full chain to:$_real_fullchain"
 | 
			
		||||
    if [ -f "$_real_fullchain" ] && [ ! "$IS_RENEW" ]; then
 | 
			
		||||
      mkdir -p "$DOMAIN_BACKUP_PATH"
 | 
			
		||||
      cp "$_real_fullchain" "$DOMAIN_BACKUP_PATH/fullchain.bak"
 | 
			
		||||
      cp "$_real_fullchain" "$_backup_path/fullchain.bak"
 | 
			
		||||
    fi
 | 
			
		||||
    cat "$CERT_FULLCHAIN_PATH" >"$_real_fullchain"
 | 
			
		||||
  fi
 | 
			
		||||
@ -4367,8 +4435,8 @@ _precheck() {
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if ! _exists "$OPENSSL_BIN"; then
 | 
			
		||||
    _err "Please install openssl first."
 | 
			
		||||
  if ! _exists "$ACME_OPENSSL_BIN"; then
 | 
			
		||||
    _err "Please install openssl first. ACME_OPENSSL_BIN=$ACME_OPENSSL_BIN"
 | 
			
		||||
    _err "We need openssl to generate keys."
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
@ -4660,6 +4728,7 @@ Commands:
 | 
			
		||||
  --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.
 | 
			
		||||
  --update-account         Update account info.
 | 
			
		||||
  --register-account       Register account key.
 | 
			
		||||
  --create-account-key     Create an account private key, professional use.
 | 
			
		||||
@ -4723,6 +4792,7 @@ Parameters:
 | 
			
		||||
  --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.
 | 
			
		||||
  --use-wget                        Force to use wget, if you have both curl and wget installed.
 | 
			
		||||
  "
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4790,9 +4860,9 @@ _processAccountConf() {
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ "$_openssl_bin" ]; then
 | 
			
		||||
    _saveaccountconf "OPENSSL_BIN" "$_openssl_bin"
 | 
			
		||||
  elif [ "$OPENSSL_BIN" ] && [ "$OPENSSL_BIN" != "$DEFAULT_OPENSSL_BIN" ]; then
 | 
			
		||||
    _saveaccountconf "OPENSSL_BIN" "$OPENSSL_BIN"
 | 
			
		||||
    _saveaccountconf "ACME_OPENSSL_BIN" "$_openssl_bin"
 | 
			
		||||
  elif [ "$ACME_OPENSSL_BIN" ] && [ "$ACME_OPENSSL_BIN" != "$DEFAULT_OPENSSL_BIN" ]; then
 | 
			
		||||
    _saveaccountconf "ACME_OPENSSL_BIN" "$ACME_OPENSSL_BIN"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ "$_auto_upgrade" ]; then
 | 
			
		||||
@ -4801,6 +4871,12 @@ _processAccountConf() {
 | 
			
		||||
    _saveaccountconf "AUTO_UPGRADE" "$AUTO_UPGRADE"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ "$_use_wget" ]; then
 | 
			
		||||
    _saveaccountconf "ACME_USE_WGET" "$_use_wget"
 | 
			
		||||
  elif [ "$ACME_USE_WGET" ]; then
 | 
			
		||||
    _saveaccountconf "ACME_USE_WGET" "$ACME_USE_WGET"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_process() {
 | 
			
		||||
@ -4845,6 +4921,7 @@ _process() {
 | 
			
		||||
  _listen_v6=""
 | 
			
		||||
  _openssl_bin=""
 | 
			
		||||
  _syslog=""
 | 
			
		||||
  _use_wget=""
 | 
			
		||||
  while [ ${#} -gt 0 ]; do
 | 
			
		||||
    case "${1}" in
 | 
			
		||||
 | 
			
		||||
@ -4907,6 +4984,9 @@ _process() {
 | 
			
		||||
      --toPkcs)
 | 
			
		||||
        _CMD="toPkcs"
 | 
			
		||||
        ;;
 | 
			
		||||
      --toPkcs8)
 | 
			
		||||
        _CMD="toPkcs8"
 | 
			
		||||
        ;;
 | 
			
		||||
      --createAccountKey | --createaccountkey | -cak | --create-account-key)
 | 
			
		||||
        _CMD="createAccountKey"
 | 
			
		||||
        ;;
 | 
			
		||||
@ -5218,7 +5298,12 @@ _process() {
 | 
			
		||||
        ;;
 | 
			
		||||
      --openssl-bin)
 | 
			
		||||
        _openssl_bin="$2"
 | 
			
		||||
        OPENSSL_BIN="$_openssl_bin"
 | 
			
		||||
        ACME_OPENSSL_BIN="$_openssl_bin"
 | 
			
		||||
        shift
 | 
			
		||||
        ;;
 | 
			
		||||
      --use-wget)
 | 
			
		||||
        _use_wget="1"
 | 
			
		||||
        ACME_USE_WGET="1"
 | 
			
		||||
        ;;
 | 
			
		||||
      *)
 | 
			
		||||
        _err "Unknown parameter : $1"
 | 
			
		||||
@ -5319,6 +5404,9 @@ _process() {
 | 
			
		||||
    toPkcs)
 | 
			
		||||
      toPkcs "$_domain" "$_password" "$_ecc"
 | 
			
		||||
      ;;
 | 
			
		||||
    toPkcs8)
 | 
			
		||||
      toPkcs8 "$_domain" "$_ecc"
 | 
			
		||||
      ;;
 | 
			
		||||
    createAccountKey)
 | 
			
		||||
      createAccountKey "$_accountkeylength"
 | 
			
		||||
      ;;
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,21 @@
 | 
			
		||||
# Using deploy api
 | 
			
		||||
 | 
			
		||||
Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert).
 | 
			
		||||
 | 
			
		||||
Here are the scripts to deploy the certs/key to the server/services.
 | 
			
		||||
 | 
			
		||||
## 1. Deploy the certs to your cpanel host.
 | 
			
		||||
 | 
			
		||||
(cpanel deploy hook is not finished yet, this is just an example.)
 | 
			
		||||
 | 
			
		||||
Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Then you can deploy now:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
export DEPLOY_CPANEL_USER=myusername
 | 
			
		||||
export DEPLOY_CPANEL_PASSWORD=PASSWORD
 | 
			
		||||
acme.sh --deploy -d example.com --deploy --deploy-hook cpanel
 | 
			
		||||
acme.sh --deploy -d example.com --deploy-hook cpanel
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 2. Deploy ssl cert on kong proxy engine based on api.
 | 
			
		||||
@ -24,6 +26,8 @@ Before you can deploy your cert, you must [issue the cert first](https://github.
 | 
			
		||||
 | 
			
		||||
## 3. Deploy the cert to remote server through SSH access.
 | 
			
		||||
 | 
			
		||||
Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert).
 | 
			
		||||
 | 
			
		||||
The ssh deploy plugin allows you to deploy certificates to a remote host
 | 
			
		||||
using SSH command to connect to the remote server.  The ssh plugin is invoked
 | 
			
		||||
with the following command...
 | 
			
		||||
@ -107,7 +111,6 @@ user
 | 
			
		||||
Any backups older than 180 days will be deleted when new certificates
 | 
			
		||||
are deployed.  This defaults to "yes" set to "no" to disable backup.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###Eamples using SSH deploy
 | 
			
		||||
The following example illustrates deploying certifcates to a QNAP NAS
 | 
			
		||||
(tested with QTS version 4.2.3)
 | 
			
		||||
@ -165,3 +168,47 @@ export DEPLOY_SSH_BACKUP=no
 | 
			
		||||
      /var/lib/unifi/unifi.example.com.p12 \
 | 
			
		||||
&& service unifi restart
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 4. Deploy the cert to local vsftpd server.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The default vsftpd conf file is `/etc/vsftpd.conf`,  if your vsftpd conf is not in the default location, you can specify one:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
export DEPLOY_VSFTPD_CONF="/etc/vsftpd.conf"
 | 
			
		||||
 | 
			
		||||
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The default command to restart vsftpd server is `service vsftpd restart`, if it doesn't work, you can specify one:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
export DEPLOY_VSFTPD_RELOAD="/etc/init.d/vsftpd restart"
 | 
			
		||||
 | 
			
		||||
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 5. Deploy the cert to local exim4 server.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
acme.sh --deploy -d ftp.example.com --deploy-hook exim4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The default exim4 conf file is `/etc/exim/exim.conf`,  if your exim4 conf is not in the default location, you can specify one:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
export DEPLOY_EXIM4_CONF="/etc/exim4/exim4.conf.template"
 | 
			
		||||
 | 
			
		||||
acme.sh --deploy -d ftp.example.com --deploy-hook exim4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The default command to restart exim4 server is `service exim4 restart`, if it doesn't work, you can specify one:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
export DEPLOY_EXIM4_RELOAD="/etc/init.d/exim4 restart"
 | 
			
		||||
 | 
			
		||||
acme.sh --deploy -d ftp.example.com --deploy-hook exim4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
#!/usr/bin/env sh
 | 
			
		||||
 | 
			
		||||
#Here is a script to deploy cert to dovecot server.
 | 
			
		||||
#Here is a script to deploy cert to apache server.
 | 
			
		||||
 | 
			
		||||
#returns 0 means success, otherwise error.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,9 @@
 | 
			
		||||
 | 
			
		||||
#returns 0 means success, otherwise error.
 | 
			
		||||
 | 
			
		||||
#DEPLOY_EXIM4_CONF="/etc/exim/exim.conf"
 | 
			
		||||
#DEPLOY_EXIM4_RELOAD="service exim4 restart"
 | 
			
		||||
 | 
			
		||||
########  Public functions #####################
 | 
			
		||||
 | 
			
		||||
#domain keyfile certfile cafile fullchain
 | 
			
		||||
@ -20,7 +23,92 @@ exim4_deploy() {
 | 
			
		||||
  _debug _cca "$_cca"
 | 
			
		||||
  _debug _cfullchain "$_cfullchain"
 | 
			
		||||
 | 
			
		||||
  _err "deploy cert to exim4 server, Not implemented yet"
 | 
			
		||||
  return 1
 | 
			
		||||
  _ssl_path="/etc/acme.sh/exim4"
 | 
			
		||||
  if ! mkdir -p "$_ssl_path"; then
 | 
			
		||||
    _err "Can not create folder:$_ssl_path"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _info "Copying key and cert"
 | 
			
		||||
  _real_key="$_ssl_path/exim4.key"
 | 
			
		||||
  if ! cat "$_ckey" >"$_real_key"; then
 | 
			
		||||
    _err "Error: write key file to: $_real_key"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  _real_fullchain="$_ssl_path/exim4.pem"
 | 
			
		||||
  if ! cat "$_cfullchain" >"$_real_fullchain"; then
 | 
			
		||||
    _err "Error: write key file to: $_real_fullchain"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  DEFAULT_EXIM4_RELOAD="service exim4 restart"
 | 
			
		||||
  _reload="${DEPLOY_EXIM4_RELOAD:-$DEFAULT_EXIM4_RELOAD}"
 | 
			
		||||
 | 
			
		||||
  if [ -z "$IS_RENEW" ]; then
 | 
			
		||||
    DEFAULT_EXIM4_CONF="/etc/exim/exim.conf"
 | 
			
		||||
    if [ ! -f "$DEFAULT_EXIM4_CONF" ]; then
 | 
			
		||||
      DEFAULT_EXIM4_CONF="/etc/exim4/exim4.conf.template"
 | 
			
		||||
    fi
 | 
			
		||||
    _exim4_conf="${DEPLOY_EXIM4_CONF:-$DEFAULT_EXIM4_CONF}"
 | 
			
		||||
    _debug _exim4_conf "$_exim4_conf"
 | 
			
		||||
    if [ ! -f "$_exim4_conf" ]; then
 | 
			
		||||
      if [ -z "$DEPLOY_EXIM4_CONF" ]; then
 | 
			
		||||
        _err "exim4 conf is not found, please define DEPLOY_EXIM4_CONF"
 | 
			
		||||
        return 1
 | 
			
		||||
      else
 | 
			
		||||
        _err "It seems that the specified exim4 conf is not valid, please check."
 | 
			
		||||
        return 1
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
    if [ ! -w "$_exim4_conf" ]; then
 | 
			
		||||
      _err "The file $_exim4_conf is not writable, please change the permission."
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
    _backup_conf="$DOMAIN_BACKUP_PATH/exim4.conf.bak"
 | 
			
		||||
    _info "Backup $_exim4_conf to $_backup_conf"
 | 
			
		||||
    cp "$_exim4_conf" "$_backup_conf"
 | 
			
		||||
 | 
			
		||||
    _info "Modify exim4 conf: $_exim4_conf"
 | 
			
		||||
    if _setopt "$_exim4_conf" "tls_certificate" "=" "$_real_fullchain" \
 | 
			
		||||
      && _setopt "$_exim4_conf" "tls_privatekey" "=" "$_real_key"; then
 | 
			
		||||
      _info "Set config success!"
 | 
			
		||||
    else
 | 
			
		||||
      _err "Config exim4 server error, please report bug to us."
 | 
			
		||||
      _info "Restoring exim4 conf"
 | 
			
		||||
      if cat "$_backup_conf" >"$_exim4_conf"; then
 | 
			
		||||
        _info "Restore conf success"
 | 
			
		||||
        eval "$_reload"
 | 
			
		||||
      else
 | 
			
		||||
        _err "Opps, error restore exim4 conf, please report bug to us."
 | 
			
		||||
      fi
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _info "Run reload: $_reload"
 | 
			
		||||
  if eval "$_reload"; then
 | 
			
		||||
    _info "Reload success!"
 | 
			
		||||
    if [ "$DEPLOY_EXIM4_CONF" ]; then
 | 
			
		||||
      _savedomainconf DEPLOY_EXIM4_CONF "$DEPLOY_EXIM4_CONF"
 | 
			
		||||
    else
 | 
			
		||||
      _cleardomainconf DEPLOY_EXIM4_CONF
 | 
			
		||||
    fi
 | 
			
		||||
    if [ "$DEPLOY_EXIM4_RELOAD" ]; then
 | 
			
		||||
      _savedomainconf DEPLOY_EXIM4_RELOAD "$DEPLOY_EXIM4_RELOAD"
 | 
			
		||||
    else
 | 
			
		||||
      _cleardomainconf DEPLOY_EXIM4_RELOAD
 | 
			
		||||
    fi
 | 
			
		||||
    return 0
 | 
			
		||||
  else
 | 
			
		||||
    _err "Reload error, restoring"
 | 
			
		||||
    if cat "$_backup_conf" >"$_exim4_conf"; then
 | 
			
		||||
      _info "Restore conf success"
 | 
			
		||||
      eval "$_reload"
 | 
			
		||||
    else
 | 
			
		||||
      _err "Opps, error restore exim4 conf, please report bug to us."
 | 
			
		||||
    fi
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  return 0
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,9 @@
 | 
			
		||||
 | 
			
		||||
#returns 0 means success, otherwise error.
 | 
			
		||||
 | 
			
		||||
#DEPLOY_VSFTPD_CONF="/etc/vsftpd.conf"
 | 
			
		||||
#DEPLOY_VSFTPD_RELOAD="service vsftpd restart"
 | 
			
		||||
 | 
			
		||||
########  Public functions #####################
 | 
			
		||||
 | 
			
		||||
#domain keyfile certfile cafile fullchain
 | 
			
		||||
@ -20,7 +23,88 @@ vsftpd_deploy() {
 | 
			
		||||
  _debug _cca "$_cca"
 | 
			
		||||
  _debug _cfullchain "$_cfullchain"
 | 
			
		||||
 | 
			
		||||
  _err "deploy cert to vsftpd server, Not implemented yet"
 | 
			
		||||
  return 1
 | 
			
		||||
  _ssl_path="/etc/acme.sh/vsftpd"
 | 
			
		||||
  if ! mkdir -p "$_ssl_path"; then
 | 
			
		||||
    _err "Can not create folder:$_ssl_path"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _info "Copying key and cert"
 | 
			
		||||
  _real_key="$_ssl_path/vsftpd.key"
 | 
			
		||||
  if ! cat "$_ckey" >"$_real_key"; then
 | 
			
		||||
    _err "Error: write key file to: $_real_key"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  _real_fullchain="$_ssl_path/vsftpd.chain.pem"
 | 
			
		||||
  if ! cat "$_cfullchain" >"$_real_fullchain"; then
 | 
			
		||||
    _err "Error: write key file to: $_real_fullchain"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  DEFAULT_VSFTPD_RELOAD="service vsftpd restart"
 | 
			
		||||
  _reload="${DEPLOY_VSFTPD_RELOAD:-$DEFAULT_VSFTPD_RELOAD}"
 | 
			
		||||
 | 
			
		||||
  if [ -z "$IS_RENEW" ]; then
 | 
			
		||||
    DEFAULT_VSFTPD_CONF="/etc/vsftpd.conf"
 | 
			
		||||
    _vsftpd_conf="${DEPLOY_VSFTPD_CONF:-$DEFAULT_VSFTPD_CONF}"
 | 
			
		||||
    if [ ! -f "$_vsftpd_conf" ]; then
 | 
			
		||||
      if [ -z "$DEPLOY_VSFTPD_CONF" ]; then
 | 
			
		||||
        _err "vsftpd conf is not found, please define DEPLOY_VSFTPD_CONF"
 | 
			
		||||
        return 1
 | 
			
		||||
      else
 | 
			
		||||
        _err "It seems that the specified vsftpd conf is not valid, please check."
 | 
			
		||||
        return 1
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
    if [ ! -w "$_vsftpd_conf" ]; then
 | 
			
		||||
      _err "The file $_vsftpd_conf is not writable, please change the permission."
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
    _backup_conf="$DOMAIN_BACKUP_PATH/vsftpd.conf.bak"
 | 
			
		||||
    _info "Backup $_vsftpd_conf to $_backup_conf"
 | 
			
		||||
    cp "$_vsftpd_conf" "$_backup_conf"
 | 
			
		||||
 | 
			
		||||
    _info "Modify vsftpd conf: $_vsftpd_conf"
 | 
			
		||||
    if _setopt "$_vsftpd_conf" "rsa_cert_file" "=" "$_real_fullchain" \
 | 
			
		||||
      && _setopt "$_vsftpd_conf" "rsa_private_key_file" "=" "$_real_key" \
 | 
			
		||||
      && _setopt "$_vsftpd_conf" "ssl_enable" "=" "YES"; then
 | 
			
		||||
      _info "Set config success!"
 | 
			
		||||
    else
 | 
			
		||||
      _err "Config vsftpd server error, please report bug to us."
 | 
			
		||||
      _info "Restoring vsftpd conf"
 | 
			
		||||
      if cat "$_backup_conf" >"$_vsftpd_conf"; then
 | 
			
		||||
        _info "Restore conf success"
 | 
			
		||||
        eval "$_reload"
 | 
			
		||||
      else
 | 
			
		||||
        _err "Opps, error restore vsftpd conf, please report bug to us."
 | 
			
		||||
      fi
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _info "Run reload: $_reload"
 | 
			
		||||
  if eval "$_reload"; then
 | 
			
		||||
    _info "Reload success!"
 | 
			
		||||
    if [ "$DEPLOY_VSFTPD_CONF" ]; then
 | 
			
		||||
      _savedomainconf DEPLOY_VSFTPD_CONF "$DEPLOY_VSFTPD_CONF"
 | 
			
		||||
    else
 | 
			
		||||
      _cleardomainconf DEPLOY_VSFTPD_CONF
 | 
			
		||||
    fi
 | 
			
		||||
    if [ "$DEPLOY_VSFTPD_RELOAD" ]; then
 | 
			
		||||
      _savedomainconf DEPLOY_VSFTPD_RELOAD "$DEPLOY_VSFTPD_RELOAD"
 | 
			
		||||
    else
 | 
			
		||||
      _cleardomainconf DEPLOY_VSFTPD_RELOAD
 | 
			
		||||
    fi
 | 
			
		||||
    return 0
 | 
			
		||||
  else
 | 
			
		||||
    _err "Reload error, restoring"
 | 
			
		||||
    if cat "$_backup_conf" >"$_vsftpd_conf"; then
 | 
			
		||||
      _info "Restore conf success"
 | 
			
		||||
      eval "$_reload"
 | 
			
		||||
    else
 | 
			
		||||
      _err "Opps, error restore vsftpd conf, please report bug to us."
 | 
			
		||||
    fi
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -323,6 +323,32 @@ acme.sh --issue --dns dns_cyon -d example.com -d www.example.com
 | 
			
		||||
 | 
			
		||||
The `CY_Username`, `CY_Password` and `CY_OTP_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 | 
			
		||||
 | 
			
		||||
## 17. Use Domain-Offensive/Resellerinterface/Domainrobot API
 | 
			
		||||
 | 
			
		||||
You will need your login credentials (Partner ID+Password) to the Resellerinterface, and export them before you run `acme.sh`:
 | 
			
		||||
```
 | 
			
		||||
export DO_PID="KD-1234567"
 | 
			
		||||
export DO_PW="cdfkjl3n2"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Ok, let's issue a cert now:
 | 
			
		||||
```
 | 
			
		||||
acme.sh --issue --dns dns_do -d example.com -d www.example.com
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 18. Use Gandi LiveDNS API
 | 
			
		||||
 | 
			
		||||
You must enable the new Gandi LiveDNS API first and the create your api key, See: http://doc.livedns.gandi.net/
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
export GANDI_LIVEDNS_KEY="fdmlfsdklmfdkmqsdfk"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Ok, let's issue a cert now:
 | 
			
		||||
```
 | 
			
		||||
acme.sh --issue --dns dns_gandi_livedns -d example.com -d www.example.com
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Use custom API
 | 
			
		||||
 | 
			
		||||
If your API is not supported yet, you can write your own DNS API.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										148
									
								
								dnsapi/dns_do.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										148
									
								
								dnsapi/dns_do.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,148 @@
 | 
			
		||||
#!/usr/bin/env sh
 | 
			
		||||
 | 
			
		||||
# DNS API for Domain-Offensive / Resellerinterface / Domainrobot
 | 
			
		||||
 | 
			
		||||
# Report bugs at https://github.com/seidler2547/acme.sh/issues
 | 
			
		||||
 | 
			
		||||
# set these environment variables to match your customer ID and password:
 | 
			
		||||
# DO_PID="KD-1234567"
 | 
			
		||||
# DO_PW="cdfkjl3n2"
 | 
			
		||||
 | 
			
		||||
DO_URL="https://soap.resellerinterface.de/"
 | 
			
		||||
 | 
			
		||||
########  Public functions #####################
 | 
			
		||||
 | 
			
		||||
#Usage: dns_myapi_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
			
		||||
dns_do_add() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
  txtvalue=$2
 | 
			
		||||
  if _dns_do_authenticate; then
 | 
			
		||||
    _info "Adding TXT record to ${_domain} as ${fulldomain}"
 | 
			
		||||
    _dns_do_soap createRR origin "${_domain}" name "${fulldomain}" type TXT data "${txtvalue}" ttl 300
 | 
			
		||||
    if _contains "${response}" '>success<'; then
 | 
			
		||||
      return 0
 | 
			
		||||
    fi
 | 
			
		||||
    _err "Could not create resource record, check logs"
 | 
			
		||||
  fi
 | 
			
		||||
  return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#fulldomain
 | 
			
		||||
dns_do_rm() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
  if _dns_do_authenticate; then
 | 
			
		||||
    if _dns_do_list_rrs; then
 | 
			
		||||
      _dns_do_had_error=0
 | 
			
		||||
      for _rrid in ${_rr_list}; do
 | 
			
		||||
        _info "Deleting resource record $_rrid for $_domain"
 | 
			
		||||
        _dns_do_soap deleteRR origin "${_domain}" rrid "${_rrid}"
 | 
			
		||||
        if ! _contains "${response}" '>success<'; then
 | 
			
		||||
          _dns_do_had_error=1
 | 
			
		||||
          _err "Could not delete resource record for ${_domain}, id ${_rrid}"
 | 
			
		||||
        fi
 | 
			
		||||
      done
 | 
			
		||||
      return $_dns_do_had_error
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
  return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
####################  Private functions below ##################################
 | 
			
		||||
_dns_do_authenticate() {
 | 
			
		||||
  _info "Authenticating as ${DO_PID}"
 | 
			
		||||
  _dns_do_soap authPartner partner "${DO_PID}" password "${DO_PW}"
 | 
			
		||||
  if _contains "${response}" '>success<'; then
 | 
			
		||||
    _get_root "$fulldomain"
 | 
			
		||||
    _debug "_domain $_domain"
 | 
			
		||||
    return 0
 | 
			
		||||
  else
 | 
			
		||||
    _err "Authentication failed, are DO_PID and DO_PW set correctly?"
 | 
			
		||||
  fi
 | 
			
		||||
  return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_dns_do_list_rrs() {
 | 
			
		||||
  _dns_do_soap getRRList origin "${_domain}"
 | 
			
		||||
  if ! _contains "${response}" 'SOAP-ENC:Array'; then
 | 
			
		||||
    _err "getRRList origin ${_domain} failed"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  _rr_list="$(echo "${response}" \
 | 
			
		||||
    | tr -d "\n\r\t" \
 | 
			
		||||
    | sed -e 's/<item xsi:type="ns2:Map">/\n/g' \
 | 
			
		||||
    | grep ">$(_regexcape "$fulldomain")</value>" \
 | 
			
		||||
    | sed -e 's/<\/item>/\n/g' \
 | 
			
		||||
    | grep '>id</key><value' \
 | 
			
		||||
    | _egrep_o '>[0-9]{1,16}<' \
 | 
			
		||||
    | tr -d '><')"
 | 
			
		||||
  [ "${_rr_list}" ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_dns_do_soap() {
 | 
			
		||||
  func="$1"
 | 
			
		||||
  shift
 | 
			
		||||
  # put the parameters to xml
 | 
			
		||||
  body="<tns:${func} xmlns:tns=\"${DO_URL}\">"
 | 
			
		||||
  while [ "$1" ]; do
 | 
			
		||||
    _k="$1"
 | 
			
		||||
    shift
 | 
			
		||||
    _v="$1"
 | 
			
		||||
    shift
 | 
			
		||||
    body="$body<$_k>$_v</$_k>"
 | 
			
		||||
  done
 | 
			
		||||
  body="$body</tns:${func}>"
 | 
			
		||||
  _debug2 "SOAP request ${body}"
 | 
			
		||||
 | 
			
		||||
  # build SOAP XML
 | 
			
		||||
  _xml='<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
 | 
			
		||||
  <env:Body>'"$body"'</env:Body>
 | 
			
		||||
</env:Envelope>'
 | 
			
		||||
 | 
			
		||||
  # set SOAP headers
 | 
			
		||||
  export _H1="SOAPAction: ${DO_URL}#${func}"
 | 
			
		||||
 | 
			
		||||
  if ! response="$(_post "${_xml}" "${DO_URL}")"; then
 | 
			
		||||
    _err "Error <$1>"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  _debug2 "SOAP response $response"
 | 
			
		||||
 | 
			
		||||
  # retrieve cookie header
 | 
			
		||||
  _H2="$(_egrep_o 'Cookie: [^;]+' <"$HTTP_HEADER" | _head_n 1)"
 | 
			
		||||
  export _H2
 | 
			
		||||
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_get_root() {
 | 
			
		||||
  domain=$1
 | 
			
		||||
  i=1
 | 
			
		||||
 | 
			
		||||
  _dns_do_soap getDomainList
 | 
			
		||||
  _all_domains="$(echo "${response}" \
 | 
			
		||||
    | tr -d "\n\r\t " \
 | 
			
		||||
    | _egrep_o 'domain</key><value[^>]+>[^<]+' \
 | 
			
		||||
    | sed -e 's/^domain<\/key><value[^>]*>//g')"
 | 
			
		||||
 | 
			
		||||
  while true; do
 | 
			
		||||
    h=$(printf "%s" "$domain" | cut -d . -f $i-100)
 | 
			
		||||
    if [ -z "$h" ]; then
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if _contains "${_all_domains}" "^$(_regexcape "$h")\$"; then
 | 
			
		||||
      _domain="$h"
 | 
			
		||||
      return 0
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    i=$(_math $i + 1)
 | 
			
		||||
  done
 | 
			
		||||
  _debug "$domain not found"
 | 
			
		||||
 | 
			
		||||
  return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_regexcape() {
 | 
			
		||||
  echo "$1" | sed -e 's/\([]\.$*^[]\)/\\\1/g'
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										123
									
								
								dnsapi/dns_gandi_livedns.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										123
									
								
								dnsapi/dns_gandi_livedns.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,123 @@
 | 
			
		||||
#!/usr/bin/env sh
 | 
			
		||||
 | 
			
		||||
# Gandi LiveDNS v5 API
 | 
			
		||||
# http://doc.livedns.gandi.net/
 | 
			
		||||
# currently under beta
 | 
			
		||||
#
 | 
			
		||||
# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable
 | 
			
		||||
#
 | 
			
		||||
#Author: Frédéric Crozat <fcrozat@suse.com>
 | 
			
		||||
#Report Bugs here: https://github.com/fcrozat/acme.sh
 | 
			
		||||
#
 | 
			
		||||
########  Public functions #####################
 | 
			
		||||
 | 
			
		||||
GANDI_LIVEDNS_API="https://dns.beta.gandi.net/api/v5"
 | 
			
		||||
 | 
			
		||||
#Usage: dns_gandi_livedns_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
			
		||||
dns_gandi_livedns_add() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
  txtvalue=$2
 | 
			
		||||
 | 
			
		||||
  if [ -z "$GANDI_LIVEDNS_KEY" ]; then
 | 
			
		||||
    _err "No API key specifed for Gandi LiveDNS."
 | 
			
		||||
    _err "Create your key and export it as GANDI_LIVEDNS_KEY"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _saveaccountconf GANDI_LIVEDNS_KEY "$GANDI_LIVEDNS_KEY"
 | 
			
		||||
 | 
			
		||||
  _debug "First detect the root zone"
 | 
			
		||||
  if ! _get_root "$fulldomain"; then
 | 
			
		||||
    _err "invalid domain"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  _debug fulldomain "$fulldomain"
 | 
			
		||||
  _debug txtvalue "$txtvalue"
 | 
			
		||||
  _debug domain "$_domain"
 | 
			
		||||
  _debug sub_domain "$_sub_domain"
 | 
			
		||||
 | 
			
		||||
  _gandi_livedns_rest PUT "domains/$_domain/records/$_sub_domain/TXT" "{\"rrset_ttl\": 300, \"rrset_values\":[\"$txtvalue\"]}" \
 | 
			
		||||
    && _contains "$response" '{"message": "Zone Record Created"}' \
 | 
			
		||||
    && _info "Add $(__green "success")"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#Usage: fulldomain txtvalue
 | 
			
		||||
#Remove the txt record after validation.
 | 
			
		||||
dns_gandi_livedns_rm() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
  txtvalue=$2
 | 
			
		||||
 | 
			
		||||
  _debug "First detect the root zone"
 | 
			
		||||
  if ! _get_root "$fulldomain"; then
 | 
			
		||||
    _err "invalid domain"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _debug fulldomain "$fulldomain"
 | 
			
		||||
  _debug domain "$_domain"
 | 
			
		||||
  _debug sub_domain "$_sub_domain"
 | 
			
		||||
 | 
			
		||||
  _gandi_livedns_rest DELETE "domains/$_domain/records/$_sub_domain/TXT" ""
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
####################  Private functions below ##################################
 | 
			
		||||
#_acme-challenge.www.domain.com
 | 
			
		||||
#returns
 | 
			
		||||
# _sub_domain=_acme-challenge.www
 | 
			
		||||
# _domain=domain.com
 | 
			
		||||
_get_root() {
 | 
			
		||||
  domain=$1
 | 
			
		||||
  i=2
 | 
			
		||||
  p=1
 | 
			
		||||
  while true; do
 | 
			
		||||
    h=$(printf "%s" "$domain" | cut -d . -f $i-100)
 | 
			
		||||
    _debug h "$h"
 | 
			
		||||
    if [ -z "$h" ]; then
 | 
			
		||||
      #not valid
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ! _gandi_livedns_rest GET "domains/$h"; then
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if _contains "$response" '"code": 401'; then
 | 
			
		||||
      _err "$response"
 | 
			
		||||
      return 1
 | 
			
		||||
    elif _contains "$response" '"code": 404'; then
 | 
			
		||||
      _debug "$h not found"
 | 
			
		||||
    else
 | 
			
		||||
      _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
 | 
			
		||||
      _domain="$h"
 | 
			
		||||
      return 0
 | 
			
		||||
    fi
 | 
			
		||||
    p="$i"
 | 
			
		||||
    i=$(_math "$i" + 1)
 | 
			
		||||
  done
 | 
			
		||||
  return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_gandi_livedns_rest() {
 | 
			
		||||
  m=$1
 | 
			
		||||
  ep="$2"
 | 
			
		||||
  data="$3"
 | 
			
		||||
  _debug "$ep"
 | 
			
		||||
 | 
			
		||||
  export _H1="Content-Type: application/json"
 | 
			
		||||
  export _H2="X-Api-Key: $GANDI_LIVEDNS_KEY"
 | 
			
		||||
 | 
			
		||||
  if [ "$m" = "GET" ]; then
 | 
			
		||||
    response="$(_get "$GANDI_LIVEDNS_API/$ep")"
 | 
			
		||||
  else
 | 
			
		||||
    _debug data "$data"
 | 
			
		||||
    response="$(_post "$data" "$GANDI_LIVEDNS_API/$ep" "" "$m")"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ "$?" != "0" ]; then
 | 
			
		||||
    _err "error $ep"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  _debug2 response "$response"
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
@ -81,7 +81,36 @@ dns_lua_add() {
 | 
			
		||||
#fulldomain
 | 
			
		||||
dns_lua_rm() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
  txtvalue=$2
 | 
			
		||||
  _debug "First detect the root zone"
 | 
			
		||||
  if ! _get_root "$fulldomain"; then
 | 
			
		||||
    _err "invalid domain"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  _debug _domain_id "$_domain_id"
 | 
			
		||||
  _debug _sub_domain "$_sub_domain"
 | 
			
		||||
  _debug _domain "$_domain"
 | 
			
		||||
 | 
			
		||||
  _debug "Getting txt records"
 | 
			
		||||
  _LUA_rest GET "zones/${_domain_id}/records"
 | 
			
		||||
 | 
			
		||||
  count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | wc -l | tr -d " ")
 | 
			
		||||
  _debug count "$count"
 | 
			
		||||
  if [ "$count" = "0" ]; then
 | 
			
		||||
    _info "Don't need to remove."
 | 
			
		||||
  else
 | 
			
		||||
    record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | _head_n 1 | cut -d: -f2 | cut -d, -f1)
 | 
			
		||||
    _debug "record_id" "$record_id"
 | 
			
		||||
    if [ -z "$record_id" ]; then
 | 
			
		||||
      _err "Can not get record id to remove."
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
    if ! _LUA_rest DELETE "/zones/$_domain_id/records/$record_id"; then
 | 
			
		||||
      _err "Delete record error."
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
    _contains "$response" "$record_id"
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
####################  Private functions below ##################################
 | 
			
		||||
@ -129,7 +158,7 @@ _LUA_rest() {
 | 
			
		||||
 | 
			
		||||
  export _H1="Accept: application/json"
 | 
			
		||||
  export _H2="Authorization: Basic $LUA_auth"
 | 
			
		||||
  if [ "$data" ]; then
 | 
			
		||||
  if [ "$m" != "GET" ]; then
 | 
			
		||||
    _debug data "$data"
 | 
			
		||||
    response="$(_post "$data" "$LUA_Api/$ep" "" "$m")"
 | 
			
		||||
  else
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										31
									
								
								dnsapi/dns_me.sh
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										31
									
								
								dnsapi/dns_me.sh
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							@ -78,7 +78,36 @@ dns_me_add() {
 | 
			
		||||
#fulldomain
 | 
			
		||||
dns_me_rm() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
  txtvalue=$2
 | 
			
		||||
  _debug "First detect the root zone"
 | 
			
		||||
  if ! _get_root "$fulldomain"; then
 | 
			
		||||
    _err "invalid domain"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  _debug _domain_id "$_domain_id"
 | 
			
		||||
  _debug _sub_domain "$_sub_domain"
 | 
			
		||||
  _debug _domain "$_domain"
 | 
			
		||||
 | 
			
		||||
  _debug "Getting txt records"
 | 
			
		||||
  _me_rest GET "${_domain_id}/records?recordName=$_sub_domain&type=TXT"
 | 
			
		||||
 | 
			
		||||
  count=$(printf "%s\n" "$response" | _egrep_o "\"totalRecords\":[^,]*" | cut -d : -f 2)
 | 
			
		||||
  _debug count "$count"
 | 
			
		||||
  if [ "$count" = "0" ]; then
 | 
			
		||||
    _info "Don't need to remove."
 | 
			
		||||
  else
 | 
			
		||||
    record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*" | cut -d : -f 2 | head -n 1)
 | 
			
		||||
    _debug "record_id" "$record_id"
 | 
			
		||||
    if [ -z "$record_id" ]; then
 | 
			
		||||
      _err "Can not get record id to remove."
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
    if ! _me_rest DELETE "$_domain_id/records/$record_id"; then
 | 
			
		||||
      _err "Delete record error."
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
    _contains "$response" ''
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
####################  Private functions below ##################################
 | 
			
		||||
@ -130,7 +159,7 @@ _me_rest() {
 | 
			
		||||
  export _H2="x-dnsme-requestDate: $cdate"
 | 
			
		||||
  export _H3="x-dnsme-hmac: $hmac"
 | 
			
		||||
 | 
			
		||||
  if [ "$data" ]; then
 | 
			
		||||
  if [ "$m" != "GET" ]; then
 | 
			
		||||
    _debug data "$data"
 | 
			
		||||
    response="$(_post "$data" "$ME_Api/$ep" "" "$m")"
 | 
			
		||||
  else
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user