From 748cb28017398ca125f507342a2c8cf5d7480a85 Mon Sep 17 00:00:00 2001 From: Ian Epperson Date: Wed, 13 May 2020 10:39:11 -0700 Subject: [PATCH 01/91] Add Discord notification --- notify/discord.sh | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 notify/discord.sh diff --git a/notify/discord.sh b/notify/discord.sh new file mode 100644 index 00000000..3cce4ee5 --- /dev/null +++ b/notify/discord.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env sh + +#Support Discord webhooks + +# Required: +#DISCORD_WEBHOOK_URL="" +# Optional: +#DISCORD_USERNAME="" +#DISCORD_AVATAR_URL="" + +discord_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + DISCORD_WEBHOOK_URL="${DISCORD_WEBHOOK_URL:-$(_readaccountconf_mutable DISCORD_WEBHOOK_URL)}" + if [ -z "$DISCORD_WEBHOOK_URL" ]; then + DISCORD_WEBHOOK_URL="" + _err "You didn't specify a Discord webhook url DISCORD_WEBHOOK_URL yet." + return 1 + fi + _saveaccountconf_mutable DISCORD_WEBHOOK_URL "$DISCORD_WEBHOOK_URL" + + DISCORD_USERNAME="${DISCORD_USERNAME:-$(_readaccountconf_mutable DISCORD_USERNAME)}" + if [ -n "$DISCORD_USERNAME" ]; then + _saveaccountconf_mutable DISCORD_USERNAME "$DISCORD_USERNAME" + fi + + DISCORD_AVATAR_URL="${DISCORD_AVATAR_URL:-$(_readaccountconf_mutable DISCORD_AVATAR_URL)}" + if [ -n "$DISCORD_AVATAR_URL" ]; then + _saveaccountconf_mutable DISCORD_AVATAR_URL "$DISCORD_AVATAR_URL" + fi + + export _H1="Content-Type: application/json" + + _content="$(printf "**%s**\n%s" "$_subject" "$_content" | _json_encode)" + _data="{\"content\": \"$_content\" " + if [ -n "$DISCORD_USERNAME" ]; then + _data="$_data, \"username\": \"$DISCORD_USERNAME\" " + fi + if [ -n "$DISCORD_AVATAR_URL" ]; then + _data="$_data, \"avatar_url\": \"$DISCORD_AVATAR_URL\" " + fi + _data="$_data}" + + if _post "$_data" "$DISCORD_WEBHOOK_URL?wait=true"; then + # shellcheck disable=SC2154 + if [ -n "$response" ]; then + _info "discord send success." + return 0 + fi + fi + _err "discord send error." + _err "$response" + return 1 +} From 6d84f59e6bdbcec0dbfe8d6ca7f8046ad92bd772 Mon Sep 17 00:00:00 2001 From: Leo <8571049+leoluo0818@users.noreply.github.com> Date: Sat, 21 Aug 2021 04:11:21 +0800 Subject: [PATCH 02/91] Add Weixin Work notify hook --- nofity/weixin_work.sh | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 nofity/weixin_work.sh diff --git a/nofity/weixin_work.sh b/nofity/weixin_work.sh new file mode 100644 index 00000000..bf3e9ad6 --- /dev/null +++ b/nofity/weixin_work.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env sh + +#Support weixin work webhooks api + +#WEIXIN_WORK_WEBHOOK="xxxx" + +#optional +#WEIXIN_WORK_KEYWORD="yyyy" + +#`WEIXIN_WORK_SIGNING_KEY`="SEC08ffdbd403cbc3fc8a65xxxxxxxxxxxxxxxxxxxx" + +# subject content statusCode +weixin_work_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + WEIXIN_WORK_WEBHOOK="${WEIXIN_WORK_WEBHOOK:-$(_readaccountconf_mutable WEIXIN_WORK_WEBHOOK)}" + if [ -z "$WEIXIN_WORK_WEBHOOK" ]; then + WEIXIN_WORK_WEBHOOK="" + _err "You didn't specify a weixin_work webhooks WEIXIN_WORK_WEBHOOK yet." + _err "You can get yours from https://work.weixin.qq.com/api/doc/90000/90136/91770" + return 1 + fi + _saveaccountconf_mutable WEIXIN_WORK_WEBHOOK "$WEIXIN_WORK_WEBHOOK" + + WEIXIN_WORK_KEYWORD="${WEIXIN_WORK_KEYWORD:-$(_readaccountconf_mutable WEIXIN_WORK_KEYWORD)}" + if [ "$WEIXIN_WORK_KEYWORD" ]; then + _saveaccountconf_mutable WEIXIN_WORK_KEYWORD "$WEIXIN_WORK_KEYWORD" + fi + + _content=$(echo "$_content" | _json_encode) + _subject=$(echo "$_subject" | _json_encode) + _data="{\"msgtype\": \"text\", \"text\": {\"content\": \"[$WEIXIN_WORK_KEYWORD]\n$_subject\n$_content\"}}" + + response="$(_post "$_data" "$WEIXIN_WORK_WEBHOOK" "" "POST" "application/json")" + + if [ "$?" = "0" ] && _contains "$response" "errmsg\":\"ok"; then + _info "weixin_work webhooks event fired success." + return 0 + fi + + _err "weixin_work webhooks event fired error." + _err "$response" + return 1 +} From 6ead01987310cda3183f9f15ce33733bccc8ee9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Th=C3=B6rnblad?= Date: Wed, 9 Mar 2022 17:12:09 +0100 Subject: [PATCH 03/91] Accept some special characters in password and added a little bit better error handling --- dnsapi/dns_loopia.sh | 46 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index 73327335..e95d8999 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -32,8 +32,12 @@ dns_loopia_add() { _info "Adding record" - _loopia_add_sub_domain "$_domain" "$_sub_domain" - _loopia_add_record "$_domain" "$_sub_domain" "$txtvalue" + if ! _loopia_add_sub_domain "$_domain" "$_sub_domain"; then + return 1 + fi + if ! _loopia_add_record "$_domain" "$_sub_domain" "$txtvalue"; then + return 1 + fi } @@ -70,12 +74,13 @@ dns_loopia_rm() { %s - ' "$LOOPIA_User" "$LOOPIA_Password" "$_domain" "$_sub_domain") + ' "$LOOPIA_User" "$Encoded_Password" "$_domain" "$_sub_domain") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" if ! _contains "$response" "OK"; then - _err "Error could not get txt records" + err_response=$(echo "$response" | grep -oPm1 "(?<=)[^<]+") + _err "Error could not get txt records: $err_response" return 1 fi } @@ -101,6 +106,12 @@ _loopia_load_config() { return 1 fi + if _contains "$LOOPIA_Password" "'" || _contains "$LOOPIA_Password" '"'; then + _err "Password contains quoute or double quoute and this is not supported by dns_loopia.sh" + return 1 + fi + + Encoded_Password=$(_xml_encode "$LOOPIA_Password") return 0 } @@ -133,11 +144,12 @@ _loopia_get_records() { %s - ' "$LOOPIA_User" "$LOOPIA_Password" "$domain" "$sub_domain") + ' "$LOOPIA_User" "$Encoded_Password" "$domain" "$sub_domain") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" if ! _contains "$response" ""; then - _err "Error" + err_response=$(echo "$response" | grep -oPm1 "(?<=)[^<]+") + _err "Error: $err_response" return 1 fi return 0 @@ -162,7 +174,7 @@ _get_root() { %s - ' "$LOOPIA_User" "$LOOPIA_Password") + ' "$LOOPIA_User" "$Encoded_Password") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" while true; do @@ -228,12 +240,13 @@ _loopia_add_record() { - ' "$LOOPIA_User" "$LOOPIA_Password" "$domain" "$sub_domain" "$txtval") + ' "$LOOPIA_User" "$Encoded_Password" "$domain" "$sub_domain" "$txtval") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" if ! _contains "$response" "OK"; then - _err "Error" + err_response=$(echo "$response" | grep -oPm1 "(?<=)[^<]+") + _err "Error: $err_response" return 1 fi return 0 @@ -257,7 +270,7 @@ _sub_domain_exists() { %s - ' "$LOOPIA_User" "$LOOPIA_Password" "$domain") + ' "$LOOPIA_User" "$Encoded_Password" "$domain") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" @@ -292,13 +305,22 @@ _loopia_add_sub_domain() { %s - ' "$LOOPIA_User" "$LOOPIA_Password" "$domain" "$sub_domain") + ' "$LOOPIA_User" "$Encoded_Password" "$domain" "$sub_domain") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" if ! _contains "$response" "OK"; then - _err "Error" + err_response=$(echo "$response" | grep -oPm1 "(?<=)[^<]+") + _err "Error: $err_response" return 1 fi return 0 } + +_xml_encode() { + encoded_string=$1 + encoded_string=$(echo "$encoded_string" | sed 's/&/\&/') + encoded_string=$(echo "$encoded_string" | sed 's//\>/') + printf "%s" "$encoded_string" +} From 227d62a5dce420c24cea210a6ff46be64656d18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikolaj=20Brinch=20J=C3=B8rgensen?= Date: Thu, 10 Mar 2022 11:13:38 +0100 Subject: [PATCH 04/91] Fixes Simply.com to use REST API version 2 with Basic Auth --- dnsapi/dns_simply.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 437e5e5c..6a8d0e18 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -5,8 +5,8 @@ #SIMPLY_AccountName="accountname" #SIMPLY_ApiKey="apikey" # -#SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" -SIMPLY_Api_Default="https://api.simply.com/1" +#SIMPLY_Api="https://api.simply.com/2/" +SIMPLY_Api_Default="https://api.simply.com/2" #This is used for determining success of REST call SIMPLY_SUCCESS_CODE='"status":200' @@ -237,12 +237,18 @@ _simply_rest() { _debug2 ep "$ep" _debug2 m "$m" - export _H1="Content-Type: application/json" + basicauth=$(printf "%s:%s" "$SIMPLY_AccountName" "$SIMPLY_ApiKey" | _base64) + + if [ "$basicauth" ]; then + export _H1="Authorization: Basic $basicauth" + fi + + export _H2="Content-Type: application/json" if [ "$m" != "GET" ]; then - response="$(_post "$data" "$SIMPLY_Api/$SIMPLY_AccountName/$SIMPLY_ApiKey/$ep" "" "$m")" + response="$(_post "$data" "$SIMPLY_Api/$ep" "" "$m")" else - response="$(_get "$SIMPLY_Api/$SIMPLY_AccountName/$SIMPLY_ApiKey/$ep")" + response="$(_get "$SIMPLY_Api/$ep")" fi if [ "$?" != "0" ]; then From b209f666547382eb5730ba11ca455f6e4fceb92d Mon Sep 17 00:00:00 2001 From: bosong Date: Fri, 11 Mar 2022 13:41:12 +0800 Subject: [PATCH 05/91] =?UTF-8?q?fix(notify)=EF=BC=9Aremove=20nofity,move?= =?UTF-8?q?=20weixin=5Fwork.sh=20to=20notify?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {nofity => notify}/weixin_work.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {nofity => notify}/weixin_work.sh (100%) diff --git a/nofity/weixin_work.sh b/notify/weixin_work.sh similarity index 100% rename from nofity/weixin_work.sh rename to notify/weixin_work.sh From 8d574ecb34af21814983ce174cb8224b19e7639e Mon Sep 17 00:00:00 2001 From: waldner Date: Tue, 15 Mar 2022 18:48:14 +0100 Subject: [PATCH 06/91] Geoscaling: get creds for removal too --- dnsapi/dns_geoscaling.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dnsapi/dns_geoscaling.sh b/dnsapi/dns_geoscaling.sh index 6d61312d..6ccf4daf 100755 --- a/dnsapi/dns_geoscaling.sh +++ b/dnsapi/dns_geoscaling.sh @@ -58,6 +58,17 @@ dns_geoscaling_rm() { txt_value=$2 _info "Cleaning up after DNS-01 Geoscaling DNS2 hook" + GEOSCALING_Username="${GEOSCALING_Username:-$(_readaccountconf_mutable GEOSCALING_Username)}" + GEOSCALING_Password="${GEOSCALING_Password:-$(_readaccountconf_mutable GEOSCALING_Password)}" + if [ -z "$GEOSCALING_Username" ] || [ -z "$GEOSCALING_Password" ]; then + GEOSCALING_Username= + GEOSCALING_Password= + _err "No auth details provided. Please set user credentials using the \$GEOSCALING_Username and \$GEOSCALING_Password environment variables." + return 1 + fi + _saveaccountconf_mutable GEOSCALING_Username "${GEOSCALING_Username}" + _saveaccountconf_mutable GEOSCALING_Password "${GEOSCALING_Password}" + # fills in the $zone_id find_zone "${full_domain}" || return 1 _debug "Zone id '${zone_id}' will be used." From 9d6d96adf3620094aae1b460ac74297a278de295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Thu, 17 Mar 2022 12:22:58 +0100 Subject: [PATCH 07/91] deploy/routeros.sh: fix routeros script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit c46ceb06b49ae32a3c51d88756941fa94642dbe7 introduced an error in routeros script. Fix it! Signed-off-by: Andreas Bießmann --- deploy/routeros.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index b2b18c5e..ec088f80 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -130,7 +130,7 @@ routeros_deploy() { $ROUTER_OS_SCP_CMD "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" _info "Trying to push cert '$_cfullchain' to router" $ROUTER_OS_SCP_CMD "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" - DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=$ROUTER_OS_USER \ + DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=$ROUTER_OS_USERNAME \ comment=\"generated by routeros deploy script in acme.sh\" \ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ \n/certificate remove [ find name=$_cdomain.cer_1 ];\ @@ -146,6 +146,8 @@ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ \n$ROUTER_OS_ADDITIONAL_SERVICES;\ \n\" " + _debug DEPLOY_SCRIPT_CMD "${DEPLOY_SCRIPT_CMD}" + # shellcheck disable=SC2029 $ROUTER_OS_SSH_CMD "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$DEPLOY_SCRIPT_CMD" # shellcheck disable=SC2029 From c603b9c40b625f17a1cd921162a9d01512bbd90c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Thu, 17 Mar 2022 14:31:01 +0100 Subject: [PATCH 08/91] deploy/routeros: add error handling for ssh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to detect errorneous scripts on remote side, catch return code and handle it respectively. Signed-off-by: Andreas Bießmann Reviewed-by: Ross Shen @sjtuross --- deploy/routeros.sh | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index ec088f80..394856e6 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -70,6 +70,7 @@ routeros_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" + _err_code=0 _debug _cdomain "$_cdomain" _debug _ckey "$_ckey" @@ -146,14 +147,35 @@ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ \n$ROUTER_OS_ADDITIONAL_SERVICES;\ \n\" " - _debug DEPLOY_SCRIPT_CMD "${DEPLOY_SCRIPT_CMD}" - # shellcheck disable=SC2029 - $ROUTER_OS_SSH_CMD "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$DEPLOY_SCRIPT_CMD" - # shellcheck disable=SC2029 - $ROUTER_OS_SSH_CMD "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\"" - # shellcheck disable=SC2029 - $ROUTER_OS_SSH_CMD "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script remove \"LE Cert Deploy - $_cdomain\"" + if ! _ssh_remote_cmd "$DEPLOY_SCRIPT_CMD"; then + return $_err_code + fi + + if ! _ssh_remote_cmd "/system script run \"LE Cert Deploy - $_cdomain\""; then + return $_err_code + fi + + if ! _ssh_remote_cmd "/system script remove \"LE Cert Deploy - $_cdomain\""; then + return $_err_code + fi return 0 } + +# inspired by deploy/ssh.sh +_ssh_remote_cmd() { + _cmd="$1" + _secure_debug "Remote commands to execute: $_cmd" + _info "Submitting sequence of commands to routeros" + # quotations in bash cmd below intended. Squash travis spellcheck error + # shellcheck disable=SC2029 + $ROUTER_OS_SSH_CMD "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$_cmd" + _err_code="$?" + + if [ "$_err_code" != "0" ]; then + _err "Error code $_err_code returned from routeros" + fi + + return $_err_code +} From 3411b736dd4b868bc1e0a5e24899fdb32a729721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Fri, 18 Mar 2022 07:58:57 +0100 Subject: [PATCH 09/91] deploy/routeros: add error handling for scp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to stop processing on failure to copy certificate to remote side, fail on error of scp command. Signed-off-by: Andreas Bießmann --- deploy/routeros.sh | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 394856e6..c4c9470d 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -127,10 +127,16 @@ routeros_deploy() { _savedeployconf ROUTER_OS_SCP_CMD "$ROUTER_OS_SCP_CMD" _savedeployconf ROUTER_OS_ADDITIONAL_SERVICES "$ROUTER_OS_ADDITIONAL_SERVICES" - _info "Trying to push key '$_ckey' to router" - $ROUTER_OS_SCP_CMD "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" - _info "Trying to push cert '$_cfullchain' to router" - $ROUTER_OS_SCP_CMD "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" + # push key to routeros + if ! _scp_certificate "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key"; then + return $_err_code + fi + + # push certificate chain to routeros + if ! _scp_certificate "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer"; then + return $_err_code + fi + DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=$ROUTER_OS_USERNAME \ comment=\"generated by routeros deploy script in acme.sh\" \ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ @@ -179,3 +185,19 @@ _ssh_remote_cmd() { return $_err_code } + +_scp_certificate() { + _src="$1" + _dst="$2" + _secure_debug "scp '$_src' to '$_dst'" + _info "Push key '$_src' to routeros" + + $ROUTER_OS_SCP_CMD "$_src" "$_dst" + _err_code="$?" + + if [ "$_err_code" != "0" ]; then + _err "Error code $_err_code returned from scp" + fi + + return $_err_code +} From c3f6112443b6f547e3403410010992bbff3f1f81 Mon Sep 17 00:00:00 2001 From: Ian Grant Date: Sat, 19 Mar 2022 20:36:11 +0000 Subject: [PATCH 10/91] feat: Configure certificate for TrueNAS S3 service (MinIO) --- deploy/truenas.sh | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 6f1a31b0..b1ed9281 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -159,7 +159,30 @@ truenas_deploy() { fi _debug3 _activate_ftp_cert "$_activate_ftp_cert" else - _info "FTP certificate not set or not the same as Web UI" + _info "FTP certificate is not configured or is not the same as TrueNAS web UI" + fi + + _info "Checking if S3 certificate is the same as the TrueNAS web UI" + _s3_list=$(_get "$_api_url/s3") + _s3_cert_id=$(echo "$_s3_list" | grep '"certificate":' | tr -d -- '"certifa:_ ,') + + if [ "$_s3_cert_id" = "$_active_cert_id" ]; then + _info "Updating the S3 certificate" + _debug _s3_cert_id "$_s3_cert_id" + _s3_data="{\"certificate\": \"${_cert_id}\"}" + _activate_s3_cert="$(_post "$_s3_data" "$_api_url/s3" "" "PUT" "application/json")" + _s3_new_cert_id=$(echo "$_activate_s3_cert" | _json_decode | grep '"certificate":' | sed -n 's/.*: \([0-9]\{1,\}\),\{0,1\}$/\1/p') + if [ "$_s3_new_cert_id" -eq "$_cert_id" ]; then + _info "S3 certificate updated successfully" + else + _err "Unable to set S3 certificate" + _debug3 _activate_s3_cert "$_activate_s3_cert" + _debug3 _s3_new_cert_id "$_s3_new_cert_id" + return 1 + fi + _debug3 _activate_s3_cert "$_activate_s3_cert" + else + _info "S3 certificate is not configured or is not the same as TrueNAS web UI" fi _info "Delete old Certificate" From d4a6d9c076e96cbe0571eacedcba9be5a33408d8 Mon Sep 17 00:00:00 2001 From: Ian Grant Date: Sat, 19 Mar 2022 20:38:47 +0000 Subject: [PATCH 11/91] fix: Adjust the sed extraction of certificate ID from JSON response Prior to this, an error in the regex didn't match. Resolves #3992 (TrueNAS deploy hook fails to set certificate for FTP or WebDAV) --- deploy/truenas.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index b1ed9281..379a7538 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -125,7 +125,7 @@ truenas_deploy() { _debug _webdav_cert_id "$_webdav_cert_id" _webdav_data="{\"certssl\": \"${_cert_id}\"}" _activate_webdav_cert="$(_post "$_webdav_data" "$_api_url/webdav" "" "PUT" "application/json")" - _webdav_new_cert_id=$(echo "$_activate_webdav_cert" | _json_decode | sed -n 's/.*: \([0-9]\{1,\}\) }$/\1/p') + _webdav_new_cert_id=$(echo "$_activate_webdav_cert" | _json_decode | grep '"certssl":' | sed -n 's/.*: \([0-9]\{1,\}\),\{0,1\}$/\1/p') if [ "$_webdav_new_cert_id" -eq "$_cert_id" ]; then _info "WebDAV Certificate update successfully" else @@ -148,7 +148,7 @@ truenas_deploy() { _debug _ftp_cert_id "$_ftp_cert_id" _ftp_data="{\"ssltls_certificate\": \"${_cert_id}\"}" _activate_ftp_cert="$(_post "$_ftp_data" "$_api_url/ftp" "" "PUT" "application/json")" - _ftp_new_cert_id=$(echo "$_activate_ftp_cert" | _json_decode | sed -n 's/.*: \([0-9]\{1,\}\) }$/\1/p') + _ftp_new_cert_id=$(echo "$_activate_ftp_cert" | _json_decode | grep '"ssltls_certificate":' | sed -n 's/.*: \([0-9]\{1,\}\),\{0,1\}$/\1/p') if [ "$_ftp_new_cert_id" -eq "$_cert_id" ]; then _info "FTP Certificate update successfully" else From afa06267a2eda9920f077c0e544293c888706051 Mon Sep 17 00:00:00 2001 From: Ian Grant Date: Sat, 19 Mar 2022 20:39:48 +0000 Subject: [PATCH 12/91] style: Neaten up some of the info & error messages, fix some typos --- deploy/truenas.sh | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 379a7538..84cfd5f4 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -38,7 +38,7 @@ truenas_deploy() { _getdeployconf DEPLOY_TRUENAS_APIKEY if [ -z "$DEPLOY_TRUENAS_APIKEY" ]; then - _err "TrueNAS Api Key is not found, please define DEPLOY_TRUENAS_APIKEY." + _err "TrueNAS API key not found, please set the DEPLOY_TRUENAS_APIKEY environment variable." return 1 fi _secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" @@ -62,15 +62,14 @@ truenas_deploy() { _info "Testing Connection TrueNAS" _response=$(_get "$_api_url/system/state") - _info "TrueNAS System State: $_response." + _info "TrueNAS system state: $_response." if [ -z "$_response" ]; then _err "Unable to authenticate to $_api_url." - _err 'Check your Connection and set DEPLOY_TRUENAS_HOSTNAME="192.168.178.x".' - _err 'or' - _err 'set DEPLOY_TRUENAS_HOSTNAME="".' - _err 'Check your Connection and set DEPLOY_TRUENAS_SCHEME="https".' - _err "Check your Api Key." + _err 'Check your connection settings are correct, e.g.' + _err 'DEPLOY_TRUENAS_HOSTNAME="192.168.x.y" or DEPLOY_TRUENAS_HOSTNAME="truenas.example.com".' + _err 'DEPLOY_TRUENAS_SCHEME="https" or DEPLOY_TRUENAS_SCHEME="http".' + _err "Verify your TrueNAS API key is valid and set correctly, e.g. DEPLOY_TRUENAS_APIKEY=xxxx...." return 1 fi @@ -78,7 +77,7 @@ truenas_deploy() { _savedeployconf DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME" _savedeployconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" - _info "Getting active certificate from TrueNAS" + _info "Getting current active certificate from TrueNAS" _response=$(_get "$_api_url/system/general") _active_cert_id=$(echo "$_response" | grep -B2 '"name":' | grep 'id' | tr -d -- '"id: ,') _active_cert_name=$(echo "$_response" | grep '"name":' | sed -n 's/.*: "\(.\{1,\}\)",$/\1/p') @@ -88,14 +87,14 @@ truenas_deploy() { _debug Active_UI_http_redirect "$_param_httpsredirect" if [ "$DEPLOY_TRUENAS_SCHEME" = "http" ] && [ "$_param_httpsredirect" = "true" ]; then - _info "http Redirect active" + _info "HTTP->HTTPS redirection is enabled" _info "Setting DEPLOY_TRUENAS_SCHEME to 'https'" DEPLOY_TRUENAS_SCHEME="https" _api_url="$DEPLOY_TRUENAS_SCHEME://$DEPLOY_TRUENAS_HOSTNAME/api/v2.0" _savedeployconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" fi - _info "Upload new certifikate to TrueNAS" + _info "Uploading new certificate to TrueNAS" _certname="Letsencrypt_$(_utc_date | tr ' ' '_' | tr -d -- ':')" _debug3 _certname "$_certname" @@ -104,30 +103,30 @@ truenas_deploy() { _debug3 _add_cert_result "$_add_cert_result" - _info "Getting Certificate list to get new Cert ID" + _info "Fetching list of installed certificates" _cert_list=$(_get "$_api_url/system/general/ui_certificate_choices") _cert_id=$(echo "$_cert_list" | grep "$_certname" | sed -n 's/.*"\([0-9]\{1,\}\)".*$/\1/p') _debug3 _cert_id "$_cert_id" - _info "Activate Certificate ID: $_cert_id" + _info "Current activate certificate ID: $_cert_id" _activateData="{\"ui_certificate\": \"${_cert_id}\"}" _activate_result="$(_post "$_activateData" "$_api_url/system/general" "" "PUT" "application/json")" _debug3 _activate_result "$_activate_result" - _info "Check if WebDAV certificate is the same as the WEB UI" + _info "Checking if WebDAV certificate is the same as the TrueNAS web UI" _webdav_list=$(_get "$_api_url/webdav") _webdav_cert_id=$(echo "$_webdav_list" | grep '"certssl":' | tr -d -- '"certsl: ,') if [ "$_webdav_cert_id" = "$_active_cert_id" ]; then - _info "Update the WebDAV Certificate" + _info "Updating the WebDAV certificate" _debug _webdav_cert_id "$_webdav_cert_id" _webdav_data="{\"certssl\": \"${_cert_id}\"}" _activate_webdav_cert="$(_post "$_webdav_data" "$_api_url/webdav" "" "PUT" "application/json")" _webdav_new_cert_id=$(echo "$_activate_webdav_cert" | _json_decode | grep '"certssl":' | sed -n 's/.*: \([0-9]\{1,\}\),\{0,1\}$/\1/p') if [ "$_webdav_new_cert_id" -eq "$_cert_id" ]; then - _info "WebDAV Certificate update successfully" + _info "WebDAV certificate updated successfully" else _err "Unable to set WebDAV certificate" _debug3 _activate_webdav_cert "$_activate_webdav_cert" @@ -136,21 +135,21 @@ truenas_deploy() { fi _debug3 _webdav_new_cert_id "$_webdav_new_cert_id" else - _info "WebDAV certificate not set or not the same as Web UI" + _info "WebDAV certificate is not configured or is not the same as TrueNAS web UI" fi - _info "Check if FTP certificate is the same as the WEB UI" + _info "Checking if FTP certificate is the same as the TrueNAS web UI" _ftp_list=$(_get "$_api_url/ftp") _ftp_cert_id=$(echo "$_ftp_list" | grep '"ssltls_certificate":' | tr -d -- '"certislfa:_ ,') if [ "$_ftp_cert_id" = "$_active_cert_id" ]; then - _info "Update the FTP Certificate" + _info "Updating the FTP certificate" _debug _ftp_cert_id "$_ftp_cert_id" _ftp_data="{\"ssltls_certificate\": \"${_cert_id}\"}" _activate_ftp_cert="$(_post "$_ftp_data" "$_api_url/ftp" "" "PUT" "application/json")" _ftp_new_cert_id=$(echo "$_activate_ftp_cert" | _json_decode | grep '"ssltls_certificate":' | sed -n 's/.*: \([0-9]\{1,\}\),\{0,1\}$/\1/p') if [ "$_ftp_new_cert_id" -eq "$_cert_id" ]; then - _info "FTP Certificate update successfully" + _info "FTP certificate updated successfully" else _err "Unable to set FTP certificate" _debug3 _activate_ftp_cert "$_activate_ftp_cert" @@ -185,19 +184,19 @@ truenas_deploy() { _info "S3 certificate is not configured or is not the same as TrueNAS web UI" fi - _info "Delete old Certificate" + _info "Deleting old certificate" _delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")" _debug3 _delete_result "$_delete_result" - _info "Reload WebUI from TrueNAS" + _info "Reloading TrueNAS web UI" _restart_UI=$(_get "$_api_url/system/general/ui_restart") _debug2 _restart_UI "$_restart_UI" if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ]; then return 0 else - _err "Certupdate was not succesfull, please use --debug" + _err "Certificate update was not succesful, please try again with --debug" return 1 fi } From 451b290b7911a38602111f1e7cb76710b4fa8684 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 20 Mar 2022 12:42:35 +0800 Subject: [PATCH 13/91] Update discord.sh --- notify/discord.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/notify/discord.sh b/notify/discord.sh index 3cce4ee5..8df42e15 100644 --- a/notify/discord.sh +++ b/notify/discord.sh @@ -23,12 +23,12 @@ discord_send() { _saveaccountconf_mutable DISCORD_WEBHOOK_URL "$DISCORD_WEBHOOK_URL" DISCORD_USERNAME="${DISCORD_USERNAME:-$(_readaccountconf_mutable DISCORD_USERNAME)}" - if [ -n "$DISCORD_USERNAME" ]; then + if [ "$DISCORD_USERNAME" ]; then _saveaccountconf_mutable DISCORD_USERNAME "$DISCORD_USERNAME" fi DISCORD_AVATAR_URL="${DISCORD_AVATAR_URL:-$(_readaccountconf_mutable DISCORD_AVATAR_URL)}" - if [ -n "$DISCORD_AVATAR_URL" ]; then + if [ "$DISCORD_AVATAR_URL" ]; then _saveaccountconf_mutable DISCORD_AVATAR_URL "$DISCORD_AVATAR_URL" fi @@ -36,10 +36,10 @@ discord_send() { _content="$(printf "**%s**\n%s" "$_subject" "$_content" | _json_encode)" _data="{\"content\": \"$_content\" " - if [ -n "$DISCORD_USERNAME" ]; then + if [ "$DISCORD_USERNAME" ]; then _data="$_data, \"username\": \"$DISCORD_USERNAME\" " fi - if [ -n "$DISCORD_AVATAR_URL" ]; then + if [ "$DISCORD_AVATAR_URL" ]; then _data="$_data, \"avatar_url\": \"$DISCORD_AVATAR_URL\" " fi _data="$_data}" From 97a45e3b02e6cfefddbc7cda69febce967952b65 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 20 Mar 2022 12:43:23 +0800 Subject: [PATCH 14/91] Update discord.sh --- notify/discord.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/discord.sh b/notify/discord.sh index 8df42e15..58362a4e 100644 --- a/notify/discord.sh +++ b/notify/discord.sh @@ -46,7 +46,7 @@ discord_send() { if _post "$_data" "$DISCORD_WEBHOOK_URL?wait=true"; then # shellcheck disable=SC2154 - if [ -n "$response" ]; then + if [ "$response" ]; then _info "discord send success." return 0 fi From 7278fd25e54cc828b5bcf164d6e45e1c72ef5be2 Mon Sep 17 00:00:00 2001 From: Timur Umarov Date: Sun, 20 Mar 2022 21:50:39 +0300 Subject: [PATCH 15/91] Added fornex.com api --- dnsapi/dns_fornex.sh | 145 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 dnsapi/dns_fornex.sh diff --git a/dnsapi/dns_fornex.sh b/dnsapi/dns_fornex.sh new file mode 100644 index 00000000..80fb68e9 --- /dev/null +++ b/dnsapi/dns_fornex.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env sh + +#Author: Timur Umarov + +FORNEX_API_URL="https://fornex.com/api/dns/v0.1" + +######## Public functions ##################### + +#Usage: dns_fornex_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_fornex_add() { + fulldomain=$1 + txtvalue=$2 + + if ! _Fornex_API; then + return 1 + fi + + if ! _get_root "$fulldomain"; then + _err "Unable to determine root domain" + return 1 + else + _debug _domain "$_domain" + fi + + _info "Adding record" + if _rest POST "$_domain/entry_set/add/" "host=$fulldomain&type=TXT&value=$txtvalue&apikey=$FORNEX_API_KEY"; then + _debug _response "$response" + if _contains "$response" '"ok": true' || _contains "$response" 'Такая запись уже существует.'; then + _info "Added, OK" + return 0 + fi + fi + _err "Add txt record error." + return 1 +} + +#Usage: dns_fornex_rm _acme-challenge.www.domain.com +dns_fornex_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! _Fornex_API; then + return 1 + fi + + if ! _get_root "$fulldomain"; then + _err "Unable to determine root domain" + return 1 + else + _debug _domain "$_domain" + fi + + _debug "Getting txt records" + _rest GET "$_domain/entry_set.json?apikey=$FORNEX_API_KEY" + + if ! _contains "$response" "$txtvalue"; then + _err "Txt record not found" + return 1 + fi + + _record_id="$(echo "$response" | _egrep_o "{[^{]*\"value\"*:*\"$txtvalue\"[^}]*}" | sed -n -e 's#.*"id": \([0-9]*\).*#\1#p')" + _debug "_record_id" "$_record_id" + if [ -z "$_record_id" ]; then + _err "can not find _record_id" + return 1 + fi + + if ! _rest POST "$_domain/entry_set/$_record_id/delete/" "apikey=$FORNEX_API_KEY"; then + _err "Delete record error." + return 1 + fi + return 0 +} + +#################### Private functions below ################################## + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + + i=2 + 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 ! _rest GET "domain_list.json?q=$h&apikey=$FORNEX_API_KEY"; then + return 1 + fi + + if _contains "$response" "\"$h\"" >/dev/null; then + _domain=$h + return 0 + else + _debug "$h not found" + fi + i=$(_math "$i" + 1) + done + + return 1 +} + +_Fornex_API() { + if [ -z "$FORNEX_API_KEY" ]; then + FORNEX_API_KEY="" + + _err "You didn't specify the Fornex API key yet." + _err "Please create your key and try again." + + return 1 + fi + + _saveaccountconf FORNEX_API_KEY "$FORNEX_API_KEY" +} + +#method method action data +_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + export _H1="Accept: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$FORNEX_API_URL/$ep" "" "$m")" + else + response="$(_get "$FORNEX_API_URL/$ep" | _normalizeJson)" + fi + + _ret="$?" + if [ "$_ret" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From a300df0020847fea6e978ff653e9f537399b4be3 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 25 Mar 2022 15:48:17 +0800 Subject: [PATCH 16/91] Update dns_fornex.sh --- dnsapi/dns_fornex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_fornex.sh b/dnsapi/dns_fornex.sh index 80fb68e9..1910f332 100644 --- a/dnsapi/dns_fornex.sh +++ b/dnsapi/dns_fornex.sh @@ -81,7 +81,7 @@ dns_fornex_rm() { _get_root() { domain=$1 - i=2 + i=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug h "$h" From 0d05f9ba800b94b455d3d57954b5f24db84da709 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 27 Mar 2022 12:08:24 +0800 Subject: [PATCH 17/91] Update acme.sh fix https://github.com/acmesh-official/acme.sh/issues/4001 --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 55fa4467..b4cf3e63 100755 --- a/acme.sh +++ b/acme.sh @@ -1845,7 +1845,9 @@ _inithttp() { _ACME_WGET="$_ACME_WGET --max-redirect 0 " fi if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then - _ACME_WGET="$_ACME_WGET -d " + if [ "$_ACME_WGET" ] && _contains "$($_ACME_WGET --help 2>&1)" "--debug"; then + _ACME_WGET="$_ACME_WGET -d " + fi fi if [ "$CA_PATH" ]; then _ACME_WGET="$_ACME_WGET --ca-directory=$CA_PATH " From fb5091a388c6cb4280cd095ab74056697be21a54 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 30 Mar 2022 22:47:12 +0800 Subject: [PATCH 18/91] support Google ACME server see: https://github.com/acmesh-official/acme.sh/wiki/Server --- acme.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index b4cf3e63..c68ff7a9 100755 --- a/acme.sh +++ b/acme.sh @@ -34,6 +34,9 @@ _ZERO_EAB_ENDPOINT="https://api.zerossl.com/acme/eab-credentials-email" CA_SSLCOM_RSA="https://acme.ssl.com/sslcom-dv-rsa" CA_SSLCOM_ECC="https://acme.ssl.com/sslcom-dv-ecc" +CA_GOOGLE="https://dv.acme-v02.api.pki.goog/directory" +CA_GOOGLE_TEST="https://dv.acme-v02.test-api.pki.goog/directory" + DEFAULT_CA=$CA_ZEROSSL DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST @@ -44,9 +47,11 @@ LetsEncrypt.org_test,letsencrypt_test,letsencrypttest BuyPass.com,buypass BuyPass.com_test,buypass_test,buypasstest SSL.com,sslcom +Google.com,google +Google.com_test,googletest,google_test " -CA_SERVERS="$CA_ZEROSSL,$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_SSLCOM_RSA" +CA_SERVERS="$CA_ZEROSSL,$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_SSLCOM_RSA,$CA_GOOGLE,$CA_GOOGLE_TEST" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" From 3fb67629c13b96a57717471a9e257a7ffe7cc40b Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 30 Mar 2022 23:06:07 +0800 Subject: [PATCH 19/91] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 91a18985..097dd7a8 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ https://github.com/acmesh-official/acmetest - Letsencrypt.org CA - [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA) - [SSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/SSL.com-CA) +- [Google.com Public CA](https://github.com/acmesh-official/acme.sh/wiki/Google-public-CA) - [Pebble strict Mode](https://github.com/letsencrypt/pebble) - Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA From 532e44bceae38ba37634ac5331bfda740a84381f Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 30 Mar 2022 23:37:38 +0800 Subject: [PATCH 20/91] normalize domains fix https://github.com/acmesh-official/acme.sh/issues/4005 --- acme.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index c68ff7a9..5566074f 100755 --- a/acme.sh +++ b/acme.sh @@ -4263,7 +4263,13 @@ issue() { _debug _saved_domain "$_saved_domain" _saved_alt=$(_readdomainconf Le_Alt) _debug _saved_alt "$_saved_alt" - if [ "$_saved_domain,$_saved_alt" = "$_main_domain,$_alt_domains" ]; then + _normized_saved_domains="$(echo "$_saved_domain,$_saved_alt" | tr "," "\n" | sort | tr '\n' ',')" + _debug _normized_saved_domains "$_normized_saved_domains" + + _normized_domains="$(echo "$_main_domain,$_alt_domains" | tr "," "\n" | sort | tr '\n' ',')" + _debug _normized_domains "$_normized_domains" + + if [ "$_normized_saved_domains" = "$_normized_domains" ]; then _info "Domains not changed." _info "Skip, Next renewal time is: $(__green "$(_readdomainconf Le_NextRenewTimeStr)")" _info "Add '$(__red '--force')' to force to renew." From d53262fab68ae24c44e572840e166a8e1cbfd8ab Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 31 Mar 2022 09:35:32 +0800 Subject: [PATCH 21/91] fix update account fix https://github.com/acmesh-official/acme.sh/issues/4009 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 5566074f..3860c301 100755 --- a/acme.sh +++ b/acme.sh @@ -3758,7 +3758,7 @@ updateaccount() { _email="$(_getAccountEmail)" - if [ "$ACCOUNT_EMAIL" ]; then + if [ "$_email" ]; then updjson='{"contact": ["mailto:'$_email'"]}' else updjson='{"contact": []}' From bcc984fc09ef319b0da74e02e0edc681dab2c866 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 31 Mar 2022 09:46:42 +0800 Subject: [PATCH 22/91] minor --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 097dd7a8..4a12d46a 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ https://github.com/acmesh-official/acmetest - Letsencrypt.org CA - [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA) - [SSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/SSL.com-CA) -- [Google.com Public CA](https://github.com/acmesh-official/acme.sh/wiki/Google-public-CA) +- [Google.com Public CA](https://github.com/acmesh-official/acme.sh/wiki/Google-Public-CA) - [Pebble strict Mode](https://github.com/letsencrypt/pebble) - Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA From de4c4eedd835f7235dd20c3f127ef8da76273e31 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 1 Apr 2022 21:22:42 +0800 Subject: [PATCH 23/91] Support NotBefore and NotAfter Add `--valid-from` and `--valid-to`: https://github.com/acmesh-official/acme.sh/wiki/Validity --- acme.sh | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 123 insertions(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index 3860c301..665dc022 100755 --- a/acme.sh +++ b/acme.sh @@ -177,6 +177,8 @@ _SERVER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Server" _PREFERRED_CHAIN_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain" +_VALIDITY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Validity" + _DNSCHECK_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dnscheck" _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." @@ -1603,12 +1605,12 @@ _durl_replace_base64() { _time2str() { #BSD - if date -u -r "$1" 2>/dev/null; then + if date -u -r "$1" -j "+%Y-%m-%dT%H:%M:%SZ" 2>/dev/null; then return fi #Linux - if date -u -d@"$1" 2>/dev/null; then + if date -u --date=@"$1" "+%Y-%m-%dT%H:%M:%SZ" 2>/dev/null; then return fi @@ -1619,7 +1621,7 @@ _time2str() { fi #Busybox - if echo "$1" | awk '{ print strftime("%c", $0); }' 2>/dev/null; then + if echo "$1" | awk '{ print strftime("%Y-%m-%dT%H:%M:%SZ", $0); }' 2>/dev/null; then return fi } @@ -1778,6 +1780,22 @@ _time() { date -u "+%s" } +#support 2 formats: +# 2022-04-01 08:10:33 to 1648800633 +#or 2022-04-01T08:10:33Z to 1648800633 +_date2time() { + #Linux + if date -u -d "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then + return + fi + #Mac/BSD + if date -u -j -f "%Y-%m-%d %H:%M:%S" "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then + return + fi + _err "Can not parse _date2time $1" + return 1 +} + _utc_date() { date -u "+%Y-%m-%d %H:%M:%S" } @@ -3768,7 +3786,7 @@ updateaccount() { if [ "$code" = '200' ]; then echo "$response" >"$ACCOUNT_JSON_PATH" - _info "account update success for $_accUri." + _info "Account update success for $_accUri." else _info "Error. The account was not updated." return 1 @@ -4207,6 +4225,40 @@ _getIdType() { fi } +# beginTime dateTo +# beginTime is full string format("2022-04-01T08:10:33Z"), beginTime can be empty, to use current time +# dateTo can be ether in full string format("2022-04-01T08:10:33Z") or in delta format(+5d or +20h) +_convertValidaty() { + _beginTime="$1" + _dateTo="$2" + _debug2 "_beginTime" "$_beginTime" + _debug2 "_dateTo" "$_dateTo" + + if _startswith "$_dateTo" "+"; then + _v_begin=$(_time) + if [ "$_beginTime" ]; then + _v_begin="$(_date2time "$_beginTime")" + fi + _debug2 "_v_begin" "$_v_begin" + if _endswith "$_dateTo" "h"; then + _v_end=$(_math "$_v_begin + 60 * 60 * $(echo "$_dateTo" | tr -d '+h')") + elif _endswith "$_dateTo" "d"; then + _v_end=$(_math "$_v_begin + 60 * 60 * 24 * $(echo "$_dateTo" | tr -d '+d')") + else + _err "Not recognized format for _dateTo: $_dateTo" + return 1 + fi + _debug2 "_v_end" "$_v_end" + _time2str "$_v_end" + else + if [ "$(_time)" -gt "$(_date2time "$_dateTo")" ]; then + _err "The validaty to is in the past: _dateTo = $_dateTo" + return 1 + fi + echo "$_dateTo" + fi +} + #webroot, domain domainlist keylength issue() { if [ -z "$2" ]; then @@ -4240,6 +4292,8 @@ issue() { _local_addr="${13}" _challenge_alias="${14}" _preferred_chain="${15}" + _valid_from="${16}" + _valid_to="${17}" if [ -z "$_ACME_IS_RENEW" ]; then _initpath "$_main_domain" "$_key_length" @@ -4381,12 +4435,52 @@ issue() { _identifiers="$_identifiers,{\"type\":\"$(_getIdType "$d")\",\"value\":\"$(_idn "$d")\"}" done _debug2 _identifiers "$_identifiers" - if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then + _notBefore="" + _notAfter="" + + if [ "$_valid_from" ]; then + _savedomainconf "Le_Valid_From" "$_valid_from" + _debug2 "_valid_from" "$_valid_from" + _notBefore="$(_convertValidaty "" "$_valid_from")" + if [ "$?" != "0" ]; then + _err "Can not parse _valid_from: $_valid_from" + return 1 + fi + if [ "$(_time)" -gt "$(_date2time "$_notBefore")" ]; then + _notBefore="" + fi + else + _cleardomainconf "Le_Valid_From" + fi + _debug2 _notBefore "$_notBefore" + + if [ "$_valid_to" ]; then + _debug2 "_valid_to" "$_valid_to" + _savedomainconf "Le_Valid_To" "$_valid_to" + _notAfter="$(_convertValidaty "$_notBefore" "$_valid_to")" + if [ "$?" != "0" ]; then + _err "Can not parse _valid_to: $_valid_to" + return 1 + fi + else + _cleardomainconf "Le_Valid_To" + fi + _debug2 "_notAfter" "$_notAfter" + + _newOrderObj="{\"identifiers\": [$_identifiers]" + if [ "$_notBefore" ]; then + _newOrderObj="$_newOrderObj,\"notBefore\": \"$_notBefore\"" + fi + if [ "$_notAfter" ]; then + _newOrderObj="$_newOrderObj,\"notAfter\": \"$_notAfter\"" + fi + if ! _send_signed_request "$ACME_NEW_ORDER" "$_newOrderObj}"; then _err "Create new order error." _clearup _on_issue_err "$_post_hook" return 1 fi + Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n " | cut -d ":" -f 2-)" _debug Le_LinkOrder "$Le_LinkOrder" Le_OrderFinalize="$(echo "$response" | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4)" @@ -5086,13 +5180,15 @@ $_authorizations_map" else _cleardomainconf Le_ForceNewDomainKey fi - - Le_NextRenewTime=$(_math "$Le_CertCreateTime" + "$Le_RenewalDays" \* 24 \* 60 \* 60) - - Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime") + if [ "$_notAfter" ]; then + Le_NextRenewTime=$(_date2time "$_notAfter") + Le_NextRenewTimeStr="$_notAfter" + else + Le_NextRenewTime=$(_math "$Le_CertCreateTime" + "$Le_RenewalDays" \* 24 \* 60 \* 60) + Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime") + Le_NextRenewTime=$(_math "$Le_NextRenewTime" - 86400) + fi _savedomainconf "Le_NextRenewTimeStr" "$Le_NextRenewTimeStr" - - Le_NextRenewTime=$(_math "$Le_NextRenewTime" - 86400) _savedomainconf "Le_NextRenewTime" "$Le_NextRenewTime" if [ "$_real_cert$_real_key$_real_ca$_reload_cmd$_real_fullchain" ]; then @@ -6629,6 +6725,11 @@ Parameters: If no match, the default offered chain will be used. (default: empty) See: $_PREFERRED_CHAIN_WIKI + --valid-to Request the NotAfter field of the cert. + See: $_VALIDITY_WIKI + --valid-from Request the NotBefore field of the cert. + See: $_VALIDITY_WIKI + -f, --force Force install, force cert renewal or override sudo restrictions. --staging, --test Use staging server, for testing. --debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted. @@ -6989,6 +7090,8 @@ _process() { _eab_kid="" _eab_hmac_key="" _preferred_chain="" + _valid_from="" + _valid_to="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -7296,6 +7399,14 @@ _process() { Le_RenewalDays="$_days" shift ;; + --valid-from) + _valid_from="$2" + shift + ;; + --valid-to) + _valid_to="$2" + shift + ;; --httpport) _httpport="$2" Le_HTTPPort="$_httpport" @@ -7557,7 +7668,7 @@ _process() { uninstall) uninstall "$_nocron" ;; upgrade) upgrade ;; issue) - issue "$_webroot" "$_domain" "$_altdomains" "$_keylength" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" + issue "$_webroot" "$_domain" "$_altdomains" "$_keylength" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" "$_valid_from" "$_valid_to" ;; deploy) deploy "$_domain" "$_deploy_hook" "$_ecc" From b49999721c6897730cf48f8688cc14f294893a58 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 1 Apr 2022 21:58:29 +0800 Subject: [PATCH 24/91] Update acme.sh --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 665dc022..4b4c7af9 100755 --- a/acme.sh +++ b/acme.sh @@ -1789,7 +1789,7 @@ _date2time() { return fi #Mac/BSD - if date -u -j -f "%Y-%m-%d %H:%M:%S" "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then + if date -u -j -f "%Y-%m-%d %H:%M:%S" "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then return fi _err "Can not parse _date2time $1" From 0f607413d08a3e067a4852b27faf096d846854bf Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 3 Apr 2022 20:05:30 +0800 Subject: [PATCH 26/91] fix for solaris time format --- acme.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 4b4c7af9..c4ca029f 100755 --- a/acme.sh +++ b/acme.sh @@ -1615,9 +1615,8 @@ _time2str() { fi #Solaris - if _exists adb; then - _t_s_a=$(echo "0t${1}=Y" | adb) - echo "$_t_s_a" + if printf "%(%Y-%m-%dT%H:%M:%SZ)T\n" $1 2>/dev/null; then + return fi #Busybox @@ -1788,6 +1787,11 @@ _date2time() { if date -u -d "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then return fi + + #Solaris + if gdate -u -d "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then + return + fi #Mac/BSD if date -u -j -f "%Y-%m-%d %H:%M:%S" "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then return From 225adcc83698cbd8a6de9580b64a7daa725db062 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 3 Apr 2022 21:58:41 +0800 Subject: [PATCH 27/91] fix renewal for validto fix renewal for validto --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index c4ca029f..25e7ad20 100755 --- a/acme.sh +++ b/acme.sh @@ -5293,7 +5293,7 @@ renew() { Le_PostHook="$(_readdomainconf Le_PostHook)" Le_RenewHook="$(_readdomainconf Le_RenewHook)" Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)" - issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" "$Le_Preferred_Chain" + issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" "$Le_Preferred_Chain" "$Le_Valid_From" "$Le_Valid_To" res="$?" if [ "$res" != "0" ]; then return "$res" From 6a90856f0eac62f5e5d7d2d0f791edebdde1496a Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 5 Apr 2022 17:05:33 +0800 Subject: [PATCH 28/91] don't renew cert if valid-to is set to an absolute date don't renew cert if valid-to is set to an absolute date --- acme.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/acme.sh b/acme.sh index 25e7ad20..fe390659 100755 --- a/acme.sh +++ b/acme.sh @@ -4317,6 +4317,13 @@ issue() { Le_NextRenewTime=$(_readdomainconf Le_NextRenewTime) _debug Le_NextRenewTime "$Le_NextRenewTime" if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then + _valid_to_saved=$(_readdomainconf Le_Valid_to) + if [ "$_valid_to_saved" ] && ! _startswith "$_valid_to_saved" "+"; then + _info "The domain is set to be valid to: $_valid_to_saved" + _info "It can not be renewed automatically" + _info "See: $_VALIDITY_WIKI" + return $RENEW_SKIP + fi _saved_domain=$(_readdomainconf Le_Domain) _debug _saved_domain "$_saved_domain" _saved_alt=$(_readdomainconf Le_Alt) @@ -5187,6 +5194,11 @@ $_authorizations_map" if [ "$_notAfter" ]; then Le_NextRenewTime=$(_date2time "$_notAfter") Le_NextRenewTimeStr="$_notAfter" + if [ "$_valid_to" ] && ! _startswith "$_valid_to" "+"; then + _info "The domain is set to be valid to: $_valid_to" + _info "It can not be renewed automatically" + _info "See: $_VALIDITY_WIKI" + fi else Le_NextRenewTime=$(_math "$Le_CertCreateTime" + "$Le_RenewalDays" \* 24 \* 60 \* 60) Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime") From 481f02de88208c6066426a23cadf0d5cf786d929 Mon Sep 17 00:00:00 2001 From: Kevin Brown Date: Wed, 6 Apr 2022 14:29:25 +1000 Subject: [PATCH 29/91] Also check for the closing quote so that only exact domain matches are found. --- dnsapi/dns_netlify.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh index 2ce13e2b..65e803c5 100644 --- a/dnsapi/dns_netlify.sh +++ b/dnsapi/dns_netlify.sh @@ -114,7 +114,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\"" >/dev/null; then - _domain_id=$(echo "$response" | _egrep_o "\"[^\"]*\",\"name\":\"$h" | cut -d , -f 1 | tr -d \") + _domain_id=$(echo "$response" | _egrep_o "\"[^\"]*\",\"name\":\"$h\"" | cut -d , -f 1 | tr -d \") if [ "$_domain_id" ]; then if [ "$i" = 1 ]; then #create the record at the domain apex (@) if only the domain name was provided as --domain-alias From 40e7eca1eedab8d89df6a301533085f591dce659 Mon Sep 17 00:00:00 2001 From: hyper_ch Date: Thu, 7 Apr 2022 11:07:06 +0200 Subject: [PATCH 30/91] dns_ispconfig: adding missing brackets --- dnsapi/dns_ispconfig.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index e68ddd49..6f0e920f 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -32,7 +32,7 @@ dns_ispconfig_rm() { #################### Private functions below ################################## _ISPC_credentials() { - if [ -z "${ISPC_User}" ] || [ -z "$ISPC_Password" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then + if [ -z "${ISPC_User}" ] || [ -z "${ISPC_Password}" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then ISPC_User="" ISPC_Password="" ISPC_Api="" From 439defca429fa53c163058d26df9d8443f24f024 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 8 Apr 2022 22:15:26 +0800 Subject: [PATCH 31/91] switch from staging api to production api https://github.com/acmesh-official/acme.sh/issues/2401 --- acme.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/acme.sh b/acme.sh index fe390659..273d399f 100755 --- a/acme.sh +++ b/acme.sh @@ -5270,6 +5270,23 @@ renew() { Le_API="$CA_LETSENCRYPT_V2" fi + #revert from staging CAs back to production CAs + case "$Le_API" in + + "$CA_LETSENCRYPT_V2_TEST") + _info "Switching back to $CA_LETSENCRYPT_V2" + Le_API="$CA_LETSENCRYPT_V2" + ;; + "$CA_BUYPASS_TEST") + _info "Switching back to $CA_BUYPASS" + Le_API="$CA_BUYPASS" + ;; + "$CA_GOOGLE_TEST") + _info "Switching back to $CA_GOOGLE" + Le_API="$CA_GOOGLE" + ;; + esac + if [ "$Le_API" ]; then if [ "$Le_API" != "$ACME_DIRECTORY" ]; then _clearAPI From 6be2bb228958f12ccae4bb7cca5aacc90d009cf4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 8 Apr 2022 22:28:21 +0800 Subject: [PATCH 32/91] Update acme.sh revert only when there is no `--server` specified. --- acme.sh | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/acme.sh b/acme.sh index 273d399f..49a1b0f1 100755 --- a/acme.sh +++ b/acme.sh @@ -5271,21 +5271,23 @@ renew() { fi #revert from staging CAs back to production CAs - case "$Le_API" in + if [ -z "$ACME_DIRECTORY" ]; then + case "$Le_API" in - "$CA_LETSENCRYPT_V2_TEST") - _info "Switching back to $CA_LETSENCRYPT_V2" - Le_API="$CA_LETSENCRYPT_V2" - ;; - "$CA_BUYPASS_TEST") - _info "Switching back to $CA_BUYPASS" - Le_API="$CA_BUYPASS" - ;; - "$CA_GOOGLE_TEST") - _info "Switching back to $CA_GOOGLE" - Le_API="$CA_GOOGLE" - ;; - esac + "$CA_LETSENCRYPT_V2_TEST") + _info "Switching back to $CA_LETSENCRYPT_V2" + Le_API="$CA_LETSENCRYPT_V2" + ;; + "$CA_BUYPASS_TEST") + _info "Switching back to $CA_BUYPASS" + Le_API="$CA_BUYPASS" + ;; + "$CA_GOOGLE_TEST") + _info "Switching back to $CA_GOOGLE" + Le_API="$CA_GOOGLE" + ;; + esac + fi if [ "$Le_API" ]; then if [ "$Le_API" != "$ACME_DIRECTORY" ]; then From 7cd6ff054bfbaf313d9b07b005a2f6592ed34a7a Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 10 Apr 2022 14:48:10 +0800 Subject: [PATCH 33/91] add --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 24be2c47..8905a651 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -3,7 +3,7 @@ github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: acmesh -ko_fi: # Replace with a single Ko-fi username +ko_fi: neilpang tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username From 00483e8cdd40593bd47c9c045ae725c928b70e4c Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 10 Apr 2022 19:42:49 +0800 Subject: [PATCH 34/91] exclude zerossl tests in the CI It's not stable --- .github/workflows/FreeBSD.yml | 10 +++++----- .github/workflows/MacOS.yml | 10 +++++----- .github/workflows/Solaris.yml | 10 +++++----- .github/workflows/Windows.yml | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 5d032769..22f8b9af 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -25,11 +25,11 @@ jobs: CA: "" CA_EMAIL: "" TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 - - TEST_ACME_Server: "ZeroSSL.com" - CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - CA: "ZeroSSL RSA Domain Secure Site CA" - CA_EMAIL: "githubtest@acme.sh" - TEST_PREFERRED_CHAIN: "" + #- TEST_ACME_Server: "ZeroSSL.com" + # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + # CA: "ZeroSSL RSA Domain Secure Site CA" + # CA_EMAIL: "githubtest@acme.sh" + # TEST_PREFERRED_CHAIN: "" runs-on: macos-10.15 env: TEST_LOCAL: 1 diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index 4b529f6a..8d52b3f6 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -25,11 +25,11 @@ jobs: CA: "" CA_EMAIL: "" TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 - - TEST_ACME_Server: "ZeroSSL.com" - CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - CA: "ZeroSSL RSA Domain Secure Site CA" - CA_EMAIL: "githubtest@acme.sh" - TEST_PREFERRED_CHAIN: "" + #- TEST_ACME_Server: "ZeroSSL.com" + # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + # CA: "ZeroSSL RSA Domain Secure Site CA" + # CA_EMAIL: "githubtest@acme.sh" + # TEST_PREFERRED_CHAIN: "" runs-on: macos-latest env: TEST_LOCAL: 1 diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 77fdcc9a..f8a3826c 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -25,11 +25,11 @@ jobs: CA: "" CA_EMAIL: "" TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 - - TEST_ACME_Server: "ZeroSSL.com" - CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - CA: "ZeroSSL RSA Domain Secure Site CA" - CA_EMAIL: "githubtest@acme.sh" - TEST_PREFERRED_CHAIN: "" + #- TEST_ACME_Server: "ZeroSSL.com" + # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + # CA: "ZeroSSL RSA Domain Secure Site CA" + # CA_EMAIL: "githubtest@acme.sh" + # TEST_PREFERRED_CHAIN: "" runs-on: macos-10.15 env: TEST_LOCAL: 1 diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 2d7eeeae..55d32519 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -25,11 +25,11 @@ jobs: CA: "" CA_EMAIL: "" TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 - - TEST_ACME_Server: "ZeroSSL.com" - CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - CA: "ZeroSSL RSA Domain Secure Site CA" - CA_EMAIL: "githubtest@acme.sh" - TEST_PREFERRED_CHAIN: "" + #- TEST_ACME_Server: "ZeroSSL.com" + # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + # CA: "ZeroSSL RSA Domain Secure Site CA" + # CA_EMAIL: "githubtest@acme.sh" + # TEST_PREFERRED_CHAIN: "" runs-on: windows-latest env: TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} From 29e23ac9ce5e90039a00dd55ec273cb82855ad9c Mon Sep 17 00:00:00 2001 From: Bruce Lam Date: Sun, 10 Apr 2022 10:41:01 +0800 Subject: [PATCH 35/91] Due to down of cloudxns.net, remove `dns_cx.sh` --- dnsapi/dns_cx.sh | 185 ----------------------------------------------- 1 file changed, 185 deletions(-) delete mode 100755 dnsapi/dns_cx.sh diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh deleted file mode 100755 index c287d507..00000000 --- a/dnsapi/dns_cx.sh +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# CloudXNS Domain api -# -#CX_Key="1234" -# -#CX_Secret="sADDsdasdgdsf" - -CX_Api="https://www.cloudxns.net/api2" - -#REST_API -######## Public functions ##################### - -#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_cx_add() { - fulldomain=$1 - txtvalue=$2 - - CX_Key="${CX_Key:-$(_readaccountconf_mutable CX_Key)}" - CX_Secret="${CX_Secret:-$(_readaccountconf_mutable CX_Secret)}" - if [ -z "$CX_Key" ] || [ -z "$CX_Secret" ]; then - CX_Key="" - CX_Secret="" - _err "You don't specify cloudxns.net api key or secret yet." - _err "Please create you key and try again." - return 1 - fi - - REST_API="$CX_Api" - - #save the api key and email to the account conf file. - _saveaccountconf_mutable CX_Key "$CX_Key" - _saveaccountconf_mutable CX_Secret "$CX_Secret" - - _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 - fi - - add_record "$_domain" "$_sub_domain" "$txtvalue" -} - -#fulldomain txtvalue -dns_cx_rm() { - fulldomain=$1 - txtvalue=$2 - CX_Key="${CX_Key:-$(_readaccountconf_mutable CX_Key)}" - CX_Secret="${CX_Secret:-$(_readaccountconf_mutable CX_Secret)}" - REST_API="$CX_Api" - if _get_root "$fulldomain"; then - record_id="" - existing_records "$_domain" "$_sub_domain" "$txtvalue" - if [ "$record_id" ]; then - _rest DELETE "record/$record_id/$_domain_id" "{}" - _info "Deleted record ${fulldomain}" - fi - fi -} - -#usage: root sub -#return if the sub record already exists. -#echos the existing records count. -# '0' means doesn't exist -existing_records() { - _debug "Getting txt records" - root=$1 - sub=$2 - if ! _rest GET "record/$_domain_id?:domain_id?host_id=0&offset=0&row_num=100"; then - return 1 - fi - - seg=$(printf "%s\n" "$response" | _egrep_o '"record_id":[^{]*host":"'"$_sub_domain"'"[^}]*\}') - _debug seg "$seg" - if [ -z "$seg" ]; then - return 0 - fi - - if printf "%s" "$response" | grep '"type":"TXT"' >/dev/null; then - record_id=$(printf "%s\n" "$seg" | _egrep_o '"record_id":"[^"]*"' | cut -d : -f 2 | tr -d \" | _head_n 1) - _debug record_id "$record_id" - return 0 - fi - -} - -#add the txt record. -#usage: root sub txtvalue -add_record() { - root=$1 - sub=$2 - txtvalue=$3 - fulldomain="$sub.$root" - - _info "Adding record" - - if ! _rest POST "record" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}"; then - return 1 - fi - - return 0 -} - -#################### Private functions below ################################## -#_acme-challenge.www.domain.com -#returns -# _sub_domain=_acme-challenge.www -# _domain=domain.com -# _domain_id=sdjkglgdfewsdfg -_get_root() { - domain=$1 - i=2 - p=1 - - if ! _rest GET "domain"; then - return 1 - fi - - 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 _contains "$response" "$h."; then - seg=$(printf "%s\n" "$response" | _egrep_o '"id":[^{]*"'"$h"'."[^}]*}') - _debug seg "$seg" - _domain_id=$(printf "%s\n" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") - _debug _domain_id "$_domain_id" - if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - _debug _sub_domain "$_sub_domain" - _domain="$h" - _debug _domain "$_domain" - return 0 - fi - return 1 - fi - p="$i" - i=$(_math "$i" + 1) - done - return 1 -} - -#Usage: method URI data -_rest() { - m=$1 - ep="$2" - _debug ep "$ep" - url="$REST_API/$ep" - _debug url "$url" - - cdate=$(date -u "+%Y-%m-%d %H:%M:%S UTC") - _debug cdate "$cdate" - - data="$3" - _debug data "$data" - - sec="$CX_Key$url$data$cdate$CX_Secret" - _debug sec "$sec" - hmac=$(printf "%s" "$sec" | _digest md5 hex) - _debug hmac "$hmac" - - export _H1="API-KEY: $CX_Key" - export _H2="API-REQUEST-DATE: $cdate" - export _H3="API-HMAC: $hmac" - export _H4="Content-Type: application/json" - - if [ "$data" ]; then - response="$(_post "$data" "$url" "" "$m")" - else - response="$(_get "$url")" - fi - - if [ "$?" != "0" ]; then - _err "error $ep" - return 1 - fi - _debug2 response "$response" - - _contains "$response" '"code":1' - -} From 201673ca8aabcd4becd90119b3d0118078daedee Mon Sep 17 00:00:00 2001 From: quthla Date: Mon, 11 Apr 2022 00:29:55 +0200 Subject: [PATCH 36/91] Store Mailcow deploy parameters --- deploy/mailcow.sh | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh index c3535e7e..987f358b 100644 --- a/deploy/mailcow.sh +++ b/deploy/mailcow.sh @@ -20,18 +20,26 @@ mailcow_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _mailcow_path="${DEPLOY_MAILCOW_PATH}" + _getdeployconf DEPLOY_MAILCOW_PATH + _getdeployconf DEPLOY_MAILCOW_RELOAD - if [ -z "$_mailcow_path" ]; then + _debug DEPLOY_MAILCOW_PATH "$DEPLOY_MAILCOW_PATH" + _debug DEPLOY_MAILCOW_RELOAD "$DEPLOY_MAILCOW_RELOAD" + + if [ -z "$DEPLOY_MAILCOW_PATH" ]; then _err "Mailcow path is not found, please define DEPLOY_MAILCOW_PATH." return 1 fi + _savedeployconf DEPLOY_MAILCOW_PATH "$DEPLOY_MAILCOW_PATH" + + [ -n "$DEPLOY_MAILCOW_RELOAD" ] && _savedeployconf DEPLOY_MAILCOW_RELOAD "$DEPLOY_MAILCOW_RELOAD" + #Tests if _ssl_path is the mailcow root directory. - if [ -f "${_mailcow_path}/generate_config.sh" ]; then - _ssl_path="${_mailcow_path}/data/assets/ssl/" + if [ -f "$DEPLOY_MAILCOW_PATH/generate_config.sh" ]; then + _ssl_path="$DEPLOY_MAILCOW_PATH/data/assets/ssl/" else - _ssl_path="${_mailcow_path}" + _ssl_path="$DEPLOY_MAILCOW_PATH" fi if [ ! -d "$_ssl_path" ]; then @@ -40,10 +48,7 @@ mailcow_deploy() { fi # ECC or RSA - if [ -z "${Le_Keylength}" ]; then - Le_Keylength="" - fi - if _isEccKey "${Le_Keylength}"; then + if _isEccKey "$Le_Keylength"; then _info "ECC key type detected" _cert_name_prefix="ecdsa-" else @@ -63,7 +68,7 @@ mailcow_deploy() { return 1 fi - DEFAULT_MAILCOW_RELOAD="docker restart $(docker ps -qaf name=postfix-mailcow); docker restart $(docker ps -qaf name=nginx-mailcow); docker restart $(docker ps -qaf name=dovecot-mailcow)" + DEFAULT_MAILCOW_RELOAD="docker restart \$(docker ps --quiet --filter name=nginx-mailcow --filter name=dovecot-mailcow)" _reload="${DEPLOY_MAILCOW_RELOAD:-$DEFAULT_MAILCOW_RELOAD}" _info "Run reload: $_reload" From 08ae8cc3cb76e1877464875e26ac4d43af5ffc6b Mon Sep 17 00:00:00 2001 From: quthla Date: Mon, 11 Apr 2022 11:39:21 +0200 Subject: [PATCH 37/91] Fix --- deploy/mailcow.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh index 987f358b..3492cea4 100644 --- a/deploy/mailcow.sh +++ b/deploy/mailcow.sh @@ -32,14 +32,11 @@ mailcow_deploy() { fi _savedeployconf DEPLOY_MAILCOW_PATH "$DEPLOY_MAILCOW_PATH" - [ -n "$DEPLOY_MAILCOW_RELOAD" ] && _savedeployconf DEPLOY_MAILCOW_RELOAD "$DEPLOY_MAILCOW_RELOAD" - #Tests if _ssl_path is the mailcow root directory. + _ssl_path="$DEPLOY_MAILCOW_PATH" if [ -f "$DEPLOY_MAILCOW_PATH/generate_config.sh" ]; then _ssl_path="$DEPLOY_MAILCOW_PATH/data/assets/ssl/" - else - _ssl_path="$DEPLOY_MAILCOW_PATH" fi if [ ! -d "$_ssl_path" ]; then @@ -48,13 +45,15 @@ mailcow_deploy() { fi # ECC or RSA - if _isEccKey "$Le_Keylength"; then + length=$(_readdomainconf Le_Keylength) + if _isEccKey "$length"; then _info "ECC key type detected" _cert_name_prefix="ecdsa-" else _info "RSA key type detected" _cert_name_prefix="" fi + _info "Copying key and cert" _real_key="$_ssl_path/${_cert_name_prefix}key.pem" if ! cat "$_ckey" >"$_real_key"; then From 2b891f7f1db192c4edd6079d97bbd1d7ba9bc17c Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 12 Apr 2022 10:11:05 +0800 Subject: [PATCH 38/91] Update dns_fornex.sh --- dnsapi/dns_fornex.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_fornex.sh b/dnsapi/dns_fornex.sh index 1910f332..53be307a 100644 --- a/dnsapi/dns_fornex.sh +++ b/dnsapi/dns_fornex.sh @@ -107,6 +107,7 @@ _get_root() { } _Fornex_API() { + FORNEX_API_KEY="${FORNEX_API_KEY:-$(_readaccountconf_mutable FORNEX_API_KEY)}" if [ -z "$FORNEX_API_KEY" ]; then FORNEX_API_KEY="" @@ -116,7 +117,7 @@ _Fornex_API() { return 1 fi - _saveaccountconf FORNEX_API_KEY "$FORNEX_API_KEY" + _saveaccountconf_mutable FORNEX_API_KEY "$FORNEX_API_KEY" } #method method action data From 2c28d6b10cb07d86efb63f41a4a4e5f3a65f0232 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 13 Apr 2022 20:20:28 +0800 Subject: [PATCH 39/91] fix for renew server --- acme.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 49a1b0f1..8d8181dc 100755 --- a/acme.sh +++ b/acme.sh @@ -5151,7 +5151,7 @@ $_authorizations_map" Le_CertCreateTime=$(_time) _savedomainconf "Le_CertCreateTime" "$Le_CertCreateTime" - Le_CertCreateTimeStr=$(date -u) + Le_CertCreateTimeStr=$(_time2str "$Le_CertCreateTime") _savedomainconf "Le_CertCreateTimeStr" "$Le_CertCreateTimeStr" if [ -z "$Le_RenewalDays" ] || [ "$Le_RenewalDays" -lt "0" ]; then @@ -5289,11 +5289,10 @@ renew() { esac fi - if [ "$Le_API" ]; then + if [ "$Le_API" ] && [ "$ACME_DIRECTORY" ]; then if [ "$Le_API" != "$ACME_DIRECTORY" ]; then _clearAPI fi - export ACME_DIRECTORY="$Le_API" #reload ca configs ACCOUNT_KEY_PATH="" ACCOUNT_JSON_PATH="" From 03c83097033f4ef5362a3089c9306a1420fc16c8 Mon Sep 17 00:00:00 2001 From: Christopher Cope Date: Wed, 13 Apr 2022 15:41:44 -0400 Subject: [PATCH 40/91] Fix dns_loopia on FreeBSD --- dnsapi/dns_loopia.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index e95d8999..399c7867 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -79,7 +79,7 @@ dns_loopia_rm() { response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" if ! _contains "$response" "OK"; then - err_response=$(echo "$response" | grep -oPm1 "(?<=)[^<]+") + err_response=$(echo "$response" | sed 's/.*\(.*\)<\/string>.*/\1/') _err "Error could not get txt records: $err_response" return 1 fi @@ -148,7 +148,7 @@ _loopia_get_records() { response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" if ! _contains "$response" ""; then - err_response=$(echo "$response" | grep -oPm1 "(?<=)[^<]+") + err_response=$(echo "$response" | sed 's/.*\(.*\)<\/string>.*/\1/') _err "Error: $err_response" return 1 fi @@ -245,7 +245,7 @@ _loopia_add_record() { response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" if ! _contains "$response" "OK"; then - err_response=$(echo "$response" | grep -oPm1 "(?<=)[^<]+") + err_response=$(echo "$response" | sed 's/.*\(.*\)<\/string>.*/\1/') _err "Error: $err_response" return 1 fi @@ -310,7 +310,7 @@ _loopia_add_sub_domain() { response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" if ! _contains "$response" "OK"; then - err_response=$(echo "$response" | grep -oPm1 "(?<=)[^<]+") + err_response=$(echo "$response" | sed 's/.*\(.*\)<\/string>.*/\1/') _err "Error: $err_response" return 1 fi From 515c9e7811bee4bb478b4b783f9d603a350ca23c Mon Sep 17 00:00:00 2001 From: Marcin Konicki Date: Fri, 15 Apr 2022 10:38:45 +0200 Subject: [PATCH 41/91] Fix DNS handling for MyDevil.net MyDevil updated their tool to require y|n confirmation when deleting record. --- dnsapi/dns_mydevil.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_mydevil.sh b/dnsapi/dns_mydevil.sh index 2f398959..953290af 100755 --- a/dnsapi/dns_mydevil.sh +++ b/dnsapi/dns_mydevil.sh @@ -74,7 +74,7 @@ dns_mydevil_rm() { validRecords="^${num}${w}${fulldomain}${w}TXT${w}${any}${txtvalue}$" for id in $(devil dns list "$domain" | tail -n+2 | grep "${validRecords}" | cut -w -s -f 1); do _info "Removing record $id from domain $domain" - devil dns del "$domain" "$id" || _err "Could not remove DNS record." + echo "y" | devil dns del "$domain" "$id" || _err "Could not remove DNS record." done } @@ -87,7 +87,9 @@ mydevil_get_domain() { domain="" for domain in $(devil dns list | cut -w -s -f 1 | tail -n+2); do + _debug "Checking domain: $domain" if _endswith "$fulldomain" "$domain"; then + _debug "Fulldomain '$fulldomain' matches '$domain'" printf -- "%s" "$domain" return 0 fi From 5e465a298f69ad802a8accb4d22da7d7224b17fc Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Fri, 15 Apr 2022 23:04:10 -0400 Subject: [PATCH 42/91] Update 1984 Hosting's URL --- dnsapi/dns_1984hosting.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index db0cbe15..6accc597 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -42,7 +42,7 @@ dns_1984hosting_add() { _debug "Add TXT record $fulldomain with value '$txtvalue'" value="$(printf '%s' "$txtvalue" | _url_encode)" - url="https://management.1984hosting.com/domains/entry/" + url="https://1984.hosting/domains/entry/" postdata="entry=new" postdata="$postdata&type=TXT" @@ -95,7 +95,7 @@ dns_1984hosting_rm() { _debug _domain "$_domain" _debug "Delete $fulldomain TXT record" - url="https://management.1984hosting.com/domains" + url="https://1984.hosting/domains" if ! _get_zone_id "$url" "$_domain"; then _err "invalid zone" "$_domain" return 1 @@ -138,7 +138,7 @@ _1984hosting_login() { _debug "Login to 1984Hosting as user $One984HOSTING_Username" username=$(printf '%s' "$One984HOSTING_Username" | _url_encode) password=$(printf '%s' "$One984HOSTING_Password" | _url_encode) - url="https://management.1984hosting.com/accounts/checkuserauth/" + url="https://1984.hosting/accounts/checkuserauth/" response="$(_post "username=$username&password=$password&otpkey=" $url)" response="$(echo "$response" | _normalizeJson)" @@ -175,7 +175,7 @@ _check_cookies() { return 1 fi - _authget "https://management.1984hosting.com/accounts/loginstatus/" + _authget "https://1984.hosting/accounts/loginstatus/" if _contains "$response" '"ok": true'; then _debug "Cached cookies still valid" return 0 @@ -204,7 +204,7 @@ _get_root() { return 1 fi - _authget "https://management.1984hosting.com/domains/soacheck/?zone=$h&nameserver=ns0.1984.is." + _authget "https://1984.hosting/domains/soacheck/?zone=$h&nameserver=ns0.1984.is." if _contains "$_response" "serial" && ! _contains "$_response" "null"; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" @@ -251,11 +251,11 @@ _htmlget() { # add extra headers to request _authpost() { - url="https://management.1984hosting.com/domains" + url="https://1984.hosting/domains" _get_zone_id "$url" "$_domain" csrf_header="$(echo "$One984HOSTING_CSRFTOKEN_COOKIE" | _egrep_o "=[^=][0-9a-zA-Z]*" | tr -d "=")" export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE" - export _H2="Referer: https://management.1984hosting.com/domains/$_zone_id" + export _H2="Referer: https://1984.hosting/domains/$_zone_id" export _H3="X-CSRFToken: $csrf_header" _response=$(_post "$1" "$2") } From 3e8d9a1987f84ff42c8d69802983d437de172245 Mon Sep 17 00:00:00 2001 From: Bruce Lam Date: Tue, 19 Apr 2022 20:34:02 +0800 Subject: [PATCH 43/91] added: ipv6 identifier support --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 8d8181dc..358ddff5 100755 --- a/acme.sh +++ b/acme.sh @@ -4530,7 +4530,7 @@ issue() { response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" - _d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2 | tr -d ' "')" + _d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2- | tr -d ' "')" if _contains "$response" "\"wildcard\" *: *true"; then _d="*.$_d" fi From c31027b2841786140cacd5e64e26a805621153d0 Mon Sep 17 00:00:00 2001 From: Sing Yu Chan Date: Sat, 16 Apr 2022 01:39:45 +0800 Subject: [PATCH 44/91] use `sleep infinity` instead `sleep 1` --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index fa11ea8a..049649f6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -65,7 +65,8 @@ RUN for verb in help \ RUN printf "%b" '#!'"/usr/bin/env sh\n \ if [ \"\$1\" = \"daemon\" ]; then \n \ trap \"echo stop && killall crond && exit 0\" SIGTERM SIGINT \n \ - crond && while true; do sleep 1; done;\n \ + crond && sleep infinity &\n \ + wait \n \ else \n \ exec -- \"\$@\"\n \ fi" >/entry.sh && chmod +x /entry.sh From 4d89ce5d5008fc550c5acbc82cab28d9381b4d9d Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 20 Apr 2022 09:14:53 +0800 Subject: [PATCH 45/91] read csr with empty subject https://github.com/acmesh-official/acme.sh/issues/4024 --- acme.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 358ddff5..ad825435 100755 --- a/acme.sh +++ b/acme.sh @@ -5543,10 +5543,13 @@ showcsr() { _initpath _csrsubj=$(_readSubjectFromCSR "$_csrfile") - if [ "$?" != "0" ] || [ -z "$_csrsubj" ]; then + if [ "$?" != "0" ]; then _err "Can not read subject from csr: $_csrfile" return 1 fi + if [ -z "$_csrsubj" ]; then + _info "The Subject is empty" + fi _info "Subject=$_csrsubj" From 019a7bd66b421919dde76175f249fa94aced8651 Mon Sep 17 00:00:00 2001 From: "Hahn Axel (hahn)" Date: Wed, 20 Apr 2022 16:03:36 +0200 Subject: [PATCH 46/91] handle challenge-alias "false" --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index 49a1b0f1..7103f7e4 100755 --- a/acme.sh +++ b/acme.sh @@ -4680,6 +4680,7 @@ $_authorizations_map" _dns_root_d="$(echo "$_dns_root_d" | sed 's/*.//')" fi _d_alias="$(_getfield "$_challenge_alias" "$_alias_index")" + test "$_d_alias" = "false" && _d_alias="" _alias_index="$(_math "$_alias_index" + 1)" _debug "_d_alias" "$_d_alias" if [ "$_d_alias" ]; then From 39bc4177068acb344653f7ccdf4cf967a1ea939e Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 21 Apr 2022 07:02:53 +0800 Subject: [PATCH 47/91] Update acme.sh --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 7103f7e4..7d211c37 100755 --- a/acme.sh +++ b/acme.sh @@ -4680,7 +4680,7 @@ $_authorizations_map" _dns_root_d="$(echo "$_dns_root_d" | sed 's/*.//')" fi _d_alias="$(_getfield "$_challenge_alias" "$_alias_index")" - test "$_d_alias" = "false" && _d_alias="" + test "$_d_alias" = "$NO_VALUE" && _d_alias="" _alias_index="$(_math "$_alias_index" + 1)" _debug "_d_alias" "$_d_alias" if [ "$_d_alias" ]; then From 9b27298d548ab912fe5aa8622165cb815d965712 Mon Sep 17 00:00:00 2001 From: Jakob Aarup Skov Date: Mon, 25 Apr 2022 09:43:38 +0200 Subject: [PATCH 48/91] Removed GratisDNS api --- dnsapi/dns_gdnsdk.sh | 177 ------------------------------------------- 1 file changed, 177 deletions(-) delete mode 100755 dnsapi/dns_gdnsdk.sh diff --git a/dnsapi/dns_gdnsdk.sh b/dnsapi/dns_gdnsdk.sh deleted file mode 100755 index 90842b25..00000000 --- a/dnsapi/dns_gdnsdk.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env sh -#Author: Herman Sletteng -#Report Bugs here: https://github.com/loial/acme.sh -# -# -# Note, gratisdns requires a login first, so the script needs to handle -# temporary cookies. Since acme.sh _get/_post currently don't directly support -# cookies, I've defined wrapper functions _myget/_mypost to set the headers - -GDNSDK_API="https://admin.gratisdns.com" -######## Public functions ##################### -#Usage: dns_gdnsdk_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_gdnsdk_add() { - fulldomain=$1 - txtvalue=$2 - _info "Using gratisdns.dk" - _debug fulldomain "$fulldomain" - _debug txtvalue "$txtvalue" - if ! _gratisdns_login; then - _err "Login failed!" - return 1 - fi - #finding domain zone - if ! _get_domain; then - _err "No matching root domain for $fulldomain found" - return 1 - fi - # adding entry - _info "Adding the entry" - _mypost "action=dns_primary_record_added_txt&user_domain=$_domain&name=$fulldomain&txtdata=$txtvalue&ttl=1" - if _successful_update; then return 0; fi - _err "Couldn't create entry!" - return 1 -} - -#Usage: fulldomain txtvalue -#Remove the txt record after validation. -dns_gdnsdk_rm() { - fulldomain=$1 - txtvalue=$2 - _info "Using gratisdns.dk" - _debug fulldomain "$fulldomain" - _debug txtvalue "$txtvalue" - if ! _gratisdns_login; then - _err "Login failed!" - return 1 - fi - if ! _get_domain; then - _err "No matching root domain for $fulldomain found" - return 1 - fi - _findentry "$fulldomain" "$txtvalue" - if [ -z "$_id" ]; then - _info "Entry doesn't exist, nothing to delete" - return 0 - fi - _debug "Deleting record..." - _mypost "action=dns_primary_delete_txt&user_domain=$_domain&id=$_id" - # removing entry - - if _successful_update; then return 0; fi - _err "Couldn't delete entry!" - return 1 -} - -#################### Private functions below ################################## - -_checkcredentials() { - GDNSDK_Username="${GDNSDK_Username:-$(_readaccountconf_mutable GDNSDK_Username)}" - GDNSDK_Password="${GDNSDK_Password:-$(_readaccountconf_mutable GDNSDK_Password)}" - - if [ -z "$GDNSDK_Username" ] || [ -z "$GDNSDK_Password" ]; then - GDNSDK_Username="" - GDNSDK_Password="" - _err "You haven't specified gratisdns.dk username and password yet." - _err "Please add credentials and try again." - return 1 - fi - #save the credentials to the account conf file. - _saveaccountconf_mutable GDNSDK_Username "$GDNSDK_Username" - _saveaccountconf_mutable GDNSDK_Password "$GDNSDK_Password" - return 0 -} - -_checkcookie() { - GDNSDK_Cookie="${GDNSDK_Cookie:-$(_readaccountconf_mutable GDNSDK_Cookie)}" - if [ -z "$GDNSDK_Cookie" ]; then - _debug "No cached cookie found" - return 1 - fi - _myget "action=" - if (echo "$_result" | grep -q "logmeout"); then - _debug "Cached cookie still valid" - return 0 - fi - _debug "Cached cookie no longer valid" - GDNSDK_Cookie="" - _saveaccountconf_mutable GDNSDK_Cookie "$GDNSDK_Cookie" - return 1 -} - -_gratisdns_login() { - if ! _checkcredentials; then return 1; fi - - if _checkcookie; then - _debug "Already logged in" - return 0 - fi - _debug "Logging into GratisDNS with user $GDNSDK_Username" - - if ! _mypost "login=$GDNSDK_Username&password=$GDNSDK_Password&action=logmein"; then - _err "GratisDNS login failed for user $GDNSDK_Username bad RC from _post" - return 1 - fi - - GDNSDK_Cookie="$(grep -A 15 '302 Found' "$HTTP_HEADER" | _egrep_o 'Cookie: [^;]*' | _head_n 1 | cut -d ' ' -f2)" - - if [ -z "$GDNSDK_Cookie" ]; then - _err "GratisDNS login failed for user $GDNSDK_Username. Check $HTTP_HEADER file" - return 1 - fi - export GDNSDK_Cookie - _saveaccountconf_mutable GDNSDK_Cookie "$GDNSDK_Cookie" - return 0 -} - -_myget() { - #Adds cookie to request - export _H1="Cookie: $GDNSDK_Cookie" - _result=$(_get "$GDNSDK_API?$1") -} -_mypost() { - #Adds cookie to request - export _H1="Cookie: $GDNSDK_Cookie" - _result=$(_post "$1" "$GDNSDK_API") -} - -_get_domain() { - _myget 'action=dns_primarydns' - _domains=$(echo "$_result" | _egrep_o ' domain="[[:alnum:]._-]+' | sed 's/^.*"//') - if [ -z "$_domains" ]; then - _err "Primary domain list not found!" - return 1 - fi - for _domain in $_domains; do - if (_endswith "$fulldomain" "$_domain"); then - _debug "Root domain: $_domain" - return 0 - fi - done - return 1 -} - -_successful_update() { - if (echo "$_result" | grep -q 'table-success'); then return 0; fi - return 1 -} - -_findentry() { - #args $1: fulldomain, $2: txtvalue - #returns id of dns entry, if it exists - _myget "action=dns_primary_changeDNSsetup&user_domain=$_domain" - _debug3 "_result: $_result" - - _tmp_result=$(echo "$_result" | tr -d '\n\r' | _egrep_o "$1\s*$2[^?]*[^&]*&id=[^&]*") - _debug _tmp_result "$_tmp_result" - if [ -z "${_tmp_result:-}" ]; then - _debug "The variable is _tmp_result is not supposed to be empty, there may be something wrong with the script" - fi - - _id=$(echo "$_tmp_result" | sed 's/^.*=//') - if [ -n "$_id" ]; then - _debug "Entry found with _id=$_id" - return 0 - fi - return 1 -} From 14b59142332d4a5753c29707a25654caed307d05 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 28 Apr 2022 18:05:52 +0800 Subject: [PATCH 49/91] fix renew bug --- acme.sh | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/acme.sh b/acme.sh index 74772b8b..a8c38a08 100755 --- a/acme.sh +++ b/acme.sh @@ -4975,7 +4975,7 @@ $_authorizations_map" return 1 fi _debug "sleep 2 secs to verify again" - sleep 2 + _sleep 2 _debug "checking" _send_signed_request "$uri" @@ -5250,7 +5250,8 @@ renew() { fi _isEcc="$2" - + #the server specified from commandline + _acme_server_back="$ACME_DIRECTORY" _initpath "$Le_Domain" "$_isEcc" _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT} _info "$(__green "Renew: '$Le_Domain'")" @@ -5271,25 +5272,28 @@ renew() { Le_API="$CA_LETSENCRYPT_V2" fi - #revert from staging CAs back to production CAs - if [ -z "$ACME_DIRECTORY" ]; then - case "$Le_API" in - - "$CA_LETSENCRYPT_V2_TEST") - _info "Switching back to $CA_LETSENCRYPT_V2" - Le_API="$CA_LETSENCRYPT_V2" - ;; - "$CA_BUYPASS_TEST") - _info "Switching back to $CA_BUYPASS" - Le_API="$CA_BUYPASS" - ;; - "$CA_GOOGLE_TEST") - _info "Switching back to $CA_GOOGLE" - Le_API="$CA_GOOGLE" - ;; - esac + if [ "$_acme_server_back" ]; then + export ACME_DIRECTORY="$_acme_server_back" + else + export ACME_DIRECTORY="$Le_API" fi + case "$Le_API" in + "$CA_LETSENCRYPT_V2_TEST") + _info "Switching back to $CA_LETSENCRYPT_V2" + Le_API="$CA_LETSENCRYPT_V2" + ;; + "$CA_BUYPASS_TEST") + _info "Switching back to $CA_BUYPASS" + Le_API="$CA_BUYPASS" + ;; + "$CA_GOOGLE_TEST") + _info "Switching back to $CA_GOOGLE" + Le_API="$CA_GOOGLE" + ;; + esac + + if [ "$Le_API" ] && [ "$ACME_DIRECTORY" ]; then if [ "$Le_API" != "$ACME_DIRECTORY" ]; then _clearAPI @@ -5298,7 +5302,7 @@ renew() { ACCOUNT_KEY_PATH="" ACCOUNT_JSON_PATH="" CA_CONF="" - _debug3 "initpath again." + _debug2 "initpath again." _initpath "$Le_Domain" "$_isEcc" fi @@ -6959,6 +6963,10 @@ _processAccountConf() { } _checkSudo() { + if [ -z "__INTERACTIVE" ]; then + #don't check if it's not in an interactive shell + return 0 + fi if [ "$SUDO_GID" ] && [ "$SUDO_COMMAND" ] && [ "$SUDO_USER" ] && [ "$SUDO_UID" ]; then if [ "$SUDO_USER" = "root" ] && [ "$SUDO_UID" = "0" ]; then #it's root using sudo, no matter it's using sudo or not, just fine From 69040dd6685edd8c34ad949ef7867646870a4de0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 28 Apr 2022 18:09:26 +0800 Subject: [PATCH 50/91] fix format --- acme.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/acme.sh b/acme.sh index a8c38a08..2a226e77 100755 --- a/acme.sh +++ b/acme.sh @@ -5293,7 +5293,6 @@ renew() { ;; esac - if [ "$Le_API" ] && [ "$ACME_DIRECTORY" ]; then if [ "$Le_API" != "$ACME_DIRECTORY" ]; then _clearAPI From 9b6f7752761d4c0993c844b531aa6823e723734e Mon Sep 17 00:00:00 2001 From: mrakopes Date: Thu, 28 Apr 2022 13:25:22 +0200 Subject: [PATCH 51/91] fix base64 decoding logic for single- ane multi-line encoded string --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 49a1b0f1..34f62afe 100755 --- a/acme.sh +++ b/acme.sh @@ -983,9 +983,9 @@ _base64() { #Usage: multiline _dbase64() { if [ "$1" ]; then - ${ACME_OPENSSL_BIN:-openssl} base64 -d -A - else ${ACME_OPENSSL_BIN:-openssl} base64 -d + else + ${ACME_OPENSSL_BIN:-openssl} base64 -d -A fi } From db83643c1ec04080edc27c136268edc9b537af95 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Thu, 28 Apr 2022 10:57:31 +0200 Subject: [PATCH 52/91] dns_world4you: fix _parse_paket_nr Signed-off-by: Lorenz Stechauner --- dnsapi/dns_world4you.sh | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index fd124754..bcf256ff 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -54,15 +54,14 @@ dns_world4you_add() { if _contains "$res" "successfully"; then return 0 else - msg=$(echo "$res" | tr '\n' '\t' | sed 's/.*

