Browse Source

Merge remote-tracking branch 'upstream/master' into ssh-deploy

pull/586/head
David Kerr 8 years ago
parent
commit
b30c1daf72
  1. 6
      .travis.yml
  2. 2
      README.md
  3. 240
      acme.sh
  4. 53
      deploy/README.md
  5. 2
      deploy/apache.sh
  6. 90
      deploy/exim4.sh
  7. 86
      deploy/vsftpd.sh
  8. 26
      dnsapi/README.md
  9. 148
      dnsapi/dns_do.sh
  10. 123
      dnsapi/dns_gandi_livedns.sh
  11. 31
      dnsapi/dns_lua.sh
  12. 31
      dnsapi/dns_me.sh

6
.travis.yml

@ -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:

2
README.md

@ -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

@ -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"
;;

53
deploy/README.md

@ -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
```

2
deploy/apache.sh

@ -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.

90
deploy/exim4.sh

@ -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"
_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
}

86
deploy/vsftpd.sh

@ -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"
_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
}

26
dnsapi/README.md

@ -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

@ -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

@ -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
}

31
dnsapi/dns_lua.sh

@ -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

@ -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…
Cancel
Save