Merge remote-tracking branch 'upstream/master' into ssh-deploy
						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. | ||||
|  |  | |||
|  | @ -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' | ||||
| } | ||||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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…
	
		Reference in New Issue
	
	 David Kerr
						David Kerr