[^\t]*\t *\([^\t]*\)\t.*/\1/') - if _contains "$msg" '^<\!DOCTYPE html>'; then - msg='Unknown error' - fi - _err "Unable to add record: $msg" - if _contains "$msg" '^<\!DOCTYPE html>'; then + msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "]*>[^<]" | sed 's/<[^>]*>\|^\s*//g') + if [ "$msg" = '' ]; then + _err "Unable to add record: Unknown error" echo "$ret" >'error-01.html' echo "$res" >'error-02.html' _err "View error-01.html and error-02.html for debugging" + else + _err "Unable to add record: my.world4you.com: $msg" fi return 1 fi @@ -119,15 +118,14 @@ dns_world4you_rm() { if _contains "$res" "successfully"; then return 0 else - msg=$(echo "$res" | tr '\n' '\t' | sed 's/.*

[^\t]*\t *\([^\t]*\)\t.*/\1/') - if _contains "$msg" '^<\!DOCTYPE html>'; then - msg='Unknown error' - fi - _err "Unable to remove record: $msg" - if _contains "$msg" '^<\!DOCTYPE html>'; then + msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "]*>[^<]" | sed 's/<[^>]*>\|^\s*//g') + if [ "$msg" = '' ]; then + _err "Unable to remove record: Unknown error" echo "$ret" >'error-01.html' echo "$res" >'error-02.html' _err "View error-01.html and error-02.html for debugging" + else + _err "Unable to remove record: my.world4you.com: $msg" fi return 1 fi @@ -199,6 +197,6 @@ _get_paketnr() { TLD="$domain" _debug domain "$domain" RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))") - PAKETNR=$(echo "$form" | grep "data-textfilter=\".* $domain " | _head_n 1 | sed 's/^.* \([0-9]*\) .*$/\1/') + PAKETNR=$(echo "$form" | grep "data-textfilter=\".* $domain " | _tail_n 1 | sed "s|.*$WORLD4YOU_API/\\([0-9]*\\)/.*|\\1|") return 0 } From 24ce7c19914917b4c78c4e49a442f0f40cf258fd Mon Sep 17 00:00:00 2001 From: nicolaspn Date: Mon, 2 May 2022 15:46:49 +0200 Subject: [PATCH 53/91] Add call dns OVH API for refresh domain after delete TXT record --- dnsapi/dns_ovh.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index e65babbd..b382e52f 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -198,6 +198,8 @@ dns_ovh_rm() { if ! _ovh_rest DELETE "domain/zone/$_domain/record/$rid"; then return 1 fi + _ovh_rest POST "domain/zone/$_domain/refresh" + _debug "Refresh:$response" return 0 fi done From 64847afc3ff8cfe214aca7db7f793d96bee95e5e Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 3 May 2022 21:19:29 +0800 Subject: [PATCH 54/91] save the default key length --- acme.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index de472865..6bdd7b7c 100755 --- a/acme.sh +++ b/acme.sh @@ -4382,10 +4382,6 @@ issue() { _alt_domains="" fi - if [ "$_key_length" = "$NO_VALUE" ]; then - _key_length="" - fi - if ! _on_before_issue "$_web_roots" "$_main_domain" "$_alt_domains" "$_pre_hook" "$_local_addr"; then _err "_on_before_issue." return 1 @@ -5327,6 +5323,10 @@ renew() { Le_PostHook="$(_readdomainconf Le_PostHook)" Le_RenewHook="$(_readdomainconf Le_RenewHook)" Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)" + #when renew from an old version, the empty Le_Keylength means 2048 + if [ -z "$Le_Keylength" ]; then + Le_Keylength=2048 + fi issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" "$Le_Preferred_Chain" "$Le_Valid_From" "$Le_Valid_To" res="$?" if [ "$res" != "0" ]; then @@ -7087,8 +7087,8 @@ _process() { _altdomains="$NO_VALUE" _webroot="" _challenge_alias="" - _keylength="" - _accountkeylength="" + _keylength="$DEFAULT_DOMAIN_KEY_LENGTH" + _accountkeylength="$DEFAULT_ACCOUNT_KEY_LENGTH" _cert_file="" _key_file="" _ca_file="" From 7f9074adbf2f2aeba61db36a3233730c4768c033 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 3 May 2022 21:35:26 +0800 Subject: [PATCH 55/91] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 6bdd7b7c..c5985f2e 100755 --- a/acme.sh +++ b/acme.sh @@ -5323,7 +5323,7 @@ renew() { Le_PostHook="$(_readdomainconf Le_PostHook)" Le_RenewHook="$(_readdomainconf Le_RenewHook)" Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)" - #when renew from an old version, the empty Le_Keylength means 2048 + #when renew from an old version, the empty Le_Keylength means 2048 if [ -z "$Le_Keylength" ]; then Le_Keylength=2048 fi From f03098551ecfb26a0fdd0acbb11bee590cd49263 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 4 May 2022 18:44:37 +0800 Subject: [PATCH 56/91] start 3.0.4 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index c5985f2e..eb9ba7ef 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.3 +VER=3.0.4 PROJECT_NAME="acme.sh" From 8d783e8e1f1ced348068a714f1b4576f335b4132 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 6 May 2022 18:04:29 +0800 Subject: [PATCH 57/91] fix https://github.com/acmesh-official/acme.sh/issues/4069 --- acme.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/acme.sh b/acme.sh index eb9ba7ef..b958a02b 100755 --- a/acme.sh +++ b/acme.sh @@ -2691,6 +2691,13 @@ _initAPI() { return 1 } +_clearCA() { + export ACME_DIRECTORY= + export CA_CONF= + export ACCOUNT_KEY_PATH= + export ACCOUNT_JSON_PATH= +} + #[domain] [keylength or isEcc flag] _initpath() { domain="$1" @@ -5357,6 +5364,7 @@ renew() { #renewAll [stopRenewOnError] renewAll() { _initpath + _clearCA _stopRenewOnError="$1" _debug "_stopRenewOnError" "$_stopRenewOnError" _ret="0" From 619bae745b36e885072c7bbf29fb0e08f4577bf3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 9 May 2022 20:08:38 +0800 Subject: [PATCH 58/91] start 3.0.5 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index b958a02b..6e07c023 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.4 +VER=3.0.5 PROJECT_NAME="acme.sh" From 8b7a86bd174ca065fe28042f84205843162fb83f Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 9 May 2022 21:48:31 +0800 Subject: [PATCH 59/91] support "server" for renew and renewall --- acme.sh | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/acme.sh b/acme.sh index 6e07c023..eadcda48 100755 --- a/acme.sh +++ b/acme.sh @@ -5244,17 +5244,18 @@ _split_cert_chain() { fi } -#domain [isEcc] +#domain [isEcc] [server] renew() { Le_Domain="$1" if [ -z "$Le_Domain" ]; then - _usage "Usage: $PROJECT_ENTRY --renew --domain [--ecc]" + _usage "Usage: $PROJECT_ENTRY --renew --domain [--ecc] [--server server]" return 1 fi _isEcc="$2" - #the server specified from commandline - _acme_server_back="$ACME_DIRECTORY" + _renewServer="$3" + _debug "_renewServer" "$_renewServer" + _initpath "$Le_Domain" "$_isEcc" _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT} _info "$(__green "Renew: '$Le_Domain'")" @@ -5269,14 +5270,9 @@ renew() { . "$DOMAIN_CONF" _debug Le_API "$Le_API" - if [ -z "$Le_API" ] || [ "$CA_LETSENCRYPT_V1" = "$Le_API" ]; then - #if this is from an old version, Le_API is empty, - #so, we force to use letsencrypt server - Le_API="$CA_LETSENCRYPT_V2" - fi - if [ "$_acme_server_back" ]; then - export ACME_DIRECTORY="$_acme_server_back" + if [ "$_renewServer" ]; then + export ACME_DIRECTORY="$_renewServer" else export ACME_DIRECTORY="$Le_API" fi @@ -5299,6 +5295,7 @@ renew() { if [ "$Le_API" ] && [ "$ACME_DIRECTORY" ]; then if [ "$Le_API" != "$ACME_DIRECTORY" ]; then _clearAPI + _clearCA fi #reload ca configs ACCOUNT_KEY_PATH="" @@ -5361,12 +5358,16 @@ renew() { return "$res" } -#renewAll [stopRenewOnError] +#renewAll [stopRenewOnError] [server] renewAll() { _initpath _clearCA _stopRenewOnError="$1" _debug "_stopRenewOnError" "$_stopRenewOnError" + + _server="$2" + _debug "_server" "$_server" + _ret="0" _success_msg="" _error_msg="" @@ -5389,7 +5390,7 @@ renewAll() { _isEcc=$(echo "$d" | cut -d "$ECC_SEP" -f 2) d=$(echo "$d" | cut -d "$ECC_SEP" -f 1) fi - renew "$d" "$_isEcc" + renew "$d" "$_isEcc" "$_server" ) rc="$?" _debug "Return code: $rc" @@ -7662,6 +7663,7 @@ _process() { if [ "$_server" ]; then _selectServer "$_server" "${_ecc:-$_keylength}" + _server="$ACME_DIRECTORY" fi if [ "${_CMD}" != "install" ]; then @@ -7736,10 +7738,10 @@ _process() { installcert "$_domain" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_ecc" ;; renew) - renew "$_domain" "$_ecc" + renew "$_domain" "$_ecc" "$_server" ;; renewAll) - renewAll "$_stopRenewOnError" + renewAll "$_stopRenewOnError" "$_server" ;; revoke) revoke "$_domain" "$_ecc" "$_revoke_reason" From 38778f8adca0d016b27ad0f2a2fc367055c90091 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 9 May 2022 22:12:07 +0800 Subject: [PATCH 60/91] fix renew server --- acme.sh | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/acme.sh b/acme.sh index eadcda48..20412f7a 100755 --- a/acme.sh +++ b/acme.sh @@ -20,8 +20,6 @@ _SUB_FOLDER_DEPLOY="deploy" _SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY" -CA_LETSENCRYPT_V1="https://acme-v01.api.letsencrypt.org/directory" - CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory" CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory" @@ -5257,6 +5255,7 @@ renew() { _debug "_renewServer" "$_renewServer" _initpath "$Le_Domain" "$_isEcc" + _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT} _info "$(__green "Renew: '$Le_Domain'")" if [ ! -f "$DOMAIN_CONF" ]; then @@ -5271,12 +5270,6 @@ renew() { . "$DOMAIN_CONF" _debug Le_API "$Le_API" - if [ "$_renewServer" ]; then - export ACME_DIRECTORY="$_renewServer" - else - export ACME_DIRECTORY="$Le_API" - fi - case "$Le_API" in "$CA_LETSENCRYPT_V2_TEST") _info "Switching back to $CA_LETSENCRYPT_V2" @@ -5292,18 +5285,21 @@ renew() { ;; esac - if [ "$Le_API" ] && [ "$ACME_DIRECTORY" ]; then - if [ "$Le_API" != "$ACME_DIRECTORY" ]; then - _clearAPI - _clearCA - fi - #reload ca configs - ACCOUNT_KEY_PATH="" - ACCOUNT_JSON_PATH="" - CA_CONF="" - _debug2 "initpath again." - _initpath "$Le_Domain" "$_isEcc" + if [ "$_server" ]; then + Le_API="$_server" fi + _info "Renew to Le_API=$Le_API" + + export ACME_DIRECTORY="$Le_API" + _clearAPI + _clearCA + + #reload ca configs + ACCOUNT_KEY_PATH="" + ACCOUNT_JSON_PATH="" + CA_CONF="" + _debug2 "initpath again." + _initpath "$Le_Domain" "$_isEcc" if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then _info "Skip, Next renewal time is: $(__green "$Le_NextRenewTimeStr")" From e1d7a6b9acdcd06f928e0fec6e1e36746924cfc6 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 9 May 2022 22:21:07 +0800 Subject: [PATCH 61/91] fix renew server --- acme.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 20412f7a..cd545aa4 100755 --- a/acme.sh +++ b/acme.sh @@ -2690,7 +2690,6 @@ _initAPI() { } _clearCA() { - export ACME_DIRECTORY= export CA_CONF= export ACCOUNT_KEY_PATH= export ACCOUNT_JSON_PATH= @@ -5290,14 +5289,11 @@ renew() { fi _info "Renew to Le_API=$Le_API" - export ACME_DIRECTORY="$Le_API" _clearAPI _clearCA + export ACME_DIRECTORY="$Le_API" #reload ca configs - ACCOUNT_KEY_PATH="" - ACCOUNT_JSON_PATH="" - CA_CONF="" _debug2 "initpath again." _initpath "$Le_Domain" "$_isEcc" From 5b42aea9e77d2f145b2777bb334bb575e77d51f6 Mon Sep 17 00:00:00 2001 From: Sandeep Mittal Date: Thu, 5 May 2022 17:50:29 +0530 Subject: [PATCH 62/91] Create callmebotWhatsApp.sh --- notify/callmebotWhatsApp.sh | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 notify/callmebotWhatsApp.sh diff --git a/notify/callmebotWhatsApp.sh b/notify/callmebotWhatsApp.sh new file mode 100644 index 00000000..a65149ef --- /dev/null +++ b/notify/callmebotWhatsApp.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env sh + +#Support CallMeBot Whatsapp webhooks + +#CallMeBot_Phone_No="" +#CallMeBot_apikey="" +#SLACK_USERNAME="" + +#SLACK_WEBHOOK_URL="" +#SLACK_CHANNEL="" +#SLACK_USERNAME="" + +slack_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + SLACK_WEBHOOK_URL="${SLACK_WEBHOOK_URL:-$(_readaccountconf_mutable SLACK_WEBHOOK_URL)}" + if [ -z "$SLACK_WEBHOOK_URL" ]; then + SLACK_WEBHOOK_URL="" + _err "You didn't specify a Slack webhook url SLACK_WEBHOOK_URL yet." + return 1 + fi + _saveaccountconf_mutable SLACK_WEBHOOK_URL "$SLACK_WEBHOOK_URL" + + SLACK_CHANNEL="${SLACK_CHANNEL:-$(_readaccountconf_mutable SLACK_CHANNEL)}" + if [ -n "$SLACK_CHANNEL" ]; then + _saveaccountconf_mutable SLACK_CHANNEL "$SLACK_CHANNEL" + fi + + SLACK_USERNAME="${SLACK_USERNAME:-$(_readaccountconf_mutable SLACK_USERNAME)}" + if [ -n "$SLACK_USERNAME" ]; then + _saveaccountconf_mutable SLACK_USERNAME "$SLACK_USERNAME" + fi + + export _H1="Content-Type: application/json" + + _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" + _data="{\"text\": \"$_content\", " + if [ -n "$SLACK_CHANNEL" ]; then + _data="$_data\"channel\": \"$SLACK_CHANNEL\", " + fi + if [ -n "$SLACK_USERNAME" ]; then + _data="$_data\"username\": \"$SLACK_USERNAME\", " + fi + _data="$_data\"mrkdwn\": \"true\"}" + + if _post "$_data" "$SLACK_WEBHOOK_URL"; then + # shellcheck disable=SC2154 + if [ "$response" = "ok" ]; then + _info "wa send success." + return 0 + fi + fi + _err "wa send error." + _err "$response" + return 1 +} From d440b2f2b2eca447cac33a893cdc59cbeee650a3 Mon Sep 17 00:00:00 2001 From: Sandeep Mittal Date: Fri, 6 May 2022 02:42:52 +0530 Subject: [PATCH 63/91] Update callmebotWhatsApp.sh Added CallMeBot API for WhatsApp Notifications. --- notify/callmebotWhatsApp.sh | 67 ++++++++++++++----------------------- 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/notify/callmebotWhatsApp.sh b/notify/callmebotWhatsApp.sh index a65149ef..e8f5b659 100644 --- a/notify/callmebotWhatsApp.sh +++ b/notify/callmebotWhatsApp.sh @@ -1,59 +1,44 @@ -#!/usr/bin/env sh +#!/usr/bin/bash #Support CallMeBot Whatsapp webhooks #CallMeBot_Phone_No="" #CallMeBot_apikey="" -#SLACK_USERNAME="" -#SLACK_WEBHOOK_URL="" -#SLACK_CHANNEL="" -#SLACK_USERNAME="" - -slack_send() { +callmebotWhatsApp_send() { _subject="$1" _content="$2" _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped _debug "_statusCode" "$_statusCode" - SLACK_WEBHOOK_URL="${SLACK_WEBHOOK_URL:-$(_readaccountconf_mutable SLACK_WEBHOOK_URL)}" - if [ -z "$SLACK_WEBHOOK_URL" ]; then - SLACK_WEBHOOK_URL="" - _err "You didn't specify a Slack webhook url SLACK_WEBHOOK_URL yet." + CallMeBot_Phone_No="${CallMeBot_Phone_No:-$(_readaccountconf_mutable CallMeBot_Phone_No)}" + if [ -z "$CallMeBot_Phone_No" ]; then + CallMeBot_Phone_No="" + _err "You didn't specify a Slack webhook url CallMeBot_Phone_No yet." return 1 fi - _saveaccountconf_mutable SLACK_WEBHOOK_URL "$SLACK_WEBHOOK_URL" - - SLACK_CHANNEL="${SLACK_CHANNEL:-$(_readaccountconf_mutable SLACK_CHANNEL)}" - if [ -n "$SLACK_CHANNEL" ]; then - _saveaccountconf_mutable SLACK_CHANNEL "$SLACK_CHANNEL" - fi - - SLACK_USERNAME="${SLACK_USERNAME:-$(_readaccountconf_mutable SLACK_USERNAME)}" - if [ -n "$SLACK_USERNAME" ]; then - _saveaccountconf_mutable SLACK_USERNAME "$SLACK_USERNAME" - fi - - export _H1="Content-Type: application/json" + _saveaccountconf_mutable CallMeBot_Phone_No "$CallMeBot_Phone_No" - _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" - _data="{\"text\": \"$_content\", " - if [ -n "$SLACK_CHANNEL" ]; then - _data="$_data\"channel\": \"$SLACK_CHANNEL\", " + CallMeBot_apikey="${CallMeBot_apikey:-$(_readaccountconf_mutable CallMeBot_apikey)}" + if [ -n "$CallMeBot_apikey" ]; then + _saveaccountconf_mutable CallMeBot_apikey "$CallMeBot_apikey" fi - if [ -n "$SLACK_USERNAME" ]; then - _data="$_data\"username\": \"$SLACK_USERNAME\", " - fi - _data="$_data\"mrkdwn\": \"true\"}" - - if _post "$_data" "$SLACK_WEBHOOK_URL"; then - # shellcheck disable=SC2154 - if [ "$response" = "ok" ]; then - _info "wa send success." - return 0 - fi + + _waUrl="https://api.callmebot.com/whatsapp.php" + + _Phone_No="$(printf "%s" "$CallMeBot_Phone_No" | _url_encode)" + _apikey="$(printf "%s" "$CallMeBot_apikey" | _url_encode)" + _message="$(printf "$CQHTTP_CUSTOM_MSGHEAD *%s*\\n%s" "$_subject" "$_content" | _url_encode)" + + _finalUrl="$_waUrl?phone=$_Phone_No&apikey=$_apikey&text=$_message" + response="$(_get "$_finalUrl")" + + if [ "$?" = "0" ] && _contains ".

Message queued. You will receive it in a few seconds."; then + _info "wa send success." + return 0 fi _err "wa send error." - _err "$response" + _debug "URL" "$_finalUrl" + _debug "Response" "$response" return 1 -} +} \ No newline at end of file From 4381657c5e5fa8a3967c82029ae00f0701076ff4 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 7 May 2022 09:40:42 +0800 Subject: [PATCH 64/91] Update callmebotWhatsApp.sh --- notify/callmebotWhatsApp.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/notify/callmebotWhatsApp.sh b/notify/callmebotWhatsApp.sh index e8f5b659..e60eff8c 100644 --- a/notify/callmebotWhatsApp.sh +++ b/notify/callmebotWhatsApp.sh @@ -23,13 +23,13 @@ callmebotWhatsApp_send() { if [ -n "$CallMeBot_apikey" ]; then _saveaccountconf_mutable CallMeBot_apikey "$CallMeBot_apikey" fi - + _waUrl="https://api.callmebot.com/whatsapp.php" - + _Phone_No="$(printf "%s" "$CallMeBot_Phone_No" | _url_encode)" _apikey="$(printf "%s" "$CallMeBot_apikey" | _url_encode)" _message="$(printf "$CQHTTP_CUSTOM_MSGHEAD *%s*\\n%s" "$_subject" "$_content" | _url_encode)" - + _finalUrl="$_waUrl?phone=$_Phone_No&apikey=$_apikey&text=$_message" response="$(_get "$_finalUrl")" @@ -41,4 +41,4 @@ callmebotWhatsApp_send() { _debug "URL" "$_finalUrl" _debug "Response" "$response" return 1 -} \ No newline at end of file +} From b5a7f46ecc6f90e89adb02a095b1ca9ff344dcf6 Mon Sep 17 00:00:00 2001 From: Sandeep Mittal <67865536+sm622@users.noreply.github.com> Date: Sat, 7 May 2022 19:52:33 +0530 Subject: [PATCH 65/91] Update callmebotWhatsApp.sh variable updated to caps --- notify/callmebotWhatsApp.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/notify/callmebotWhatsApp.sh b/notify/callmebotWhatsApp.sh index e60eff8c..e5a2e97c 100644 --- a/notify/callmebotWhatsApp.sh +++ b/notify/callmebotWhatsApp.sh @@ -2,8 +2,8 @@ #Support CallMeBot Whatsapp webhooks -#CallMeBot_Phone_No="" -#CallMeBot_apikey="" +#CALLMEBOT_YOUR_PHONE_NO="" +#CALLMEBOT_API_KEY="" callmebotWhatsApp_send() { _subject="$1" @@ -11,23 +11,23 @@ callmebotWhatsApp_send() { _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped _debug "_statusCode" "$_statusCode" - CallMeBot_Phone_No="${CallMeBot_Phone_No:-$(_readaccountconf_mutable CallMeBot_Phone_No)}" - if [ -z "$CallMeBot_Phone_No" ]; then - CallMeBot_Phone_No="" - _err "You didn't specify a Slack webhook url CallMeBot_Phone_No yet." + CALLMEBOT_YOUR_PHONE_NO="${CALLMEBOT_YOUR_PHONE_NO:-$(_readaccountconf_mutable CALLMEBOT_YOUR_PHONE_NO)}" + if [ -z "$CALLMEBOT_YOUR_PHONE_NO" ]; then + CALLMEBOT_YOUR_PHONE_NO="" + _err "You didn't specify a Slack webhook url CALLMEBOT_YOUR_PHONE_NO yet." return 1 fi - _saveaccountconf_mutable CallMeBot_Phone_No "$CallMeBot_Phone_No" + _saveaccountconf_mutable CALLMEBOT_YOUR_PHONE_NO "$CALLMEBOT_YOUR_PHONE_NO" - CallMeBot_apikey="${CallMeBot_apikey:-$(_readaccountconf_mutable CallMeBot_apikey)}" - if [ -n "$CallMeBot_apikey" ]; then - _saveaccountconf_mutable CallMeBot_apikey "$CallMeBot_apikey" + CALLMEBOT_API_KEY="${CALLMEBOT_API_KEY:-$(_readaccountconf_mutable CALLMEBOT_API_KEY)}" + if [ -n "$CALLMEBOT_API_KEY" ]; then + _saveaccountconf_mutable CALLMEBOT_API_KEY "$CALLMEBOT_API_KEY" fi _waUrl="https://api.callmebot.com/whatsapp.php" - _Phone_No="$(printf "%s" "$CallMeBot_Phone_No" | _url_encode)" - _apikey="$(printf "%s" "$CallMeBot_apikey" | _url_encode)" + _Phone_No="$(printf "%s" "$CALLMEBOT_YOUR_PHONE_NO" | _url_encode)" + _apikey="$(printf "%s" "$CALLMEBOT_API_KEY" | _url_encode)" _message="$(printf "$CQHTTP_CUSTOM_MSGHEAD *%s*\\n%s" "$_subject" "$_content" | _url_encode)" _finalUrl="$_waUrl?phone=$_Phone_No&apikey=$_apikey&text=$_message" From 5a36b9075fde180d824dc89ad5bdcafe62b68cd4 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 9 May 2022 10:40:36 +0800 Subject: [PATCH 66/91] Update callmebotWhatsApp.sh --- notify/callmebotWhatsApp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/callmebotWhatsApp.sh b/notify/callmebotWhatsApp.sh index e5a2e97c..389932db 100644 --- a/notify/callmebotWhatsApp.sh +++ b/notify/callmebotWhatsApp.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env sh #Support CallMeBot Whatsapp webhooks From 915ced7b9273e0ef6024f9a1a9191b8d312ca84d Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 9 May 2022 10:43:23 +0800 Subject: [PATCH 67/91] Update callmebotWhatsApp.sh --- notify/callmebotWhatsApp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/callmebotWhatsApp.sh b/notify/callmebotWhatsApp.sh index 389932db..60835161 100644 --- a/notify/callmebotWhatsApp.sh +++ b/notify/callmebotWhatsApp.sh @@ -20,7 +20,7 @@ callmebotWhatsApp_send() { _saveaccountconf_mutable CALLMEBOT_YOUR_PHONE_NO "$CALLMEBOT_YOUR_PHONE_NO" CALLMEBOT_API_KEY="${CALLMEBOT_API_KEY:-$(_readaccountconf_mutable CALLMEBOT_API_KEY)}" - if [ -n "$CALLMEBOT_API_KEY" ]; then + if [ "$CALLMEBOT_API_KEY" ]; then _saveaccountconf_mutable CALLMEBOT_API_KEY "$CALLMEBOT_API_KEY" fi From 9aaae24583e5d9fc82a5ef052c06b9e8b821f30b Mon Sep 17 00:00:00 2001 From: Sandeep Mittal <67865536+sm622@users.noreply.github.com> Date: Mon, 9 May 2022 16:33:26 +0530 Subject: [PATCH 68/91] Update callmebotWhatsApp.sh unused variable removed and cleaned. --- notify/callmebotWhatsApp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/callmebotWhatsApp.sh b/notify/callmebotWhatsApp.sh index 60835161..1c15b283 100644 --- a/notify/callmebotWhatsApp.sh +++ b/notify/callmebotWhatsApp.sh @@ -28,7 +28,7 @@ callmebotWhatsApp_send() { _Phone_No="$(printf "%s" "$CALLMEBOT_YOUR_PHONE_NO" | _url_encode)" _apikey="$(printf "%s" "$CALLMEBOT_API_KEY" | _url_encode)" - _message="$(printf "$CQHTTP_CUSTOM_MSGHEAD *%s*\\n%s" "$_subject" "$_content" | _url_encode)" + _message="$(printf "*%s*\\n%s" "$_subject" "$_content" | _url_encode)" _finalUrl="$_waUrl?phone=$_Phone_No&apikey=$_apikey&text=$_message" response="$(_get "$_finalUrl")" From f16e060e871c407d8963b3d5be233b967579b0f0 Mon Sep 17 00:00:00 2001 From: denkristoffer Date: Mon, 9 May 2022 21:59:27 +0200 Subject: [PATCH 69/91] Create dns_vercel.sh --- dnsapi/dns_vercel.sh | 142 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 dnsapi/dns_vercel.sh diff --git a/dnsapi/dns_vercel.sh b/dnsapi/dns_vercel.sh new file mode 100644 index 00000000..7bf6b0e5 --- /dev/null +++ b/dnsapi/dns_vercel.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env sh + +# Vercel DNS API +# +# This is your API token which can be acquired on the account page. +# https://vercel.com/account/tokens +# +# VERCEL_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje" + +VERCEL_API="https://api.vercel.com" + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_vercel_add() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + VERCEL_TOKEN="${VERCEL_TOKEN:-$(_readaccountconf_mutable VERCEL_TOKEN)}" + + if [ -z "$VERCEL_TOKEN" ]; then + VERCEL_TOKEN="" + _err "You have not set the Vercel API token yet." + _err "Please visit https://vercel.com/account/tokens to generate it." + return 1 + fi + + _saveaccountconf_mutable VERCEL_TOKEN "$VERCEL_TOKEN" + + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Adding record" + if _vercel_rest POST "v2/domains/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\"}"; then + if printf -- "%s" "$response" | grep "\"uid\":\"" >/dev/null; then + _info "Added" + return 0 + else + _err "Unexpected response while adding text record." + return 1 + fi + fi + _err "Add txt record error." +} + +dns_vercel_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _vercel_rest GET "v2/domains/$_domain/records" + + count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\"" | wc -l | tr -d " ") + + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + _record_id=$(printf "%s" "$response" | _egrep_o "\"id\":[^,]*,\"slug\":\"[^,]*\",\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\",\"value\":\"$txtvalue\"" | cut -d: -f2 | cut -d, -f1 | tr -d '"') + + if [ "$_record_id" ]; then + echo "$_record_id" | while read -r item; do + if _vercel_rest DELETE "v2/domains/$_domain/records/$item"; then + _info "removed record" "$item" + return 0 + else + _err "failed to remove record" "$item" + return 1 + fi + done + fi + fi +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain="$1" + ep="$2" + i=1 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _vercel_rest GET "v4/domains/$h"; then + return 1 + fi + + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_vercel_rest() { + m="$1" + ep="$2" + data="$3" + + path="$VERCEL_API/$ep" + + export _H1="Content-Type: application/json" + export _H2="Authorization: Bearer $VERCEL_TOKEN" + + if [ "$m" != "GET" ]; then + _secure_debug2 data "$data" + response="$(_post "$data" "$path" "" "$m")" + else + response="$(_get "$path")" + fi + _ret="$?" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + _debug "http response code $_code" + _secure_debug2 response "$response" + if [ "$_ret" != "0" ]; then + _err "error $ep" + return 1 + fi + + response="$(printf "%s" "$response" | _normalizeJson)" + return 0 +} From b376dfa1e65b2614848974648f74566ab77242cb Mon Sep 17 00:00:00 2001 From: Clark Boylan Date: Tue, 10 May 2022 10:42:19 -0700 Subject: [PATCH 70/91] Fix Le_Keylength checks during renewals When performing renewals acme.sh checks key length values to determine if a new key should be created with createDomainKey(). However, older acme.sh stored key length as an empty value if the default of 2048 was desired. Now it is explicit and the explict check of 2048 against "" is causing createDomainKey() to always be called with fails without --force. Fix this by converting the keylength value to 2048 if an empty string is returned from the config file. acme.sh will then write out 2048 updating old keys and configs to the explicit version. Issue: 4077 --- acme.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index cd545aa4..260733a2 100755 --- a/acme.sh +++ b/acme.sh @@ -4406,7 +4406,13 @@ issue() { if [ -f "$CSR_PATH" ] && [ ! -f "$CERT_KEY_PATH" ]; then _info "Signing from existing CSR." else + # When renewing from an old version, the empty Le_Keylength means 2048. + # Note, do not use DEFAULT_DOMAIN_KEY_LENGTH as that value may change over + # time but an empty value implies 2048 specifically. _key=$(_readdomainconf Le_Keylength) + if [ -z "$_key" ]; then + _key=2048 + fi _debug "Read key length:$_key" if [ ! -f "$CERT_KEY_PATH" ] || [ "$_key_length" != "$_key" ] || [ "$Le_ForceNewDomainKey" = "1" ]; then if ! createDomainKey "$_main_domain" "$_key_length"; then @@ -5319,7 +5325,10 @@ renew() { Le_PostHook="$(_readdomainconf Le_PostHook)" Le_RenewHook="$(_readdomainconf Le_RenewHook)" Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)" - #when renew from an old version, the empty Le_Keylength means 2048 + # When renewing from an old version, the empty Le_Keylength means 2048. + # Note, do not use DEFAULT_DOMAIN_KEY_LENGTH as that value may change over + # time but an empty value implies 2048 specifically. + Le_Keylength="$(_readdomainconf Le_Keylength)" if [ -z "$Le_Keylength" ]; then Le_Keylength=2048 fi From bee5cb55a133905c49794a4962fdb1b16b9c92f9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 11 May 2022 10:20:35 +0800 Subject: [PATCH 71/91] fix test --- .github/workflows/Linux.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 63e3136c..c665652a 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -25,6 +25,7 @@ jobs: env: TEST_LOCAL: 1 TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_ACME_Server: "LetsEncrypt.org_test" steps: - uses: actions/checkout@v2 - name: Clone acmetest From 2280e66d7366d51a937ebaf2fe126c759c721395 Mon Sep 17 00:00:00 2001 From: Manuel Sanchez Pinar Date: Thu, 12 May 2022 10:51:15 +0200 Subject: [PATCH 72/91] dns_aws: Fix when _acme-challenge is a hostedzone The function '_get_root' tries to retrieve the hostedzone iterating the domains, eg: 1. srv.prod.example.com 2. prod.example.com 3. example.com This doesn't work if '_acme-challenge' is in it's own hostedzone for security reasons. Starting that iteration with '_acme-challenge.srv.prod.example.com' fixes this issue. --- dnsapi/dns_aws.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 14a4594d..78008f5b 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -151,8 +151,8 @@ dns_aws_rm() { #################### Private functions below ################################## _get_root() { - domain=$1 - i=2 + domain=_acme-challenge.$1 + i=1 p=1 if aws_rest GET "2013-04-01/hostedzone"; then From 873b113cb3625746b3010bcdf47d86d03f78f009 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 12 May 2022 17:36:19 +0800 Subject: [PATCH 73/91] Update dns_aws.sh --- dnsapi/dns_aws.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 78008f5b..376936f5 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -151,7 +151,7 @@ dns_aws_rm() { #################### Private functions below ################################## _get_root() { - domain=_acme-challenge.$1 + domain=$1 i=1 p=1 From 6d5743c506b13edc35cb0b2b2bee35b1d3b783e0 Mon Sep 17 00:00:00 2001 From: Paul Lettington Date: Thu, 12 May 2022 18:57:32 +0100 Subject: [PATCH 74/91] Squash new lines in API response --- dnsapi/dns_aws.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 14a4594d..37ac5156 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -179,7 +179,7 @@ _get_root() { fi if _contains "$response" "$h."; then - hostedzone="$(echo "$response" | sed 's//#&/g' | tr '#' '\n' | _egrep_o "[^<]*<.Id>$h.<.Name>.*false<.PrivateZone>.*<.HostedZone>")" + hostedzone="$(echo "$response" | tr -d '\n' | sed 's//#&/g' | tr '#' '\n' | _egrep_o "[^<]*<.Id>$h.<.Name>.*false<.PrivateZone>.*<.HostedZone>")" _debug hostedzone "$hostedzone" if [ "$hostedzone" ]; then _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o ".*<.Id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>") From 5ba2068fc22c0ec816e4f1ed09ba507c27f9455b Mon Sep 17 00:00:00 2001 From: Sebastiaan Hoogeveen Date: Mon, 16 May 2022 14:27:24 +0200 Subject: [PATCH 75/91] Fix dns_nederhost to work correctly with wget instead of curl. The dns_nederhost DNS API relies on the exact HTTP status code to be returned (e.g. 204); however, the _get function always returns 200 for a succesful call when using wget instead of curl. This patch fixes this by using the _post function for all requests done by dns_nederhost. --- dnsapi/dns_nederhost.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_nederhost.sh b/dnsapi/dns_nederhost.sh index 0954ab65..61839cc7 100755 --- a/dnsapi/dns_nederhost.sh +++ b/dnsapi/dns_nederhost.sh @@ -112,12 +112,8 @@ _nederhost_rest() { export _H1="Authorization: Bearer $NederHost_Key" export _H2="Content-Type: application/json" - if [ "$m" != "GET" ]; then - _debug data "$data" - response="$(_post "$data" "$NederHost_Api/$ep" "" "$m")" - else - response="$(_get "$NederHost_Api/$ep")" - fi + _debug data "$data" + response="$(_post "$data" "$NederHost_Api/$ep" "" "$m")" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" _debug "http response code $_code" From 4047adcc35eb66abbddff5a2ea8efa0b27ceb95b Mon Sep 17 00:00:00 2001 From: Sebastiaan Hoogeveen Date: Wed, 18 May 2022 16:12:37 +0200 Subject: [PATCH 76/91] Force a commit. --- dnsapi/dns_nederhost.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nederhost.sh b/dnsapi/dns_nederhost.sh index 61839cc7..abaae42b 100755 --- a/dnsapi/dns_nederhost.sh +++ b/dnsapi/dns_nederhost.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -#NederHost_Key="sdfgikogfdfghjklkjhgfcdcfghjk" +#NederHost_Key="sdfgikogfdfghjklkjhgfcdcfghj" NederHost_Api="https://api.nederhost.nl/dns/v1" From 32adc38e94fa4a699801e289d19fa6d36199af3b Mon Sep 17 00:00:00 2001 From: Avi Miller Date: Sat, 21 May 2022 14:36:10 +1000 Subject: [PATCH 77/91] Fix _dbase64 decode of OCI_CLI_KEY The change made in #4057 broke the decoding of OCI_CLI_KEY from the encoded OCI_CLI_KEY_FILE content so this removes the multiline parameter to fix it. Signed-off-by: Avi Miller --- dnsapi/dns_oci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index eb006120..18d74410 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -159,7 +159,7 @@ _oci_config() { fi if [ "$(printf "%s\n" "$OCI_CLI_KEY" | wc -l)" -eq 1 ]; then - OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64 multiline) + OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64) fi return 0 From 58a89edad7e88886dd980f5b91f9144111e89c9b Mon Sep 17 00:00:00 2001 From: Lukas Brocke Date: Sun, 22 May 2022 13:24:18 +0200 Subject: [PATCH 78/91] dnsapi/ionos: Update to API version 1.0.1 The REST API now sends back response bodies for UPDATE and CREATE operations. --- dnsapi/dns_ionos.sh | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index c2c431bb..e4ad3318 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Supports IONOS DNS API Beta v1.0.0 +# Supports IONOS DNS API v1.0.1 # # Usage: # Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh: @@ -26,7 +26,7 @@ dns_ionos_add() { _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" - if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ -z "$response" ]; then + if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then _info "TXT record has been created successfully." return 0 fi @@ -47,7 +47,7 @@ dns_ionos_rm() { return 1 fi - if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ -z "$response" ]; then + if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then _info "TXT record has been deleted successfully." return 0 fi @@ -85,7 +85,7 @@ _get_root() { p=1 if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then - response="$(echo "$response" | tr -d "\n")" + _response="$(echo "$_response" | tr -d "\n")" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -93,7 +93,7 @@ _get_root() { return 1 fi - _zone="$(echo "$response" | _egrep_o "\"name\":\"$h\".*\}")" + _zone="$(echo "$_response" | _egrep_o "\"name\":\"$h\".*\}")" if [ "$_zone" ]; then _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') if [ "$_zone_id" ]; then @@ -120,9 +120,9 @@ _ionos_get_record() { txtrecord=$3 if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then - response="$(echo "$response" | tr -d "\n")" + _response="$(echo "$_response" | tr -d "\n")" - _record="$(echo "$response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")" + _record="$(echo "$_response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")" if [ "$_record" ]; then _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') @@ -142,22 +142,30 @@ _ionos_rest() { export _H1="X-API-Key: $IONOS_API_KEY" + # clear headers + : >"$HTTP_HEADER" + if [ "$method" != "GET" ]; then export _H2="Accept: application/json" export _H3="Content-Type: application/json" - response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")" + _response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")" else export _H2="Accept: */*" export _H3= - response="$(_get "$IONOS_API$route")" + + _response="$(_get "$IONOS_API$route")" fi + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + if [ "$?" != "0" ]; then - _err "Error $route: $response" + _err "Error $route: $_response" return 1 fi - _debug2 "response" "$response" + + _debug2 "_response" "$_response" + _debug2 "_code" "$_code" return 0 } From 606e59a5d0a6b3fc1963aeae2b23898cb2715a8f Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 29 May 2022 14:56:30 +0800 Subject: [PATCH 79/91] fix https://github.com/acmesh-official/acme.sh/issues/4110 fix https://github.com/acmesh-official/acme.sh/issues/4110 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 94252d81..bfe501fe 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -120,7 +120,7 @@ _get_root() { return 1 fi - if _contains "$response" "\"name\": \"$h\","; then + if _contains "$response" "\"name\": *\"$h\","; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h _debug "Getting domain id for $h" From 3ce67b282fafd42a1807f556a742fb5b23a60f21 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 29 May 2022 15:03:09 +0800 Subject: [PATCH 80/91] merge https://github.com/acmesh-official/acme.sh/pull/4108 merge https://github.com/acmesh-official/acme.sh/pull/4108 --- dnsapi/dns_selectel.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index bfe501fe..1b09882d 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -76,7 +76,7 @@ dns_selectel_rm() { return 1 fi - _record_seg="$(echo "$response" | _egrep_o "\"content\" *: *\"$txtvalue\"[^}]*}")" + _record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")" _debug2 "_record_seg" "$_record_seg" if [ -z "$_record_seg" ]; then _err "can not find _record_seg" @@ -120,7 +120,7 @@ _get_root() { return 1 fi - if _contains "$response" "\"name\": *\"$h\","; then + if _contains "$response" "\"name\" *: *\"$h\","; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h _debug "Getting domain id for $h" From 993c187e375477f7ac6cc18a3cbdcb43e732c6b0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 29 May 2022 15:08:15 +0800 Subject: [PATCH 81/91] fix https://github.com/acmesh-official/acme.sh/issues/4105 fix https://github.com/acmesh-official/acme.sh/issues/4105 --- dnsapi/dns_edgedns.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 2e5c7d30..11c132fa 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -176,6 +176,7 @@ _EDGEDNS_credentials() { _debug "GettingEdge DNS credentials" _log "$(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION})" args_missing=0 + AKAMAI_ACCESS_TOKEN="${AKAMAI_ACCESS_TOKEN:-$(_readaccountconf_mutable AKAMAI_ACCESS_TOKEN)}" if [ -z "$AKAMAI_ACCESS_TOKEN" ]; then AKAMAI_ACCESS_TOKEN="" AKAMAI_CLIENT_TOKEN="" @@ -184,6 +185,7 @@ _EDGEDNS_credentials() { _err "AKAMAI_ACCESS_TOKEN is missing" args_missing=1 fi + AKAMAI_CLIENT_TOKEN="${AKAMAI_CLIENT_TOKEN:-$(_readaccountconf_mutable AKAMAI_CLIENT_TOKEN)}" if [ -z "$AKAMAI_CLIENT_TOKEN" ]; then AKAMAI_ACCESS_TOKEN="" AKAMAI_CLIENT_TOKEN="" @@ -192,6 +194,7 @@ _EDGEDNS_credentials() { _err "AKAMAI_CLIENT_TOKEN is missing" args_missing=1 fi + AKAMAI_HOST="${AKAMAI_HOST:-$(_readaccountconf_mutable AKAMAI_HOST)}" if [ -z "$AKAMAI_HOST" ]; then AKAMAI_ACCESS_TOKEN="" AKAMAI_CLIENT_TOKEN="" @@ -200,6 +203,7 @@ _EDGEDNS_credentials() { _err "AKAMAI_HOST is missing" args_missing=1 fi + AKAMAI_CLIENT_SECRET="${AKAMAI_CLIENT_SECRET:-$(_readaccountconf_mutable AKAMAI_CLIENT_SECRET)}" if [ -z "$AKAMAI_CLIENT_SECRET" ]; then AKAMAI_ACCESS_TOKEN="" AKAMAI_CLIENT_TOKEN="" From 444a0282d7ac7e2fba871011823c00dd374f215e Mon Sep 17 00:00:00 2001 From: Bob Belnap Date: Tue, 31 May 2022 11:41:22 -0400 Subject: [PATCH 82/91] rename _error _err When there are errors with namecheap hosts, acme.sh fails with: dns_namecheap.sh: line 262: _error: command not found Based on usage elsewhere in the file, I believe this should be _err --- dnsapi/dns_namecheap.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index d15d6b0e..dcd87723 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -259,7 +259,7 @@ _set_namecheap_TXT() { _debug hosts "$hosts" if [ -z "$hosts" ]; then - _error "Hosts not found" + _err "Hosts not found" return 1 fi @@ -313,7 +313,7 @@ _del_namecheap_TXT() { _debug hosts "$hosts" if [ -z "$hosts" ]; then - _error "Hosts not found" + _err "Hosts not found" return 1 fi From 5440fcdf54e3402c6089c79a3e5c5c79758280c3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 1 Jun 2022 18:05:51 +0800 Subject: [PATCH 83/91] check the file path before copying --- acme.sh | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/acme.sh b/acme.sh index 260733a2..bc667359 100755 --- a/acme.sh +++ b/acme.sh @@ -5752,7 +5752,9 @@ _installcert() { if [ -f "$_real_cert" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_cert" "$_backup_path/cert.bak" fi - cat "$CERT_PATH" >"$_real_cert" || return 1 + if [ "$CERT_PATH" != "$_real_cert" ]; then + cat "$CERT_PATH" >"$_real_cert" || return 1 + fi fi if [ "$_real_ca" ]; then @@ -5764,7 +5766,9 @@ _installcert() { if [ -f "$_real_ca" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_ca" "$_backup_path/ca.bak" fi - cat "$CA_CERT_PATH" >"$_real_ca" || return 1 + if [ "$CA_CERT_PATH" != "$_real_ca" ]; then + cat "$CA_CERT_PATH" >"$_real_ca" || return 1 + fi fi fi @@ -5773,12 +5777,14 @@ _installcert() { if [ -f "$_real_key" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_key" "$_backup_path/key.bak" fi - if [ -f "$_real_key" ]; then - cat "$CERT_KEY_PATH" >"$_real_key" || return 1 - else - touch "$_real_key" || return 1 - chmod 600 "$_real_key" - cat "$CERT_KEY_PATH" >"$_real_key" || return 1 + if [ "$CERT_KEY_PATH" != "$_real_key" ]; then + if [ -f "$_real_key" ]; then + cat "$CERT_KEY_PATH" >"$_real_key" || return 1 + else + touch "$_real_key" || return 1 + chmod 600 "$_real_key" + cat "$CERT_KEY_PATH" >"$_real_key" || return 1 + fi fi fi @@ -5787,7 +5793,9 @@ _installcert() { if [ -f "$_real_fullchain" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_fullchain" "$_backup_path/fullchain.bak" fi - cat "$CERT_FULLCHAIN_PATH" >"$_real_fullchain" || return 1 + if [ "$_real_fullchain" != "$CERT_FULLCHAIN_PATH" ]; then + cat "$CERT_FULLCHAIN_PATH" >"$_real_fullchain" || return 1 + fi fi if [ "$_reload_cmd" ]; then From 8a144ebfee0b0ffba5a7712cb97086ae1da79fde Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 1 Jun 2022 18:06:14 +0800 Subject: [PATCH 84/91] fix https://github.com/acmesh-official/acme.sh/issues/4117 --- dnsapi/dns_cyon.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cyon.sh b/dnsapi/dns_cyon.sh index 2c08812b..830e8831 100644 --- a/dnsapi/dns_cyon.sh +++ b/dnsapi/dns_cyon.sh @@ -44,7 +44,7 @@ dns_cyon_rm() { _cyon_load_credentials() { # Convert loaded password to/from base64 as needed. if [ "${CY_Password_B64}" ]; then - CY_Password="$(printf "%s" "${CY_Password_B64}" | _dbase64 "multiline")" + CY_Password="$(printf "%s" "${CY_Password_B64}" | _dbase64)" elif [ "${CY_Password}" ]; then CY_Password_B64="$(printf "%s" "${CY_Password}" | _base64)" fi From c2b14d307587f46cf305a8c73cebb8315673b2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reto=20Sch=C3=BCttel?= Date: Wed, 1 Jun 2022 16:51:01 +0200 Subject: [PATCH 85/91] dns_gcloud: disable argument parsing for challenges fixes #3596 --- dnsapi/dns_gcloud.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index d560996c..bda5cbd7 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -98,7 +98,7 @@ _dns_gcloud_remove_rrs() { --ttl="$ttl" \ --type=TXT \ --zone="$managedZone" \ - --transaction-file="$tr"; then + --transaction-file="$tr" --; then _debug tr "$(cat "$tr")" rm -r "$trd" _err "_dns_gcloud_remove_rrs: failed to remove RRs" @@ -113,7 +113,7 @@ _dns_gcloud_add_rrs() { --ttl="$ttl" \ --type=TXT \ --zone="$managedZone" \ - --transaction-file="$tr"; then + --transaction-file="$tr" --; then _debug tr "$(cat "$tr")" rm -r "$trd" _err "_dns_gcloud_add_rrs: failed to add RRs" From f426940bd2723647c03d936f6e166c3c51f1c57f Mon Sep 17 00:00:00 2001 From: rm Date: Sat, 4 Jun 2022 20:24:33 +0200 Subject: [PATCH 86/91] check all pages first, the go up --- dnsapi/dns_aws.sh | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 376936f5..c5241258 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -155,29 +155,16 @@ _get_root() { i=1 p=1 - if aws_rest GET "2013-04-01/hostedzone"; then - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - _debug2 "Checking domain: $h" - if [ -z "$h" ]; then - if _contains "$response" "true" && _contains "$response" ""; then - _debug "IsTruncated" - _nextMarker="$(echo "$response" | _egrep_o ".*" | cut -d '>' -f 2 | cut -d '<' -f 1)" - _debug "NextMarker" "$_nextMarker" - if aws_rest GET "2013-04-01/hostedzone" "marker=$_nextMarker"; then - _debug "Truncated request OK" - i=2 - p=1 - continue - else - _err "Truncated request error." - fi - fi - #not valid - _err "Invalid domain" - return 1 - fi + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug "Checking domain: $h" + if [ -z "$h" ]; then + _error "invalid domain" + return 1 + fi + aws_rest GET "2013-04-01/hostedzone" + while true; do if _contains "$response" "$h."; then hostedzone="$(echo "$response" | sed 's//#&/g' | tr '#' '\n' | _egrep_o "[^<]*<.Id>$h.<.Name>.*false<.PrivateZone>.*<.HostedZone>")" _debug hostedzone "$hostedzone" @@ -192,10 +179,19 @@ _get_root() { return 1 fi fi - p=$i - i=$(_math "$i" + 1) + if _contains "$response" "true" && _contains "$response" ""; then + _debug "IsTruncated" + _nextMarker="$(echo "$response" | _egrep_o ".*" | cut -d '>' -f 2 | cut -d '<' -f 1)" + _debug "NextMarker" "$_nextMarker" + else + break + fi + _debug "Checking domain: $h - Next Page " + aws_rest GET "2013-04-01/hostedzone" "marker=$_nextMarker" done - fi + p=$i + i=$(_math "$i" + 1) + done return 1 } From e48d7de7636e10f7ab667766a703babd5eb74643 Mon Sep 17 00:00:00 2001 From: rm Date: Sun, 5 Jun 2022 15:46:42 +0200 Subject: [PATCH 87/91] push to run actions --- dnsapi/dns_aws.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index c5241258..1fcdb149 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -155,6 +155,7 @@ _get_root() { i=1 p=1 + # iterate over names (a.b.c.d -> b.c.d -> c.d -> d) while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug "Checking domain: $h" @@ -163,6 +164,7 @@ _get_root() { return 1 fi + # iterate over paginated result for list_hosted_zones aws_rest GET "2013-04-01/hostedzone" while true; do if _contains "$response" "$h."; then From b5f49d9563e3daab9fdc24af3e2e27edcc42d956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Capil=C3=A9?= Date: Mon, 6 Jun 2022 19:57:35 -0300 Subject: [PATCH 88/91] fixed compatibility for UltraDNS API v3: https://docs.ultradns.neustar/Content/REST%20API/Content/REST%20API/Zone%20API/Zone%20API.htm; also a minor bugfix for fecthing the domain_id using egrep --- dnsapi/dns_ultra.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_ultra.sh b/dnsapi/dns_ultra.sh index 0100b3b7..9337ad4a 100644 --- a/dnsapi/dns_ultra.sh +++ b/dnsapi/dns_ultra.sh @@ -5,7 +5,8 @@ # # ULTRA_PWD="some_password_goes_here" -ULTRA_API="https://restapi.ultradns.com/v2/" +ULTRA_API="https://api.ultradns.com/v3/" +ULTRA_AUTH_API="https://api.ultradns.com/v2/" #Usage: add _acme-challenge.www.domain.com "some_long_string_of_characters_go_here_from_lets_encrypt" dns_ultra_add() { @@ -121,7 +122,7 @@ _get_root() { return 1 fi if _contains "${response}" "${h}." >/dev/null; then - _domain_id=$(echo "$response" | _egrep_o "${h}") + _domain_id=$(echo "$response" | _egrep_o "${h}" | head -1) if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="${h}" @@ -142,23 +143,25 @@ _ultra_rest() { ep="$2" data="$3" _debug "$ep" + if [ -z "$AUTH_TOKEN" ]; then + _ultra_login + fi _debug TOKEN "${AUTH_TOKEN}" - _ultra_login export _H1="Content-Type: application/json" export _H2="Authorization: Bearer ${AUTH_TOKEN}" if [ "$m" != "GET" ]; then _debug data "${data}" - response="$(_post "${data}" "${ULTRA_API}"/"${ep}" "" "${m}")" + response="$(_post "${data}" "${ULTRA_API}${ep}" "" "${m}")" else - response="$(_get "$ULTRA_API/$ep")" + response="$(_get "$ULTRA_API$ep")" fi } _ultra_login() { export _H1="" export _H2="" - AUTH_TOKEN=$(_post "grant_type=password&username=${ULTRA_USR}&password=${ULTRA_PWD}" "${ULTRA_API}authorization/token" | cut -d, -f3 | cut -d\" -f4) + AUTH_TOKEN=$(_post "grant_type=password&username=${ULTRA_USR}&password=${ULTRA_PWD}" "${ULTRA_AUTH_API}authorization/token" | cut -d, -f3 | cut -d\" -f4) export AUTH_TOKEN } From 4f816c06b01950559916eb0ad2f7205749c8729f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Capil=C3=A9?= Date: Tue, 7 Jun 2022 11:59:34 -0300 Subject: [PATCH 89/91] variable expansion consistency & actions push --- dnsapi/dns_ultra.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_ultra.sh b/dnsapi/dns_ultra.sh index 9337ad4a..0f26bd97 100644 --- a/dnsapi/dns_ultra.sh +++ b/dnsapi/dns_ultra.sh @@ -146,14 +146,14 @@ _ultra_rest() { if [ -z "$AUTH_TOKEN" ]; then _ultra_login fi - _debug TOKEN "${AUTH_TOKEN}" + _debug TOKEN "$AUTH_TOKEN" export _H1="Content-Type: application/json" - export _H2="Authorization: Bearer ${AUTH_TOKEN}" + export _H2="Authorization: Bearer $AUTH_TOKEN" if [ "$m" != "GET" ]; then - _debug data "${data}" - response="$(_post "${data}" "${ULTRA_API}${ep}" "" "${m}")" + _debug data "$data" + response="$(_post "$data" "$ULTRA_API$ep" "" "$m")" else response="$(_get "$ULTRA_API$ep")" fi From b169a5c707786b50ef9a71a8e1e13e3ee9a20ee3 Mon Sep 17 00:00:00 2001 From: Debian Bear Date: Wed, 8 Jun 2022 22:44:10 +0800 Subject: [PATCH 90/91] change _dbase64 to single line --- deploy/qiniu.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index 70669917..02250ed3 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -53,7 +53,7 @@ qiniu_deploy() { sslcert_access_token="$(_make_access_token "$sslcert_path")" _debug sslcert_access_token "$sslcert_access_token" export _H1="Authorization: QBox $sslcert_access_token" - sslcert_response=$(_post "$sslcerl_body" "$QINIU_API_BASE$sslcert_path" 0 "POST" "application/json" | _dbase64 "multiline") + sslcert_response=$(_post "$sslcerl_body" "$QINIU_API_BASE$sslcert_path" 0 "POST" "application/json" | _dbase64) if ! _contains "$sslcert_response" "certID"; then _err "Error in creating certificate:" @@ -75,7 +75,7 @@ qiniu_deploy() { update_access_token="$(_make_access_token "$update_path")" _debug update_access_token "$update_access_token" export _H1="Authorization: QBox $update_access_token" - update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64 "multiline") + update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64) if _contains "$update_response" "error"; then _err "Error in updating domain $domain httpsconf:" From 6ccf617d62f1d73dc9fa2afbea8ca080be294194 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 21 Jun 2022 10:12:06 +0800 Subject: [PATCH 91/91] clear CF_Zone_ID --- dnsapi/dns_cf.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index c2430086..cd8d9a8d 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -32,7 +32,8 @@ dns_cf_add() { else _saveaccountconf_mutable CF_Token "$CF_Token" _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID" - _saveaccountconf_mutable CF_Zone_ID "$CF_Zone_ID" + _clearaccountconf_mutable CF_Zone_ID + _clearaccountconf CF_Zone_ID fi else if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then @@ -51,6 +52,14 @@ dns_cf_add() { #save the api key and email to the account conf file. _saveaccountconf_mutable CF_Key "$CF_Key" _saveaccountconf_mutable CF_Email "$CF_Email" + + _clearaccountconf_mutable CF_Token + _clearaccountconf_mutable CF_Account_ID + _clearaccountconf_mutable CF_Zone_ID + _clearaccountconf CF_Token + _clearaccountconf CF_Account_ID + _clearaccountconf CF_Zone_ID + fi _debug "First detect the root zone"